Aan de slag met Crafty The Game Loop

Tot nu toe in deze serie, heb je geleerd hoe je verschillende entiteiten manipuleert en het toetsenbord gebruikt om ze te verplaatsen. In dit deel leer je hoe je de gamelus in Crafty gebruikt om continu te controleren op verschillende gebeurtenissen en verschillende entiteiten te animeren.

De game-loop in Crafty is geïmplementeerd in Crafty.timer.step, dat wereldwijde evenementen gebruikt om te communiceren met de rest van de engines. De lus wordt bestuurd door requestAnimationFrame indien beschikbaar. Elke lus bestaat uit een of meer oproepen naar de enterFrame evenement en een enkele oproep naar RenderScene wat resulteert in het opnieuw tekenen van elke laag. 

De definitieve waarde van alle eigenschappen en variabelen wordt opgelost voordat een scène wordt gerenderd. Als u bijvoorbeeld uw speler 5 keer naar rechts tien keer binnen een single verplaatst enterFrame gebeurtenis, wordt het rechtsboven 50 px naar rechts getrokken door alle tussentijdse tekeningen over te slaan.

EnterFrame en RenderScene

Alles in je spel dat in de loop van de tijd moet veranderen, is uiteindelijk gekoppeld aan de enterFrame evenement. U kunt de .binden() methode om verschillende entiteiten aan deze gebeurtenis te binden. Functies die aan deze gebeurtenis zijn gekoppeld, krijgen ook een object doorgegeven met eigenschappen zoals dt die het aantal milliseconden bepaalt dat is gepasseerd sinds de laatste enterFrame evenement. 

U kunt de dt eigenschap om een ​​soepele spelervaring te bieden door te bepalen hoe ver de spelstatus moet zijn.

De RenderScene evenement wordt gebruikt om ervoor te zorgen dat alles zichtbaar op het scherm overeenkomt met de huidige status van het spel op het laatst enterFrame evenement. Normaal gesproken hoeft u deze gebeurtenis niet zelf te binden tenzij u besluit uw eigen aangepaste weergavelaag te implementeren.

Tween gebruiken om 2D-eigenschappen te animeren

U kunt de Tween component wanneer u de 2D-eigenschappen van een entiteit over een specifieke periode alleen maar wilt animeren. Je kunt het animeren X, Y, w, h, omwenteling, en alpha eigenschappen met dit onderdeel. Laten we de x-waarde en hoogte van de oranje en zwarte vakken animeren die u in de laatste twee zelfstudies hebt gemaakt. 

Hier is de code die je nodig hebt:

blackBox.tween (x: 500, 3000); orangeBox.tween (x: 50, h: 100, rotation: 360, 3000);

U hebt waarschijnlijk gemerkt dat de oranje doos niet draait rond het midden maar de linkerbovenhoek. U kunt het rotatiecentrum wijzigen met behulp van de .oorsprong() methode. Het kan twee gehele argumenten accepteren, die de pixeloffset van oorsprong in de x- en y-assen bepalen. 

Het accepteert ook een stringwaarde als argument. De tekenreekswaarde kan een combinatie van midden, boven, onder, midden, links en rechts zijn. Bijvoorbeeld, .oorsprong ( "center") draait de entiteit rond zijn middelpunt, en .oorsprong ("rechtsonder") draait de entiteit rond de rechteronderhoek. 

U kunt alle tweens die aan een bepaalde entiteit zijn gekoppeld pauzeren of hervatten met behulp van de .pauseTweens () en .resumeTweens () methoden. Evenzo kunt u ook gebruiken .cancelTween () om een ​​specifieke tween te annuleren.

De Crafty Timer begrijpen

De Crafty.timer object verwerkt alle speltikken in Crafty. U kunt de .FPS () methode met dit object om de doelframesnelheid te krijgen. Houd er rekening mee dat dit niet de werkelijke framesnelheid is.

U kunt ook de .simulateFrames (Aantal frames [, Number tijdstap]) methode om de spelstatus met een bepaald aantal frames vooruit te gaan. De tijd stap is de duur om elk frame te passeren. Als dit niet is opgegeven, wordt een standaardwaarde van 20ms gebruikt.

Een andere handige methode is .stap(), wat het spel zal bevorderen door een stap uit te voeren. Een enkele stap kan bestaan ​​uit een of meer frames gevolgd door een render. Het aantal frames hangt af van de timer steptype. Deze methode activeert verschillende evenementen zoals enterFrame en exitFrame  voor elk frame en PreRender, RenderScene, en PostRender evenementen voor elke render.

Er zijn drie verschillende modi van steptypevast, veranderlijk, en semifixed. In vast modus, elk frame in Crafty krijgt dezelfde waarde van dt. Dit echter steptype kan meerdere frames activeren voor elke render om de doelgamesnelheid te bereiken. 

U kunt ook slechts één frame activeren voor elke render met behulp van de veranderlijk modus. In dit geval is de waarde van dt is gelijk aan de werkelijke tijd die is verstreken sinds het laatste frame. 

eindelijk, de semifixed modus activeert meerdere frames per render en de tijd sinds het laatste frame is gelijk verdeeld over de frames.

Een heel eenvoudig spel maken

Als je alle tutorials in deze serie hebt gelezen, zou je nu genoeg kennis moeten hebben opgedaan om een ​​heel basisspel te maken. In dit gedeelte leer je alles wat je geleerd hebt te gebruiken en maak je een spel waarbij de hoofdspeler een stuk voedsel moet eten. 

Het voedsel zal een roterend rood vierkant zijn. Zodra het voedsel in contact komt met de speler, verdwijnt het van de oude locatie en komt het op een nieuwe willekeurige locatie. De speler kan worden verplaatst met A, W, S, D of de pijltoetsen.

Nog een ding dat je moet doen is de positie van de speler. Het hoort bij de grenzen van de gamefase te blijven.

Laten we eerst de code voor het eten schrijven:

var foodBox = Crafty.e ("2D, Canvas, Color, Food") .attr (x: 150, y: 250, w: 15, h: 15) .color ("red") .origin ("centre "). bind (" EnterFrame ", functie (eventData) this.rotation + = 4;);

Standaard zou Crafty de linkerbovenhoek van de voedselentiteit hebben gebruikt om deze te roteren. Door de oorsprong in het midden te plaatsen, zorgt u ervoor dat de voedseleenheid rond het midden roteert.

var playerBox = Crafty.e ("2D, Canvas, Kleur, Vierweg, Botsing") .attr (x: 50, y: 360, w: 50, h: 50) .color ("black") .fwayway ( 200) .bind ("EnterFrame", functie (eventData) if (this.x < 0)  this.x = 0;  if(this.y < 0)  this.y = 0;  if(this.x > (stageWidth - this.w)) this.x = stageWidth - this.w;  if (this.y> (stageHeight - this.h)) this.y = stageHeight - this.h; );

De spelerentiteit controleert de huidige locatie van de speler in elk frame en stelt de locatie opnieuw in als de speler buiten de gamefase probeert te gaan.

U kunt een a gebruiken Tekst entiteit om de score bij te houden. De score wordt weergegeven in de linkerbovenhoek. De gameScore variabele slaat het aantal keren op dat de speler de voedselentiteit raakt.

var scoreText = Crafty.e ('2D, DOM, Text') .attr (x: 10, y: 10) .textFont (size: '25px'); scoreText.text (gameScore.toString ());

Nu hoeft u alleen maar de code te schrijven om het voedsel naar een andere locatie te verplaatsen wanneer een hit wordt gedetecteerd. De volgende code zal precies dat doen.

playerBox.checkHits ("Food"). bind ("HitOn", functie (hitData) foodBox.x = Math.random () * (stageWidth - foodBox.w); foodBox.y = Math.random () * (stageHeight - foodBox.h); gameScore + = 1; scoreText.text (gameScore.toString ()););

U moet er rekening mee houden dat u de breedte en hoogte van uw voedselentiteit aftrekt van respectievelijk de breedte en hoogte van de tafel. Dit zorgt ervoor dat het eten altijd volledig binnen het podium is. Hier is een demo van het spel:

Laatste gedachten

Met de hulp van Crafty heb je een heel eenvoudig spel gemaakt door een paar regels code te schrijven. Op dit moment mist het spel een paar functies die het interessanter kunnen maken. Ten eerste zijn er geen geluiden. Ten tweede is er geen manier voor de speler om eruit te komen, en de moeilijkheidsgraad blijft ook hetzelfde gedurende het spel. In de volgende serie leert u meer over geluid, sprites, muisgebeurtenissen en andere functies van de bibliotheek.

Als je problemen of twijfels had tijdens het doornemen van alle voorbeelden in de serie, laat het me weten in de reacties.