Kollisjonsdeteksjon er en gren av algoritmer som kontrollerer om to former overlapper. Hvis du bygger fysikk eller actionspill med ActionScript, vil du absolutt ikke unnslippe bekjennelse med dette emnet. Dette er den første av serien om kollisjonsdeteksjon. I denne Quick Tip skal vi se på ActionScripts innebygde kollisjonsdeteksjonsmetode, hitTestObject ()
, og skriv vår egen for å oppdage overlapping mellom to sirkler.
Dette er den endelige SWF vi skal skape i denne Quick Tip. Klikk den blå sirkelen og dra den mot den grønne. Når de overlapper, endrer den grønne sirkelen sin farge; Hvis du fjerner den blå sirkelen igjen, kommer den andre tilbake til å være grønn.
De som er kjent med ActionScript 2.0, vil definitivt gjenkjenne metoden, hitTest ()
. Denne kommandoen kontrollerer overlapping mellom to former, eller mellom en form og et enkelt punkt. I ActionScript 3.0 er det delt inn i to separate metoder: hitTestObject ()
og hitTestPoint ()
.
Vi skal se på hitTestObject ()
først. Denne kommandoen passer vanligvis til kollisjonsdeteksjon for bokslignende former (firkanter, rektangler). En avgrensingsboks er tegnet rundt figurer og når disse avgrensingsboksene overlapper hverandre, hitTestObject ()
returnerer sant.
Sjekk ut eksemplet nedenfor. Dra den blå boksen mot den grønne. Når de overlapper, blir den grønne boksens skygge mørkere.
Jeg vedlegger den tilsvarende ActionScript som genererer den ovennevnte presentasjonen. Eske
er en skreddersydd skriftlig klasse for enkelt å generere firkantede former. Jeg har tatt med klassene i kildemappen; referer til dem. Det viktige skriptet for kollisjon gjenkjenning er uthevet nedenfor.
pakke import flash.display.Graphics; importer flash.display.Sprite; importer flash.events.MouseEvent; / ** * Enkel hitTest med bokser * @author Shiu * / [SWF (bredde = 400, høyde = 300)] offentlig klasse Enkel utvider Sprite private var box1: Box, box2: Box; offentlig funksjon Enkel () box1 = ny boks (0x0000FF); addChild (BOX1); boks1.x = 250; boks1.y = 250; box1.addEventListener (MouseEvent.MOUSE_DOWN, start); box1.addEventListener (MouseEvent.MOUSE_UP, end); box2 = ny boks (0x00FF00); addChild (BOX2); box2.x = 100; box2.y = 50; privat funksjonstart (e: MouseEvent): void e.target.startDrag (); e.target.addEventListener (MouseEvent.MOUSE_MOVE, sjekk); privatfunksjonens slutt (e: MouseEvent): void e.target.stopDrag (); e.target.removeEventListener (MouseEvent.MOUSE_MOVE, sjekk); private funksjonskontroll (e: MouseEvent): void if (e.target.hitTestObject (box2)) box2.color = 0x00AA00; ellers box2.color = 0x00FF00;
Kollisjon mellom sirkler kan imidlertid ikke kontrolleres effektivt ved hjelp av denne kommandoen. Sjekk ut presentasjonen nedenfor. Dra den blå sirkelen mot den grønne. Før fasene kolliderer, overlapper grensene sine allerede og hitTestObject ()
er sant. Vi trenger en mer nøyaktig løsning.
Dette problemet er utbredt, ikke bare for kollisjonsdeteksjon mellom sirkler, men ikke-firkantede former generelt. Se diagrammet under. For organiske former som er vanskelige å løse ved polygoner, skal vi gjøre bruk av piksel-presis kollisjonsdeteksjon.
Løsningen på dette problemet er ganske enkelt: vi skal måle avstanden mellom sentrene i disse kretsene. Hvis sentrene kommer nær nok til hverandre, skal vi flagg kollisjon som sant. Men hvor nær er nær nok?
Vær oppmerksom på diagrammet ovenfor. r1 refererer til radius av sirkel1 og r2 refererer til radius av sirkel2. Avstanden mellom sirkler er beregnet på hver ramme. Hvis (og bare hvis) det er lik eller mindre enn summen av begge radiene (r1+ r2), så må de to sirklene røre eller overlappe hverandre.
Her er den viktige ActionScript for implementering av konseptet ovenfor:
minDist = circle1.radius + circle2.radius;
privat funksjonskontroll (e: MouseEvent): void varavstand: Number = Math2.Pythagoras (circle1.x, circle1.y, circle2.x, circle2.y); hvis (avstand <= minDist) circle2.color = 0x00FFAA; else circle2.color = 0x00FF00;
Her er et utvalg av løsningen. Dra den blå sirkelen mot den grønne. Når de overlapper, ser du grønns fargeendring. Den vender tilbake til normal når begge sirkler ikke kolliderer.
Jeg har inkludert ActionScript-implementeringen nedenfor.
pakke import flash.display.Sprite; importer flash.events.MouseEvent; / ** * Enkel kollisjon mellom 2 sirkler * @author Shiu * / [SWF (bredde = 400, høyde = 300)] offentlig klasse Simple3 utvider Sprite privat varcirkel1: Sirkel, sirkel2: Sirkel; privat var minDist: Nummer; offentlig funksjon Simple3 () circle1 = ny sirkel (0x0055AA, 30); addChild (CIRCLE1); sirkel1.x = 250; circle1.y = 250; circle1.addEventListener (MouseEvent.MOUSE_DOWN, start); circle1.addEventListener (MouseEvent.MOUSE_UP, end); circle2 = ny sirkel (0x00FF00, 30); addChild (CIRCLE2); circle2.x = 100; circle2.y = 50; minDist = circle1.radius + circle2.radius; privat funksjonstart (e: MouseEvent): void e.target.startDrag (); e.target.addEventListener (MouseEvent.MOUSE_MOVE, sjekk); privatfunksjonens slutt (e: MouseEvent): void e.target.stopDrag (); e.target.removeEventListener (MouseEvent.MOUSE_MOVE, sjekk); private funksjonskontroll (e: MouseEvent): void varavstand: Nummer = Math2.Pythagoras (circle1.x, circle1.y, circle2.x, circle2.y); hvis (avstand <= minDist) circle2.color = 0x00FFAA; else circle2.color = 0x00FF00;
Som du kan se, er det generelle prinsippet om kollisjonsdeteksjon å bruke matematiske formler for å kontrollere overlappinger mellom ulike former. Vector matematikk spiller også en viktig rolle. Ved siden av kommer er kollisjon mellom en sirkel og en linje. Takk for at du leser og ser deg snart.