Search code examples
actionscript-3flashgame-physicsgravity

as3 applying gravity to a missile


I'm trying to create a "worms" style turn based artillery game is as3. I am able to add my ball on the x/y location of the character and have the ball fire in the direction of the mouses location when the click is made but I am now having difficulty in applying gravity to the ball. If anybody can help me at all with what I need to do to make the ball drop in an arc after being fired that would be great.

My code for adding the ball and having it fire in the selected direction is: Game Main:

function redFollow(e:MouseEvent):void {

        var a1 = mouseY - redPower.y;
        var b1 = mouseX - redPower.x;
        var radians1 = Math.atan2(a1,b1);
        var degrees1 = radians1 / (Math.PI/180);
        redPower.rotation = degrees1;


    }


    public function redFIRE(Event:MouseEvent)
    {

        removeChild(redPower);
        turnchangeover();
        addChild(RPBall);
        trace("FIRE!");
        RPBall.x = red.x;
        RPBall.y = red.y;
        RPBall.rotation = redPower.rotation + 90;

    }

and then the ball's class code is:

package {

import flash.display.MovieClip;
import flash.events.Event;

public class redBall extends MovieClip {


    public function redBall() {
        this.addEventListener(Event.ENTER_FRAME, moveShot);
    }
  function moveShot(event:Event){
        var thisMissile:redBall = redBall(event.target);
        var _missileSpeed:int = 7;
        var gravity:int = 0.8;


        //get the x,y components of the angle
        var missileAngleRadians = ((-thisMissile.rotation - 180) * Math.PI /180);
        //trace("missle angle: " + missileAngleRadians);

        var yMoveIncrement = Math.cos(missileAngleRadians) * _missileSpeed;
        var xMoveIncrement = Math.sin(missileAngleRadians) * _missileSpeed;




        thisMissile.y = thisMissile.y +yMoveIncrement;


        thisMissile.x = thisMissile.x + xMoveIncrement;

        trace(thisMissile.y);

  }



}

}


Solution

  • You need to store speed separately by X and by Y. See, after your ball has been launched, you don't care about angle, but only care about speed, and speed is what's affected by gravity. You already split speed by X and Y components in yMoveIncrement,xMoveIncrement, now you just need to have them be properties of the ball (it'll be its velocity), and add a small per-frame increment to Y component of velocity.

    public class redBall extends MovieClip {
    
        public var yVelocity:Number=0;
        public var xVelocity:Number=0; // these will be assigned when the ball is shot
        public static var gravity:Number=0.5; // Number, not "int"
        // also "static" so that it'll affect all balls similarly
        public function redBall() {
            this.addEventListener(Event.ENTER_FRAME, moveShot);
        }
        function moveShot(event:Event){
            // var thisMissile:redBall = redBall(event.target);
            // why is ^ this? You can use "this" qualifier in this function
            // we already have the x,y components of the angle
            this.y = this.y + this.yVelocity;
            this.x = this.x + this.xVelocity;
            this.yVelocity = this.yVelocity + gravity; 
            // also, you care for rotation - let's add a trick
            var angle:Number=Math.atan2(this.yVelocity,this.xVelocity); 
            // direction angle, in radians
            this.rotation=angle*180/Math.PI; // make into degrees and rotate 
            trace(thisMissile.y);
        }
    }
    

    It'll be a good practice if you will add a shoot function to redBall class that will accept angle and initial velocity, to assign xVelocity and yVelocity as you did in the listener.