Rilevamento di collisioni isometriche


11

Sto riscontrando alcuni problemi con il tentativo di rilevare la collisione di due tessere isometriche.

Ho provato a tracciare le linee tra ogni punto sulla tessera e quindi a controllare le intercettazioni delle linee, ma ciò non ha funzionato (probabilmente a causa di una formula errata)

Dopo aver esaminato questo per un po 'oggi credo che ci sto pensando molto e ci deve essere un modo più semplice.

Non sto cercando codice solo alcuni consigli sul modo migliore per ottenere il rilevamento della sovrapposizione


4
Cosa stai cercando di fare esattamente? Rileva quando il mouse si trova su una tessera o rileva se due unità si sovrappongono? Se è tardi, dovresti davvero pensare a separare il tuo "gioco" dalla "grafica"
John McDonald

Devo farcela quando il lato di una iso-tessera mobile colpisce una tessera non mobile che si ferma. L'unica cosa con cui ho problemi è il test di collisione. Potrei usare una scatola rilegata ma ho bisogno che la collisione sia accurata.
Chris Crew,

Risposte:


23

Verrò subito e dirò che non so come risolvere il problema che hai descritto nella domanda (rilevamento delle collisioni tra rettangoli a forma di piastrella iso), ma posso dirti come altri lo hanno risolto in passato :

Il modo in cui viene fatto in altri giochi è quello di separare il mondo di gioco dal mondo dello schermo . Quando inizi, è normale immaginare che siano la stessa cosa, ma poi porta a problemi come quello che stai descrivendo.

L'idea generale è che il mondo di gioco è completamente archiviato nella memoria, dietro le quinte, sono solo numeri, riferimenti e logica. Il fatto che tu stia disegnando il mondo di gioco in modo isometrico è irrilevante. Il tuo mondo di gioco non dovrebbe avere il concetto di isometrico, o quadrato, o anche se lo schermo viene disegnato in 3D. Tutto ciò viene curato quando si disegna il mondo di gioco sullo schermo (ovvero il mondo dello schermo ). Il mondo di gioco dovrebbe essere memorizzato e mantenuto nel modo più semplice che abbia senso per il gioco, nei giochi isometrici, in genere si ignora completamente il fatto che è iso e invece si memorizzano le posizioni come se si stesse utilizzando una griglia allineata agli assi. La maggior parte dei giochi avrà metodi per convertire le coordinate tra i due mondi, io chiamo il mio ScreenToWorld(x, y)eWorldToScreen(x, y). La conversione viene spesso eseguita con la matematica Matrix, ma può essere ottenuta in altri modi. Userai ScreenToWorld quando usi il mouse e WorldToScreen quando disegni.

Ci sono molti vantaggi nel dividere il mondo di gioco e il mondo dello schermo . Uno dei vantaggi è che il rilevamento e il movimento delle collisioni avvengono tutti nel mondo di gioco ed è quindi abbastanza semplice perché non si ha a che fare con una griglia inclinata, con coordinate oblique o dove si trova lo schermo, ecc. , avresti a che fare con rettangoli e quadrati allineati agli assi. Una volta che il mondo di gioco è stato aggiornato, si disegna una rappresentazione del mondo di gioco sullo schermo, parola chiave: rappresentazione. All'inizio può sembrare controintuitivo, ma il tuo schermo è solo una rappresentazione di ciò che sta accadendo nel mondo di gioco. Ciò rende possibili cose come server dedicati e client simili a terminali.

FreeCiv è in realtà un ottimo esempio di tutte queste cose. Puoi visualizzare lo stesso mondo esatto di uno qualsiasi: una griglia quadrata nord / sud, isometrica o persino esadecimale. Ogni gioco che esegui ha un server dedicato in esecuzione in background, anche per i giochi a giocatore singolo, quindi il client è anche solo una porta di visualizzazione, niente di più.

Per farla breve: separare il mondo di gioco e la logica dal mondo dello schermo semplifica la logica di gioco, riduce l' accoppiamento del display <-> del gioco e, a sua volta, rende il rilevamento delle collisioni tra tessere "iso" più facile da gestire e più facile da visualizzare.


Grazie per la risposta ben spiegata Stavo separando la logica in ciò che è stato disegnato e ciò che sta accadendo in background, ma stavo trattando tutto come una griglia inclinata.
Chris Crew,

1
Per le persone del futuro; la grafica è un'interpretazione dei dati. I quattro pezzi principali di un gioco: logica, dati, input, output. Evita di raggrupparli insieme. Inoltre, eccellente risposta John, +1
Aarowaim

9

La risposta di John è giusta, ma cercherò di spiegarla in modo diverso:

Non esiste un rilevamento isometrico delle collisioni.

Il rilevamento delle collisioni non interessa l'aspetto della matrice / trasformazione di proiezione. Il rilevamento delle collisioni non dovrebbe importare se si esegue il rendering delle cose (dopo tutto, gli oggetti che sono fuori dallo schermo possono ancora scontrarsi, giusto?)

È una domanda più filosofica: un albero che cade in una foresta si scontrano ancora con il terreno quando non c'è nessuno?

La saggezza convenzionale direbbe: Sì. Non importa come lo guardi. Le cose si scontrano nello spazio-mondo, non nello spazio-vista.


2
+1 Ben messo. "Non esiste un rilevamento isometrico delle collisioni"
John McDonald,

1
Grazie, ho appena detto quello che hai già detto. Ma un po 'diversamente.
Mark R

0

Puoi provare ad allocare una matrice di pixel componendo una bitmap di ciascun valore getRGB () di ogni singolo pixel. Quindi confrontare i valori con un'istruzione if poiché i bordi della piastrella sono un valore di colore separato rispetto a quello di ciò che la piastrella rappresenta (acqua, sabbia, erba). Quello per una griglia isometrica di base. Oppure puoi avere due livelli della mappa stessa. Un livello contenente una specie di schermo verde che disegna il contorno di ciascun rappresentante di un oggetto in collisione e l'altro livello sarà la mappa stessa.

Non si compone una matrice bitmap di ciascun pixel del livello della mappa, ma si desidera calcolare un set di colori che rappresentano gli effetti che ha quando un oggetto si scontra / interseca il bordo del valore di colore di mantenimento. O si desidera che i valori diminuiscano di valore o aumentino la velocità con cui l'oggetto si sta muovendo. Ogni oggetto che si muove è solo un duplicato della memoria memorizzata in un punto diverso.

Vorrei esaminare la collisione perfetta dei pixel e la comprensione degli array bitmap. Ogni rettangolo è un limite che contiene la replica di una specie di memoria simile alla memoria impressa, ogni evento viene attivato a seconda di dove viene eseguito il rendering di un oggetto in una posizione o vettore. Ogni punto sullo schermo è su un piano 2D solo che la profondità dell'ombra fornisce l'illusione che l'oggetto si rappresenti come 3D. La trasformazione di forme in un disallineamento dà senso che l'oggetto è inclinato. C'è un punto centrale del punto in cui la fotocamera presenta la vista, tutto viene trasportato attorno a questo punto centrale allontanandosi da esso diminuendo di dimensioni o avvicinandosi ad esso aumentando di dimensioni.

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.