Repository navigation
Core Input e Eventi
Il core distingue gli eventi discreti (pressione di un tasto, click, ridimensionamento) dallo stato continuo dei comandi (un tasto tenuto premuto). La distinzione conta: i primi arrivano tramite SDL_PollEvent(), il secondo si legge durante l'aggiornamento.
SDL_PollEvent -> Game::dispatchEvent -> Scene::event -> eventuale sottoclasse
Game::processEvents() svuota la coda SDL prima di aggiornare le scene. dispatchEvent() gestisce prima i comandi globali, poi distribuisce gli eventi:
- gli eventi di finestra raggiungono tutte le scene, perché ciascuna
Viewpuò dover ricalcolare il viewport; sul ridimensionamento viene aggiornata anche laWindow; -
Ctrl+Shift+Su/Giùmodifica la scala temporale globale; -
Vattiva/disattiva il sonoro tramiteAudio::toggleMute(), anche nei menu e in pausa; la ripetizione automatica del tasto viene ignorata e il comando non interviene durante l'inserimento di testo; - gli altri eventi partono dalla scena in cima allo stack e scendono fino alla prima scena
blocking.
Scene::event() aggiorna il viewport per gli eventi di finestra. Se ridefinisci event(), chiama prima la versione base (o GameScene::event() se derivi da GameScene), così non perdi questo comportamento e gli eventuali comandi già previsti. GameScene inoltra gli eventi di finestra anche ai propri overlay.
La richiesta di chiusura dell'applicazione o della finestra viene gestita da Game. Il tasto Esc viene invece distribuito alle scene: può aprire la pausa nel gioco o annullare lo strumento nell'editor. Una scena bloccante impedisce che lo stesso tasto raggiunga il gameplay sottostante.
Per un'azione che deve scattare una volta, controlla SDL_EVENT_KEY_DOWN e !evt.key.repeat dentro event():
void MyScene::event(SDL_Event& evt)
{
GameScene::event(evt);
if (evt.type == SDL_EVENT_KEY_DOWN &&
evt.key.scancode == SDL_SCANCODE_SPACE && !evt.key.repeat)
player()->jump();
}L'esempio è schematico: jump() appartiene alla classe del giocatore del progetto, non a Object del core. Il controllo del tipo di evento deve precedere l'uso dei campi specifici di tastiera.
Per un movimento mantenuto mentre il tasto è premuto, leggi SDL_GetKeyboardState() durante l'aggiornamento. CustomPlatformer e ActionRPG impostano i comandi del personaggio in updateControls(), chiamato una volta per frame prima dei passi di updateWorld(). Attacchi e apertura dei menu passano invece da event().
Box2DPlatformer applica le forze dei controlli in PlatformerGameScene::updatePhysicsControls(), chiamato prima di ogni passo fisico. Box2D azzera le forze dopo ogni step: applicarle una sola volta per frame renderebbe il movimento dipendente da FPS e VSync. Camera ed eventi discreti conservano il proprio aggiornamento. Vedi timestep di Box2DPlatformer.
Le coordinate del mouse fornite da SDL sono nello spazio della finestra. Gli oggetti vivono nello spazio della scena. Prima di usare un click per selezionare o posizionare un oggetto nella scena di gioco, passa per la sua View:
PointF worldPoint = view()->mapToScene(mouseX, mouseY);
auto selected = objects(worldPoint);mapToScene() applica posizione della camera, zoom, viewport, rapporto d'aspetto e orientamento dell'asse Y. Usare direttamente mouseX e mouseY come coordinate della scena può funzionare per caso a una risoluzione e rompersi al ridimensionamento. L'editor usa questa conversione per i click; il percorso inverso è mapFromScene().
Una UIScene in cima allo stack può intercettare l'input e fermare l'aggiornamento del gioco impostando setBlocking(true). Con false, l'evento continua anche verso le scene sottostanti. Non esiste un flag generico «evento consumato»: la propagazione è determinata da blocking, quindi una UI non bloccante deve essere progettata tenendo conto dell'eventuale input ricevuto anche dalla scena di gioco.
Il rendering non segue questa regola: anche con una UI bloccante, le scene sotto vengono comunque disegnate. Questo permette di mostrare un menu di pausa sopra il gioco fermo.
Prosegui con Scene, oggetti e scheduling.
- Panoramica
- Diagramma delle classi
- Architettura e game loop
- Sequenza di un frame
- Input ed eventi
- Scene e oggetti
- Rendering e coordinate
- Sprite e testo
- UI e overlay
- Quadtree
- Servizi e asset
- Estendere il core
- Editor dei livelli
- LevelData e livelli JSON
- Shader