Text a UI
Tyhle moduly mění řetězce a stisky tlačítek na pixely: vykreslíš text z libovolného fontu, přidáš HUD label, vyvoláš dialogové okno nebo spustíš menu s kurzorem. Holé signatury najdeš v referenci; kompletní hry od začátku do konce ukazují tutoriály.
picogame_font
Sekce “picogame_font”Vykreslí řetězec libovolným fontio fontem (typicky přibaleným terminalio.FONT) do picogame.Bitmap - žádné extra soubory s assety, žádný reflash. Sáhni po něm, když chceš ostrý text z fontu, který už máš, a nevadí ti HUD pozadí.
render_text(pg, font, text, fg, bg=None)- poskládátextdoPAL8bitmapy a vrátí n-tici(bmp, w, h)(bitmapu plus rozměr v pixelech).fg/bgjsou wire barvy zpg.rgb565(...).bg=Nonenechá pozadí průhledné (index palety 0); neprůhlednébgznamená, že překreslení úplně přepíše starý text, takže HUD aktualizace nepotřebují samostatný clear.render_text_pal(pg, font, text, fg, bg=None)- to samé jako výše, ale vrátí(bmp, w, h, palette). Podrž sipalette(array('H')) a měňpalette[1](barvu fg) pro živé barevné mihotání bez přestavování bitmapy - CBitmapčte ten samý buffer.Label(pg, font, x, y, fg, bg)- umístěný label vykreslený okamžitě (dobré pro HUD nad obrazovkou, kterou vykreslíš sám)..set(text)- překreslí jen tehdy, když se text změnil; vrátíTrue, pokud ano,False, pokud přeskočil. Ne-řetězce převede přesstr()..move(x, y)- přemístí a vynutí překreslení na novém místě při dalšímset/draw..draw(display, buffer)- překreslí jen obdélník labelu přespg.render(jediný present)..w,.h- rozměr posledního vykresleného textu v pixelech.
import picogame_font, terminaliohud = picogame_font.Label(pg, terminalio.FONT, 4, 4, pg.rgb565(255, 255, 255), BG)# each frame, after you draw the screen:hud.set("SCORE %06d" % score) # rebuilds only on changehud.draw(board.DISPLAY, bufA) # repaints just its rectZáludnosti: Bitmap.palette není na zařízení Python atribut, takže pro mihotání musíš měnit palette pole z render_text_pal, ne bmp.palette. Nad živou, scrollující scénou použij radši picogame_ui.SceneLabel - okamžitý Label se pere se scene.refresh().
picogame_bitfont
Sekce “picogame_bitfont”Samostatný 8x8, 2bitový (4 odstíny, anti-aliasovaný/obtažený) bitmapový font s herními glyphy (kódy 0..31 jsou šipky/srdíčka/hvězda/nota/roury; 32+ je ASCII). Jeho vestavěné tmavé obtažení dává kontrast nad hrou bez HUD boxu, takže index 0 je průhledný a text je čitelný nad světem. Sáhni po něm pro plovoucí bojový text, “+10”, srdíčka nebo jakýkoli label, který chceš bez panelu na pozadí.
render_text(pg, text, fg=None, outline=None, mid=None, bg=None)- vykreslítextdoPAL8bitmapy a vrátí(bitmap, w, h). Čtyři odstíny se mapují na:0 -> bg/průhledné,1 -> outline,2 -> mid,3 -> fg. Výchozí barvy:fgbílá,outlinečerná,midstředně šedá; všechny jsourgb565wire barvy. Podporuje\npro více řádků. Předejbgpro neprůhledné pozadí (jinak je index 0 průhledný).- Konstanty symbolů (jednoznakové řetězce, které zřetězíš do textu):
ARROW_U,ARROW_D,ARROW_R,ARROW_L,BOXX,STAR,HEART,BALL,NOTE. GLYPH_W,GLYPH_H- obě8, velikost buňky na glyph.
import picogame_bitfont as bfbmp, w, h = bf.render_text(pg, "LIVES " + bf.HEART * 3) # white, outlined, transparentspr = pg.Sprite(bmp, x, y) # place anywherespr.scale = 2 # scale up for big textZáludnosti: žádná Label/widget třída tady není, jen render_text -> Sprite si spravuješ sám. Tenhle font je ekosystémová vrstva (grafika odvozená z circuitpython-stage, MIT), ne čistý bundle; pokud je RAM nadoraz, vrať se k picogame_font + terminalio. Viz memory pro RAM kompromis.
picogame_ui
Sekce “picogame_ui”Lešení pro UI: na kameře nezávislý HUD label, víceřádkové textové boxy a menu s kurzorem. Klíčové rozdělení je scene-layer vs. okamžité:
Scene*widgety (SceneLabel,SceneBox,SceneMenu) žijí ve scéně jakofixed(na kameře nezávislé) vrstvy, takže jescene.refresh()vykreslí každý frame bez extra draw volání. Tyhle použij nad živou, scrollující scénou.- Okamžité widgety (
Labelvpicogame_font,TextBox,Menu,HudBar) kreslí přespg.rendera jsou pro statickou obrazovku, kterou vykreslíš celou sám - nad živou scénou se perou sescene.refresh()a blikají.
Widgety založené na tick() vrací: vybraný index/buňku na A (potvrdit), ui.CANCEL (-2) na B (zpět), nebo None během navigace. Viz scene-format pro fixed vrstvu a hardware pro tlačítka.
SceneLabel(scene, pg, font, x, y, fg, bg) - jeden řádek textu připnutý nad scrollujícím světem.
.set(text)- překreslí jen při změně (vymění bitmapu spritu; dirty-rect ošetří staré/nové hranice). Prázdný řetězec sprite skryje, nezbyde žádná zbytková záplata pozadí.
SceneBox(scene, pg, font, x, y, w, h, fg, bg, nlines=3, key=None, border=None) - víceřádkový dialogový/stavový panel (Canvas + řádky SceneLabel) nad živou scénou, v jednom present bez blikání. key je barva, která je při skrytí průhledná (výchozí magenta); předej border pro 3D rám.
.show(lines)- naplní panel a nastaví text, pak ho zobrazí. Volej jednou, ne každý frame..hide()- udělá panel úplně průhledný a vymaže řádky..set_line(i, text)- aktualizuje jeden řádek na místě (bez překreslení Canvasu/rámu).
HudBar(pg, display, buffer, x, y, w, h, bg) - HUD proužek vykreslený mimo scénu, v oblasti, kterou si scéna rezervuje přes Scene(..., top=/bottom=). Scéna tam nikdy nekreslí, takže to každý frame nic nestojí; redraw() voláš jen při změnách HUD. buffer je libovolný scratch proužkový buffer (např. scénin bufA); bg je plochá barva.
.add(sprite)- uloží sprite (srdíčka, ukazatele) do baru; vrátí ho..label(font, x, y, fg, text=" ")- vytvoří textový sprite uložený v baru; vrátíSprite. Pamatuje si svůj font/fg proset_text..set_text(sprite, text)- znovu vykreslí label sprite vytvořený přes.label()..redraw()- překreslí proužek (plochý bg + viditelné sprity) v jednompg.render.
hud = ui.HudBar(pg, board.DISPLAY, bufA, 0, 0, W, BAR, pg.rgb565(10, 12, 24))hud_l = hud.label(terminalio.FONT, 4, 3, INK, "SCORE 0 LIVES 3")hud.redraw()# later, only when it changes:hud.set_text(hud_l, "SCORE %d LIVES %d" % (score, lives))hud.redraw()TextBox(pg, font, x, y, w, h, fg, bg, maxlines=6) - víceřádkový box v prostoru obrazovky (vyplněný obdélník + řádky textu) pro statické dialogové/bojové/menu obrazovky.
.draw(display, buffer, lines, force=False)- přeskočí překreslení, když selinesnezměnily; když už kreslí, jdou bg a každý řádek ven v jednompg.render(bez probliknutí prázdné výplně). Předejforce=Truepoté, co se obrazovka pod ním vymazala (např. celoobrazovkovýpg.render)..draw_line(display, buffer, i, text)- překreslí jeden řádek na místě, atomicky.
Menu(pg, font, x, y, items, fg, bg, *, title=None, rows=None, width=None, paged=True) - menu s kurzorem nad TextBox (okamžité; pro statické obrazovky). UP/DOWN navigují s auto-repeatem; draw() vykreslí značku > . rows=None zobrazí všechny položky (bez scrollu); nastav to pro scrollování dlouhého seznamu. paged=True (výchozí) skáče na okrajích o celou stránku (levné; plné překreslení jen na hranici stránky) - mnohem svižnější než řádkový scroll paged=False u téměř celoobrazovkových seznamů, protože tenhle hardware neumí panel hardwarově scrollovat. Klíčové argumenty jsou keyword-only (po *).
.tick(btn)- vrátí vybraný index na A,ui.CANCELna B, jinakNone..draw(display, buffer, force=False)- překreslí jen to, co se změnilo (nic / 2 dotčené řádky při pohybu kurzoru / celý box při scrollu).force=Truepřekreslí bezpodmínečně po vymazání.
bmenu = ui.Menu(pg, terminalio.FONT, 8, H - 72, ["ATTACK", "MAGIC", "HEAL", "FLEE"], WHITE, NAVY)# each frame:act = bmenu.tick(btn) # index on A, ui.CANCEL on B, else Nonebmenu.draw(board.DISPLAY, bufA)SceneMenu(scene, pg, font, x, y, items, fg, bg, title=None, rows=None, width=None, border=None, paged=True) - to samé menu, ale postavené na SceneBox, pro použití nad živou scénou (bojové akce, popup ve hře). Stejná navigace/stránkování jako Menu.
.show(sel=0)- zobrazí ho (resetuje kurzor). Od té chvíle ho vykresluje scéna - žádné volánídraw()..hide()- skryje ho..tick(btn)- stejný kontrakt návratu jakoMenu; překreslí jen řádky, které se změnily.
GridCursor(cols, rows, tx=0, ty=0, wrap=False) - čistě logický 2D kurzor pro bojiště, inventář dlaždic nebo match-3. Vlastní pohyb (auto-repeat D-padu) a potvrzení/zrušení; mřížku a zvýraznění na (cursor.tx, cursor.ty) kreslíš ty. wrap=True na okrajích zalomí, jinak omezí (clamp).
.tick(btn)- vrátí n-tici(tx, ty)na A,ui.CANCELna B, jinakNone..tx,.ty- aktuální buňka..index(property) -ty * cols + tx, šikovné pro indexování plochého seznamu.
cur = ui.GridCursor(N, N) # N x N board# each frame:pick = cur.tick(btn) # (tx, ty) on A, ui.CANCEL on B, else None# you draw the highlight yourself at (cur.tx, cur.ty)Záludnosti: největší past je míchání těchhle dvou rodin - okamžité Menu/TextBox nad živou scénou se vymaže tím, jak Display posílá proužky přes něj (prostě “zmizí”); použij tam jeho Scene* dvojče. Výchozí heuristika width u menu (~11 px/znak) nadhodnocuje velikost u úzkého fontu a může utéct mimo obrazovku - předej width= pro dlouhé labely nebo celoobrazovkové seznamy. SceneBox.show() se volá jednou, ne každý frame.
picogame_options
Sekce “picogame_options”Menu nastavení/hodnot postavené na picogame_ui.SceneBox, pro vzor nastavení / obchod / nábor. Sáhni po něm, když obyčejné ui.Menu (vyber index) nestačí, protože každý řádek nese upravitelnou hodnotu: volbu obtížnosti, krokovač hlasitosti, přepínač zvuku plus prostou akci jako “Start”. Je to scene-layer widget, takže ho použij nad živou scénou; úpravy hodnot se zobrazují okamžitě. Je záměrně provizorní - držený mimo zamrzlé ui jádro, aby se mohl vyvíjet.
OptionsMenu(scene, pg, font, x, y, w, rows, fg, bg, title=None, border=None)-rowsje seznam slovníků, každý skind:choice-{"key", "label", "kind": "choice", "choices": [...]}; cykluje seznamem. (Neprázdnéchoicesje povinné - jinak rovnou vyhodíValueError.)stepper-{"key", "label", "kind": "stepper", "value", "min", "max"}; ctí i volitelný"step"(výchozí 1). Omezí namin/max.toggle-{"key", "label", "kind": "toggle", "value": True/False}.action-{"key", "label", "kind": "action"}; žádná hodnota, jen vrátí svůj key na A.
.show(sel=0)- zobrazí a vykreslí (volej jednou);scene.refresh()ho pak vykresluje..hide()- skryje panel..tick(btn)- UP/DOWN posunou kurzor; LEFT/RIGHT mění hodnotu vybraného řádku živě (steppery/choices auto-repeatují při držení; toggle se překlopí jen na čerstvém stisku, takže nemůže oscilovat). Vrátíkeyvybraného řádku na A,ui.CANCELna B, jinakNone..value(key)- kdykoli přečte aktuální hodnotu řádku:choicevrátí vybraný řetězec,stepperint,togglebool;None, pokud takový key není.
import picogame_options as optmenu = opt.OptionsMenu(scene, pg, font, 40, 40, 240, [ {"key": "diff", "label": "Difficulty", "kind": "choice", "choices": ["Easy", "Normal", "Hard"]}, {"key": "vol", "label": "Volume", "kind": "stepper", "value": 7, "min": 0, "max": 10}, {"key": "snd", "label": "Sound", "kind": "toggle", "value": True}, {"key": "done", "label": "Start", "kind": "action"},], WHITE, NAVY, title="OPTIONS")menu.show()while True: btn.poll() k = menu.tick(btn) if k == "done": diff = menu.value("diff") # read live values on the action row elif k == opt.CANCEL: menu.hide() scene.refresh() # paints the menu - no draw() callZáludnosti: importuje CANCEL z picogame_ui, takže opt.CANCEL a ui.CANCEL jsou to samé -2. Protože je to SceneBox widget, potřebuje pod sebou živý scene.refresh() - na statické obrazovce vykreslené čistě přes pg.render se nevykreslí.