Eenvoudige, vloeiende toetsenbordbeweging in AS3 met de ingangsklasse

Er zijn veel games beschikbaar met schokkerige, onrealistische bewegingen en dat kan maar één ding doen voor je product: maak het onaantrekkelijk voor het publiek. Maar vloeiende bewegingen zijn niet moeilijk te bereiken - laten we aan het werk gaan!


Eindresultaat voorbeeld

Laten we eens kijken naar het eindresultaat waar we naartoe zullen werken:


Stap 1: de omgeving instellen

Dit is een eenvoudige tutorial, dus het instellen zal ook eenvoudig zijn.

Maak een nieuw ActionScript 3.0 Flash-project. De grootte en kleur van het podium doen er niet toe, gebruik gewoon waar je comfortabel mee bent.

Ik gebruik FlashDevelop voor codering, maar dit kan ook in elke AS-editor, zoals Flash Pro (of een teksteditor, misschien Notepad;)). Dus, maak een Class-bestand, zorg ervoor dat uw code lijkt op de mijne; zie hieronder. Ik heb de mijne 'beweging' genoemd. (Als u Flash Pro gebruikt, raadpleegt u deze handleiding voor het maken van een les.)

 pakket import flash.display.Sprite; public class Movement breidt public function Movement (): void  uit

Nadat u klaar bent, zorgt u ervoor dat uw klasse is gekoppeld aan het Flash-project als de hoofdklasse.


Stap 2: Maak het kwadraat en de variabelen

Dus nadat u de verplaatsingsklasse aan uw document hebt gekoppeld, definieert u de variabelen zoals ik hieronder heb gedaan

 pakket import flash.display.Sprite; import flash.events.Event; public class Movement breidt Sprite uit // Het object dat private var square verplaatst: Sprite; // De maximale snelheid private var _max: Number = 10; // De variabelen die zullen worden toegepast om de vierkante private var dx te verplaatsen: Number = 0; privévar dy: Number = 0; public function Movement (): void // Luister naar toegevoegd aan fasegebeurtenis addEventListener (Event.ADDED_TO_STAGE, init);  private function init (e: Event): void removeEventListener (Event.ADDED_TO_STAGE, init); // Een nieuwe Sprite maken en binnen een vierkant vierkant tekenen = nieuwe Sprite (); square.graphics.beginFill (0x333333); square.graphics.drawRect (0, 0, 30, 30); square.x = stage.stageWidth / 2 - square.width / 2; square.y = stage.stageHeight / 2 - square.height / 2; addChild (vierkant); 

Dit is vrijwel alles wat we zullen doen om het object te maken. Je kunt je eigen object gebruiken, maar voor deze tutorial met eenvoudige bewegingen heb ik dit eenvoudige vierkant gebruikt.


Stap 3: Introductie van de klasse Input.as

Hallo allemaal, dit is de klasse Input.as; Input.as Class dit zijn de jongens waar ik je over heb verteld - wees aardig voor ze! :)

Dus waar gaat deze klas over, vraag je je misschien af. In principe doet het uw sleutelafhandelingstaak voor u. Het voegt een luisteraar toe aan ENTER_FRAME-events - met lage prioriteit - en een key-listener die sommige private Dictionaries vult. Ook gebruikt het een andere Klasse voor sleutelcodes. Je kunt binnen naar binnen kijken en zelf zien hoe werken.

Opmerking: de klasse Input.as is niet van mij. Het is gemaakt door Matthew Bush, die Box2D heeft geport naar Flash.

 // Voorbeeld van Input.as Class usage // Je moet het altijd initialiseren als dit met de stage parameter Input.initialize (stage); // Na het initialiseren kunt u de methoden kd (), kp () of ku () gebruiken, die // een Booleaanse waarde retourneren als aan de voorwaarden is voldaan. // Deze methoden accepteren meerdere argumenten, // dus voor één gebeurtenis kunt u meerdere sleutels gebruiken. // Dit maakt het een stuk eenvoudiger om de toegankelijkheid van uw app te verbeteren. //e.g Zie hieronder als ik één oproep gebruik voor het detecteren van de UP-pijl of W voor het omhoog gaan. Input.kd ("UP", "W");

Stap 4: De klassen importeren

Dus nu u bekend bent met de klasse Input.as, gaan we deze importeren in onze Movement Class en deze initialiseren.

 pakket import flash.display.Sprite; import flash.events.Event; import Input; public class Movement breidt Sprite uit // Het object dat private var square verplaatst: Sprite; // De maximale snelheid private var _max: Number = 10; // De variabelen die zullen worden toegepast om de vierkante private var dx te verplaatsen: Number = 0; privévar dy: Number = 0; public function Movement (): void // Luister naar toegevoegd aan fasegebeurtenis addEventListener (Event.ADDED_TO_STAGE, init);  private function init (e: Event): void removeEventListener (Event.ADDED_TO_STAGE, init); // Een nieuwe Sprite maken en binnen een vierkant vierkant tekenen = nieuwe Sprite (); square.graphics.beginFill (0x333333); square.graphics.drawRect (0, 0, 30, 30); square.x = stage.stageWidth / 2 - square.width / 2; square.y = stage.stageHeight / 2 - square.height / 2; addChild (vierkant); // Initialiseer de klasse Input.as met handler op het podium Input.initialize (stage); // Voeg de refresh-loop toe addEventListener (Event.ENTER_FRAME, refresh);  persoonlijke functie vernieuwen (e: Event): void 

Stap 5: omgaan met de sleutelinvoer

Ik gebruik een op ENTER_FRAME gebaseerde lus voor het detecteren van de toetsingangen; hieronder is de refresh () methode die de handlerfunctie is voor deze gebeurtenis.

 persoonlijke functie verversen (e: Event): void // Key Handler if (Input.kd ("A", "LEFT")) // Verplaats naar links if (Input.kd ("D", "RIGHT ")) // Verplaats naar rechts als (! Input.kd (" A "," LEFT "," D "," RIGHT ")) // Als er geen links / rechts is ingedrukt als (Input .kd ("W", "UP")) // Omhoog verplaatsen if (Input.kd ("S", "DOWN")) // Omlaag als (! Input.kd ("W", "UP", "S", "DOWN")) // Als er geen actie omhoog / omlaag is

Stap 6: De berekeningen uitleggen - Omgaan met de snelheid

Dit is redelijk rechttoe rechtaan. Detecteer of een van de toetsen is ingedrukt en handel dan overeenkomstig.

Ik gebruik de ternaire operator veel: waarde = conditie? waar onwaar;
Dit is in feite een if-statement dat is gecondenseerd tot een enkele regel.

Voor elke belangrijke detectie, gebruik ik deze methode: als de waarde groter is dan _max stel het dan gelijk aan _max; anders verhoogt of verlaagt u die specifieke waarde naargelang het geval. Op deze manier wordt het binnen bepaalde grenzen gehouden. Eenvoudig, toch?

Hieronder kun je de voorwaarden bestuderen:

 persoonlijke functie vernieuwen (e: Event): void // Key Handler if (Input.kd ("A", "LEFT")) // Verplaats naar links dx = dx < 0.5 - _max ? _max * -1 : dx - 0.5;  if (Input.kd("D", "RIGHT"))  //Move to the right dx = dx > _max - 0,5? _max: dx + 0,5;  if (! Input.kd ("A", "LEFT", "D", "RIGHT")) // Als er geen links / rechts wordt ingedrukt als (dx> 0.5) dx = dx < 0.5 ? 0 : dx - 0.5;  else  dx = dx > -0,5? 0: dx + 0,5;  if (Input.kd ("W", "UP")) // Omhoog bewegen dy = dy < 0.5 - _max ? _max * -1 : dy - 0.5;  if (Input.kd("S", "DOWN"))  //Move down dy = dy > _max - 0,5? _max: dy + 0,5;  if (! Input.kd ("W", "UP", "S", "DOWN")) // Als er geen op / neer-actie is als (dy> 0,5) dy = dy < 0.5 ? 0 : dy - 0.5;  else  dy = dy > -0,5? 0: dy + 0,5;  // Pas deze toe op het object square.x + = dx; square.y + = dy; 

Als u niet vertrouwd bent met de ternaire operator, pak dan een stuk papier en een pen en schrijf er een paar op in if ... else-formaat; het is een geweldige oefening om daar grip op te krijgen.

Houd in gedachten dat ik het manipuleer dx en dy variabelen en stel alleen de werkelijke x- en y-waarden aan het einde in. Dit helpt ons de beweging vloeibaar te maken; het is niet schokkelen, we veranderen hun waarden direct in de hele functie ...

Ga door, test het! Zie hoe mooi het beweegt?


Stap 7: Boundary Collisions gebruiken

Oke. Alles klopt, beweegt vloeiend - maar buiten het toneel! Hieronder heb ik de voorwaarden voor collision detection toegevoegd.

 persoonlijke functie vernieuwen (e: Event): void // Key Handler if (Input.kd ("A", "LEFT")) // Verplaats naar links dx = dx < 0.5 - _max ? _max * -1 : dx - 0.5;  if (Input.kd("D", "RIGHT"))  //Move to the right dx = dx > _max - 0,5? _max: dx + 0,5;  if (! Input.kd ("A", "LEFT", "D", "RIGHT")) // Als er geen links / rechts wordt ingedrukt als (dx> 0.5) dx = dx < 0.5 ? 0 : dx - 0.5;  else  dx = dx > -0,5? 0: dx + 0,5;  if (Input.kd ("W", "UP")) // Omhoog bewegen dy = dy < 0.5 - _max ? _max * -1 : dy - 0.5;  if (Input.kd("S", "DOWN"))  //Move down dy = dy > _max - 0,5? _max: dy + 0,5;  if (! Input.kd ("W", "UP", "S", "DOWN")) // Als er geen op / neer-actie is als (dy> 0,5) dy = dy < 0.5 ? 0 : dy - 0.5;  else  dy = dy > -0,5? 0: dy + 0,5;  // Grens detectie als (square.x - dx < 0 || square.x + dx + square.width > stage.stageWidth) // x axis detection if (square.y - dy < 0 || square.y + dy + square.height > stage.stageHeight) // y-asdetectie // Pas deze na alles toe op het object square.x + = dx; square.y + = dy; 

Het zoekt naar grenzen op een meer precieze manier, door te controleren of de randen van het vierkant de grenzen raken (daarvoor, controleerde het alleen het midden van het vierkant tegen de grenzen).

Super goed. Nu moeten we de code toevoegen om het vierkant van de grenzen te laten weerkaatsen. Wat ik daarvoor doe, is vermenigvuldigen met -1 de aswaarde dx of dy. Maar dat is niet voldoende! Als de snelheid vrij snel is, zal het vierkant door de marges gaan of gewoon gek worden. Dus voordat we vermenigvuldigen, moeten we instellen dat de x of y van het object hetzelfde is als de grens waaraan het voldoet.

Dus als x object.x = 0; en vermenigvuldig het dx met -1.

 // Margin detection if (square.x - dx < -dx || square.x + dx + square.width > stage.stageWidth) // x axis detection square.x = square.x - dx < -dx ? 0 : stage.stageWidth - square.width; dx *= -1;  if (square.y - dy < -dy || square.y + dy + square.height > stage.stageHeight) // y axis detection square.y = square.y - dy < -dy ? 0 : stage.stageHeight - square.height; dy *= -1; 

Test het nu! Bouncy toch? :)

Om het nog beter te maken, blijf experimenteren met verschillende waarden - zoals in plaats van vermenigvuldigen met -1, probeer -0.7 en zie de resultaten.


Conclusie

Dus je hebt de Input.as Class leren kennen, hebt leren werken en hebt een aardige vloeiende beweging gemaakt in slechts een paar minuten. Ik denk dat dit als een geweldige tijd telt!

Laat hieronder uw opmerkingen en eventuele andere vragen achter, ik zal u graag antwoorden.

Maar als u een probleem tegenkomt, controleer dan tweemaal uw code, vergelijk het met het bronbestand en als u het dan niet kunt laten werken, kunt u een vraag stellen.