Sfat rapid detectarea coliziunilor între cercuri

Detectarea coliziunilor este o ramură a algoritmilor care verifică dacă două forme se suprapun. Dacă construiți fizică sau jocuri de acțiune cu ActionScript, cu siguranță nu veți scăpa de cunoașterea acestui subiect. Aceasta este prima din seria privind detecția coliziunilor. În acest sfat rapid, vom analiza metoda de detecție a coliziunii încorporate ActionScript, hitTestObject (), și scrie propriile noastre pentru a detecta suprapunerea între două cercuri.


Rezultatul final al rezultatelor

Acesta este SWF-ul final pe care îl vom crea în acest sfat rapid. Faceți clic pe cercul albastru și trageți-l spre cel verde. Odată ce se suprapun, cercul verde își va schimba culoarea; dacă scoateți cercul albastru din nou, celălalt va reveni la verde.


Pasul 1: Controale ale casetei de legătură

Cei care sunt familiarizați cu ActionScript 2.0 vor recunoaște cu siguranță metoda, hitTest (). Această comandă verifică suprapunerea între două forme sau între o formă și un singur punct. În ActionScript 3.0 este împărțit în două metode separate: hitTestObject () și hitTestPoint ().

Ne vom uita hitTestObject () primul. Această comandă se potrivește, în general, cu detectarea coliziunilor pentru formele de tip box-like (pătrate, dreptunghiuri). O casetă de legare este desenată în jurul unor forme și atunci când aceste cutii de delimitare se suprapun reciproc, hitTestObject () întoarce adevărat.

Consultați exemplul de mai jos. Trageți cutia albastră spre cea verde. Pe măsură ce se suprapun, umbra cutiei verzi se întunecă.

Am atașat aici ActionScript corespunzător care generează prezentarea de mai sus. Cutie este o clasă scrisă personalizată pentru a genera cu ușurință forme pătrate. Am inclus clasele în dosarul sursă; se referă la ele. Scriptul important pentru detectarea coliziunilor este evidențiat mai jos.

 pachet import flash.display.Graphics; import flash.display.Sprite; importul flash.events.MouseEvent; / ** * Simplu hitTest cu cutii * @author Shiu * / [SWF (lățime = 400, înălțime = 300)] clasa publică simplă extinde Sprite privat var box1: Box, box2: Box; funcția publică simplă () box1 = casetă nouă (0x0000FF); addChild (Box1); box1.x = 250; box1.y = 250; box1.addEventListener (MouseEvent.MOUSE_DOWN, start); box1.addEventListener (MouseEvent.MOUSE_UP, sfârșit); caseta2 = caseta nouă (0x00FF00); addChild (cutia2); box2.x = 100; box2.y = 50;  funcția privată de pornire (e: MouseEvent): void e.target.startDrag (); e.target.addEventListener (MouseEvent.MOUSE_MOVE, verificați);  sfârșitul funcției private (e: MouseEvent): void e.target.stopDrag (); e.target.removeEventListener (MouseEvent.MOUSE_MOVE, verificați);  verificarea funcției private (e: MouseEvent): void if (e.target.hitTestObject (caseta2)) box2.color = 0x00AA00; altfel box2.color = 0x00FF00; 

Pasul 2: Deficiențe ale cutiilor de îmbinare

Cu toate acestea, coliziunea dintre cercuri nu poate fi verificată eficient utilizând această comandă. Consultați prezentarea de mai jos. Trageți cercul albastru spre cel verde. Înainte ca formele să se ciocnească, cutiile de delimitare se suprapun deja hitTestObject () este adevarat. Avem nevoie de o soluție mai precisă.

Această problemă este răspândită nu numai pentru detectarea coliziunilor între cercuri, ci și pentru formele non-pătrat în general. Respectați diagrama de mai jos. Pentru formele organice care sunt greu de rezolvat de către poligoane, vom folosi detecția coliziunii precisă a pixelilor.


Diverse inadecvate coliziuni detectate prin hitTestObject.

Pasul 3: Distanța între centre

Soluția la această problemă este destul de simplă: vom măsura distanța dintre centrele acestor cercuri. Dacă centrele se vor apropia destul de aproape unul de altul, vom semna coliziunea ca fiind adevărată. Dar cât de aproape este destul de aproape?


Distanța dintre cercuri.

Respectați diagrama de mai sus. r1 se referă la raza cercului1 și r2 se referă la raza cercului2. Distanța dintre cercuri se calculează pe fiecare cadru. Dacă (și numai dacă) este egală cu sau mai mică decât suma ambelor raze (r1+ r2), atunci cele două cercuri trebuie să se atingă sau să se suprapună între ele.


Pasul 4: Detectarea coliziunii în cerc-cerc

Iată importanța ActionScript pentru implementarea conceptului de mai sus:

 minDist = circle1.radius + circle2.radius;
 verificarea funcției private (e: MouseEvent): void var distanță: Număr = Math2.Pythagoras (cerc1.x, cerc1.y, cerc2.x, cerc2.y); dacă (distanța <= minDist) circle2.color = 0x00FFAA; else circle2.color = 0x00FF00; 

Pasul 5: Soluție de probă

Iată o mostră a soluției. Trageți cercul albastru spre cel verde. Pe măsură ce se suprapun, veți vedea schimbarea culorii verde. Se întoarce la normal când ambele cercuri nu se ciocnesc.

Am inclus implementarea ActionScript de mai jos.

 pachet import flash.display.Sprite; importul flash.events.MouseEvent; / ** * Coliziune simplă între 2 cercuri * @author Shiu * / [SWF (lățime = 400, înălțime = 300)] clasa publică Simple3 extinde Sprite priv var cerc1: Cerc, cerc2: Cerc; privat var minDist: număr; funcția publică Simple3 () cercle1 = nou Cerc (0x0055AA, 30); addChild (CIRCLE1); cerc1.x = 250; cerc1.y = 250; cerc1.addEventListener (MouseEvent.MOUSE_DOWN, start); cerc1.addEventListener (MouseEvent.MOUSE_UP, sfârșit); cerc2 = cerc nou (0x00FF00, 30); addChild (CIRCLE2); cerc2.x = 100; cerc2.y = 50; minDist = circle1.radius + circle2.radius;  funcția privată de pornire (e: MouseEvent): void e.target.startDrag (); e.target.addEventListener (MouseEvent.MOUSE_MOVE, verificați);  sfârșitul funcției private (e: MouseEvent): void e.target.stopDrag (); e.target.removeEventListener (MouseEvent.MOUSE_MOVE, verificați);  verificarea funcției private (e: MouseEvent): void var distanță: Număr = Math2.Pythagoras (cerc1.x, cerc1.y, cerc2.x, cerc2.y); dacă (distanța <= minDist) circle2.color = 0x00FFAA; else circle2.color = 0x00FF00;   

Concluzie

După cum puteți vedea, principiul general al detectării coliziunilor este de a folosi formule matematice pentru a verifica suprapunerile între diferite forme. Vector matematica joaca un rol important prea. Trebuie să vină o coliziune între un cerc și o linie. Vă mulțumim că ați citit și vă voi vedea în curând.

Cod