Přeskočit na obsah

Kreslicí cesty — kterou zvolit

Kreslicí cestu vybírej podle toho, kdy se obsah mění a zda potřebuje uložené pixely:

  • Retained Scene použij pro svět, který přetrvává mezi snímky.
  • pg.render() použij pro jednorázovou obrazovku nebo rezervovaný pruh HUDu.
  • StripDraw použij tam, kde můžeš pixely znovu vytvořit místo jejich uložení do Canvasu.

Jeden kompozitor, dva výstupy

Sekce “Jeden kompozitor, dva výstupy”

Všechny cesty používají stejný kompozitor vrstev. Na SPI cílech prochází každý dirty region po vodorovných pásech a posílá je na panel. Na cílech s vlastním obrazovým výstupem, například Fruit Jam, skládá dirty regiony přímo do framebufferu. Tam formát pixelu určuje barevná hloubka bufferu: 16bitový framebuffer bere RGB565 přímo, u 8bitového (jediná hloubka, kterou picodvi nabízí při 640×480) se každý dokončený pás kvantuje 565→332 při publikování — v obou případech kreslíš přes pg.rgb565(...).

Volba vrstvy určuje, kolik další pixelové paměti hra uchovává. Celoobrazovkový StripDraw nemá vlastní pixelový buffer; RGB565 Canvas o velikosti 320×240 drží přibližně 150 KB. Případný Výstupní framebuffer patří zobrazovací cestě a do této ceny se nepočítá.

Jeden kompozitor vrstev napájí dva výstupy: SPI panel (dirty region prochází po vodorovných pásech) nebo scanout framebuffer (skládá se přímo jako 16bit RGB565 nebo 8bit RGB332)

Co spouští kreslení (dva režimy)

Sekce “Co spouští kreslení (dva režimy)”
RežimPro coPřekresluje
scene.refresh() — retained režimtrvalý herní svět: vrstvy přidáš, měníš a obnovuješ. Kamera (set_view), fixed vrstvy a rezervované pruhy (top=/bottom=/left=/right=).dirty regions
pg.render(display, items, buffer, x0,y0,x1,y1, *, background) — immediate režimjednorázové kreslení mimo scénu: HUD v rezervovaném pruhu, titulní obrazovka nebo konec úrovně.při zavolání

Oba režimy berou stejné typy vrstev: seznam pro pg.render může držet Sprity, StripDraw, Canvas, Tilemap i Particles, přesně jako scéna.

Pět typů vrstev (co kreslíš) — a jejich RAM

Sekce “Pět typů vrstev (co kreslíš) — a jejich RAM”
TypRAMPro co
Sprite (obaluje Bitmap)bitmapa: PAL8 = w*h (1 B/px), RGB565 = w*h*2pohyblivé objekty, postavy, střely
Tilemapcols*rows (1 B/buňka) + sada dlaždicvelké statické nebo posouvající se mapy
Canvasw*h*2 uchovaných bajtůplocha kreslená občas a používaná opakovaně — statický panel, dialog
StripDraw0 uchovaných pixelových bajtů (pohled na aktuální cíl vykreslování)dynamický celosnímkový obsah — obloha, silnice, gradienty, HUD a text. Ve výchozím stavu překresluje každý snímek; s always_dirty=False a .invalidate() kreslí na vyžádání
Particlespevný pooljiskry, stopy, krátké výtrysky

Pět typů vrstev podle uchovávané RAM: StripDraw drží nula bajtů, Tilemap a Particles jsou levné, Sprite závisí na bitmapě a uchovávaný Canvas stojí nejvíc

Text používá tyto vrstvy

Sekce “Text používá tyto vrstvy”
  • Canvas.text(x, y, s, fg, font, bg=None) složí glyfy v C přímo do plochy: žádná mezipaměť glyfů ani nová Bitmap či Sprite při každém volání. Plocha může být uchovávaný Canvas nebo pohled StripDraw, který míří na právě vykreslovaný pás. Jedna metoda pokrývá obojí.
  • picogame_font.render_text(...) vyrastruje řetězec do PAL8 Bitmap, který ukážeš jako Sprite, vhodné pro pohyblivý text (plovoucí čísla poškození), kde sprite stejně chceš.

Dynamický text přes pohled StripDraw neuchovává bitmapu glyfů ani panelu. Kreslicí funkce ale spotřebuje CPU pokaždé, když se oblast překreslí.

Rozhodovací matice (HUD, panely, obrazovky)

Sekce “Rozhodovací matice (HUD, panely, obrazovky)”
CoSprávná cestaRAM
Dynamický, tenký HUD (skóre / životy)StripDraw (+ view.text), přes scene nebo pg.render0 uchovaných pixelů
Statický, velký panel (boční panel, titulní grafika, nápověda)Canvas nakreslený jednou (canvas.text), držený jako vrstvaw*h*2 (nakreslí se jednou a používá opakovaně)
Statický panel + pár živých číselstatický Canvas na fixní část + malý StripDraw na číslamalá
Panel/dialog/menu uvnitř živé scény (překresluje jen při změně)StripDraw na vyžádání (always_dirty=False, .invalidate() při změně), přidaný do scény0 uchovaných pixelů
Jednorázová obrazovka (titulní obrazovka / konec úrovně / konec hry)pg.render([stripdraw]) — procedurální pozadí + view.text, bez scény0 uchovaných pixelů
Pohyblivý text (plovoucí čísla poškození)picogame_font.render_text → Spritebitmapa o velikosti textu

Past, které se vyhnout: pás Canvas pro dynamický HUD. Canvas uchovává w*h*2 bajtů; pás 320×16 zabere trvale 10 KB a plnovýškový boční panel mnohem víc. Dynamický HUD patří na StripDraw bez uchovaných pixelů a při změně se znovu levně vykreslí v C. Po Canvas sáhni, jen když je obsah statický (nakreslen jednou a znovupoužit).

Další past: okamžitý pg.render přes živou retained scénu. Scéna neví, že render() změnil pixely, takže její další refresh() překreslí jen vlastní dirty regiony a na obrazovce nechá zbytky překryvu. Pokud vykreslená oblast zasahuje do hracího obdélníku scény (pauza, menu, meziscéna, banner), zavolej poté scene.invalidate() — nebo použij picogame_game.overlay(...), což je pg.render + scene.invalidate() v jednom volání. HUD pásy mimo hrací obdélník (top=/bottom= rezervy) to nepotřebují: scéna se jich nikdy nedotkne.

HUD bez uloženého bufferu panelu

Sekce “HUD bez uloženého bufferu panelu”

picogame_ui.HudBar tento postup už používá: jde o StripDraw bez vlastního bufferu, který se při změně vykreslí přes pg.render. Stejný vzor můžeš použít ručně pro HUD ve vyhrazeném pásu:

scene, bufA, bufB = picogame_game.setup(background=BG, strip_h=BAR, top=BAR)
hud = ui.HudBar(pg, board.DISPLAY, bufA, 0, 0, W, BAR, BG) # bez uchovaných pixelů
score = hud.label(FONT, 4, 3, INK, "SCORE 0") # vrací objekt popisku
# ... při změně:
score.set("SCORE %d" % pts)
hud.draw() # znovu složí v C, bez mezipaměti

Formátuj při změně, ne každý snímek. .set() přeskočí překreslení nezměněného řetězce, ale samotné formátování přes "%" při každém volání vytvoří nový řetězec. Formátuj v místě, kde se hodnota mění (jako výše), nebo při pravidelné kontrole ve smyčce porovnej poslední zobrazenou hodnotu: if pts != shown_pts: shown_pts = pts; score.set("SCORE %d" % pts). U plynule běžících hodnot nejdřív kvantuj na zobrazovanou jednotku (sekundy, procenta).

Nebo úplně ručně, například na titulní obrazovce bez scény a vlastních bufferů:

def draw_title(view, vx, vy, vw, vh):
view.clear(SKY)
view.text(60 - vx, 90 - vy, "PRESS A", INK, FONT) # místní bod = obrazovka - (vx, vy)
title = pg.StripDraw(draw_title, 0, 0, W, H)
pg.render(board.DISPLAY, [title], bufA, 0, 0, W, H, background=SKY) # bez uchovaných pixelů

Místní bod (0,0) pohledu view odpovídá bodu obrazovky (vx, vy). Při kreslení na souřadnice obrazovky proto odečti (vx, vy).

Překreslení na vyžádání: panel bez bufferu uvnitř scény

Sekce “Překreslení na vyžádání: panel bez bufferu uvnitř scény”

StripDraw ve výchozím stavu překresluje každý snímek (always_dirty=True), což se hodí pro oblohu nebo silnici, které se mění pořád. Ale vytvoř ho s always_dirty=False a překreslí se jen když zavoláš .invalidate() (nebo ho překryje jiná změněná vrstva). Tím vznikne panel bez vlastního bufferu uvnitř scény (dialog, stavový panel nebo menu), který se znovu nerasterizuje ani neodesílá, dokud se jeho obsah skutečně nezmění. Pak se jednou překreslí. Jde o alternativu k retained Canvas bez vlastního bufferu pro obsah, který je většinou statický, ale občas se musí aktualizovat.

panel = pg.StripDraw(draw_panel, x, y, w, h, always_dirty=False) # zahálí, dokud není invalidován
scene.add(panel, fixed=True)
# ... když se text změní:
panel.invalidate() # překreslí se jednou při dalším refresh

Tak fungují picogame_ui.SceneBox a SceneMenu: dialog nebo menu uvnitř scény se překreslí při show/hide/set_line, ne v každém snímku.

  • Pohyblivý objekt → Sprite. Velká mapa → Tilemap. Dynamický celosnímkový obsah nebo HUD → StripDraw. Statický panel používaný opakovaně → Canvas.
  • Dynamický HUD nikdy nepotřebuje Canvas. Když jsi napsal pg.Canvas(W, BAR, ...) na HUD, přepni na StripDraw.
  • Canvas se vyplatí, když je obsah statický a používá se opakovaně; buffer ušetří rasterizaci v každém snímku.
  • Oba scene.refresh() i pg.render() berou všechny typy vrstev, takže režim vybírej podle toho, kdy se má překreslit (každý dirty refresh vs. na vyžádání), ne podle toho, co kreslíš.
  • Bojuješ s MemoryError? Rozpočet, měření i arénu popisuje Správa RAM.
  • Přesné signatury Canvas, StripDraw, pg.render a Sprite: Reference.
  • Hotové widgety HUDu, dialogu a menu postavené na těchto cestách: Text a UI.
  • Podložení Canvasu znovu používanou pamětí místo nového bufferu: Ukládání a paměť (picogame_arena).