def _showText(self, timercallbackvar=None): text = self.text if len(text) > self.limit: chunk = text[self._iterator:self._iterator + self.limit] if self._delayState < self.delay: self._delayState += 1 else: self._iterator += self._itdir if self.sliding: if self._itdir == 1 and self._iterator >= (len(text) - self.limit): self._itdir *= -1 self._delayState = 0 if self._itdir == -1 and self._iterator == 0: self._itdir *= -1 self._delayState = 0 else: txtlen = len(text) if self._iterator >= txtlen - self.limit and self._iterator <= txtlen: lcd.fillRect(self.x + len(chunk) * 4, self.y, 180, self.y + 15, 0) if self._iterator > txtlen and self._iterator < self.limit + txtlen: offset = self.limit + txtlen - self._iterator chunk = ' ' * offset + text[:self._iterator - txtlen] if self._iterator >= self.limit + txtlen: self._iterator = 0 lcd.print(chunk, self.x, self.y, self.color) else: lcd.print(text, self.x, self.y, self.color)
def gamesMenu(itemOffset=0): ofy = 0 data = twitchAPI('games/top', {'limit': 3, 'offset': itemOffset}) games = [] lcd.clear() lcd.drawLine(0, 0, 80, 0, 0x6441a5) for item in data['top']: lcd.fillRect(0, ofy, 80, 45, 0x333333) lcd.text(lcd.CENTER, ofy + 16, 'LOADING') loadAndDrawOnePreview( item['game']['box']['template'].replace('{width}', '80').replace( '{height}', '45'), 0, 1 + ofy) trippleText(2, ofy + 2, item['game']['name'], 0xffffff) games.append(item['game']['name']) trippleText(lcd.RIGHT, ofy + 32, str(item['viewers']), 0xFF0000) ofy += 46 lcd.text(4, 144, 'more', 0xFFFFFF) lcd.text(44, 144, 'back', 0xFFFFFF) def gameCallback(sel): global gameFilter if sel < 3: if sel >= len(games): return mainMenu gameFilter = games[sel].replace(' ', '+') return [(streamsMenu, streamsMenu, streamsMenu, gamesMenu, mainMenu)[sel], (itemOffset + sel if sel == 3 else 0)] return SelectionManager(3, offsetY=1, boxH=46, callback=gameCallback, menu=2).loop()
def streamsMenu(streamOffset=0): ofy = 0 data = twitchAPI('streams', { 'limit': 3, 'offset': streamOffset, 'game': gameFilter }) channels = [] lcd.clear() lcd.drawLine(0, 0, 80, 0, 0x6441a5) for item in data['streams']: lcd.fillRect(0, ofy, 80, 45, 0x333333) lcd.text(lcd.CENTER, ofy + 16, 'LOADING') loadAndDrawOnePreview(item['preview']['small'], 0, 1 + ofy) trippleText(2, ofy + 2, item['channel']['name'], 0xffffff) channels.append(item['channel']['name']) trippleText(lcd.RIGHT, ofy + 32, str(item['viewers']), 0xFF0000) ofy += 46 del data lcd.text(4, 144, 'more', 0xFFFFFF) lcd.text(44, 144, 'back', 0xFFFFFF) def sc(n=0): return selectChannel(channels[n]) def channelCallback(sel): return [(sc, sc, sc, streamsMenu, mainMenu)[sel], (streamOffset + sel if sel == 3 else sel)] return SelectionManager(3, offsetY=1, boxH=46, callback=channelCallback, menu=2).loop()
def loadAndDrawOnePreview(img, x, y): import urequests as rq try: img = img.replace('./', '') jpg = jpeg(rq.get(img).content, callback=lcd.drawPixel, quality=5).render(x, y) del jpg except (MemoryError, NotImplementedError): lcd.fillRect(x, y, 80, 44, 0x444444) gc.collect()
def selectionRenderer(smInstance): oldSel = smInstance.sel - 1 if smInstance.sel - 1 >= 0 else smInstance.total - 1 if smInstance.type == 0: lcd.fillRect(2, 22 + 12 * smInstance.sel, 76, 12, 0x88bfb9) lcd.fillRect(2, 22 + 12 * oldSel, 76, 12, 0x2b4860) mainMenuText() else: lcd.drawRect(smInstance.sel * 10, 148, 4 + (10 if smInstance.sel < 4 else 12), 12, 0x88bfb9) lcd.drawRect(oldSel * 10, 148, 4 + (10 if oldSel < 4 else 12), 12, 0x2b4860)
def render(self): # 清空上一帧内容 lcd.setColor(0) for ob in self.obs[self.type]: lcd.fillRect(self.old_x + ob[0], self.y + ob[1], ob[2], ob[3]) # lcd.drawRect(self.collision[self.type][0]+ self.old_x, self.collision[self.type][1] + self.y, self.collision[self.type][2], self.collision[self.type][3]) if not self.off_screen(): # 绘制当前帧内容 lcd.setColor(0x00ff00) for ob in self.obs[self.type]: lcd.fillRect(self.x + ob[0], self.y + ob[1], ob[2], ob[3])
def _showLayout(self): lcd.fillRect(0, 104, 80, 4, self.keyboardBG) lcd.print('123456789', 0, 108, self.textColor) lcd.print('0', 71, 108, self.textColor) lcd.print('QWERTYUIO', 0, 120, self.textColor) lcd.print('P', 71, 120, self.textColor) lcd.print('ASDFGHJKL', 0, 132, self.textColor) lcd.print('-', 71, 132, self.textColor) lcd.print('ZXCVBNM._', 0, 144, self.textColor) lcd.drawLine(78, 148, 78, 152, self.textColor) lcd.drawLine(78, 152, 74, 152, self.textColor) return self
def mainMenu(): def worldMap(): return mapView def leave(): import sys sys.exit() lcd.clear(0x2b4860) lcd.fillRect(0, 0, 80, 12, 0xc6585a) lcd.font(lcd.FONT_Arial12) lcd.text(lcd.CENTER, 0, 'MAPS', 0xFFFFFF) lcd.font(lcd.FONT_Small) callbacks = (worldMap, search, findMe) s = SelectionManagerV2(0, 4, selectionRenderer).loop() return callbacks[s]
def loop(self): from libs.imu import IMU #from hardware import mpu6050 mpu = IMU() #mpu = mpu6050.MPU6050() maxX = 80.0 maxY = 160.0 accel = [0.0, 0.0] accelSense = self.sensitivity curSize = self.cursorSize curPos = [40.0, 40.0] self._drawInputForm() self._drawLayoutBG() while True: self._showLayout() self._drawSelectedLetter(curPos) if curPos[1] <= 21: self._drawInputForm() self._drawInputText() accelX = mpu.acceleration[0] * accelSense * -1 accelY = mpu.acceleration[1] * accelSense lcd.fillRect(round(curPos[0]), round(curPos[1]), curSize, curSize, self.topBG if curPos[1] < 104 else self.keyboardBG) if curPos[0] + accelX < 80 - curSize and curPos[0] + accelX > 0: curPos[0] += accelX if curPos[1] + accelY < 160 - curSize and curPos[1] + accelY > 0: curPos[1] += accelY lcd.fillRect(round(curPos[0]), round(curPos[1]), curSize, curSize, self.cursorColor) if btnA.isPressed(): key = self._getLetter(curPos) if key == '>': self._hide() return self.input else: self.input += key self._drawInputText() while btnA.isPressed(): pass if btnB.isPressed(): if len(self.input) > 0: self.input = self.input[:-1] self._drawInputText() while btnB.isPressed(): pass
def render(self): lcd.setColor(0) if self.act == 2 or self.act == 3 or self.act == 4: # 跳跃状态才需要清空之前一帧绘制的内容 # 清空上一帧绘制的内容 for line in self.head_lines: lcd.drawLine(self.old_x + line[0], self.old_y + line[1], self.old_x + line[2], self.old_y + line[3]) for rect in self.body_rects: lcd.fillRect(self.old_x + rect[0], self.old_y + rect[1], rect[2], rect[3]) for pixel in self.extra_pixels: lcd.drawPixel(self.old_x + pixel[0], self.old_y + pixel[1]) # 清空运动中上一帧眨眼的坐标 lcd.drawPixel(self.old_x + 12, self.old_y + 1) # self.act == 4这是从跳跃状态转移至普通状态的中间状态, # 此时仍然需要清空上一帧内容,不然会导致状态错误而留下残影 if self.act == 4: # 清空完上一帧内容,再去转变状态 self.act = 1 self.leg_status = 0 self.clear_leg() # 绘制本一帧的内容 lcd.setColor(0xffffff) for line in self.head_lines: lcd.drawLine(self.x + line[0], self.y + line[1], self.x + line[2], self.y + line[3]) for rect in self.body_rects: lcd.fillRect(self.x + rect[0], self.y + rect[1], rect[2], rect[3]) for pixel in self.extra_pixels: lcd.drawPixel(self.x + pixel[0], self.y + pixel[1]) # 由于不断更新的,所以脚单独绘制 self.draw_leg() if self.blink < 40: lcd.setColor(0) lcd.drawPixel(self.x + 12, self.y + 1) elif self.blink < 60: # 闭眼效果在此 lcd.setColor(0xffffff) lcd.drawPixel(self.x + 12, self.y + 1) else: self.blink = 0 self.blink += 1
def loop(): #render snake for tailpart in Snake.tail: lcd.fillRect(tailpart[0], tailpart[1], 2, 2) #clear old tail coords lcd.fillRect(Snake.notail[0], Snake.notail[1], 2, 2, 0) #render food lcd.fillRect(Food.pos[0], Food.pos[1], 2, 2, 0x00ff00) return not Snake.isDead
def draw_leg(self): # 脚相关的坐标 # 大腿 rects = [[5, 16, 2, 2], [9, 16, 2, 2]] # 正常左脚 left_nor_leg = [[5, 18], [5, 19], [6, 19], [7, 16]] # 正常右脚 right_nor_leg = [[10, 18], [10, 19], [11, 19]] # 左脚抬起相关的坐标 up_left_leg = [[5, 16, 5, 18], [5, 17, 7, 17]] # 右脚抬起相关的坐标 up_right_leg = [[10, 16, 10, 18], [11, 17, 12, 17]] # 换脚的时候清空上一帧抬起的脚 # 绘制静止状态的脚 if self.act != 1: for rect in rects: lcd.fillRect(self.x + rect[0], self.y + rect[1], rect[2], rect[3]) for pixel in left_nor_leg: lcd.drawPixel(self.x + pixel[0], self.y + pixel[1]) for pixel in right_nor_leg: lcd.drawPixel(self.x + pixel[0], self.y + pixel[1]) else: # 跑步 # 抬起左脚 if self.leg_status < 10: lcd.fillRect(self.x + rects[1][0], self.y + rects[1][1], rects[1][2], rects[1][3]) for pixel in right_nor_leg: lcd.drawPixel(self.x + pixel[0], self.y + pixel[1]) for left_leg in up_left_leg: lcd.drawLine(self.x + left_leg[0], self.y + left_leg[1], self.x + left_leg[2], self.y + left_leg[3]) # 抬起右脚 elif self.leg_status < 20: lcd.fillRect(self.x + rects[0][0], self.y + rects[0][1], rects[0][2], rects[0][3]) for pixel in left_nor_leg: lcd.drawPixel(self.x + pixel[0], self.y + pixel[1]) for right_leg in up_right_leg: lcd.drawLine(self.x + right_leg[0], self.y + right_leg[1], self.x + right_leg[2], self.y + right_leg[3]) else: self.leg_status = 0
def _drawSelectedLetter(self, curPos): lcd.fillRect(0, 92, 11, 11, self.topBG) lcd.print(self._getLetter(curPos), 0, 92, self.cursorColor)
def drawHeader(): lcd.fillRect(0, 0, 80, 16, 0x6441a5) lcd.text(lcd.CENTER, 2, 'TwitchIoT')
def _drawInputText(self): lcd.fillRect(10, 10, 90, 10, self.topBG) txt = self.input if len(self.input) < 8 else ('~' + self.input[-7:]) lcd.print(txt, 10, 9, self.textColor)
def clear_leg(self): lcd.setColor(0) lcd.fillRect(self.old_x + 5, self.old_y + 16, 10, 4)
def drawControls(): lcd.fillRect(0, 148, 80, 11, 0x2b4860) pos = array('b', (4, 14, 24, 34, 44, 48, 54, 58, 66, 68, 70)) txt = '+-<>/\\\\/...' for i, char in enumerate(txt): lcd.text(pos[i], 148, char, 0xffffff)
def _hide(self): for i in range(68): lcd.fillRect(0, 90, 80, 3 + i, self.topBG)
def _drawLayoutBG(self): for i in range(56): lcd.fillRect(0, 160 - i, 80, 160, self.keyboardBG) return self
def statusText(text): lcd.fillRect(0, 0, 80, 32, 0) lcd.print(text, 0, 0)