Unlimited WordPress themes, graphics, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Game Development
  2. Programming

Hoe te Detecteren Wanneer een Object Is Omcirkeld Door een Gebaar

by
Difficulty:IntermediateLength:LongLanguages:

Dutch (Nederlands) translation by Adjatay Bashroh Aldad (you can also view the original English article)

Je bent nooit te oud voor een spelletje Spot the Difference - ik herinner me het als een kind te spelen, en ik merk nu dat mijn vrouw het nog steeds af en toe speelt! In deze zelfstudie bekijken we hoe je kunt detecteren wanneer een ring rond een object is getrokken, met een algoritme dat kan worden gebruikt met de muis, de stylus of de invoer via een touchscreen.


Opmerking: hoewel de demo's en broncode van deze tutorial Flash en AS3 gebruiken, zou je in bijna elke game-ontwikkelomgeving dezelfde technieken en concepten moeten kunnen gebruiken.


Eindresultaat Voorbeeld

Laten we eens kijken naar het uiteindelijke resultaat waar we naartoe zullen werken. Het scherm is verdeeld in twee afbeeldingen, die bijna identiek maar niet helemaal zijn. Probeer de zes verschillen te herkennen en omcirkel die op de linker afbeelding. Succes!

Opmerking: je hoeft geen perfecte cirkel te tekenen! Je hoeft alleen maar een ruwe ring of lus rond elk verschil te tekenen.

Heb je geen Flits? Bekijk deze videodemo:


Stap 1: De Omcirkelende Motie

We zullen enkele vectorberekeningen in het algoritme gebruiken. Zoals altijd is het goed om de onderliggende wiskunde te begrijpen voordat je het toepast, dus hier is een korte opfriscursus van vector wiskunde.

Vector definition

De afbeelding hierboven toont de vector A uitgesplitst naar zijn horizontale en verticale componenten (respectievelijk Ax en Ay).

Laten we nu eens kijken naar de werking van het puntproduct, geïllustreerd in de onderstaande afbeelding. Eerst ziet u de bewerking van het puntproduct tussen de vectoren A en B.

Vector math

Om de hoek tussen de twee vectoren te vinden, kunnen we gebruik maken van dit puntproduct.

|A| en |B| geven de magnitudes van vectoren A en B aan, dus gegeven |A| en |B| en een punt B, wat theta onbekend blijft, is onbekend. Met een beetje algebra (weergegeven in de afbeelding) wordt de laatste vergelijking geproduceerd, die we kunnen gebruiken om theta te vinden.

Voor meer informatie over vectorpixels, verwijs naar de volgende Wolfram page.

De andere nuttige werking is kruisproduct. Bekijk onderstaand beschreven:

Cross vector

Deze bewerking is handig om te bepalen of de ingeklemd hoek met de klok mee of tegen de klok in is ten opzichte van een specifieke vector.

Ik zal het verder uitwerken. In het bovenstaande diagram is rotatie van A naar B met de klok mee, dus A-kruis B is negatief. Rotatie van B naar A is tegen de klok in, dus B-kruising A is positief. Merk op dat deze bewerking sequentiegevoelig is. Een kruising B zal een ander resultaat opleveren dan B-kruising A.

Dat is niet alles. Het komt voor dat in veel coördinatiereeksen van ontwikkelplatforms de y-as wordt omgekeerd (y neemt toe naarmate we naar beneden gaan). Dus onze analyse is omgekeerd en A kruis B zal positief zijn terwijl B kruis A negatief is.

Dat is genoeg revisie. Laten we naar ons algoritme gaan.


Stap 2: Circuit Interactie

Spelers moeten het juiste detail omcirkelen in de afbeelding. Hoe doen we dat? Voordat we deze vraag beantwoorden, moeten we de hoek tussen twee vectoren berekenen. Zoals u zich nu herinnert, kunnen we het puntproduct hiervoor gebruiken, dus we zullen die vergelijking hier implementeren.

Hier is een demo om te illustreren wat we doen. Sleep een van de pijlen rond om de feedback te zien.

Laten we kijken hoe dit werkt. In de onderstaande code heb ik eenvoudig de vectoren en een timer geïnitialiseerd en een aantal interactieve pijlen op het scherm geplaatst.

Elke 50 milliseconden wordt de onderstaande functie uitgevoerd en gebruikt om de grafische en tekstfeedback bij te werken:

U zult opmerken dat de magnitude voor v1 en v2 in dit scenario beide 1 eenheid zijn (zie regel 52 en 53 hierboven gemarkeerd), dus ik sloeg de noodzaak over om de grootte van de vectoren nu te berekenen.

Als u zien van de volledige broncode wilt, Bekijk u Demo1.as in het downloadpakket van de bron.


Stap 3: Detecteer een volledige cirkel

Ok, nu we het basisidee hebben begrepen, zullen we het nu gebruiken om te controleren of de speler met succes een punt omcirkelde.

Calculate the angles

Ik hoop dat het diagram voor zichzelf spreekt. Het begin van de interactie is wanneer de muisknop wordt ingedrukt en het einde van de interactie is wanneer de muisknop wordt losgelaten.

Bij elk interval (van bijvoorbeeld 0,01 seconde) tijdens de interactie, berekenen we de hoek ingeklemd tussen huidige en vorige vectoren. Deze vectoren worden geconstrueerd vanaf de markeringslocatie (waar het verschil is) naar de muislocatie bij die instantie. Tel hierbij alle hoeken op (t1, t2, t3) en als de gemaakte hoek 360 graden is aan het einde van de interactie, dan heeft de speler een cirkel getekend.

Natuurlijk kun je de definitie van een volledige cirkel aanpassen tot 300-340 graden, waardoor er ruimte is voor spelerfouten bij het uitvoeren van muisbewegingen.

Hier is een demo voor dit idee. Sleep een cirkelvormig gebaar rond de rode markering in het midden. U kunt de positie van de rode markering verplaatsen met de toetsen W, A, S, D.


Stap 4: De Implementatie

Laten we de implementatie voor de demo bekijken. We zullen hier alleen de belangrijke berekeningen bekijken.

Bekijk de gemarkeerde code hieronder en vergelijk deze met de wiskundige vergelijking in stap 1. Je zult merken dat de waarde voor arccos soms niet een getal (NaN) oplevert als je regel 92 overslaat. Ook, Constants_value is soms groter dan 1 vanwege afrondingsonnauwkeurigheden, dus we moeten deze handmatig terugbrengen tot een maximum van 1. Elk inputnummer voor arccos groter dan 1 levert een NaN op.

De volledige bron hiervoor is te vinden in Demo2.as


Stap 5: De Fout

Een probleem dat je misschien zult zien, is dat zolang ik een grote cirkel teken die het canvas omsluit, de marker als omcirkeld wordt beschouwd. Ik hoef niet echt te weten waar de marker is.

Welnu, om dit probleem tegen te gaan, kunnen we de nabijheid van de cirkelvormige beweging controleren. Als de cirkel binnen de grenzen van een bepaald bereik wordt getrokken (waarvan de waarde onder uw controle staat), wordt alleen dat als een succes beschouwd.

Bekijk de onderstaande code. Als de gebruiker ooit MIN_DIST overschrijdt (in dit geval met een waarde van 60), wordt dit beschouwd als een willekeurige schatting.

Nogmaals, probeer de marker te omcirkelen. Als je denkt dat MIN_DIST een beetje meedogenloos is, kan deze altijd worden aangepast aan de afbeelding.


Stap 6: Verschillende Vormen

Wat als het "verschil" geen exacte cirkel is? Sommige kunnen rechthoekig of driehoekig zijn of een andere vorm hebben.
In deze gevallen kunnen we, in plaats van slechts één markering te gebruiken, er een paar plaatsen:

Circling multiple cirlce

In het bovenstaande diagram worden bovenaan twee muisaanwijzers weergegeven. Te beginnen met de meest rechtse cursor, maken we een cirkelvormige beweging met de klok mee naar het andere uiteinde aan de linkerkant. Merk op dat het pad alle drie markeringen omcirkelt.

Ik heb ook de hoeken getekend die zijn verstreken door dit pad op elk van de markeringen (lichte streepjes naar donkere streepjes). Als alle drie de hoeken meer dan 360 graden zijn (of welke waarde u ook kiest), tellen we het alleen als een cirkel.

Maar dat is niet voldoende. Denk aan de fout in stap 4? Welnu, hetzelfde geldt hier: we moeten controleren of we in de buurt zijn. In plaats van te vereisen dat het gebaar een bepaalde straal van een specifieke markering niet overschrijdt, controleren we alleen of de muiscursor althans een korte instantie dicht bij alle markeringen kwam. Ik zal pseudo-code gebruiken om dit idee uit te leggen:


Stap 7: Demo voor het idee

Hier gebruiken we drie punten om een ​​driehoek weer te geven.

Probeer rond te cirkelen:

  • één stip
  • twee stippen
  • drie puntjes

.. .in de afbeelding hieronder. Neem nota dat het gebaar alleen slaagt als het bevat alle drie puntjes.

Laten we eens kijken naar de code voor deze demo. Ik heb de belangrijkste lijnen voor het onderstaande idee belicht; het volledige script staat in Demo4.as.


Stap 8: De Cirkels Tekenen

De beste methode om de regel die u volgt daadwerkelijk te tekenen, is afhankelijk van uw ontwikkelplatform, dus ik zal alleen de methode beschrijven die we hier in Flash zouden gebruiken.

Actionscript drawing API

Er zijn twee manieren om lijnen in AS3 te tekenen, zoals aangegeven door de afbeelding hierboven.

De eerste benadering is vrij eenvoudig: gebruik moveTo() om de positie van de tekening te coördineren (10, 20). Teken vervolgens een lijn om verbinding te maken (10, 20) tot (80, 70) met lineTo().

De tweede benadering is om alle details op te slaan in twee arrays, opdrachten[] en coцrdons[] (met coördinaten opgeslagen in (x, y) paren binnen de coördinaten[]) en later alle grafische details op canvas te tekenen met drawPath() in één enkele schot. Ik heb gekozen voor de tweede benadering in mijn demo.

Bekijk het: probeer de muis op het canvas te klikken en te slepen om de lijn te tekenen.

En hier is de AS3-code voor deze demo. Bekijk de volledige bron in Drawing1.as.

In Flash gebruikt het gebruik van het grafische object voor tekenen op deze manier het behouden van de modusweergave, wat betekent dat de eigenschappen van de afzonderlijke regels afzonderlijk worden opgeslagen - in tegenstelling tot de onmiddellijke modusweergave, waarbij alleen de uiteindelijke afbeelding wordt opgeslagen. (Dezelfde concepten bestaan ​​ook in andere ontwikkelingsplatforms, bijvoorbeeld in HTML5 maakt tekenen naar SVG gebruik van de behouden modus, terwijl het tekenen naar canvas de directe modus gebruikt.)

Als er veel lijnen op het scherm staan, kan het langzaam en laggy worden als u ze allemaal apart opslaat en opnieuw genereert. De oplossing hiervoor hangt af van uw platform - in Flash kunt u BitmapData.draw() gebruiken om elke regel op te slaan in een enkele bitmap nadat deze is getekend.


Stap 9: Voorbeeldniveau

Hier heb ik een demo gemaakt voor het voorbeeldniveau van een Spot the Difference-game. Bekijken! De volledige bron bevindt zich in Sample2.as van de brondownload.

Conclusie

Bedankt voor het lezen van dit artikel; Ik hoop dat het je een idee heeft gegeven voor het bouwen van je eigen spel. Laat enkele opmerkingen achter als er een probleem is met de code en ik neem zo snel mogelijk contact met u op.

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.