Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
Delphi - verificare collisioni
Forum - Delphi - verificare collisioni

Avatar
haberdasherv (Member)
Newbie


Messaggi: 17
Iscritto: 27/11/2009

Segnala al moderatore
Postato alle 12:31
Domenica, 20/12/2009
riguardo il giochino Breakout che sto realizzando vorrei modificare un pò la procedura che mi verifica le collisioni ma apparte questa che sto usando ora non ho altre idee su come potrei impostarla...
In pratica questa procedura io l'ho inserita in un timer che (in teoria) dovrebbe scattare ogni 10 millisecondi e mi verifica uno per uno se la pallina interseca uno dei 92 mattoncini. potete capire quanto questa operazione sia pesante per il computer ma non riesco proprio a pensare modi diversi per controllare l'avvenuta collisione...
Codice sorgente - presumibilmente Delphi

  1. procedure TForm1.HitMattone;
  2. var i :integer;
  3.     basta :boolean;
  4. begin
  5.   basta := False;
  6.   for i := 1 to 92 do
  7.   if basta = False then
  8.     if IntersectRect(rettangolo,Mattoncino[i].BoundsRect,Palla.BoundsRect) then
  9.     begin
  10.       if Mattoncino[i].Visible = False then exit;
  11.       velocita.Y := 0 - velocita.Y;
  12.       try
  13.         Punteggio.Caption := IntToStr( StrToInt(Punteggio.Caption) + 20 );
  14.       except
  15.         Showmessage('Errore punteggio');
  16.       end;
  17.       Mattoncino[i].Visible := False;
  18.       basta := True;
  19.     end;
  20. end;


vi posto anche il link al progetto inserito sul sito: http://pierotofy.it/pages/sorgenti/dettagli/18291-Breakout/

PM Quote
Avatar
TheKaneB (Member)
Guru^2


Messaggi: 1792
Iscritto: 26/06/2009

Segnala al moderatore
Postato alle 14:10
Lunedì, 21/12/2009
tanto tempo fa avevo realizzato un giochino simile, con un algoritmo altamente ottimizzato per fare il check delle collisioni, ma a discapito della flessibilità (i mattoncini sono vincolati a rientrare in una griglia di dimensioni fisse).

Se ti interessa vedo se riesco a recuperare quel vecchio codice (in C++ mi pare), altrimenti lascia pure questa tua implementazione. Con così pochi elementi va più che bene per un gioco senza troppe pretese.

In sostanza hai 1 proiettile e 100 target, il numero di collisioni da testare è 1x100 = 100, abbastanza piccolo.

Se avessi tipo 300 proiettili, con 1000 target possibili, dovresti fare 300x1000 = 300.000 test di collisione, e allora le cose si farebbero più interessanti e si potrebbero implementare delle tecniche di ricerca spaziale basate su quadtree, ma in questo caso mi sembra eccessivo come ammazzare una sardina con un sottomarino nucleare.... ;) take it easy!

PM Quote
Avatar
haberdasherv (Member)
Newbie


Messaggi: 17
Iscritto: 27/11/2009

Segnala al moderatore
Postato alle 15:50
Lunedì, 21/12/2009
se pensi di poterlo recuperare mi interesserebbe vedere quel codice, comunque anche se l'operazione potrebbe sembrare leggera se usata per questi dati, mi piacerebbe cercare di sviluppare qualcosa di più complesso (anche perchè con questa procedura succede alcune volte che la palla passa attraverso il primo mattoncino e solo quando si trova a metà tra questo e il mattoncino sopra il programma rileva la collisione e li fa sparire entrambi facendo così spostare la palla sempre di lato fino a che non elimina 2 righe "con un solo colpo")

PM Quote
Avatar
TheKaneB (Member)
Guru^2


Messaggi: 1792
Iscritto: 26/06/2009

Segnala al moderatore
Postato alle 16:25
Lunedì, 21/12/2009
eh, capisco... evidentemente la velocità della pallina è così alta che nello spazio temporale di un frame riesce ad attraversare un mattoncino...

per risolvere dovresti fare un check migliore:

invece di aumentare le coordinate e poi fare il test, prova a generare delle coordinate intermedie (usando i numeri in floating point se necessario) suddividendo lo spazio del frame in un certo numero di settori, e facendo il check per ogni settore.

Altro metodo potrebbe essere quello di ricavare l'equazione della retta seguita dalla pallina (avendo dx e dy è un gioco da ragazzi) e fare un test di tipo "line to rect", anzichè il test "point to rect" che usi nel tuo codice. Il codice sarebbe un pelo più complesso ma ti consentirebbe di ricavare il tempo di collisione prima ancora che questa avvenga. In questo modo potrai prevedere dopo quanti secondi (o frames) la tua pallina andrà a collidere e potrai quindi diminuire il numero di test necessari. Cioè, se i mattoncini non si muovono mai, e sai che per esempio la prossima collisione avverrà tra 40 frames, puoi benissimo saltare il calcolo delle collisioni per ben 39 volte, risparmiando un discreto numero di calcoli...

Il mio vecchio algoritmo non è così sofisticato comunque, si basa solo sul calcolo della posizione della pallina in termini di griglia, e controlla le celle della griglia adiacenti per detectare una collisione, per questo motivo tutti i mattoncini sono obbligati a stare su una griglia con celle di dimensioni tutte uguali.

PM Quote