Bewegte Bilder auf PicoBoy Color
technische Daten wie beim RPi Pico
Microcontroller RP2040 - 1,69 Zoll Farbdisplay mit 240 x 280 Pixeln
Projekte und Anleitung in CircuitPython 9.x.x
Bildbox 1 (klick hier)
Bewegte Bilder auf PicoBoy Color
technische Daten wie beim RPi Pico
Microcontroller RP2040 - 1,69 Zoll Farbdisplay mit 240 x 280 Pixeln
Projekte und Anleitung in CircuitPython 9.x.x
Bildbox 1 (klick hier)
Hardware
- PicoBoy-Color
bewegte Sprites
Zunächst brauchen wir ein weiteres Sprite_Sheet, welches den PicoMax darstellt. Dazu habe ich genau wie für den Hintergrund eine Bitmap-Datei
picomax.bmp vorbereitet. Auch die können Sie
von hier herunterladen, entpacken und in den Ordner 'images' speichern.
Die 'Sprites' (32x32 Pixel) sind untereinander angeordnet und enthalten wie bei einer animierten gif-Datei die einzelnen Elemente. Außer 'PicoMax nach rechts' und 'PicoMax nach links' gibt es für später noch weitere 'Figuren'. Das oberste Sprite ist 32x32 Pixel weiss. Diese Farbe wird im Programm für die Transparenz genutzt. Im Programm wird die sprite_sheet wie bereits der Hintergrund geladen, einer TileGrid zugewiesen und der selben Gruppe 'main' hinzugefügt, wie der Hintergrund. Wenn Sie in der TileGrid 'default_tile=0' wählen, ist PicoMax beim Programmstart nicht sichtbar. Rufen Sie dann z.B. 'picomax[0] = 3' auf, wird das 4. Sprite (Zählweise beginnt immer bei 0) von oben angezeigt. Um jetzt noch die Position auf dem Display festzulegen braucht es eine entsprechende x- und y-Koordinate. Z.B.
picomax.x = 120 (von links nach rechts)
picomax.y = 90 (von oben nach unten)
Kopieren Sie den Code aus dem unteren Kasten ins Thonny und schauen sich das Ergebnis an:
1 import time 2 import board 3 import busio 4 import displayio 5 import terminalio 6 import digitalio 7 from adafruit_st7789 import ST7789 8 import adafruit_imageload 9 10 # 1,69 Zoll 240x280 Pixel ST7789 Display 11 # SPI, in Landscape format 12 dc=board.GP8 13 reset=board.GP9 14 cs=board.GP10 15 sck=board.GP18 16 mosi=board.GP19 17 bl=board.GP26 18 # Release any resources currently in use for the displays 20 19 displayio.release_displays() 21 spi = busio.SPI(sck, mosi) 22 display_bus = displayio.FourWire(spi, command=dc, chip_select=cs, reset=reset) 23 display = ST7789(display_bus, rotation=90, width=280, height=240, backlight_pin=bl, rowstart=20, colstart=0) 24 display.brightness = 1 25 main = displayio.Group() 26 27 # Load the backgr sprite sheet (bitmap) 28 sprite_sheet, palette = adafruit_imageload.load("/images/floor.bmp", bitmap=displayio.Bitmap, palette=displayio.Palette) 29 backgr_group = displayio.TileGrid(sprite_sheet, pixel_shader=palette, width=7, height=6, tile_width=40, tile_height=40, default_tile=7) 30 31 # Load the sprite sheet for PicoMax (bitmap) 32 sprite_sheet, palette = adafruit_imageload.load("/images/picomax.bmp", bitmap=displayio.Bitmap, palette=displayio.Palette) palette.make_transparent(1) 33 picomax = displayio.TileGrid(sprite_sheet, pixel_shader=palette, width=1, height=1, tile_width=32, tile_height=32, default_tile=0) 34 picomax_group = displayio.Group(scale=1) 35 picomax_group.append(picomax) 36 37 backgr = [15, 16, 13, 13, 13, 13, 13, 38 18, 19, 20, 14, 20, 14, 20, 39 7, 7, 7, 7, 7, 7, 7, 40 7, 1, 5, 5, 5, 8, 6, 41 7, 0, 7, 7, 7, 7, 2, 42 12, 0, 11, 11, 8, 10, 11] 43 44 def floor(): 45 # show the 42 sprites 46 for x in range(0, 7): 47 for y in range(0, 6): 48 backgr_group[x, y] = backgr[y*7 +x] 49 50 def set_sprites(): 51 picomax.x = 90 52 picomax.y = 90 53 picomax[0] = 3 54 55 main.append(backgr_group) 56 main.append(picomax_group) 57 display.root_group = main 58 59 floor() 60 set_sprites() 61 right = True 62 left = False 63 step = time.monotonic() 64
Nun muss PicoMax laufen. Dazu definiere ich die Variablen 'right', 'left' und 'step'. In der 'while-Schleife' zeigen die Kommentarzeilen die jeweilige Funktionalität an. Durch die Änderung des Wertes von m werden in picomax[0] = m die Sprites 1 bis 4 (nach rechts) bzw. von 5 bis 8 (nach links) angezeigt. Um den Programmablauf nicht mit time.sleep(xx) zu unterbrechen, verwende ich die Variable step und gleiche diese jeweils mit time.monotonic() ab. Beim Erreichen des rechten Randes bei if picomax.x >= 250 bzw. des linken Umkehrpunktes bei if picomax.x <= 90 wird die Laufrichtung durch Ändern der Variable right bzw. left erreicht. Ergänzen Sie zum Probieren den Code aus dem unteren Kasten:
65 while True: 66 # PicoMax laeuft nach rechts 67 if right == True: 68 if time.monotonic() - step > 0.07: 69 picomax[0] = m 70 m += 1 71 picomax.x += 4 72 if m == 4: 73 m = 1 74 step = time.monotonic() 75 # PicoMax laeuft nach links 76 if left == True: 77 if time.monotonic() - step > 0.07: 78 picomax[0] = m 79 m += 1 80 picomax.x -= 4 81 if m == 8: 82 m = 5 83 step = time.monotonic() 84 # pruefen ob PicoMax rechts oder links angekommen ist 85 # rechts 86 if picomax.x >= 250: 87 right = False 88 left = True 89 m = 5 90 # links 91 if picomax.x <= 90: 92 right = True 93 left = False 94 m = 1
Und so sieht das jetzt aus:
Wenn wir die 'while-Schleife' noch mit ein paar Ergänzungen versehen, ergibt das schon fast ein 'PicoMax rennt'-Demo. Hier noch einmal der komplette Code:
Und so sieht das jetzt aus:
1 import time 2 import board 3 import busio 4 import displayio 5 import terminalio 6 import digitalio 7 from adafruit_st7789 import ST7789 8 import adafruit_imageload 9 10 # 1,69 Zoll 240x280 Pixel ST7789 Display 11 # SPI, in Landscape format 12 dc=board.GP8 13 reset=board.GP9 14 cs=board.GP10 15 sck=board.GP18 16 mosi=board.GP19 17 bl=board.GP26 18 # Release any resources currently in use for the displays 19 displayio.release_displays() 20 spi = busio.SPI(sck, mosi) 21 display_bus = displayio.FourWire(spi, command=dc, chip_select=cs, reset=reset) 22 display = ST7789(display_bus, rotation=90, width=280, height=240, backlight_pin=bl, rowstart=20, colstart=0) 23 display.brightness = 1 24 main = displayio.Group() 25 26 # Load the backgr sprite sheet (bitmap) 27 sprite_sheet, palette = adafruit_imageload.load("/images/floor.bmp", bitmap=displayio.Bitmap, palette=displayio.Palette) 28 backgr_group = displayio.TileGrid(sprite_sheet, pixel_shader=palette, width=7, height=6, tile_width=40, tile_height=40, default_tile=7) 29 30 # Load the sprite sheet for PicoMax (bitmap) 31 sprite_sheet, palette = adafruit_imageload.load("/images/picomax.bmp", bitmap=displayio.Bitmap, palette=displayio.Palette) 32 palette.make_transparent(1) 33 picomax = displayio.TileGrid(sprite_sheet, pixel_shader=palette, width=1, height=1, tile_width=32, tile_height=32, default_tile=0) 34 picomax_group = displayio.Group(scale=1) 35 picomax_group.append(picomax) 36 37 backgr = [15, 16, 13, 13, 13, 13, 13, 38 18, 19, 20, 14, 20, 14, 20, 39 7, 7, 7, 7, 7, 7, 7, 40 7, 0, 5, 5, 5, 8, 6, 41 7, 0, 7, 7, 7, 7, 2, 42 12, 0, 11, 11, 8, 10, 11] 43 44 def floor(): 45 # show the 42 sprites 46 for x in range(0, 7): 47 for y in range(0, 6): 48 backgr_group[x, y] = backgr[y*7 +x] 49 50 def set_sprites(): 51 picomax.x = 90 52 picomax.y = 90 53 picomax[0] = 3 54 55 main.append(backgr_group) 56 main.append(picomax_group) 57 display.root_group = main 58 59 floor() 60 set_sprites() 61 right = True 62 left = False 63 m = 1 64 step = time.monotonic() 65 66 while True: 67 # PicoMax laeuft nach rechts 68 if right == True: 69 if time.monotonic() - step > 0.07: 70 picomax[0] = m 71 m += 1 72 picomax.x += 4 73 if m == 4: 74 m = 1 75 step = time.monotonic() 76 # PicoMax laeuft nach links 77 if left == True: 78 if time.monotonic() - step > 0.07: 79 picomax[0] = m 80 m += 1 81 picomax.x -= 4 82 if m == 8: 83 m = 5 84 step = time.monotonic() 85 # pruefen ob PicoMax rechts oder links angekommen ist 86 if picomax.x >= 240: 87 backgr_group[6, 3] = 7 88 backgr_group[1, 2] = 7 89 picomax.y = 130 90 right = False 91 left = True 92 m = 5 93 if picomax.x <= 50: 94 picomax[0] = 0 95 backgr_group[1, 2] = 3 96 backgr_group[1, 4] = 0 97 time.sleep(0.2) 98 picomax.y = 90 99 picomax[0] = 1 100 #backgr_group[1, 2] = 0 101 right = True 102 left = False 103 m = 1 104 if picomax.x < 215 and picomax.x > 210 and left: 105 backgr_group[6, 3] = 6 106 backgr_group[1, 4] = 3 107 picomax.y = 170