|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Senior Member
Iscritto dal: Dec 2002
Messaggi: 3359
|
Collision detect e oggetti veloci
Come posso determinare la collisione tra un proiettile(un oggetto che si muove a velocità altà rispetto il sistema) e una matrice di bit(true=terreno, false=nulla)?
Mi spiego, io ora controllo semplicemente se nella matrice di bit alla posizione del proiettile ho un true o un false. Funziona benone e sopratutto è velocissimo, il problema è che se l'oggetto in questione si muove troppo veloce, quindi nel tempo dt di elaborazione si sposta di troppi pixel, vado incontro a due problemi: 1) Mettiamo che ogni dt l'ogetto si sposti di 10 pixel, un attimo prima di elaborare la posizione esso non collide, ma l'attimo dopo si...e siccome si è spostato di molto la collisione viene "registrata" in una posizione troppo distante da dove effettivamente c'era. 2)L'effetto di vedere un oggetto spostarsi di tanti pixel alla volta non è bello anche se il tutto è fluido, come posso creare una certa continuità della scena? Per ora la mia unica effettiva soluzione è stata quella di diminuire il tempo di elaborazione, in questo modo la CPU fa molti più calcoli di posizioni ma il carico diventa troppo... |
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: Dec 2002
Messaggi: 3359
|
Il fatto di conoscere la vera posizione di collisione è fondamentale in quanto mi serve per sapere dove danneggiaere il terreno.
Nella situazione attuale accade che se il proiettile va molto veloce il terreno si danneggia internamente e non sulla superficie...tenete come esempio worms. |
|
|
|
|
|
#3 | |
|
Senior Member
Iscritto dal: Feb 2002
Messaggi: 906
|
Quote:
se tu conosci la posizione del tuo terreno, una volta che determini la collisione, danneggi il terreno in quel punto. Per esempio: Ora non sò se è 3D cmq, se hai coordinate del terreno per esempio un quadrato in pixel xyz 10,0,10 (y è l'altezza) e il proiettile ha coordinate (come tu dici, sorpassa il terreno ovvero posizioneProiettile <=0 ovvero y l'altezza) se il proiettile ha coordinate 7,0,8 significa che collide con il terreno ma come tu dici si sposta per 10 pixel in avanti quindi con il tuo proiettile fai un controllo della collisione tipo: posizioneProiettile 7,-10,8 terreno 10,0,10 il risultato è che -10 è < di 0 quindo collisione a questo punto danneggi il terreno alle coordinate del terreno 7,0,8 è chiaro che devi sempre danneggiare il terreno a coordinate 0 ovvero la y infatti se danneggi il terreno a coordinate -10 danneggeresti il terreno a -10 pixel dal sul punto reale. Pseudo code: posizioneTerreno = 10,0,10 PosizioneProiettile = 7,47,4 PosizioneProiettile = 7,37,4 PosizioneProiettile = 7,27,4 PosizioneProiettile = 7,17,4 PosizioneProiettile = 7,7,4 PosizioneProiettile = 7,-3.4 // cè collisione allora danneggiamentoTerreno = 7,0,4 quale è il problema?? |
|
|
|
|
|
|
#4 |
|
Senior Member
Iscritto dal: Dec 2002
Messaggi: 3359
|
Non è così semplice, il gioco è in 2D, come terreno ho una immagine, fai conto che l'immagine sia a 2 colori, bianco e nero, nero=terreno bianco=aria.
Il proiettile si sposta dentro questa immagine quindi le sue coordinate sono gli indici della matrice terreno[y][x]. Io non so a priori a che altezza si trova il terreno, io so che ho impattato quando effettivamente tocco il terreno, se non lo tocco non so nemmeno che esiste...
|
|
|
|
|
|
#5 |
|
Senior Member
Iscritto dal: Dec 2000
Città: bologna
Messaggi: 1309
|
invece di fare la collision per pixel, falla per range.
prendi il punto di partenza, il punto di arrivo e verifichi se al suo interno sia presente del terreno. pero nel caso di traiettorie curve la cosa è abbastanza complicata.. |
|
|
|
|
|
#6 |
|
Senior Member
Iscritto dal: Dec 2002
Messaggi: 3359
|
Si ci avevo pensato ma il problema non è che è complicato, ma esoso per la cpu, considera che lo dovrebbe fare per ogni proiettile, e i proiettili sono davvero tanti...
|
|
|
|
|
|
#7 |
|
Senior Member
Iscritto dal: Feb 2002
Messaggi: 906
|
Quote:
Allora puoi fare in 2 modi: 1. Metodo molto performante. Leggi l'immagine come si fà per un terrain engine calcolando i punti dei pixel dell'immagine dove il bianco è 0 e il nero 255 (ovvero i pixel dell'immagine) infatti se hai solo il bianco e il nero ricavi una matrice, matrice ovviamente la fai bidimensionale (x,z), come la coordinata del proiettile (x,z) si trova interpola il 255 di valore ci sarà collisione. Il tutto lo devi precalcolare prima nell'init(); e poi con le coordinate del proiettile fai l'algoritmo di iterpolazione. 2. Metodo Non sò di quanti pixel è l'immagine che adotti cmq se è quella postata essa è di 246, 188 pixel (per esempio) prepari una griglia bidimensionale di: griglia(246, 188); Ora fai contenere in questa griglia tanti quadrati di 10 pixel x 10 pixel. Ti trovi quanti quadrati ci sono in griglia, che ne sò in questo caso avrai 24.6 quadrati in x e 18.8 quadrati in z. Totale quadrati 18.8 x 24.6. L'algoritmo di rilevamento in pseudo code è: fori i=QuadratiOrizzontali for j=QuadratiVerticali ... quì calcoli se la coordinata del proiettile stà nel quadrato dove c'è del nero = 1 oppure bianco = 0. I quadrati della griglia li puoi fare piccoli piccoli e non si noterà nulla. Avrai i punti di contatto nella griglia e li confronti con la posizione del proiettile. Poi anche quì fai l'algoritmo per verificare la collisione. In tutti e 2 i modi puoi ottimizzare i calcoli in questo modo: E' inutile eseguire l'algoritmo per verificare se c'è collisione se la coordinata del proiettile non stà nel quadrato della griglia marcato a 0. Se il proiettile stà in un quadrato della griglia ovvero = 1 dove c'è il nero allora c'è collisione Ultima modifica di okay : 18-08-2006 alle 15:45. |
|
|
|
|
|
#8 |
|
Senior Member
Iscritto dal: Dec 2002
Messaggi: 3359
|
Io l'immagine la leggo e la trasformo già in matrice di bit questo non è un problema. Quindi io ora ho già la matrice di bit.
Per il primo metodo non ho capito come esegue l'interpolazione, mi potresti spiegare un attimo? Ti faccio un piccolo esempio in modo che tuo lo puoi usare per spigarmi se vuoi. Codice:
Questa è la matrice di bit(1=nero 0=bianco): 0 0 0 0 0 0 0 0 0 0 riga 0 0 0 0 0 0 0 0 0 0 0 riga 1 0 0 0 0 0 0 0 0 0 0 riga 2 0 0 0 0 0 0 0 0 0 0 riga 3 1 1 1 1 1 1 1 1 1 1 riga 4 1 1 1 1 1 1 1 1 1 1 riga 5 0 0 0 0 0 0 0 0 0 0 riga 6 0 0 0 0 0 0 0 0 0 0 riga 7 0 0 0 0 0 0 0 0 0 0 riga 8 0 0 0 0 0 0 0 0 0 0 riga 9 Prendiamo un proiettile che per semplificare è in caduta libera percorrendo la colonna 5, e si muove di 3 pixel alla volta, quindi ad un certo istante si trova nella colonna 5 e riga 3, qui non collide. L'istante dopo si trova sempre nella colonna 5 ma riga 6, nemmeno qui collide quindi per lui il rettangolo nero non esiste... In questo caso come uso l'interpolazione? Il metodo 2 da quel che ho capito è un'ottimizzazione del tutto, prima controllo se si trova in una parte con del terreno, e solo in quel caso inizio con l'elaborazione vera e propria. Non ho capito però l'elaborazione che intendi, penso sia quella del metodo 1. |
|
|
|
|
|
#9 |
|
Senior Member
Iscritto dal: Dec 2002
Messaggi: 3359
|
Io in mente ho già un metodo, cioè quella di vedere se c'è terreno non solo alla cordinata del proiettile, ma lungo una retta che ha la stessa inclinazione della traiettoria del proiettile e lunga abbastanza da essere più lunga dello spazio percorso in un dt di elaborazione.
Per l'altro problema, cioè quella della visualizzazzione non ci sono soluzioni? Nei giochi come fanno...quando ci sono oggetti molto veloci sembra sempre che si muovo con una certa continuità...come si ottiene quell'effetto? Ultima modifica di MEMon : 18-08-2006 alle 16:22. |
|
|
|
|
|
#10 | |
|
Senior Member
Iscritto dal: Feb 2002
Messaggi: 906
|
Quote:
Si prende il tempo attuale in secondi e si sottrae al tempo precedente /1000 che corrisponde ad un secondo. In questo modo se su un pc datato 486 i cicli per l'fps sono di 150 al secondo mentre su un xp moderno i cicli sono1500 per secondo eseguendo il calcolo di far passare in un secondo 60 frame in un secondo avrai che su tutti e due i pc il gioco sarà identico come fluidità ovvero su tutti e 2 i pc passeranno 60 frame per secondo, si no come ti spieghi che un 486 e un xp possono giocare in rete senza questo accorgimento?? Se non si usasse questa tecnica dell'fps il missile sparato dall'xp il 486 neanche lo vedrebbe... - per il quesito dei bit dici che ottieni la matrice con i 0 e 1 quindi lavori con i pixel impostati sulla matrice e la costruisci... perchè devi avere in memoria uesta matrice. Okay... ora non ti rimane che confrontare la posizione dei pixel del missile con la griglia degli 0 e 1. if posPixelProiettile(x,z)==pos(x,z) && posPixelImmagine(x,z)==0 salta if posPixelProiettile(x,z)==pos(x,z) && posPixelImmagine(x,z)==1 collidi for(i=0; i<10; i++) for(j=0; j<10; j++) pos(i,j)=j; |
|
|
|
|
|
|
#11 | |
|
Senior Member
Iscritto dal: Dec 2002
Messaggi: 3359
|
Quote:
|
|
|
|
|
|
|
#12 |
|
Senior Member
Iscritto dal: May 2006
Città: Salerno
Messaggi: 936
|
anziche farlo muovere e poi controllare, controlla e poi muovi: (pp = posizione proiettile)
pp=[50][0] //il proiettile viene sparato controlli se tra 50-0 e 50-10 (il prossimo frame) c'è del terreno (con un for). se c'è il terreno fai esplodere il proiettile dove c'è il terreno, altrimenti lo fai arrivare a destinazione. controlli e lo fai ripartire di nuovo. Ultima modifica di AngeL) : 18-08-2006 alle 18:59. |
|
|
|
|
|
#13 | |
|
Senior Member
Iscritto dal: Feb 2002
Messaggi: 906
|
Quote:
pixel+=1; //un pixel alla volta posProiettile=pixel; prova invece a muoverti per float. come variabile globale metti float pixelAvanti; //per il movimento pixelAvanti+=0.01; //se è ancora troppo veloce prova 0.001 e via //0.0001 così via // finchè non trovi la giusta velocità per il proiettile posProiettile=pixelAvanti; ciao Ultima modifica di okay : 18-08-2006 alle 19:07. |
|
|
|
|
|
|
#14 |
|
Senior Member
Iscritto dal: May 2006
Città: Salerno
Messaggi: 936
|
scusa ma se lo fai andare a 0.001 alla volta non è un po lento?..
|
|
|
|
|
|
#15 | |
|
Senior Member
Iscritto dal: Feb 2002
Messaggi: 906
|
Quote:
dato che lui non usa l'fps sulla sua cpu deve addattare la velocità del suo proiettile. Non ha ancora risposto ma presumo che faccia muovere il proiettile di int = 1; come i pixel è naturale che il proiettile schizza esempio: pixel 1 pixel 2 pixel 3 se lui fà pixel+=1; a 3.ghz neanche lo vedo il proiettile dopo il 3 passaggio di rendere stà già a 4 mentre se usa il float e dosa la velocità farà: pixel+=0.01;//ovvero ad ogni passaggio incrementa così dopo 100 passaggi starà ora a 2 e dopo altri 100 passaggi starà a 3 se ha un xp veloce penso che 0.0001 sia buono per valutare la corsa del proiettile. Se risponde c'è lo confermerà... oppure non ho capito!! |
|
|
|
|
|
|
#16 |
|
Senior Member
Iscritto dal: May 2006
Città: Salerno
Messaggi: 936
|
ahh ora ho capito...
ma lui non voleva cambiae la velocità, voleva un aiuto per aggiustare la funzione che valuta il pnto di collisione |
|
|
|
|
|
#17 | |
|
Senior Member
Iscritto dal: Feb 2002
Messaggi: 906
|
Quote:
pixel+=10 significa che ad ogni passaggio si spota di 10 pixel quindi se sta a coordinate 3 e a 7 il bit 1 lui lo scavalca in quanto 3+10 = 13 in pratica scavalca il bit 7 in cui non può fare il confronto. Nel modo che gli propongo io è di far camminare + lenatmente il proiettile per float come spiegato prima e poi fare un calcolo per le proporzioni al pixel/bit |
|
|
|
|
|
|
#18 |
|
Senior Member
Iscritto dal: Dec 2002
Messaggi: 3359
|
Si ma il proiettile è un proiettile deve andare veloce!
se lo sposto di meno poi devo elaborare più volte la scena per ottenere la stessa velocità! Ora io faccio l'update della situazione ogni 40ms per avere circa 25 fps, non voglio scendere sotto i 40 ms per non sovraccaricare troppo la cpu, in sostanza il mio gameLoop è controllato da un timer. Leggendo in giro però ho scoperto che molti non temporizzono il ciclo ma lasciano che la cpu sfrutti tuutta la sua potenza, forse è quella che intendevi tu vero okay? in quel caso si penso che devo ridurre gli spostamenti, ma il mio problema era rivolto a come avevo progettato ora il gioco. Essendo temporizzato a 40ms, la scena la elaboro ogni 40ms ma per far andare veloce un'oggetto mi serve spostarlo di molti pixel alla volta! E' per questo che ho il problema. Ora forse la soluzione è effettivamente quella tua okay, sto sbagliando il metodo. Se ho capito bene te dici di lasciare la cpu al 100% e quindi di regolare lo spostamento considerando la grande velocità di esecuzione del codice. Se un pc lento impiega 10 ms in + di uno veloce a renderizzare tutto lo spostamento nel pc lento sara x+=dx+10ms, è questo che intendi vero? dimmi di si...o non ho capito nulla ancora |
|
|
|
|
|
#19 | |
|
Senior Member
Iscritto dal: Dec 2002
Messaggi: 3359
|
Quote:
Ma se salta fuori che ho sbagliato proprio il metodo non posso che abbassare la testa e riscrivermi tutto... |
|
|
|
|
|
|
#20 | |
|
Registered User
Iscritto dal: Aug 2006
Messaggi: 305
|
Quote:
Insieme alla sprite del proiettile, assocerei una shape invisibile, più lunga del proiettile. Le collisioni verranno poi calcolate in base alla shape invisibile. |
|
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 05:48.




















