Domanda

In che modo i giochi con gravità gestiscono la relazione tra oggetti in movimento come giocatori, mostri o oggetti e il pavimento? Il giocatore "cade costantemente in" quot? il pavimento ed essere rimbalzato su?

Due modi per reagire alle collisioni che ho riscontrato sono spostare il giocatore nella sua posizione precedente prima della collisione e testare la nuova posizione prima di spostarsi per vedere se si tradurrebbe in una collisione, ma non vedo come uno di questi potrebbe avere a che fare con una piattaforma che sta salendo verso l'alto e deve essere in grado di sollevare il giocatore. Sto guardando questo dal punto di vista della progettazione di giochi 2D, ma immagino che lo stesso problema si verifichi nella progettazione di giochi 3D. Qualche suggerimento? Qualche riferimento che dovrei controllare? Grazie.

È stato utile?

Soluzione

Potresti dare un'occhiata alle Domande frequenti sulla gravità di GameDev.net per alcune informazioni di base.

Dato che stai realizzando un gioco e non un modellatore di fisica estremamente preciso di quanto possiamo cavartela facendo Integrazioni di Eulero . Se la tua necessità di accuratezza aumenta il metodo di integrazione più popolare che vedo usato è un Runge-Kutta (RK4 ) integrazione . Molto probabilmente non avrai bisogno di questi per un gioco semplice ma sono sicuramente usati in simulazioni fisiche più avanzate e giochi 3d. Lo svantaggio dell'utilizzo di RK4 è una complessità leggermente aumentata e leggermente più lenta. È molto accurato però, ma per ora, restiamo fedeli al buon ole Euler.

Ho fatto una domanda simile, " Come posso applicare la gravità al mio gioco della palla che rimbalza " e ho ottenuto diverse risposte valide? La prima cosa che farai è scegliere una costante di gravità arbitraria per il tuo gioco. Nella mia applicazione a palla che rimbalza uso una costante di gravità predefinita di 2000 px / s. Ti consigliamo di giocare con questa costante di gravità per ottenere l'effetto desiderato per il tuo gioco particolare.

Successivamente, devi assicurarti di rendere il tuo gioco e aggiornare gli oggetti di gioco in modo indipendente. Questo per evitare che gli oggetti del gioco si muovano molto velocemente su computer veloci e rallentino su computer lenti. Vuoi che la fisica e la velocità con cui i tuoi oggetti si muovono siano indipendenti dalla velocità del computer. Un buon articolo su questo è Fisica del gioco: correggi il tuo tempo! .

Quindi, come possiamo farlo? Tieni traccia di quanto tempo è trascorso dall'ultima chiamata al tuo metodo di aggiornamento. Ho creato 2 thread, anche se non è direttamente necessario. Ho un thread di aggiornamento del gioco e un thread di rendering. Il thread di aggiornamento controlla l'aggiornamento delle posizioni degli oggetti di gioco. Il thread di aggiornamento sa quando è stato chiamato in precedenza, l'ora corrente e da quel momento calcola il tempo trascorso da quando è stato chiamato il metodo di aggiornamento.

Per applicare la gravità aggiungeremo semplicemente alla velocità Y del nostro oggetto per la nostra costante di gravità moltiplicata per il tempo trascorso.

private long previousTime = System.currentTimeMillis();
private long currentTime = previousTime;

public void updateGame()
{
    currentTime = System.currentTimeMillis();
    float elapsedSeconds = (currentTime - previousTime) / 1000f; 

    foreach(GameObject gameObject in gameObjects)
    {
        // Apply gravity to velocity vector
        gameObject.velocity.y += (gravityConstant * elapsedSeconds); 

        // Move objects x/y position based off it's velocity vector
        gameObject.position.x += (gameObject.velocity.x * elapsedSeconds); 
        gameObject.position.y += (gameObject.velocity.y * elapsedSeconds);

    }

    checkCollisions();

    previousTime = currentTime;
}

Ciò sposterà tutti i tuoi oggetti in base al loro vettore di velocità e applicherà la gravità in base alla tua costante di gravità. Ma soprattutto lo fa indipendentemente dalla velocità del computer!

Per rispondere alla tua altra domanda, sì, gli oggetti avranno costantemente la "forza" di gravità sul loro vettore y. Quindi si scontrerà costantemente con il pavimento. Tuttavia, una cosa che vuoi fare è usare un valore Epsilon per portare a zero la velocità del tuo gameObject. Quindi, durante il rilevamento delle collisioni come parte del processo di potatura, di solito è possibile saltare il controllo se un oggetto non mobile si scontra con qualcosa (non viceversa!).

Quello che mi piace fare delle collisioni è quando trovo gli oggetti che si scontrano (penetrandosi a vicenda), li spingerò via per la loro minima distanza di traduzione (MTD) che li separa. Questo passaggio è fondamentale, altrimenti otterrai il bug più frequente nei giochi di oggetti "bloccati". muoversi agilmente insieme. Una volta separati, calcolo la risposta alla collisione.

Usando questo metodo funzionerà bene nello scenario descritto di una piattaforma in aumento. La piattaforma continuerà a salire, il gameObject si separerà usando l'MTD tra se stesso e la piattaforma e si alzerà naturalmente con i

Altri suggerimenti

Un approccio usato in alcuni giochi è imbrogliare: avere uno stato separato per camminare contro l'aria. Mentre cammina, il motore di gioco può determinare la pendenza della superficie da percorrere e, se non troppo ripida, spostare il personaggio nella direzione della superficie, oltre a dare al personaggio il corretto posizionamento verticale rispetto alla superficie.

Per quanto riguarda la fisica, sto diventando un fan dell'integrazione dei verlet come descritto in Gamasutra : Fisica avanzata dei personaggi . Semplifica le equazioni di aggiornamento della fisica (non è necessario tenere traccia della velocità!) E semplifica le collisioni (non è necessario regolare la velocità!). Detto questo, ha alcune sfumature se hai bisogno di precisione.

Non sono specificamente un programmatore di giochi, ma questa è la mia comprensione:

  • in un mondo ideale con una "frequenza di fotogrammi infinita", rileveresti la collisione proprio nel momento in cui si è verificato, e utilizzeresti un po 'di fisica standard per modellare le nuove velocità e accelerazioni dei corpi a seguito della collisione ( vedere un manuale di meccanica delle scuole superiori standard o vari libri intitolati cose come " Physics for Games Programmers ")
  • in realtà, poiché hai un frame rate fisso e quindi i corpi si muovono solo con una certa granularità, di solito devi aggiungere un trucco extra, come calcolare in anticipo il percorso relativo che i corpi percorreranno sul frame successivo e vedere se uno dei percorsi si interseca
  • se si intersecano, allora il punto di intersezione sarà in realtà una stima , ma leggermente imprecisa, del punto in cui i corpi si sarebbero realmente scontrati; hai quindi la scelta di non preoccuparti e prendere quella stima come punto di intersezione e interpolare linearmente per ottenere le velocità nel punto di collisione, o fare un calcolo più preciso ora che hai scoperto che si intersecheranno, per ottenere il punto / tempo / velocità effettivi di collisione

Oltre a modellare le collisioni, un buon approccio è anche quello di modellare continui trasferimenti di energia (o quantità di moto, o solo velocità, a seconda della complessità della simulazione). Quando il tuo giocatore si trova su una piattaforma, archivia tali informazioni nell'oggetto che rappresenta la piattaforma e ogni volta che la velocità dell'oggetto viene regolata puoi applicare direttamente tale modifica al giocatore così collegato o ad altri oggetti.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top