Come posso facilmente implementare lo swing in un gioco platform?


9

Sto sviluppando un gioco in cui il giocatore può usare le corde per oscillare (proprio come hanno fatto Spiderman o Bionic Commando ) e sto riscontrando problemi nell'implementazione di questo comportamento. Qualcuno può aiutarmi a fare questo, intendo formule di fisica e così via. Fino ad ora ho escogitato 3 idee. Uno sta usando la primavera, ma richiede molto tempo e talvolta è nervoso. Gli altri due stanno cercando di calcolare il passaggio successivo (uno tramite il calcolo dell'energia potenziale e uno tramite il calcolo della coppia) ed entrambi si schiantano quasi ogni volta che l'attore sta cercando di oscillare.

Ecco il codice che ho scritto per calcolare la coppia:

float dx = Runner->getPosition().x - ancher.x; 
float dy = Runner->getPosition().y - ancher.y;
float t0 = atan2(dy,dx); //my current angle
float k = ((dy) *vx - (dx) * vy) / (dx * dx+dy * dy); //previus angular velocity
k -= gravity * cos(t0) *dt; // new angular velocity (gravity is positive)
t0 += k * dt - acc * cos(t0) *dt * dt / 2; // rotate the rope
float dx1 = r0 * cos(t0); // new position (r0 is rope length)
float dy1 = r0 * sin(t0);
vx = (dx1 - dx) / dt; //calculate velocity
vy = (dy1 - dy) / dt;

Rilevante (durante la fabbricazione di una corda): Rilevamento di collisioni di corda 2D
doppelgreener

@JonathanHobbs la risposta a questa domanda è esattamente come sto cercando di implementare la mia corda con un'eccezione, dal momento che la collisione è indesiderata nel mio caso ho impostato ogni parte della corda come un sensore in modo che possano muoversi liberamente senza incastrarsi l'uno nell'altro.
Ali1S232

Che dire del semplice pendolo per corda + di alcune animazioni che sembrano cordiali? Non credo che i vecchi giochi come Bionic Commando avessero qualcosa di diverso dal pendolo.
user712092,

@utente che l'idea del pendolo dovrebbe funzionare bene. ma nel mio caso o a causa del rapido movimento del giocatore o della mia cattiva implementazione, non ha dato buoni risultati.
Ali1S232,

@Gajet prova a fare qualche disegno di debug fino a quando non hai capito bene? Questa linea del pendolo potrebbe essere fatta come una scatola sufficientemente sottile in Box2D per ottenere collisioni (e forse escluderla dalla fisica e muoverla a mano?).
user712092,

Risposte:


6

Se vuoi uno swing rigido, quindi la distanza dal punto di rotazione è costante, considera il personaggio come un punto su un cerchio centrato nel punto di rotazione. Dagli una velocità angolare unidimensionale (lungo il cerchio). Ogni fotogramma dovrebbe essere l'accelerazione angolare accelerationDueToGravity * cos(angleOfPlayerOnCircle)(con 0 gradi che punta a destra).

Se vuoi che la corda si allungi / accorci, puoi utilizzare lo schema sopra e variare il raggio di ciascun telaio.


la tua risposta è stata il mio secondo tentativo, ma si muove con molta più velocità che dovrei modificare la mia domanda e aggiungere il mio codice, forse puoi individuare dove si trova il problema.
Ali1S232,

3

dopo molti tentativi sono andato con box2d.

ci sono generalmente due approcci per questa simulazione o almeno ho trovato 2:

  1. uno è usare alcune forme circolari e collegarle usando giunti distanti.
  2. e l'altro è a rettangoli per la catena stessa e quindi attaccarli usando giunti rotanti

in ogni senario devi avere un ancher (che nel mio caso era una scatola statica). è meglio se riduci il peso delle parti della corda (o usi forme circolari o rettangolari), ad esempio per avere una fisica più realistica ho impostato la loro densità su 0,1 e per la scatola collegata all'estremità della corda ho usato la densità 10.

un'altra cosa di cui devi preoccuparti di come il tuo segmento di corda reagisce l'un l'altro. volevo solo che la mia corda si muovesse liberamente in scena, quindi ho contrassegnato tutti i dispositivi come sensori. potresti aver bisogno di un approccio diverso.

la prossima cosa di cui devi preoccuparti è il numero di iterazioni che stai passando all'aggiornamento mondiale: per un segmento di corda basso (forse 8 al massimo) non è necessario utilizzare un valore di iterazione elevato forse 10/10 quale box2d stesso ha suggerito è sufficiente ma se aumenti il ​​numero di segmenti, ad esempio, ho provato 30 segmenti, con un basso numero di iterazioni la tua corda sembra aumentare la lunghezza più di quanto dovrebbe, quindi potresti aver bisogno di circa 40/40 iterazioni per risolvere quelle situazioni.

dopo alcuni test sembra che la casella 2d sia progettata per scene con dimensioni degli oggetti da 0,1 ma 10 me la dimensione massima suggerita per scene di grandi dimensioni è di circa 50 mx 50 m. quindi, in pratica, è necessario ridimensionare l'oggetto in modo che corrisponda a questi parametri. nel mio caso ho provato prima a passare le posizioni dei pixel direttamente a box2d ma sembrava che ci fossero dei limiti di velocità che impedivano al mondo di muoversi il più velocemente possibile, quindi ho dovuto ridimensionare la mia scena di 64 volte per ottenere i migliori risultati. anche se non ho testato me stesso, ci sono alcuni limiti in box2d che ti impediscono di usare scene più grandi. per esempio c'è un valore definito nel b2Setting.hfile #define b2_maxTranslation 2.0fche puoi cambiare nelle impostazioni box2d ma sembra non essere raccomandato.


perché sbaglio con box2d per farmi guadagnare un voto ??
Ali1S232,

Questo non risponde alla domanda. Almeno scrivi come l' hai fatto funzionare usando Box2D.
bummzack,

@bummzack: ok lo aggiungerò alla mia risposta
Ali1S232

Se accetti questa come risposta, la tua domanda è imperfetta. La fisica della corda segmentata è molto diversa da quella che hai descritto.
Attaccando

@attackingHobo: il quesiton era corretto in quel momento ma quando ho trasformato il mio codice in box2d, ho capito lì senza troppi sforzi che posso implementare la fisica della corda segmentata. e non è molto diverso, pensa alla mia domanda come a un solo segmento di una corda segmentata. e quasi tutte le mie soluzioni erano modi per implementare la corda in stile cerchio senza box2d.
Ali1S232

2

Hai considerato di rallentare la velocità del movimento dell'oscillazione in base alla distanza della fune dalla linea a piombo (al centro)?


per tutti i 3 approcci la lunghezza della fune è uno dei parametri che ho usato per calcolare la velocità di oscillazione. Ma non posso garantire di averlo usato correttamente. Ho appena fatto alcuni calcoli fisici e applicato la loro versione risolta al gioco.
Ali1S232,

Più è lontano dal centro, più lungo è il ritardo prima del successivo movimento dell'oscillazione della corda. Puoi anche moltiplicare il valore ASSOLUTO del ritardo per qualcosa come 0,28 (dovrai sperimentare con questo).
Randolf Richardson,

Non riesco a ottenere quello che stai cercando di dire, quando sto calcolando il passaggio successivo ho un valore costante per delta_time e uso tutti i parametri che ho (come la velocità precedente, la posizione precedente, la lunghezza della corda, ecc.) Per calcolare nuova velocità, quindi aggiungere questa velocità moltiplicata per delta_time all'ultima posizione per generare una nuova posizione. se intendi qualcos'altro, fornisci tutti i dettagli nella tua risposta.
Ali1S232,

1

Quando il giocatore è oltre la lunghezza della corda, il giocatore verrà immediatamente respinto con una forza pari alla distanza che l'ha superata. Questo dovrebbe funzionare senza sentirsi elastico e dovrebbe sembrare intuitivo per il giocatore. Tuttavia, potresti dover modificare la fisica per ottenere i migliori risultati per il tuo gioco.

Quando la corda è attaccata. Salva un maxLengthvalore.

Ad ogni aggiornamento, controlla distancetra player, eattachPoint

Se normalmente distanceè inferiore maxLengthall'aggiornamento, nessun effetto dalla corda.

Se la distanza è maggiore di maxLength, trova il normalda attachPointal giocatore. Ottieni la differenza tra il distancee maxLength. Aggiungi a playerVelocity, normalmoltiplicato per la differenza.

Codice pseudo:

dx = (attachPoint.x - player.x)
dy = (attachPoint.y - player.y)

distance = sqrt(dx*dx+dy*dy);

if (distance > maxDistance)
{
    float dx1 = dx / distance * maxDistance;
    float dy1 = dy / distance * maxDistance;
    v.x += (dx1 - dx) / dt;
    v.y += (dy1 - dy) / dt;
}

playerVel += v * dt;

quindi il codice che ho modificato nella tua risposta (mi dispiace ma non ho trovato posto migliore per aggiungerlo) quello che stai suggerendo?
Ali1S232,

Ho approvato la modifica e sì, penso che dovrebbe essere così. Anche se prima avevo usato la fisica delle corde e usato un modo molto più contorto per fare la stessa cosa, per questo non sono del tutto sicuro che questo codice funzionerà correttamente, ma penso che dovrebbe, e anche se non lo fa, ti dà 95 % del modo in cui lì.
Attaccando

dopo alcuni tentativi immagino che proverò box2d per questo problema e dal modo in cui devi cambiare quel codice in modo da avere dx = player.x - attachpoint.xe dy = player.y - attachpoint.y.
Ali1S232,

1

Se guardi http://www.cocos2d-iphone.org/archives/1112 c'è un'implementazione di una corda con un corpo rigido attaccato all'estremità della corda. Usa Box2D per il motore fisico. Se guardi il codice sorgente, sono sicuro che puoi implementarlo in qualsiasi lingua tu voglia.

Inoltre, il link sopra alla domanda Rope è mio e questa demo (link fornito) sopra ha davvero aiutato.

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.