actionscript-3keyboard-eventshittestenterframeevent

AS3 - How to stop player when touching object using hitTestObject?


I would like to know how to stop a the player when touching an object. I have movements set up here but I could not find a way to make my player properly stop when touching objects.

My player's movement code in the player Class:

This is the event listener for when the keys are pressed. The Boolean values become true when pressed.

public function onKeyDown(event:KeyboardEvent):void
{
    if (event.keyCode == Keyboard.D)
    {
        isRight = true;
    }
    if (event.keyCode == Keyboard.A)
    {
        isLeft = true;
    }
    if (event.keyCode == Keyboard.W)
    {
        isUp = true;
    }
    if (event.keyCode == Keyboard.S)
    {
        isDown = true;
    }
}

This is the the event listener for when the key are not pressed. The Boolean values become false when not pressed.

private function onKeyUp(event:KeyboardEvent):void
{
    if (event.keyCode == Keyboard.D)
    {
        isRight = false;
    }

    if (event.keyCode == Keyboard.A)
    {
        isLeft = false;
    }

    if (event.keyCode == Keyboard.W)
    {
        isUp = false;
    }

    if (event.keyCode == Keyboard.S)
    {
        isDown = false;;
    }

}

This is the enter frame, vx and vy are int variables and are 0 when keys are not pressed, but they change value when keys are pressed. The vx and vy also add to the player's x and y every frame but when they are 0, the player won't move.

private function onEnterFrame(event:Event):void
{
    _vx = 0;
    _vy = 0;

    if (isRight)
    {
        _vx = 5;
    }

    if (isLeft)
    {
        _vx = -5;
    }

    if (isUp)
    {
        _vy = -5;
    }

    if (isDown)
    {
        _vy = 5;
    }

    x += _vx;
    y += _vy;

}

Solution

  • You don't need to have many conditions, take a look at this example:

    _keys = new Object();
    
    _keys[Keyboard.D] = false;
    _keys[Keyboard.A] = false;
    _keys[Keyboard.W] = false;
    _keys[Keyboard.S] = false;  
    
    this.stage.addEventListener(KeyboardEvent.KEY_DOWN, keyInteraction);
    this.stage.addEventListener(KeyboardEvent.KEY_UP, keyInteraction);
    
    //---Key events
    function keyInteraction(evt:KeyboardEvent){
    
        if( _keys.hasOwnProperty(evt.keyCode) ){
    
            _keys[evt.keyCode] = Boolean( evt.type == KeyboardEvent.KEY_DOWN );
    
        }
    
    }
    

    When you press or release A, W, D or S keys, the respective _keys Object properties changes from true to false.

    Now, the hitTest part. Maybe is better the hitTestPoint method than the hitestObject method because this last one only checks if the bounds of both objects are touching. While the hitTestPoint method checks if the point touches any of the pixels of the Object.

    As you move the player every five pixels, it is necessary restore the player to correct position in which it no touch the object (I've made a while cycle for this purpose). Depends of your game design, you need to change the code, but this guide you in your purpose:

    The maze is the object that the player can't touch:

    Player's getPoint method

    public function getPoint(corner:uint){
    
        var point:Point = this.parent.localToGlobal( new Point( this.x, this.y ) );
    
        if(corner == 1 || corner == 2) point.x += _w;
        if(corner == 2 || corner == 3) point.y += _h;
    
        return point;
    
    }
    

    HitTest Code (Game Tick)

    //---Move the player
    private function gameTick(evt:Event):void{
    
        var hit:Boolean = false;
    
        //---Sum the vars horizontal
        if( _keys[Keyboard.D] ) _player.x += 5;
        if( _keys[Keyboard.A] ) _player.x -= 5;
    
        //---Check if the point is inside the scene in the horizontal
        if(_player.x < 0) _player.x = 0;
        if(_player.x > this.stage.stageWidth - _player.width) _player.x = this.stage.stageWidth - _player.width;            
    
        var TL:Point = _player.getPoint(0);
        var TR:Point = _player.getPoint(1);
        var BR:Point = _player.getPoint(2);
        var BL:Point = _player.getPoint(3);
    
        //---Hittest in the horizontal
        if(
            _maze.hitTestPoint(TL.x, TL.y, true)
            ||
            _maze.hitTestPoint(TR.x, TR.y, true)
            ||
            _maze.hitTestPoint(BR.x, BR.y, true)
            ||
            _maze.hitTestPoint(BL.x, BL.y, true)
        ){
    
            var sumX:int = 0;
    
            if( _keys[Keyboard.D] ) sumX = -1;
            if( _keys[Keyboard.A] ) sumX = 1;
    
            hit = true;
    
            while(hit){
    
                TL.x += sumX;
                TR.x += sumX;
                BR.x += sumX;
                BL.x += sumX;
    
                if(
                    !_maze.hitTestPoint(TL.x, TL.y, true)
                    &&
                    !_maze.hitTestPoint(TR.x, TR.y, true)
                    &&
                    !_maze.hitTestPoint(BR.x, BR.y, true)
                    &&
                    !_maze.hitTestPoint(BL.x, BL.y, true)
                ){
    
                    hit = false;
    
                    _player.x = TL.x;
    
                }
    
            }
    
        }
    
        //---Sum the vars vertical
        if( _keys[Keyboard.S] ) _player.y += 5;
        if( _keys[Keyboard.W] ) _player.y -= 5;
    
        //---Check if the point is inside the scene in the vertical
        if(_player.y < 0) _player.y = 0;
        if(_player.y > this.stage.stageHeight - _player.height) _player.y = this.stage.stageHeight - _player.height;            
    
        TL = _player.getPoint(0);
        TR = _player.getPoint(1);
        BR = _player.getPoint(2);
        BL = _player.getPoint(3);
    
        if(
            _maze.hitTestPoint(TL.x, TL.y, true)
            ||
            _maze.hitTestPoint(TR.x, TR.y, true)
            ||
            _maze.hitTestPoint(BR.x, BR.y, true)
            ||
            _maze.hitTestPoint(BL.x, BL.y, true)
        ){
    
            var sumY:int = 0;
    
            if( _keys[Keyboard.S] ) sumY = -1;
            if( _keys[Keyboard.W] ) sumY = 1;
    
            hit = true;
    
            while(hit){
    
                TL.y += sumY;
                TR.y += sumY;
                BR.y += sumY;
                BL.y += sumY;
    
                if(
                    !_maze.hitTestPoint(TL.x, TL.y, true)
                    &&
                    !_maze.hitTestPoint(TR.x, TR.y, true)
                    &&
                    !_maze.hitTestPoint(BR.x, BR.y, true)
                    &&
                    !_maze.hitTestPoint(BL.x, BL.y, true)
                ){
    
                    hit = false;
    
                    _player.y = TL.y;
    
                }
    
            }
    
        }
    
    }
    

    Download the example