Научим кладовщика двигаться при нажатии на кнопки «вверх», «вниз», «влево» и «вправо».
Подключим кнопки к микроконтроллеру. Три кнопки подтянуты к земле, а одна к питанию. Это сделано специально, чтобы обеспечить условия для правильной загрузки микроконтроллера. Микроконтроллер при включении проверяет состояние некоторых выводов и на основании этого принимает решение о режиме работы — выполнение программы или переход в режим перепрошивки. Для нормального режима работы необходимо, чтобы уровень сигнала на выводе 15 был низким, а на 2 и 0 был высоким. Чтобы соблюсти эти условия и пришлось подключить кнопки по-разному.
from machine import Pin, SPI from tft import TFT_GREEN _init() machine.freq(160000000) dc = Pin(4, Pin.OUT) #a0 cs = Pin(2, Pin.OUT) rst = Pin(5, Pin.OUT) spi = SPI(1, baudrate=40000000, polarity=0, phase=0) # TFT object, this is ST7735R green tab version tft = TFT_GREEN(128, 160, spi, dc, cs, rst, rotate=0) Map = [ [1,1,0,1,1,1,0,1], [0,1,1,1,1,1,1,0], [1,1,0,0,0,1,1,1], [0,1,0,1,0,1,0,1], [0,1,0,0,0,1,0,1], [1,1,1,1,0,0,0,1], [1,0,0,0,0,0,0,1], [1,0,0,0,1,0,0,1], [1,0,0,0,1,1,1,1], [1,1,1,1,1,0,0,0] ] Gates = [] Boxes = [] 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() 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) 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() class Button: def __init__(self, p, pressSate): self.pin = Pin(p, Pin.IN) self.pressSate = pressSate self.oldState = not pressSate def onPress(self): state = self.pin.value() if state != self.oldState: self.oldState = state if state == self.pressSate: return True return False # init TFT tft.initr(tft.BGR) # tft.initr(tft.RGB) #Если вместо синего цвета отображается красный, а вместо красного синий tft.clear(tft.COLOR_BLACK) #b, g, r x = 0 y = 0 for row in Map: for col in row: if col: tft.draw_bmp(x * 16, y * 16,'brick.bmp') x+=1 x=0 y+=1 Boxes.append(Box(tft, 3,4)) Boxes.append(Box(tft, 4,6)) Boxes.append(Box(tft, 2,7)) Gates.append(Gate(tft, 6,3)) Gates.append(Gate(tft, 6,4)) Gates.append(Gate(tft, 6,5)) man = Man(tft, 5, 6) btnUp = Button(16, 1) btnDown = Button(15, 1) btnLeft = Button(12, 1) btnRight = Button(0, 0) while True: mPos = man.getPos() if btnUp.onPress(): newPos = (mPos[0], mPos[1]-1) man.setPos(newPos[0], newPos[1]) if btnDown.onPress(): newPos = (mPos[0], mPos[1]+1) man.setPos(newPos[0], newPos[1]) if btnLeft.onPress(): newPos = (mPos[0]-1, mPos[1]) man.setPos(newPos[0], newPos[1]) if btnRight.onPress(): newPos = (mPos[0]+1, mPos[1]) man.setPos(newPos[0], newPos[1])
В код прошлого эксперимента мы добавили класс кнопки, который уже использовали ранее, например в проекте секундомера. Объявили 4 кнопки, на выводах 16, 15, 12 и 0:
btnUp = Button(16, 1) btnDown = Button(15, 1) btnLeft = Button(12, 1) btnRight = Button(0, 0)
Добавили бесконечный цикл, в котором постоянно мониторим события нажатия на кнопки:
while True: mPos = man.getPos() if btnUp.onPress(): newPos = (mPos[0], mPos[1]-1) man.setPos(newPos[0], newPos[1]) if btnDown.onPress(): newPos = (mPos[0], mPos[1]+1) man.setPos(newPos[0], newPos[1]) if btnLeft.onPress(): newPos = (mPos[0]-1, mPos[1]) man.setPos(newPos[0], newPos[1]) if btnRight.onPress(): newPos = (mPos[0]+1, mPos[1]) man.setPos(newPos[0], newPos[1])
При нажатии на кнопку «вверх» уменьшаем координату Y и задаем новую координату кладовщику. Аналогичные действия производим при нажатии на другие кнопки. Теперь наш кладовщик может двигаться по экрану. Но сейчас нет никаких ограничений — он свободно проходит сквозь стены и ящики, никак на них не влияя. Теперь самое время реализовать логику игры, описать условия и взаимодействия. Этим займемся в следующем эксперименте.