BeeLadybug — Documentazione Tecnica
Occhio del motore:
F2 overlay,
F3 slow-mo,
F4 freeze,
hitbox in spazio mondo
📁 Panoramica
BeeLadybug è l’occhio del motore, non una classe di gameplay. Vive in
src/debug/BeeLadybug.js e il barrel la re-esporta con
BEE_LADYBUG_DEFAULTS. Disegna hitbox AABB (e OBB se c’è una transform)
dentro la camera, e un pannello HUD dopo
ctx.restore(), in spazio schermo. Non usa F12 (DevTools) né la tilde:
sui layout italiani la tilde non è un tasto unico.
Quello che non è: il collision system, un profiler, un logger.
Il rosso sulle hitbox è overlap AABB dei draw-bounds, calcolato con un
BeeSpatialHash privato. Non è collisions.run() e non
è engine.spatial.
BeeEngine crea subito this.debug = new BeeLadybug(this)
e chiama attach(). L’overlay parte spento
(enabled = false). F2 lo accende. enableLadybug() fa
configure + attach + show: visibile al primo frame.
📁 Due pass di disegno
Il loop ufficiale chiama Ladybug in tre punti. L’ordine conta: le hitbox devono
vedere la camera, l’HUD no, i click arrivano prima di
input.endFrame().
Dentro BeeEngine.loop.
drawWorld gira solo se enabled.
drawOverlay e poll vengono chiamati sempre
(early-return se l’overlay è spento).
-
1. mondoScene, layer,
render. Poi, se enabled,debug.drawWorldprima direstore. -
2. schermo
ctx.restore, layer screen, UI, touch. Poidebug.drawOverlayconsetTransform(1,0,0,1,0,0). -
3. click
debug.pollsui tre pulsanti, poiinput.endFrame.
📁 Tasti e pulsanti
Il listener è su window keydown, confronta
event.code (quindi 'F2', non
event.key e non 'f2'). Ignora
event.repeat e fa preventDefault sui tre tasti.
F2 funziona anche a overlay spento. F3 e F4 solo se
enabled.
| Ingresso | Metodo | Effetto reale |
|---|---|---|
F2 / toggle() |
toggle / show / hide |
Accende o spegne enabled. Non tocca timeScale né
la pausa. |
| F3 / bottone SLOW | applySlowMo() |
Se time.paused, prima resume. Poi
alterna timeScale tra slowScale
(default 0.25) e 1, via engine.setTimeScale. |
| F4 / bottone STOP | toggleFreeze() |
time.togglePause(). Il mondo vede
dt = 0, il rAF e il draw continuano: ispezioni
le hitbox da fermo. |
| bottone 1x LIVE | restoreRealtime() |
Resume se in pausa, poi setTimeScale(1). |
I tre rettangoli sull’HUD (268×168, angolo
overlayX/Y default 12,12) fanno le stesse tre azioni.
Si accendono in rosso se lo stato corrente li riguarda (slow e non
frozen, frozen, live 1×).
📁 Chi viene disegnato
drawWorld ricalcola la lista ogni frame. Visita, con un
Set anti-duplicato e i figli ricorsivi:
engine.entities,
engine.scenes.currentScene.entities (fallback
engine.currentScene), i bucket di
engine.collisions.groups, e
engine.physics.bodies[i].entity.
Salta destroyed. L’AABB viene da
engine.getEntityDrawBounds: prima
entity.getWorldAABB(), poi il rect del
collider, altrimenti
worldX/Y (o x/y) +
width/height. Senza size positiva non c’è box.
Poi il tratto: se c’è entity.body.drawDebug lo chiama
(forma del body, non solo il rettangolo). Altrimenti, se la
transform ha transformPoint, traccia l’OBB locale
(0,0)→(w,h). Altrimenti strokeRect
sull’AABB.
📁 Colori: verde / rosso / grigio
Verde = active !== false e niente
overlap. Grigio = inattiva.
Rosso = la sua AABB si sovrappone a un’altra
AABB della stessa lista. Broadphase: hash a celle da 64px
(default di BeeSpatialHash), poi test AABB-AABB.
L’overlay scrive verde=ok rosso=collide: collide
qui vuol dire “i rettangoli di disegno si toccano”, non
“il gruppo player/enemy ha sparato un evento”.
L’HUD legge la lista dell’ultimo
drawWorld: FPS da time.fps, ciclo da
unscaledDt * 1000, scala, RUN/FREEZE, conteggio
attive / in memoria. Se chiami solo drawOverlay a
mano, i numeri restano quelli (o zero) del frame precedente.
📁 Dove è facile sbagliare
Il rosso non è collisions.run().
Ladybug ha il suo hash. Due sprite che si coprono diventano
rosse anche se non sono nello stesso gruppo e anche se la
scena non chiama mai il collision system.
F3 da freeze scongela.
applySlowMo fa resume prima di
toccare la scala. F3 non è “slow anche in pausa”.
Il click sull’HUD arriva anche al gioco.
poll legge input.mouse.wasPressed
(coordinate canvas, spazio schermo) e non lo consuma. Lo
stesso frame può far partire un impulso, uno spawn, un UI
click. I tasti F* invece fanno preventDefault.
Le chiavi sono event.code.
Default 'F2' / 'F3' / 'F4'
coincidono col code dei function key. Se rinomini con
configure({ toggleKey: 'KeyD' }) va. Con
'd' o 'D' no.
F3/F4 muti a overlay spento. F2 è l’unico
tasto vivo quando enabled è false. Il costruttore
del motore ha già fatto attach(): non serve
riattaccare il listener a ogni start.
📁 Esempio: accendi, configura, ispeziona
📁 Riepilogo API
Fluent: configure, attach,
detach, show, hide,
toggle, applySlowMo,
toggleFreeze, restoreRealtime
ritornano this. Default frozen:
BEE_LADYBUG_DEFAULTS.
| Membro | Ritorna | Scopo |
|---|---|---|
BEE_LADYBUG_DEFAULTS |
oggetto frozen | toggleKey F2 · slowKey F3 · freezeKey F4 · slowScale 0.25 · colori active/colliding/inactive · overlay 12,12. |
new BeeLadybug(engine, options?) |
BeeLadybug |
Parte enabled: false, listener non
attaccato. Il motore lo costruisce e fa
attach() da solo. |
configure(options) |
this |
Merge sui default. Non tocca
enabled né il listener. |
attach() / detach() |
this |
keydown su window. Seconda
attach è no-op. |
show / hide /
toggle |
this |
Flag enabled. Non stacca i tasti. |
applySlowMo() |
this |
Resume se paused, poi toggle scala
slowScale ↔ 1. |
toggleFreeze() |
this |
time.togglePause(). No-op senza
engine.time. |
restoreRealtime() |
this |
Resume + scala 1. |
drawWorld(ctx) |
— | Raccoglie entity, refresh overlap, fill+stroke hitbox. Chiamare dentro la camera. |
drawOverlay(ctx) |
— | HUD 268×168, reset transform, pulsanti. Dopo
restore. |
poll() |
— | Hit-test mouse canvas sui tre bottoni. Prima di
endFrame. Non consuma
wasPressed. |
destroy() |
— | detach, enabled = false,
svuota liste/Set/bottoni. Il motore lo chiama in
BeeEngine.destroy. |
gioco.debug /
gioco.enableLadybug(options?) |
istanza | Stessa coccinella. enableLadybug
configura, attacca e show. |