Sestavování scén
Tyto čtyři moduly pokrývají statickou “světovou” část hry: načítání připravené scény, dotazování na vlastnosti dlaždic, tvorbu grafiky bez PNG assetů a recyklaci fixní sady spritů. Čistě signatury najdeš v /cs/reference/; ukázky níže vysvětlují chování a záludnosti.
picogame_scene
Sekce “picogame_scene”Jednorázový loader, který přemění připravený SCENE dict (viz /cs/scene-format/) na živý pg.Scene a pojmenované handle. Sáhni po něm, když je tvůj level sestavený editorem nebo scene_build.py, a chceš, aby stejný loader běžel na zařízení i v simulátoru. Načítání není horká cesta, takže žije v Pythonu.
load(pg, scene, display=None, strip_h=24, font=None, bank=None) sestaví a vrátí View. Nastaví display.auto_refresh = False, vyčistí root_group, alokuje dva strip buffery (bufA/bufB, každý width * strip_h * 2), zkonstruuje pg.Scene a přidá každou vrstvu (tilemap, sprite, group, particles, hudlabel). display se defaultně bere z board.DISPLAY. Předej font (např. terminalio.FONT), pokud je některá vrstva HUD label. Detaily k displeji najdeš v /cs/hardware/ a náklady na strip buffer v /cs/memory/.
load_bank(pg, bank) sestaví sdílené bitmapy/zvuky/animace JEDNOU; výsledek předej jako load(..., bank=...) pro každý level, aby se nezměněná grafika nepřestavovala znovu.
Vrácený View je tvůj handle na vše:
view.scene- živýpg.Scene. Volejview.scene.refresh()každý frame aview.scene.set_view(ox, oy)pro posouvání.view.named[name]- dict name -> sprite / particles / HUD label pro každou vrstvu, které byl přiřazenname.view.group(tag)- list spritů pro group vrstvu (vrací[], pokud tag neznáš, takže je bezpečné iterovat).view.tick(dt)- posuň všechny automaticky animované sprity; volej jednou za frame sdtv sekundách.view.tile_xy(px, py)- světové pixely -> buňka(tx, ty)primárního (prvního) tilemapu.view.is_solid(tx, ty)- zkratka protile_has(tx, ty, "solid").view.tile_has(tx, ty, prop)- True, pokud má dlaždice primárního tilemapu v dané buňce pojmenovanou vlastnost (z připravenéhotileprops).view.point(name)-(x, y)pojmenovaného bodu, nebo None.view.in_zone(x, y, tag=None)- první zóna(tag, x, y, w, h)obsahující daný bod (volitelně filtrovaná podle tagu), jinak None.view.play(sound_id)- přehraj připravený sfx podle id (nic nedělá, pokud audio/sample chybí).view.tilemap/view.camera/view.zones/view.points/view.anims- primární tilemap objekt, camera tuple a raw kolekce.
import board, terminalioimport picogame as pgimport picogame_scene as pgsimport world1_scene
view = pgs.load(pg, world1_scene.SCENE, font=terminalio.FONT)player = view.named["player"]enemies = view.group("enemies")while True: view.tick(1 / 30) # advance auto-animations tx, ty = view.tile_xy(player.x, player.y) if not view.is_solid(tx, ty): player.move(player.x + 2, player.y) view.scene.refresh()Záludnosti: PRVNÍ vrstva tilemapu je “primární” - tile_xy, is_solid a tile_has dotazují pouze tuto mapu. view.named obsahuje jen vrstvy, kterým byl přiřazen název; nepojmenovaná vrstva se přidá do scény, ale nejde přes ni dostat. Zvuky se načítají best-effort: na simulátoru (bez wavs) jsou položky view.sounds None a play() tiše nedělá nic.
picogame_tiles
Sekce “picogame_tiles”Bitfield metadat na dlaždici, klíčovaný indexem dlaždice. Flagy patří grafice dlaždice, takže je sdílejí všechny buňky nakreslené touto dlaždicí. Sáhni po něm, když ručně stavíš pg.Tilemap (ne přes picogame_scene) a chceš kolizní/coin/exit logiku jako one-linery místo boční tabulky. Pokud načítáš scény pomocí picogame_scene, použij raději view.is_solid / view.tile_has - tento modul je nízkoúrovňová alternativa.
Osm pojmenovaných bitů a jejich masek: B_SOLID, B_HAZARD, B_LADDER, B_PLATFORM, B_WATER, B_COIN, B_EXIT, B_CUSTOM jsou bitové indexy 0..7; SOLID, HAZARD, LADDER, PLATFORM, WATER, COIN, EXIT, CUSTOM jsou odpovídající masky 1 << bit. Při sestavování tabulky používej masky, při dotazování B_* indexy.
TileFlags(flags=None, tile_px=8) sestaví tabulku. flags je buď dict {tile_index: bitfield}, nebo list/bytes indexovaný indexem dlaždice; tile_px je velikost dlaždice používaná pixelovým pomocníkem.
tf.get(tile, bit=None)- celý bitfield dlaždice, nebo jeden bool flag, pokud zadášbit(indexB_*).tf.set(tile, bit, value=True)- nastav (nebo smaž) bit na dlaždici za běhu.tf.at(tilemap, tx, ty, bit)- flagbitdlaždice v buňce(tx, ty).tf.at_px(tilemap, px, py, bit)- flagbitdlaždice pod MAP-LOCAL pixelem(px, py); běžná kolizní sonda.
import picogame as pgimport picogame_tiles as tiles
TILE = 8tf = tiles.TileFlags({1: tiles.SOLID, 2: tiles.COIN, 3: tiles.EXIT}, tile_px=TILE)
def blocked(level, tx, ty): # level is a pg.Tilemap return tf.at(level, tx, ty, tiles.B_SOLID)
if tf.at_px(level, px, py, tiles.B_SOLID): # is the tile under pixel (px, py) solid? stop()Záludnosti: at_px předpokládá, že mapa je na souřadnicích (0, 0) - pokud je posunutá, odečti před voláním počátek mapy od px/py sám. Dlaždice chybějící v tabulce se čtou jako 0 (žádné flagy). Sestavuj pomocí MASK konstant (tiles.SOLID), ale dotazuj se pomocí BIT indexů (tiles.B_SOLID); záměna tiše kontroluje nesprávný bit.
picogame_shapes
Sekce “picogame_shapes”Generátory, které PEČOU jednobarevné PAL8 pg.Bitmapy v kódu - zástupné sprity a tilesety bez PNG assetů a bez změn firmware. Sáhni po nich pro prototypy, geometrické grafické prvky (kuličky, cihly, lodě) nebo cokoliv, co bys jinak řešil ručním packing loopm. Poznámka: toto NENÍ C Canvas (který kreslí do živého povrchu) - shapes vrací znovupoužitelný Bitmap, který předáš Sprite nebo Tilemap. Index 0 je průhledný, 1 je barva.
rect(w, h, color)- vyplněný obdélníkw x h.circle(d, color)- vyplněný disk průměrud.ring(d, color, thickness=2)- obrys kružnice průměrud.from_mask(mask, color)- bitmapa z listu stringů;#,Xnebo1nastaví pixel. Velikost odpovídá masce.atlas(frames_data, w, h, color)- zabalí listw*hbufferů 0/1 do jedné horizontální víceframové bitmapy (jedna barva). Obecný builder “frame sheetu”.color_frames(w, h, colors)- víceframová bitmapa, kde frameije plná výplňcolors[i]; frame 0 je už barevný. Index 0 je průhledný.tileset_colors(w, h, colors)- tileset, kde frame 0 je PRÁZDNÝ (průhledný) a frameije plná výplňcolors[i-1]. Tilemap tak čte hodnotu dlaždice 0 jako prázdnou a 1..N jako barevné dlaždice.poly_frames(size, points, nframes, color, fill=True)- upečenframesrotací polygonu (body kolem středu, +y dolů) do atlasusize x size. Engine nemá za běhu rotaci, takže toto je vzor předrotovaných framů pro lodě/asteroidy. Nastavfill=Falsepro obrys.
import picogame as pgimport picogame_shapes as shp
ball = shp.circle(4, pg.rgb565(255, 255, 120))bricks = shp.tileset_colors(16, 8, [pg.rgb565(220, 70, 70), pg.rgb565(80, 140, 240)]) # value 0 empty, 1..2 colouredship = shp.poly_frames(16, [(0, -8), (6, 7), (0, 4), (-6, 7)], 16, pg.rgb565(200, 220, 255)) # 16 pre-rotated framessprite = pg.Sprite(ball, 100, 60)Záludnosti: frame 0 v color_frames je viditelná barva, ale v tileset_colors je frame 0 průhledný (prázdný) - vyber ten, který odpovídá tomu, jak tvůj Tilemap zachází s hodnotou 0. circle vyplňuje bitmapu od okraje k okraji, takže při zvětšení vypadá jako by měla ploché hrany. poly_frames s nframes=1 upeče jediný neotočený frame (použij pro tvar s pevným směrem).
picogame_pool
Sekce “picogame_pool”Znovupoužitelný sprite pool fixní velikosti - vzor pre-alokace / spawn / free / iterace, který si každá hra se spawnováním (střely, nepřátelé, orby) doteď dělala ručně. Jako příznak živosti používá sprite.visible (žádné paralelní data["on"]) a sprite.data pro stav každé entity. Sáhni po něm kdykoliv máš omezený počet přechodných spritů a chceš nulovou alokaci za frame. Proč na zařízení záleží pre-alokace, se dočteš v /cs/memory/.
Pool(scene, bitmap, capacity, anchor=None, fixed=False) předalokuje capacity skrytých spritů sdílejících bitmap, nastaví každému anchor (pokud je zadán) a data = None a přidá je všechny do scene (fixed= se předává přímo do scene.add).
pool.items- underlying list spritů; iteruj ho přímo pro zero-alloc aktualizace.pool.spawn()- udělá první volný (skrytý) sprite viditelným a vrátí ho, nebo None, pokud je pool plný.pool.free(s)- skryje sprites(vrátí ho do poolu).pool.free_all()- skryje všechny sprity (použij při resetu levelu).pool.count()- počet živých (viditelných) spritů; levné, ale pro samotné sprity iterujitems.
import picogame as pgimport picogame_pool
bullets = picogame_pool.Pool(scene, bullet_bm, 6, anchor=(0.5, 0.5))
b = bullets.spawn() # a now-visible sprite, or None if fullif b: b.data = {"vx": 6} b.move(x, y)
for s in bullets.items: # zero-alloc iteration if not s.visible: continue s.move(s.x + s.data["vx"], s.y) if off_screen(s): bullets.free(s)Záludnosti: při iteraci vždy přeskakuj skryté sloty (if not s.visible: continue) - items obsahuje každý slot, živý i mrtvý. spawn() znovupoužívá naposledy uvolněný slot, takže pokud ve stejném kroku zavoláš free(s) a spawn(), přečti si stav z s.data PŘED uvolněním - nový spawn ho přepíše. Plný pool vrátí z spawn() None; zkontroluj to. Všechny sprity sdílejí jednu bitmapu, takže frame/animaci pro každou entitu musíš nastavit na každém spritu po spawn().