Cosa c'è in un motore di fisica proiettile?

In questo articolo, esamineremo l'uso della fisica per simulare gli effetti del proiettile in giochi come Angry Birds. Vedremo le basi dell'utilizzo della fisica 2D nello spazio del mondo di gioco, come la creazione di corpi e l'applicazione di impulsi e forze.

Motori di fisica

Perché usare un motore fisico? Cosa fa in realtà? 

Un motore fisico ci aiuta a fare due cose molto importanti per il nostro gioco:

  1. individuare collisioni tra i nostri oggetti di gioco.
  2. Simulare le forze e il movimento risultante dei nostri oggetti da quelle collisioni ...

Rilevamento delle collisioni: I giochi non sarebbero molto divertenti se il tuo personaggio cadesse dal pavimento prima che tu potessi saltare, o se, quando colpisci un nemico con il piede, cadi. Il rilevamento delle collisioni mediante un motore fisico consente un ascolto dei contatti molto preciso e consente di simulare le interazioni tra gli oggetti forze.

Simulazione della forza:Dopo una collisione, cosa dovrebbe accadere? Si potrebbe chiamare la logica del gioco, si potrebbe rimbalzare, l'altro oggetto del gioco potrebbe rimbalzare o non si può semplicemente spostare oltre. Tutto questo è gestito dietro le quinte, usando le forze calcolate del motore. Ma le forze non si limitano al contatto; possono verificarsi altre forze, come la gravità e gli impulsi, senza che gli oggetti possano realmente toccarsi. Le forze influenzano le azioni di gioco e il movimento di oggetti, personaggi e persino lo stesso spazio del mondo.

.

Guarderemo Come i motori fisici funzionano a breve, ma prima lasciamo guardare che cosa motori che potresti voler usare, e perché potresti decidere di usarli, in base alle tue particolari esigenze.

Scegliere il tuo motore

Quando inizi a pensare di usare la fisica nel tuo gioco, dovrai decidere come affrontare il problema e cosa richiederà il tuo gioco in termini di simulazione. Hai due opzioni per usare la fisica:

  1. Utilizzare un motore fisico esistente.
  2. Creare una simulazione fisica personalizzata

Utilizzo di un motore fisico esistente

Esistono molte opzioni eccellenti per i motori fisici predefiniti e pronti all'uso. Una delle scelte più popolari per i giochi 2D è Box2D; è un motore scritto C ++ nativo, ma ha wrapper, porte ed estensioni che ne consentono l'utilizzo in quasi tutte le piattaforme 2D. Un'altra scelta popolare è il chipmunk 2D, che viene utilizzato in diversi motori di gioco tradizionali, come Cocos2D.

Creazione di un motore personalizzato

In alcuni giochi, l'utilizzo di un motore predefinito non è necessariamente la scelta ottimale. L'utilizzo di un motore fisico può causare un sovraccarico non necessario quando non è richiesta la sua piena funzione. In casi come semplici platform o giochi di tipo brick-breaker, in cui non è necessario il rilevamento delle collisioni pixel-perfect o alcune delle altre funzionalità di un motore, è possibile utilizzare inutilmente risorse che potrebbero essere meglio impiegate altrove. 

Costruire il tuo motore può darti più flessibilità sul prodotto finale, ma può anche complicare le cose se hai a che fare con più di poche istanze di personaggi e oggetti.

Il ciclo di gioco

Prima di discutere le proprietà e i dettagli di una simulazione fisica, diamo un'occhiata a come viene chiamato all'interno del loop della scena di gioco.

Il ciclo di gioco tipico verrà eseguito nel seguente modo per ciascun fotogramma, nell'ordine:

  1. Ingresso
  2. Aggiornamento / Game Logic
  3. Simula la fisica del gioco
  4. Render Screen / Scene

Ciò significa che il calcolo della fisica risultante è l'ultima attività eseguita nel ciclo prima che lo schermo venga aggiornato. Questo ha senso, poiché il punto della simulazione è reagire a ciò che è accaduto nello spazio del mondo del gioco. 

Nota che questa immagine mostra che la fisica viene simulata durante ogni fotogramma del tuo ciclo di gioco. Ciò può comportare un sovraccarico di grandi dimensioni se la simulazione diventa eccessivamente grande o complicata. Per questo motivo, è meglio mantenere la gestione del gioco e le chiamate alla simulazione e ai suoi ascoltatori limitati. 

Fisica a frequenza fissa e fisica dipendente da frame

Ha senso ora discutere due diversi metodi di interrogazione della simulazione fisica: tassi fissi e frame-dipendenti. Considera il (Vuoto) aggiornamento: metodo coerente nella maggior parte dei circuiti di gioco. Questo ciclo è chiamato una volta per fotogramma della scena del gioco. Se viene chiamato il metodo "simula fisica" (Vuoto) aggiornamento:, la fisica del tuo mondo di gioco dipenderà dal tuo frame-rate, e questo può portare ad alcune simulazioni mosse e irrealistiche. In iOS, questo effetto è mitigato dall'uso di usesPreciseCollisionDetection Proprietà booleane, ma che dire in altri motori? 

Considera il seguente segmento di codice:

 CFTimeInterval timeSinceLast = currentTime - self.lastUpdateTimeInterval; self.lastUpdateTimeInterval = currentTime; if (timeSinceLast> 1) timeSinceLast = 1.0 / 60.0; 

Questo codice è progettato per compensare i problemi con il valore delta per tempo. Considera una situazione in cui stavi giocando al telefono e ricevetti una chiamata: sarebbe stato utile per il tuo gioco ripristinare il delta indietro al previsto 1/60 (per un gioco a 60 fps). 

Questo è in realtà il primo passo in una discussione sul disaccoppiamento della simulazione fisica dal passo temporale del (Vuoto) aggiornamento: metodo. Mentre un intervallo di tempo modificato sarebbe di certo di aiuto in una chiamata di simulazione fisica più stabile, non si adatta a tutte le situazioni. Per fare ciò, dovremmo effettivamente farlo rimuovere la chiamata di simulazione fisica dal ciclo di rendering del gioco e crea un ciclo fisso all'interno del quale potrebbe essere eseguito. Per esempio; se il tuo gioco è pensato per funzionare a 60 fps, puoi impostare la fisica per simulare 60 volte al secondo. Questo disaccoppiamento rimuove qualsiasi preoccupazione relativa ai problemi di rendering causando un feedback discontinuo nella simulazione fisica.

In breve, sii coscienzioso nella tua implementazione della fisica. Se ti trovi a utilizzare un motore in un ambiente in cui stai tassando le risorse di sistema, considera una simulazione fisica a step fisso per mantenere l'equità e la fedeltà.

Dal corpo di Sprite al corpo di fisica

UN folletto è un'immagine resa allo schermo del tuo gioco. Uno sprite non ha proprietà di default all'interno di una simulazione fisica. Puoi "fingere" alcuni dei comportamenti di un mondo fisico usando le proprietà di uno sprite come un riquadro di delimitazione e una chiamata di intersezione, ma poi devi scrivere tu stesso tutta la logica risultante. Non sarebbe meglio se il gioco potesse gestire tutto questo per noi?

In questi frammenti, creiamo uno sprite:

 SKSpriteNode * sprite = [SKSpriteNode spriteNodeWithImageNamed: @ "image"]; sprite.position = posizione; [self addChild: sprite];

... e chiama una collisione tra due folletti:

-(vuoto) aggiornamento: (CFTimeInterval) currentTime / * Chiamato prima che ogni frame sia reso * / if (CGRectIntersectsRect (sprite1.frame, sprite2.frame)) // fa qualcosa

Forme del corpo

Fisica corpi sono forme "semplici" che definiscono le dimensioni e la forma approssimative del tuo sprite, o forse definiscono un'area attiva del tuo sprite. Considera quanto segue:

Un corpo fisico non è predefinito dall'immagine del tuo sprite ed è tipicamente invisibile all'interno del gioco. Crei la forma dinamicamente, spesso chiamando un metodo per disegnare la forma che comporterà il corpo o utilizzando un programma per aiutarti a disegnare e definire il corpo. Quindi colleghi il corpo allo sprite e ottieni l'accesso agli effetti simulati e alle proprietà assegnate a quel corpo.

Puoi avere più corpi fisici legati a un singolo sprite. Prendi, ad esempio, un folletto di un eroe che porta una spada. Avrebbe senso creare un corpo per il personaggio dell'eroe e un altro per la spada che porta. Questo ti permetterebbe di creare una logica di gioco basata su collisioni tra diversi corpi. 

In pseudocodice, la logica sarebbe simile a questa:

// fisica logica - (void) physicsCollisionDidOccur switch (collision bitmask) case (Player || Sword): // non fare nulla; rompere; case (Player || Enemy): // ouch !!; rompere; case (Sword || Enemy): // do damage !!; rompere; default: // non fare nulla; rompere; 

Riferire il corpo fisico allo Sprite

Considera la situazione di un gioco spaziale, in cui hai una nave eroe e una nave nemica:

Probabilmente vorrai rendere il corpo fisico del lettore un po 'più piccolo dell'immagine di sprite di base per due motivi:

Enhanced Visual Collision: Quando un giocatore entra in collisione con un oggetto nel tuo gioco, creando questo corpo fisico più piccolo, le immagini dello sprite si sovrappongono temporaneamente al punto di contatto, che ha un bell'aspetto visivo. (Oltre a questo punto: quando disegni i valori z, mantieni il carattere del tuo giocatore nella parte anteriore della gerarchia della scena.)

Equità percepita dall'utente: Per cercare di rendere il tuo gioco "giusto" al giocatore, tieni il corpo in collisione limitato alla maggior parte dell'oggetto e lontano da sporgenze estranee come la pinna posteriore dell'immagine qui sopra. In questo modo, non ci saranno "colpi economici" per infastidire i giocatori del tuo gioco. Viceversa, di solito si desidera che il corpo fisico del nemico abbia almeno la dimensione dell'immagine di base; se diamo al nostro eroe dello spazio un laser per sparare al suo nemico, un corpo nemico leggermente troppo grande rende più ragionevole per il nostro giocatore ottenere un colpo. Considera anche questo stesso approccio per le tessere in un gioco platform o puzzle che richiede al tuo giocatore di saltare da una piattaforma all'altra. I giocatori sono abituati a un po 'di "grazia" in questi tipi di giochi; estendere il corpo della fisica un po 'ti aiuterà a mantenere il tuo gioco ragionevolmente "giusto".

Tipici vincoli del motore 2D

Esistono due tipi principali di corpi fisici:

  1. Corpi a bordo
  2. Corpi basati sul volume

Un corpo basato sul bordo è una linea statica e immobile che crea un confine per gli altri corpi con cui entrare in collisione. Ha un spazio negativo al suo interno che non ha alcun effetto su nessun corpo. Una grande applicazione di questo sarebbe creare un contorno attorno allo schermo per contenere qualsiasi corpo all'interno.

Un corpo basato sul volume ha volume e massa e può essere dinamico o statico. Poiché questi corpi hanno massa, gli oggetti li rimbalzano e possono essere influenzati dai contatti di forza. I corpi basati sul volume possono essere una delle quattro forme principali:

  1. Cerchio
  2. Rettangolo
  3. Catena
  4. Poligono complesso

Esistono alcuni vincoli all'utilizzo di corpi all'interno del tipico motore fisico 2D. Ecco i due limiti principali:

Corpi fisici convessi 

Se una forma è convesso, significa che nessun angolo interno è inferiore a 180 gradi. 

Per essere chiari, è possibile eseguire simulazioni fisiche su forme concave, ma il costo di elaborazione è così elevato che non è semplicemente realistico per il 2D, specialmente quando si esegue su un dispositivo palmare o meno potente. Concavo-piace le forme possono essere costruite collegando tra loro due forme convesse usando qualcosa chiamato a Giunto statico. I giunti sono un'altra grande funzionalità disponibile con i motori 2D, ma non rientrano nell'ambito di questa discussione.

Corpi di fisica rigida

Quando una palla colpisce un muro, nel mondo "reale" succederà qualcosa del genere:

Il tuo personaggio folletto può subire questo tipo di trasformazione, ma il suo corpo fisico non può. Puoi controllare certe proprietà del corpo per influenzarne la "forza di rimbalzo", ma in realtà non può avere una forma mutevole. Questo è noto come a Corpo rigido, il che significa che il corpo stesso non può essere deformato o schiacciato.

Proprietà di un corpo di fisica

Diamo una rapida occhiata a quali sono alcune delle proprietà più utili disponibili su un corpo fisico tipico:

  1. Restituzione è una misura di quanto è "rimbalzante" un oggetto. Più formalmente, è la misura della quantità di energia che un oggetto conserva dopo che si è scontrata con un altro oggetto.
  2. Densità è la misura di quanto sia "pesante" un oggetto. È usato come una qualità relativa, per esempio, una roccia sarebbe più densa di una palla, quindi quando la palla colpisce la roccia, sarà influenzata più pesantemente.
  3. Attrito è la misura di quanto è "scivoloso" un oggetto. Questo viene usato quando un oggetto scorre lungo un altro e determina quanto tempo impiegherà per fermarsi.
  4. Se un corpo è dinamico, quindi le forze imposte dal mondo e altri oggetti avranno un effetto; se è un statico corpo, allora non lo faranno.
  5. Rotazione è in genere una variabile booleana che può essere impostata su un corpo fisico. In alcuni casi potresti voler limitare un corpo e non permetterlo di ruotare, ma vuoi che le forze siano ancora applicate a quell'oggetto.

La maggior parte dei motori ha più proprietà disponibili di questa, ma ai fini di questa discussione, queste saranno sufficienti per iniziare.

Moto e Momento


In un mondo di fisica simulato, i corpi vengono mossi dall'applicazione di forze e impulsi.

forze: Generalmente le forze generali influenzano i corpi più gradualmente degli impulsi. Sono una forza costante applicata su un tempo unitario (come la gravità o un motore).

Impulses (Impulse Forces): Gli impulsi sono regolazioni immediatamente applicate all'impulso di un corpo. Gli impulsi vengono solitamente applicati a una simulazione basata sull'input dell'utente.

Cosa Avanti?

Ora che hai compreso la teoria, il modo migliore per rafforzare la tua comprensione dei motori di fisica dei proiettili è costruirne uno tu stesso. Successivamente, analizzerò il codice per un semplice gioco basato sulla fisica che ho scritto, in modo che tu possa vedere esattamente come funziona!