Formát scény picogame
Scéna popisuje úroveň nebo mapu jako data, která používá hra na zařízení, desktopový simulátor i webový editor. Do dat patří grafické soubory, umístění spritů, tilemapy, význam tilů, pořadí vrstev, HUD a nastavení kamery. Herní logika, například pohyb, AI a podmínky výhry, zůstává v Pythonu.
Postup převodu
Sekce “Postup převodu”*.scene.json ──tools/scene_build.py──▶ <name>_scene.py ──mpy-cross──▶ <name>_scene.mpy(úprava v editoru nebo ručně) (převedený modul) (kopie do CIRCUITPY)- Zdrojový JSON (
*.scene.json) může upravovat člověk i editor. Barvy zapisuje jako[r, g, b]a mapy jako mřížky. - Převedený modul Pythonu (
SCENE = {...}) obsahuje barvy RGB565 ve wire order, mřížku tilů jakobytess jedním bajtem na buňku a grafiku převedenou na atlasy PAL8. Pro zařízení jej zkompiluj do.mpy. - Stejné načítání na obou cílech:
picogame_scene.load(pg, SCENE, ...)sestavípg.Scenepřes veřejné API picogame. Použití popisuje stránka Sestavování scén.
Zapečení:
python3 tools/scene_build.py examples/levels/world1.scene.json# -> examples/levels/world1_scene.py (atribut modulu SCENE)tools/build_mpy.sh # případně přelož modul pro zařízení přes mpy-crossZdrojové schéma (verze 2)
Sekce “Zdrojové schéma (verze 2)”{ "format": "picogame-scene", "version": 2, "size": [320, 240], "background": [8, 10, 24], // při převodu -> RGB565 ve wire order
"assets": { // sdílená banka, položky se odkazují přes id "hero": { "type": "sprite", "src": "hero.png", "frames": 6, "transparent": 0, "animations": { "walk": { "frames": [0,1,2,1], "fps": 8, "loop": true } } }, "tiles": { "type": "tileset", "src": "tiles.png", "tile": [16, 16], "frames": 5, "props": { "1": {"solid": true}, "2": {"coin": true}, "3": {"goal": true} } }, "flag": { "type": "rect", "size": [8, 16], "color": [255, 220, 60] } }, "sounds": { "jump": { "src": "jump.wav" } },
"layers": [ // pořadí zdola nahoru { "kind": "tilemap", "asset": "tiles", "cols": 80, "rows": 15, "pos": [0, 0], "map": "rle:..." }, { "kind": "sprite", "asset": "hero", "name": "player", "pos": [40, 208], "anchor": [0.5, 1.0], "anim": "walk", "data": { "lives": 3 } }, { "kind": "group", "asset": "goomba", "anchor": [0.5, 1.0], "instances": [[224, 208], [480, 208], [704, 208]], "tag": "enemies" }, { "kind": "tilemap", "asset": "tiles", "fg": true, "cols": 80, "rows": 15, "map": "rle:..." }, // fg: true kreslí nad sprity { "kind": "particles", "capacity": 64, "size": 2, "gravity": 0.5, "fade": true, "name": "fx" }, { "kind": "hudlabel", "name": "score", "pos": [4, 4], "fg": [255,255,255], "bg": [0,0,0] } // bez vlivu kamery (fixed je odvozené) ],
"zones": [ { "tag": "door", "x": 300, "y": 180, "w": 20, "h": 40 } ], "points": [ { "name": "spawn", "x": 40, "y": 208 } ], "camera": { "mode": "follow", "target": "player", "axis": "x", "bounds": [0, 0, 1280, 240] }, "music": "theme", "meta": { "editor": { "grid": 16, "name": "World 1-1" } } // runtime tuto část ignoruje}Poznámky k polím:
- assets — typy
sprite/tileset/bitmap(srcPNG +frames,tile,transparent),rect,tileset_color; tileset může připojit props pro jednotlivé tily (solid/coin/goal/hazard/vlastní) a sprite může deklarovat animations ({name: {frames, fps, loop}}). - druhy vrstev —
tilemap(povoleno několik; jedna může mítfg: true, aby kreslila přes sprity),sprite(name/anchor/frame/anim/data),group(mnoho instancí jedné bitmapy, adresovatelných přestag),particles,hudlabel(nezávislý na kameře). Jakákoli vrstva může nastavit"fixed": true. - zones / points — pojmenované obdélníky a pozice, na které se hra ptá za běhu
(
view.in_zone,view.point). - camera obsahuje nastavení, které hra může použít přes
set_view; kameru může řídit také vlastní logikou. - meta je volný prostor pro editor; načítání za běhu neznámé klíče ignoruje.
Dvě podoby nejvyšší úrovně
Sekce “Dvě podoby nejvyšší úrovně”"format": "picogame-scene"— jedna samostatná scéna s grafikou uvnitř → převedená do jednoho modulu<name>_scene."format": "picogame-project"— banka sdílených prostředků +levels[]→ převedeno do jednoho modulu_bankplus jednoho modulu_levelna úroveň; načti přesbank = picogame_scene.load_bank(pg, BANK)a pakload(..., bank=bank), takže se sdílená grafika nestaví znovu pro každou úroveň.
Validace
Sekce “Validace”Při neznámém typu prostředku nebo vrstvy skončí převod s ValueError, která označí
problematickou položku. Chybějící nebo vadný soubor PNG vyvolá původní chybu převodníku.
Načítání toleruje neznámé klíče na nejvyšší úrovni, ale n-tice vrstev používají pevné pozice.
Modul vytvořený novější verzí scene_build.py proto může vyžadovat odpovídající verzi
picogame_scene.
Převedený modul pro zařízení
Sekce “Převedený modul pro zařízení”# world1_scene.py (potom -> world1_scene.mpy)SCENE = { "bg": 0x2001, # RGB565 už ve wire order "assets": { "hero": ("pal8", "a1b2...", 12, 16, 6, 0, (0x0000, 0xF80F, ...)), # data(hex),w,h,snímky,průhlednost,paleta "tiles": ("pal8", "00ff...", 16, 16, 5, None, (...)), }, "tileprops": { "tiles": { "solid": b"\x00\x01\x00\x00\x00", "coin": b"\x00\x00\x01\x00\x00" } }, # indexováno hodnotou tilu "anims": { "hero": { "walk": ((0, 1, 2, 1), 8, True) } }, "layers": [ ("tilemap", "tiles", 80, 15, 0, 0, b"\x01\x01..."), # cols,rows,ox,oy,grid bytes ("sprite", "hero", "player", 40, 208, 128, 256, 0, {"lives": 3}), # kotevní bod v 1/256 ("group", "goomba", "enemies", 128, 256, ((224,208), (480,208))), ("particles", "fx", 64, 2, 0.5, True), ("hudlabel", "score", 4, 4, 0xFFFF, 0x0000), ], "camera": ("follow", "player", "x", 0, 0, 1280, 240),}Vrstvy a prostředky jsou n-tice místo slovníků, aby modul .mpy zůstal malý; načítání je
rozbaluje podle pozice. Mřížka a tabulky vlastností tilů jsou bytes, každá v jedné
alokaci. Pixelová data jsou hexadecimální řetězec dekódovaný přes bytes.fromhex(...).
Přímé načítání JSON na zařízení by pro mřížku vytvořilo seznam samostatných Python čísel
(v měřené verzi přibližně 28 B na číslo): mapa 28×18 spotřebuje asi 14 KB jen za tento seznam,
navíc k textu JSON. Stejná mřížka jako
bytes literál v .mpy má ~500 B a jednu alokaci.
API načítání za běhu
Sekce “API načítání za běhu”import picogame_scene as pgs, terminalioview = pgs.load(pg, world1_scene.SCENE, font=terminalio.FONT)view.scene # naplněná a seřazená picogame.Sceneview.named["player"] # objekt Spriteview.group("enemies") # list of Spritesview.tick(dt) # posune automatické animace jednou za snímekview.is_solid(tx, ty) # vlastnost tilu v první hlavní mapěview.tile_has(tx, ty, "coin")view.tile_xy(px, py) # pixel světa -> (tx, ty) v hlavní mapěview.in_zone(x, y, "door") # first zone containing (x, y), or Noneview.point("spawn") # named point (x, y), or Noneview.play("jump") # play a loaded sound by idview.camera # (režim, cíl, osa, hranice), které hra použije pro kameruÚplné chování a omezení načítání popisuje stránka Sestavování scén.