Come gestire la fisica delle piattaforme mobili in un platform?


8

Quindi, dopo alcune ore di ricerche su Internet, devo ancora trovare una risposta piacevole su come gestire le piattaforme mobili in un gioco con piattaforma 2D. Così ho deciso di realizzare un semplice prototipo in cui interagisci con 2 piattaforme diverse, una che si sposta in verticale e una in orizzontale. Mi piacerebbe un po 'di aiuto per dissezionare e vedere cosa non funziona e come risolverli. Ho inviato il file .fla + il file .as di seguito, accompagnato da un collegamento al file .swf riproducibile.

L'obiettivo è far interagire l'Eroe con le piattaforme come se fossero oggetti solidi su cui poter stare in piedi, spinti a fianco, saltare su / sotto ecc. Ecc.

I problemi con il mio prototipo sono questi:

  • Quando ti trovi sulla piattaforma in movimento orizzontale, senza muoverti (senza toccare alcun tasto), l'eroe si muove insieme alla piattaforma, ma con un leggero ritardo fa scivolare indietro un po 'l'eroe.

  • Quando ti trovi sulla piattaforma in movimento orizzontale e salti, ti muovi insieme all'a mezz'aria della piattaforma (alcuni giochi preferiscono averlo in questo modo, ma non sembra naturale e non è voluto qui). Ciò potrebbe essere causato dall'eroe che mantiene la velocità sull'asse X dalla piattaforma.

  • Quando salti sul lato inferiore della piattaforma mobile verticalmente, mentre la piattaforma si muove verso il basso, ti affondi al suo interno per un breve secondo. L'eroe penetra come se la collisione fosse inesistente per un momento.

  • Quando salti su una piattaforma in movimento verticale, la velocità sull'asse Y viene mantenuta, quindi quando esci dalla piattaforma, cadi a una velocità maggiore. Con la velocità della velocità mantenuta, viene aggiunta + gravità (questo è principalmente perché non riesco a capire un modo per ripristinare la velocità sull'asse Y su 0 quando atterri sulla piattaforma, senza che il giocatore si blocchi a mezz'aria).

Sono un programmatore alle prime armi, quindi sono sicuro che ci sono MIGLIORI modi per farlo, e mi piacerebbe ascoltarli tutti. Tutte le idee su come migliorare il codice o altri metodi in cui è possibile implementare piattaforme mobili in un gioco basato su Tile sono benvenute. Alla fine, sto cercando di trovare un modo solido per gestire le piattaforme mobili nei platform 2D.

SWF riproducibile: http://dl.dropbox.com/u/28271061/PlatformerhowtoFLA.html (Sposta con i tasti freccia, Salta con il tasto X, Esegui con il tasto Z)

Sourcecode AS-file: http://dl.dropbox.com/u/28271061/Platformerhowto.as

SourcefileFLA: http://dl.dropbox.com/u/28271061/PlatformerhowtoFLA.fla

Se preferisci semplicemente leggere il codice tramite Pastie online: http://pastie.org/2266764



Ho letto quel thread, ma dal momento che non uso i nodi in alcun modo, sembra che non abbia risolto il problema. Il gioco che sto costruendo è basato su tessere, ma le piattaforme mobili saranno implementate come sopra (movimento libero). L'uso dei nodi richiederebbe una riscrittura del mio motore nel suo insieme, su cui ho già trascorso molto tempo. Immagino che sperassi che qualcuno guardasse il codice e offrisse una soluzione simile a quella proposta, o trovasse un miglioramento al codice.
Scherza il

Si sarebbe prevede di utilizzare i nodi una volta si sceglie di implementare questa soluzione per piattaforme mobili, anche se questo è l'unico posto che li utilizzano. Risolverebbe il tuo problema di scorrimento.
doppelgreener,

2
"(alcuni giochi preferiscono averlo così, ma non sembra naturale e non è voluto qui)" Come fa a "non sentirsi naturale"? Google Inertia and Momentum ...
Riki,

1
@Felheart, naturale in termini di gioco, non vero mondo fisico. Se giochi a Super Mario Bros o ad uno dei platform classici, noterai che NON mantengono lo slancio mentre saltano su piattaforme in movimento. Distrugge la sensazione di stare in piedi e interagire con una piattaforma mobile.
Kid

Risposte:


17

Separiamo il problema in problemi distinti ...

Una parola sulla qualità del codice

Il tuo codice ha attualmente le tue piattaforme che controllano direttamente la velocità del tuo giocatore e persino la costante di gravità del mondo . È confuso ed è procedurale quando dovrebbe essere orientato agli oggetti. Una volta che inizi a espandere questo gioco, le cose diventeranno brutte in fretta .

Devi riformattare il tuo codice. Implementa una classe giocatore, una classe piattaforma e una classe piano. Separa le loro preoccupazioni: chiedi al giocatore di interpretare i controlli da tastiera e di controllare come corre e salta, e che le piattaforme modifichino il suo slancio se necessario (aggiungendo la propria velocità alla velocità già determinata del giocatore, quando necessario).

Chiedi al tuo giocatore di determinare dove si trova rispetto a un oggetto di tipo pavimento (piattaforme e piani avrebbero entrambi un BodyType = BodyTypes.Floor, o qualcosa del genere) e determinare da solo dove si trova rispetto all'oggetto, come dovrebbe reagire e se sta cadendo o per terra.

Questo può meritare un argomento separato in quanto è un problema piuttosto separato da tutto ciò che hai sollevato. Tuttavia, dovrai farlo ad un certo punto.

Inerzia orizzontale / verticale all'uscita da una piattaforma

Per risolvere i tuoi problemi di velocità verticale e orizzontale, nota due cose:

  • Per quanto riguarda la velocità orizzontale: il tuo codice imposta la velocità orizzontale su 0 solo quando il giocatore colpisce il suolo (sulla linea Pastie 200) o su una piattaforma.
  • Per quanto riguarda la velocità verticale: il tuo giocatore ha un'accelerazione di caduta costante. Quando si allontana dalla piattaforma verticale, questa accelerazione in caduta continua ad aggiungersi al suo movimento già verso il basso.

Il tuo giocatore soffre semplicemente di inerzia : il suo slancio viene mantenuto fino a quando qualcosa non lo ferma.

Soluzione: entrambi i problemi sarebbero risolti dalla soluzione di jSepia su Come gestisco le piattaforme mobili in un gioco platform? poiché separerebbe completamente il processo di movimento del giocatore da come le piattaforme lo muovono. Semplicemente non caderesti più velocemente camminando da una piattaforma verticale e non conserveresti il ​​tuo momento orizzontale saltando da una piattaforma orizzontale, perché le piattaforme non influenzeranno più il vx e il vy del tuo giocatore .

Nota: potresti avere qualche difficoltà ad implementare la soluzione di jSepia prima che il tuo codice venga refactored.

Scivolare lateralmente attorno alla piattaforma orizzontale

Il tuo giocatore non si muove effettivamente in orizzontale abbastanza velocemente quanto la piattaforma si muove. Non è ovvio per me perché. Questo problema sarebbe anche probabilmente essere risolto mediante l'attuazione di una soluzione di jSepia e correttamente refactoring il codice (quest'ultimo sarebbe semplicemente fare la causa ovvia).

Rilevamento delle collisioni: sovrapposizione con la piattaforma verticale

Vedi la linea 381 di Pastie: ad ogni passo si reimposta il vy del giocatore su 0 fintanto che il giocatore si scontra con la parte inferiore della piattaforma verticale. Nel passaggio seguente, vy viene aumentato dall'accelerazione di gravità e quindi il giocatore viene spostato (e quindi ripristinato nuovamente a 0).

Ciò significa che fino a quando il tuo giocatore si scontra con il fondo della piattaforma, si sta muovendo verso il basso a una velocità costante (la costante di gravità). La piattaforma verticale è più veloce di così, quindi si sovrappone. Se la piattaforma verticale si spostava su una distanza maggiore, scivolava attraverso di lui fino a quando il giocatore non veniva registrato come in piedi sulla piattaforma.

Soluzione: non reimpostare il vy del giocatore su 0. Basta impostare il vy del giocatore sulla velocità verticale della piattaforma ( se la piattaforma sta viaggiando verso il basso ). Il tuo giocatore si allontanerà quindi dalla piattaforma verticale almeno quanto la piattaforma e accelererà lontano da essa.


Eccellente! Innanzitutto grazie per la soluzione al salto e alla penetrazione della piattaforma verticale (funziona!). E secondo, hai ragione, il codice è terribile in questo stato. Anche se questo non è il gioco in sé, si tratta di un prototipo veloce realizzato per sperimentare e comprendere meglio le piattaforme in movimento. Tuttavia, se devo tradurre questo nel vero codice dei giochi, dovrei mantenere un codice più strutturato e orientato agli oggetti. Agevolerà il trasferimento. Ora, per quanto riguarda la soluzione jSpeias, penso di avere il concetto di struttura ad albero dei nodi, è solo che non so come implementarlo correttamente.
Kid

Il mio primo pensiero è quello di creare valori booleani che descrivano lo stato dei giocatori, come ad esempio: "onFloor", "onPlatform", "onGround", "falling", "jumping", ecc. E poi passare attraverso un'istruzione if nel evento enterFrame che controlla lo stato corrente e modifica le proprietà dei giocatori di conseguenza (?) Ad esempio: if (Hero.onPlatform == true) {Player.x = platform.x (relativo ai giocatori globali x);}. Qualcosa in quel modo.
Kid

Ci sto lavorando mentre parliamo, ma allo stesso tempo sto separando il codice in diverse classi come hai suggerito, il che è anche un po 'confuso (comunicare tra le classi piattaforma / collisione / giocatore è piegare la mente).
Kid

@Kid: Playerha un metodo GetPositione variabili interne parent(per il suo nodo genitore) e position(per la sua posizione rispetto al suo genitore). Player.GetPosition()ritorna position + parent.GetPosition(). Il suo genitore fa la stessa cosa finché non raggiungi la radice dell'albero - il nodo del mondo. Quando il tuo giocatore si muove, hai a che fare solo con la positionvariabile privata . Il tuo giocatore viene disegnato sulla schermata di gioco in base al GetPosition()valore di. Ti farò capire come la transizione tra i nodi. ;)
doppelgreener,

Avere una classe di giocatori che sappia come modificare la propria velocità ovviamente non sostiene la separazione delle preoccupazioni
Andy Ray
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.