Come posso rilevare il giocatore schiacciato in un platform 2D?


19

Sto verificando la collisione per un personaggio platform come mostrato in # 1. I punti rossi sono i pixel che vengono controllati e le linee grigie indicano gli assi a cui appartengono. Mi piacciono i risultati che ottengo controllando la collisione in questo modo (rispetto, diciamo, riquadro di selezione). Tutto funziona esattamente come mi piacerebbe tranne un problema: il rilevamento della schiacciamento.

Nelle immagini seguenti, il riquadro azzurro rappresenta il terreno, il riquadro arancione è un oggetto e le frecce indicano la direzione del movimento.

La semplice soluzione per rilevare quando il giocatore è schiacciato è vedere se i punti di collisione sui lati opposti stanno entrambi innescando. Se lo sono, il giocatore viene schiacciato. Nel # 2, puoi vedere uno scenario normale di schiacciamento. Il giocatore è messo a terra e i punti di collisione più alti si intersecano con l'oggetto che cade. Questo innesca una cotta.

# 3, 4 e 5 presentano scenari problematici. Nel # 3, il giocatore si sta muovendo verso l'oggetto, che si sta muovendo verso l'alto. Un punto di collisione sul lato destro sta colpendo l'oggetto, causando una collisione e fermando il giocatore.

Ora, se l'oggetto continua a spostarsi verso l'alto e il giocatore continua a muoversi a destra (come mostrato in # 4), l'oggetto cancella il punto di collisione del lato destro del giocatore e il giocatore si sposta a destra. Ma ora, dopo averlo fatto, l'oggetto sta intersecando un punto di collisione superiore causando una compressione verticale indesiderata.

Uno scenario simile è mostrato in # 5. Due oggetti sono abbastanza distanti da consentire la cancellazione dei punti di collisione inferiori, consentendo al giocatore di cadere, ma no fino al punto di consentire ai punti di collisione laterali di liberarsi, causando una schiacciata orizzontale indesiderata.

Mi sono scervellato per trovare una soluzione, ma nulla di ciò che ho escogitato ha funzionato particolarmente bene, quindi mi chiedo se qualcuno là fuori abbia un'idea o un'idea su come risolvere questi problemi.

inserisci qui la descrizione dell'immagine

Per chiarire un po 'di confusione, i punti di collisione rossi sarebbero all'interno dello sprite e le linee grigie sarebbero state utilizzate solo per indicare l'asse pertinente per ciascun punto di collisione. Ad esempio, se lo sprite del personaggio fosse un semplice quadrato verde, i punti di collisione sarebbero simili a questo:

inserisci qui la descrizione dell'immagine

Risposte:


34

Penso che dovrai prendere in considerazione il movimento della scatola . Cioè, schiaccia solo se la scatola si sta muovendo verso il giocatore.

Questo è simile ad altri problemi nei platform, in cui il movimento è importante. Ad esempio, per piattaforme su cui puoi saltare da e verso il basso, non controllare la collisione se il giocatore si sta muovendo verso l'alto.

Quindi un blocco può schiacciare il giocatore dall'alto solo se il blocco si sta muovendo verso il basso; dal basso solo se il blocco si sta spostando verso l'alto; da sinistra solo se il blocco si sta spostando a destra e così via.


13
+1 Prendi in considerazione che il blocco agisce qui, non il giocatore. Quindi, se controlli se la scatola sta schiacciando il giocatore invece di controllare se il giocatore viene schiacciato, il problema dovrebbe essere più facile da risolvere
Niels,

Che dire di quando i blocchi non si muovono? Ora mi rendo conto di aver messo le frecce sui blocchi nel numero 5, ma quello doveva essere due blocchi fissi.
IanLarson,

Se decidi che i blocchi fissi non devono schiacciare, assicurati solo che il giocatore non sia bloccato e possa spostarsi di mezzo.
congusbongus,

Argh, odio essere schiacciato da due oggetti che si stanno effettivamente allontanando l' uno dall'altro, solo perché l'ho reso perfetto per pixel e cornice e lo sviluppatore era pigro.
rinoceronte,

9

Fai in modo che i punti del "test di schiacciamento" siano all'interno della casella grigia mostrata nell'immagine n. 1, ovvero uccidi il giocatore solo se rilevi un colpo su uno dei pixel lì.


1
Intendi i punti di controllo di schiacciamento addizionale "dentro" i limiti dei punti di collisione? Il problema che vedo con questo è che la risoluzione della collisione si verificherà in ciascun asse quando uno dei suoi punti di collisione viene "innescato" prima che l'oggetto abbia persino la possibilità di raggiungere i punti di controllo della compressione interna.
IanLarson,

6

Come persona cresciuta con platform degli anni '80, il mio primo commento è che i punti di contatto devono essere esattamente sullo sprite, non ovunque al di fuori di esso. Ci sono state poche esperienze più frustranti della morte quando un'arma / un frantoio / nemico era chiaramente a diversi pixel di distanza dal tuo personaggio - e quel tipo di esperienza è ciò che impedisce alle persone di giocare.

Con questo in mente, l'idea di avere punti separati per la collisione orizzontale e verticale semplicemente non vola. Quindi i tuoi casi 3 e 5 non esistono.

Per quanto riguarda il rilevamento delle collisioni, come è stato detto in precedenza, è necessario considerare la direzione del movimento e si devono considerare due assi di movimento. Se un frantoio è a terra, il giocatore non dovrebbe essere in grado di camminare in avanti - dovrebbe agire come un muro. Quindi, con i punti di rilevamento orizzontale e verticale nello stesso posto, non è possibile ottenere il caso 4, anche prima di aggiungere la direzione del movimento al mix.

Il frantoio verso l'alto aggiunge ulteriore complessità. Se è così veloce che il giocatore non ha alcuna possibilità di scappare, allora OK. Ma se è più lento, il giocatore si aspetta di essere in grado di correre sulla piattaforma in salita e saltare dall'altra parte. Lo sprite del giocatore sale verso l'alto sul frantoio e il rilevamento della schiacciamento avviene sul soffitto .


3
Punto minore: non sai come sia il suo sprite. Per quanto ne sappiamo, potrebbe essere esattamente come mostrato nelle immagini sopra, quindi i casi 3 e 5 potrebbero essere del tutto validi.
Alex,

1
Alex ha ragione. Ho fatto una modifica per chiarire. Concordo sul fatto che non c'è niente di peggio delle scatole di collisione incostanti. Penso di capire il tuo punto di non usare punti separati per i diversi assi. Se lo faccio, ciò trasformerebbe l'esempio sopra da otto a quattro, uno in ogni angolo, giusto? In realtà ho fatto alcuni test con questo in mente (con risultati meno che desiderabili), ma sono fortemente riluttante a farlo, poiché avere gli angoli "separati" raggiunge il comportamento che sto cercando quasi perfettamente. Questi sono davvero gli unici scenari problematici in cui mi sono imbattuto.
IanLarson,

0

Potresti rendere l'oggetto "più duro" del terreno, nel senso che, supponendo una collisione, il giocatore viene spinto "nel" terreno, invece di essere spinto "nell'oggetto in movimento".

Ciò presuppone che il giocatore non sia in grado di spingersi "dentro" né oggetti né terra.


0

Se riesci a rilevare la sovrapposizione di oggetti senza dover aspettare che vengano visualizzati, un approccio semplice è elaborare il movimento per il lettore e altri oggetti in modo indipendente, un pixel alla volta, con controlli di collisione separati in seguito. Se il giocatore si muove liberamente e si scontra con il suo oggetto a seguito di tale movimento, arretralo. Se si verifica una collisione con un oggetto a causa del movimento dell'oggetto, controlla se il giocatore può muoversi nella stessa direzione dell'oggetto. In tal caso, sposta il giocatore. In caso contrario, gestire la situazione di "schiacciamento" in modo appropriato (danneggiando o uccidendo il giocatore e / o spostando l'oggetto in collisione all'indietro, a seconda del contatto).

A proposito, se solo un numero limitato di combinazioni di forme può scontrarsi, può essere utile pre-calcolare bitmap di "rilevamento di collisioni" in modo tale che se un pixel è impostato nel primo sprite in offset (x1, y1) e nel secondo all'offset (x2, y2) del secondo, il pixel all'offset (x1-x2, y1-y2) verrà impostato nella mappa delle collisioni. Tale mappa di collisione pre-calcolata consentirà di rilevare le collisioni tra i due sprite controllando lo stato di un singolo pixel nella mappa di collisione.


0

Ci vogliono due oggetti per schiacciare un giocatore. Il tuo rilevamento di schiacciamento dovrebbe verificare che il giocatore si trovi tra due oggetti, che lo spazio tra loro sia uguale alla dimensione del giocatore e che la distanza diminuisca.


0

Trovo il prossimo a lavorare finora. Non richiede informazioni "esterne" sul movimento dei frantoi e risolve il problema dei falsi positivi. Quando viene rilevato un falso positivo, viene trattato come una collisione (e questo è quello che realmente è):

L'idea è: perché verificare se il frantoio si sta muovendo quando ci interessa davvero se il personaggio si sta muovendo. Entrambi possono rispondere se la cotta è falsa positiva causata dal movimento stesso del personaggio o vera cotta dal movimento dell'oggetto frantoio.

Se il personaggio è in movimento e schiacciato (collisioni su lati opposti per il frame in arrivo), controlla di nuovo lo schiacciamento sull'ultimo frame / coordinate di iterazione:

  1. Se non confermato di nuovo, è dovuto al movimento del personaggio e il personaggio deve essere riportato all'ultimo frame / coordinate di iterazione proprio come una collisione

  2. Se la cotta viene confermata la seconda volta, procedere con la cotta.

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.