Search code examples
actionscript-3flashbox2dflashdevelop

Moving b2body With Keyboard


I have this code that gives the b2Body an impulse towards the cursor when you click on stage.

private function clicked(e:MouseEvent):void 
{
var impulse_x:Number = (mouseX / world_scale - mainChar.GetPosition().x);
var impulse_y:Number = (mouseY / world_scale - mainChar.GetPosition().y);
var impulse:b2Vec2 = new b2Vec2(impulse_x, impulse_y);

mainChar.ApplyImpulse(impulse, mainChar.GetPosition());
}

I was trying to use keyboard right arrow key for movement and so in the update function I added the if key[Keyboard.RIGHT]:

private function update(e:Event):void {
world.Step (1 / 30, 10, 10);
if (key[Keyboard.RIGHT]) {
impulse_x = 3;              
mainChar.ApplyImpulse(impulse, mainChar.GetPosition());
}
}


private function onKeyUp(e:KeyboardEvent):void 
{
key[e.keyCode] = false;
}

private function onKeyDown(e:KeyboardEvent):void 
{
key[e.keyCode] = true;
}

But the b2body goes to top left on the screen and stays there and doesn't move. I am changing the impulse value that then goes into the vector that is applied to the body.

Although it doesn't give me any errors.

EDIT: The whole code!

package 
{
    import Box2D.Collision.Shapes.b2PolygonShape;
    import Box2D.Common.Math.b2Vec2;
    import Box2D.Dynamics.b2Body;
    import Box2D.Dynamics.b2BodyDef;
    import Box2D.Dynamics.b2FixtureDef;
    import Box2D.Dynamics.b2World;
    import Box2D.Dynamics.Contacts.b2ContactEdge;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.KeyboardEvent;
    import flash.events.MouseEvent;
    import flash.ui.Keyboard;

    public class Main extends Sprite 
    {
        public var world:b2World = new b2World(new b2Vec2(0, 0), true);
        public var world_scale:Number = 30;
        public var mainChar:b2Body;
        private var ground:b2Body;
        public var keys:Array = [];
        public var beingPressed:Boolean;
        public var impulse_x:Number;
        public var impulse_y:Number;
        public var impulse:b2Vec2 = new b2Vec2(impulse_x, impulse_y);

        public function Main():void 
        {
            createMainCharacter(stage.stageWidth / 2, stage.stageHeight / 2, 50, 100);

            var th:uint = 10;

            addEventListener(Event.ENTER_FRAME, update);
            //stage.addEventListener(MouseEvent.CLICK, clicked);
            stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
            stage.addEventListener(KeyboardEvent.KEY_UP, onKeyUp);
        }

        /**private function clicked(e:MouseEvent):void 
        {
            var impulse_x:Number = (mouseX / world_scale - mainChar.GetPosition().x);
            var impulse_y:Number = (mouseY / world_scale - mainChar.GetPosition().y);

            var impulse:b2Vec2 = new b2Vec2(impulse_x, impulse_y);
            mainChar.ApplyImpulse(impulse, mainChar.GetPosition());
        }**/

        private function update(e:Event):void 
        {
            world.Step (1 / 30, 10, 10);


            var temp:Sprite;
            for (var body:b2Body = world.GetBodyList(); body != null; body = body.GetNext())
            {
                if (body.GetUserData())
                {
                    temp = body.GetUserData() as Sprite;
                    temp.x = body.GetPosition().x * world_scale;
                    temp.y = body.GetPosition().y * world_scale;
                    temp.rotation = body.GetAngle() * (180 / Math.PI); // radians to degrees
                }
            }

            if (keys[Keyboard.RIGHT]) 
            {
                impulse_x = 3;
                impulse_y = 0;
                mainChar.ApplyImpulse(impulse, mainChar.GetPosition());
            } else {
                impulse_x = 0;
                impulse_y = 0;
                }

        }

        private function createMainCharacter(x:Number, y:Number, width:Number, height:Number):void 
        {

            var mainCharSprite:Sprite = new Sprite();
            mainCharSprite.graphics.beginFill(0x000000);
            mainCharSprite.graphics.drawRect( -width / 2, -height / 2 , width, height);
            mainCharSprite.graphics.endFill;
            mainCharSprite.x = x;
            mainCharSprite.y = y;
            addChild(mainCharSprite);

            var mainCharDef:b2BodyDef = new b2BodyDef();
            mainCharDef.userData = mainCharSprite;
            mainCharDef.type = b2Body.b2_dynamicBody;
            mainCharDef.position.Set (x / world_scale, y / world_scale);

            mainChar = world.CreateBody(mainCharDef);

            var shape:b2PolygonShape = new b2PolygonShape();
            shape.SetAsBox((width / 2) / world_scale, (height / 2) / world_scale);

            var fixtureDef:b2FixtureDef = new b2FixtureDef();
            fixtureDef.shape = shape;
            fixtureDef.restitution = 0.1;
            fixtureDef.friction = 0.1;
            fixtureDef.density = 0.5;

            mainChar.CreateFixture(fixtureDef);

        }

        private function onKeyUp(e:KeyboardEvent):void 
        {
            keys[e.keyCode] = false;
        }

        private function onKeyDown(e:KeyboardEvent):void 
        {
            keys[e.keyCode] = true;
        }

    }

}

Solution

  • Changing the values of impulse_x and impulse_y is not going to update the values used by the b2Vec2 impulse. In AS3 primitives are passed by value not by reference. If you want the b2Vec2 object referenced by the variable impulse to change its values you need to change them directly on the object itself:

    impulse.x = 3.0;
    impulse.y = 0.0;
    mainChar.ApplyImpulse(impulse, mainChar.GetPosition());