Hoe programmeer je zwaartekracht in AS3?

Posted at January 03, 2011

You’ve found a dinosaur. This is one of my first posts about programming and the code quality is very poor, it is only here for archiving purposes.

In deze tutorial maak ik zwaartekracht in een hele simpele vorm, je houdt een bal over die valt tot op de grond. En als je op een toets drukt springt hij omhoog. Dit is misschien niet de meest efficiente manier maar hij is volgens mij het meest simpel. (In het boek heb je een uitgebreidere manier met acceleratie.)

Eerst wat basis dingetjes:

  • zwaartekracht is gewoon een getal die elke keer bij de Y positie van een object wordt toegepast.
  • zwaartekracht mag alleen iets laten vallen op het moment dat het niet op de grond staat.
  • wanneer je een sprong maakt ga je in het begin snel, en daarna steeds langzamer tot je weer valt.

En hier zie je alvast de code gecompileerd (druk op toets voor sprong).

Hier is de code:

/** zwaartekracht.as -- 2011
 *
 * Beschrijving: bestand ter info voor
 * mede studenten, hopelijk heeft iemand
 * er iets aan.
 * 
 * @mike van rossum
 *
 * Copyleft 2010, all wrongs reversed.
 */
package
{
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    import flash.events.KeyboardEvent;

public class Zwaartekracht extends Sprite
{
    public var bal:Sprite;
    public var grond:Sprite;
    public var sprong:int;

    public function Zwaartekracht()
    {
        // Stel de stage in op niet meeschalen
        stage.align = StageAlign.TOP_LEFT;
        stage.scaleMode = StageScaleMode.NO_SCALE;

        addEventListener(Event.ENTER_FRAME, beweegBal);
        stage.addEventListener(KeyboardEvent.KEY_DOWN, toets);

        bal = new Sprite;
        bal.graphics.beginFill(0xff0000);
        bal.graphics.drawCircle(0,0,20);
        bal.graphics.endFill();
        bal.y = 100;
        bal.x = 100;
        addChild(bal);

        grond = new Sprite;
        grond.graphics.beginFill(0x00000);
        grond.graphics.drawRect(0,0,1000,10);
        grond.graphics.endFill();
        grond.y = 500;
        grond.x = 0;
        addChild(grond);

        sprong = new int;
        sprong = 0;
    }

    public function beweegBal(event:Event):void
    {
        if (bal.y + bal.height/2 < grond.y)
        {
            bal.y = bal.y + 10 - sprong;
        }
        else
        {
            bal.y = bal.y - sprong;
        }
        if (sprong > 0)
        {
        sprong--;
        }   
    }

    public function toets(Event:KeyboardEvent):void 
    {
        sprong = 20;
    }
}

regel 22, 50 en 51 Hier maak ik een variabele aan met de naam sprong, overal waar je verder sprong ziet staan kan je dit woord vervangen door de waarde die hij heeft (een getal). Op regel 51 zie je dat die waarde standaard 0 is.

regel 54 tot 68 In deze functie gebeurt alle beweging.

Ik kijk eerst of de bal in de lucht hangt of op de grond ligt. Als het randje van de bal hoger is dan de Y as van de grond dan ligt hij dus NIET op de grond. En dan moet hij vallen dus: de Y van de bal WORDT de Y van de bal PLUS de zwaartekracht (ik koos voor 10). Ik doe hier nog iets namelijk – sprong. Zoals je weet staat sprong voor een getal, en staandaard op 0. Standaard kan je dit dus negeren.

Daarnaast haal ik elk frame 1 van sprong af behalve als hij 0 is.

regel 72 Nu valt je bal mooi omlaag maar hij moest ook kunnen springen, alles staat al goed omdat ik een variabele sprong heb: Elke keer als je op een toets drukt wordt de sprong gereset naar 20. Dit zorgt ervoor dat je de formule voor het berekenen van de Y iets veranderd: de Y van de bal WORDT de Y van de bal PLUS de zwaartekracht (ik koos voor 10) MIN de sprong. de sprong is 20 dus we kijken wat de Y as is, tellen daar 10 bij op en halen er dan weer 20 vanaf (oftewel we halen er 10 vanaf). Let erop dat als we de bal omhoog willen krijgen we iets van de Y as af moeten halen, we moeten namelijk richting de 0 (bovenkant).

En ik had ook gezegd dat elk frame er 1 van sprong (20) afgehaald moet worden zodat de sprong langzaam afremt en vanaf de 10 de bal weer valt (want + 10 – 10 is 0 en hierna wordt het alleen maar lager).

Dit is een hele simpele vorm van zwaartekracht, er zitten wat kleine bugs in zoals dat je kan springen in de lucht (te verhelpen met een simpel if statement) en dat hij soms in de grond valt (ook heel simpel te verhelpen).

Posted at January 03, 2011, under AS3.