AS3 Stop character from moving through walls

Opoe picture Opoe · Oct 9, 2011 · Viewed 10.5k times · Source

I want to stop the movieclips movement when it hits a wall (another movieclip). The example below works, but after the collision the movieclip 'blocks' all movement to the left... My question to you is, is this a good way and why isn't it working well?

There will be something wrong in this code, but i'm learning. For now the example with the leftArrow key;

variables to check the key, if it's hitting the walls and if it's moving or not:

var leftArrow:Boolean;
var speed:int = 10;
var hitting:Boolean;
var ismoving:Boolean;

event listeners for the keys/movement and detecting collision:

stage.addEventListener(KeyboardEvent.KEY_DOWN, keyPressed);
stage.addEventListener(KeyboardEvent.KEY_UP, keyReleased);
stage.addEventListener(Event.ENTER_FRAME, walking);
stage.addEventListener(Event.ENTER_FRAME, detectHit);

detecting collision function:

function detectHit(e:Event) :void
{
   if(char.hitTestObject(bounds))
   {
       hitting = true;
   }
}

function to the left arrow key:

function keyPressed(event:KeyboardEvent):void
{

    if (event.keyCode == Keyboard.LEFT)
    {
       leftArrow = true;
    }

}

function keyReleased(event:KeyboardEvent):void 
{

    if (event.keyCode == Keyboard.LEFT) 
    {
        leftArrow = false;
    }

}

And the reason it's not working is probably here, but I don't understand why not:

function walking(event:Event):void {
    if (rightArrow) {
        char.x += speed;    
    }

    if (leftArrow && ! hitting) {
        char.x -= speed;
    }
    else
    {
        ismoving = false
    }

Answer

taskinoor picture taskinoor · Oct 9, 2011
if (leftArrow && ! hitting)

char will move if hitting is false. When char.hitTestObject(bounds) is true you are setting hitting to true. You are not setting hitting again to false anywhere. That's why once left wall is hit it stops left movement permanently. You need to figure out suitable condition to set hitting to false again.

Adding an else branch in detectHit should solve the problem.

function detectHit(e:Event):void {
   if(char.hitTestObject(bounds))
   {
       hitting = true;
   } else { 
       hitting = false;    // add this
   }
}