Snelle tip Collision Detection Between Circles

Botsingsdetectie is een tak van algoritmen die controleert of twee vormen elkaar overlappen. Als je fysica of actiegames bouwt met ActionScript, zul je zeker niet ontsnappen aan de kennismaking met dit onderwerp. Dit is de eerste van de serie met betrekking tot botsingsdetectie. In deze Snelle tip zullen we kijken naar de ingebouwde botsingsdetectiemethode van ActionScript, hitTestObject (), en schrijf onze eigen om overlapping tussen twee cirkels te detecteren.


Eindresultaat voorbeeld

Dit is de laatste SWF die we in deze Quick Tip zullen maken. Klik op de blauwe cirkel en sleep deze naar de groene. Zodra ze elkaar overlappen, verandert de groene cirkel van kleur; als je de blauwe cirkel weer verwijdert, wordt de andere weer groen.


Stap 1: selectievakje checkboxen

Degenen die vertrouwd zijn met ActionScript 2.0 zullen de methode zeker herkennen, hitTest (). Met deze opdracht wordt gecontroleerd op overlapping tussen twee vormen of tussen een vorm en een enkel punt. In ActionScript 3.0 is het opgesplitst in twee afzonderlijke methoden: hitTestObject () en hitTestPoint ().

We zullen kijken hitTestObject () eerste. Deze commnad is in het algemeen geschikt voor botsdetectie voor doosachtige vormen (vierkanten, rechthoeken). Een selectiekader wordt rond vormen getekend en wanneer deze selectiekaders elkaar overlappen, hitTestObject () geeft waar terug.

Bekijk het onderstaande voorbeeld. Sleep het blauwe vak naar de groene. Terwijl ze elkaar overlappen, wordt de schaduw van de groene doos donkerder.

Ik voeg hier het bijbehorende ActionScript toe dat de bovenstaande presentatie genereert. Doos is een aangepaste geschreven klasse om eenvoudig vierkante vormen te genereren. Ik heb de klassen in de bronmap opgenomen; verwijs ernaar. Het belangrijke script voor detectie van botsingen is hieronder gemarkeerd.

 pakket import flash.display.Graphics; import flash.display.Sprite; import flash.events.MouseEvent; / ** * Eenvoudige hitTest met vakken * @author Shiu * / [SWF (width = 400, height = 300)] public class Simple extends Sprite private var box1: Box, box2: Box; openbare functie Simple () box1 = nieuwe Box (0x0000FF); addChild (box1); box1.x = 250; box1.y = 250; box1.addEventListener (MouseEvent.MOUSE_DOWN, start); box1.addEventListener (MouseEvent.MOUSE_UP, einde); box2 = nieuw vak (0x00FF00); addChild (box 2); box2.x = 100; box2.y = 50;  start privéfunctie (e: MouseEvent): void e.target.startDrag (); e.target.addEventListener (MouseEvent.MOUSE_MOVE, check);  private function end (e: MouseEvent): void e.target.stopDrag (); e.target.removeEventListener (MouseEvent.MOUSE_MOVE, check);  controle van persoonlijke functie (e: MouseEvent): void if (e.target.hitTestObject (box2)) box2.color = 0x00AA00; anders box2.color = 0x00FF00; 

Stap 2: tekortkomingen van begrenzende dozen

Een botsing tussen cirkels kan echter niet effectief worden gecontroleerd met deze opdracht. Bekijk de onderstaande presentatie. Sleep de blauwe cirkel naar de groene. Voordat de vormen botsen, overlappen hun selectiekaders elkaar al en hitTestObject () is waar. We hebben een meer accurate oplossing nodig.

Dit probleem komt niet alleen voor bij botsingsdetectie tussen cirkels maar in het algemeen in niet-vierkante vormen. Bekijk het diagram hieronder. Voor organische vormen die moeilijk op te lossen zijn door veelhoeken, zullen we gebruik maken van pixel-precieze botsingsdetectie.


Verschillende onnauwkeurige botsingen gedetecteerd door hitTestObject.

Stap 3: Afstand tussen centra

De oplossing voor dit probleem is vrij eenvoudig: we zullen de afstand tussen de middelpunten van deze cirkels meten. Als de centra dicht genoeg bij elkaar komen, zullen we botsing als waar markeren. Maar hoe dichtbij is dichtbij genoeg?


Afstand tussen cirkels.

Bekijk het diagram hierboven. r1 verwijst naar de straal van cirkel 1 en r2 verwijst naar de straal van circle2. De afstand tussen cirkels wordt op elk frame berekend. Als (en alleen als) het gelijk is aan of kleiner is dan de som van beide stralen (r1+ r2), dan moeten de twee cirkels elkaar raken of elkaar overlappen.


Stap 4: Circle-Circle Collision Detection

Hier zijn de belangrijke ActionScript-code voor de implementatie van het bovenstaande concept:

 minDist = circle1.radius + circle2.radius;
 controle van persoonlijke functies (e: MouseEvent): void var distance: Number = Math2.Pythagoras (circle1.x, circle1.y, circle2.x, circle2.y); als (afstand <= minDist) circle2.color = 0x00FFAA; else circle2.color = 0x00FF00; 

Stap 5: Monsteroplossing

Hier is een voorbeeld van de oplossing. Sleep de blauwe cirkel naar de groene cirkel. Terwijl ze elkaar overlappen, zie je de kleurverandering van groen. Het keert terug naar normaal wanneer beide cirkels niet botsen.

Ik heb de ActionScript-implementatie hieronder opgenomen.

 pakket import flash.display.Sprite; import flash.events.MouseEvent; / ** * Eenvoudige botsing tussen 2 cirkels * @author Shiu * / [SWF (width = 400, height = 300)] public class Simple3 breidt Sprite uit private var circle1: Circle, circle2: Circle; private var minDist: Number; openbare functie Simple3 () circle1 = new Circle (0x0055AA, 30); addChild (circle1); circle1.x = 250; circle1.y = 250; circle1.addEventListener (MouseEvent.MOUSE_DOWN, start); circle1.addEventListener (MouseEvent.MOUSE_UP, einde); circle2 = new Circle (0x00FF00, 30); addChild (circle2); circle2.x = 100; circle2.y = 50; minDist = circle1.radius + circle2.radius;  start privéfunctie (e: MouseEvent): void e.target.startDrag (); e.target.addEventListener (MouseEvent.MOUSE_MOVE, check);  private function end (e: MouseEvent): void e.target.stopDrag (); e.target.removeEventListener (MouseEvent.MOUSE_MOVE, check);  controle van persoonlijke functie (e: MouseEvent): void var distance: Number = Math2.Pythagoras (circle1.x, circle1.y, circle2.x, circle2.y); als (afstand <= minDist) circle2.color = 0x00FFAA; else circle2.color = 0x00FF00;   

Conclusie

Zoals je kunt zien, is het algemene principe van botsingsdetectie om wiskundige formules te gebruiken om te controleren op overlappingen tussen verschillende vormen. Vector wiskunde speelt ook een belangrijke rol. Hierna komt de botsing tussen een cirkel en een lijn. Bedankt voor het lezen en tot ziens.