Это старая версия документа!


Эксперимент 53. Классы ящиков, человека и цели

В прошлом эксперименте мы подключили TFT дисплей, создали игровую карту в виде двумерного массива и отобразили ее на экране. Теперь давайте поймем какие вообще объекты задействованы в игровом процессе. Как мы уже поняли, это стены, ящики, кладовщик и цели, куда нужно перетащить ящики. Теперь нужно описать каждый из классов.

Класс ящика

Начнем с класса ящика. Главные свойства ящика, это его координаты на карте и его состояние — находится он на цели или нет.

class Box:
    def __init__(self, tft, x, y):
        self.tft = tft
        self.x = x
        self.y = y
        self.picture = 'box.bmp'
        self.picture_onGate = 'boxngate.bmp'
        self.onGate = False
        self.draw()
 
    def draw(self):
        if (self.onGate):
            self.tft.draw_bmp(self.x * 16,self.y * 16,  self.picture_onGate)
        else:
            self.tft.draw_bmp(self.x * 16,self.y * 16, self.picture)
 
    def setOnGate(self, state):
        self.onGate = state
 
    def getOnGate(self):
        return self.onGate
 
    def getPos(self):
        return (self.x, self.y)
 
    def setPos(self, x, y):
        self.x = x
        self.y = y
        self.draw()

В конструктор мы передаем такие параметры как объект дисплея, координата x, координата y. Координата ящика указывается не в пикселях, а в клетках игрового поля. В самом конструкторе мы задаем имя спрайта для ящика на цели self.picture_onGate = 'boxngate.bmp' и вне цели self.picture = 'box.bmp'. Свойство onGate как раз описывает состояние ящика. В конце конструктор вызывает метод отрисовки draw.

Метод draw() предназначена для отрисовки ящика. Если ящик находится на цели, то функция отображает спрайт self.picture_onGate, иначе self.picture. Координата ящика указывается не в пикселях, а в клетках игрового поля, поэтому для отображения картинки ее необходимо пересчитать в пиксели. Для этого координата умножается на размер ящика в пикселях.

Метод setOnGate() служит для установки свойства нахождения на цели. А метод getOnGate() для чтения этого свойства.

Метод getPos возвращает текущие координаты ящика. А метод setPos устанавливает новые координаты ящика, после чего перерисовывает его на новом месте.

Класс цели

Класс цели намного проще. Цель никуда не перемещается и свойтсв не имеет. Цель имеет только координаты и должна отображаться на экране с помощью своего спрайта.

class Gate:
    def __init__(self, tft, x, y):
        self.tft = tft
        self.x = x
        self.y = y
        self.picture = 'gate.bmp'
        self.draw()
 
    def draw(self):
        self.tft.draw_bmp(self.x * 16,self.y * 16, self.picture)
 
    def getPos(self):
        return (self.x, self.y)

Метод daraw служит для отрисовки спрайта цели в заданных координатах. Так как координаты цели задаются не в пикселях, а в клетках поля, необходимо пересчитать их в пиксели для оборажения. Поэтому координаты в клетках умножаются на размер клетки — 16.

Класс кладовщика

Кладовщик также имеет координаты своего нахождения на поле и имеет свой спрайт.

class Man:
    def __init__(self, tft, x, y):
        self.tft = tft
        self.x = x
        self.y = y
        self.picture = 'man.bmp'
        self.draw()
 
    def draw(self):
        self.tft.draw_bmp(self.x * 16,self.y * 16, self.picture)
 
    def getPos(self):
        return (self.x, self.y)
 
    def setPos(self, x, y):
        self.tft.rect(self.x * 16, self.y * 16, 16, 16, tft.COLOR_BLACK)
        self.x = x
        self.y = y
        self.draw()

Конструктор и методы draw() и getPos() аналогичны одноименным методам предыдещих классов, поэтому не будем повторно заострять на них внимание. Небольшая разница есть в методе setPos(). Отличие заключается в том, что при изменении координаты кладовщика на игровом поле, мы не только рисуем его в новом месте, но и стираем в предыдущем. Это делается с помощью рисования черного прямоугольника по старым координатам кладовщика. Если «старого» кладовщика не закрасить, то он никуда не исчезнет, а просто появится еще один в новом месте. Но почему же мы не закрашивали «старые» ящики при смене их координат? Потому что ящик изменяет координаты только когда его толкает кладовщик. И он сам оказывается на старом месте ящика и закрашивает его собой.

Класса стен не будет. Мы будем пользоваться нашим двумерным массивом в котором уже описали план уровня.

Теперь, когда мы имеем лабиринт и классы для ящика, кладовщика и цели, самое время отобразить это все на дисплее.

Схема эксперимента

Схема не изменилась.

Рисунок 1. Монтажная схема эксперимента

Программный код эксперимента