Search code examples
actionscript-3flashcollision-detectiongame-physicsrectangles

Flash Collision Detection (Platformer game)


I am trying to make a platformer game in flash, using ActionScript 3. Currently everything is working except for one thing.

The Problem:

When the player collides with the bottom of a platform, if his xVel is not equal to zero, the horizontal collision detection loop is called and the player is moved horizontally as well as vertically. This means he bounces off the platform from underneath but is also displaced to one side of the platform. If the player's xVel is equal to zero, everything works fine. This is because the horizontal collision loop is not called. I cannot figure out why this happens. Any help would be greatly appreciated.

The Code:

import flash.events.Event;
import flash.geom.Rectangle;

var level:Array = new Array();

var xVel = 0;
var yVel = 0;

var xSpeed = 15;

var accel =1.5;
var grav = 2;
var jumpHeight = 15*grav;


for(var i = 0; i<numChildren;i++){
    if(getChildAt(i) is platform){
        level.push(getChildAt(i).getRect(this));
    }   
}

var upKeyDown = false;
var leftKeyDown = false;
var rightKeyDown = false;
var downKeyDown = false;


stage.addEventListener(KeyboardEvent.KEY_DOWN,keyDown);
stage.addEventListener(KeyboardEvent.KEY_UP,keyUp);
stage.addEventListener(Event.ENTER_FRAME,gameLoop);

function keyDown(e:KeyboardEvent){
    if(e.keyCode == Keyboard.UP){
        upKeyDown = true;
    }   
    if(e.keyCode == Keyboard.LEFT){
        leftKeyDown = true;
    }   
    if(e.keyCode == Keyboard.RIGHT){
        rightKeyDown = true;
    }   
    if(e.keyCode == Keyboard.DOWN){
        downKeyDown = true;
    }   
}
function keyUp(e:KeyboardEvent){
    if(e.keyCode == Keyboard.UP){
        upKeyDown = false;
    }   
    if(e.keyCode == Keyboard.LEFT){
        leftKeyDown = false;
    }   
    if(e.keyCode == Keyboard.RIGHT){
        rightKeyDown = false;
    }   
    if(e.keyCode == Keyboard.DOWN){
        downKeyDown = false;
    }   
}

function gameLoop(e:Event){
    if(rightKeyDown){
        if(xVel<xSpeed){
            xVel+=accel;
        }

    }else if(leftKeyDown){
        if(xVel>-xSpeed){
            xVel-=accel;
        }

    }else{
        xVel *=0.6;
    }
    //horizontal
    player.x+=xVel;
    for(i = 0; i<level.length;i++){
        if(player.getRect(this).intersects(level[i])){
            if(xVel>0){
                player.x = level[i].left-player.width/2;
            }
            if(xVel<0){
                player.x = level[i].right+player.width/2;
            }
            xVel = 0;
        }
    }

    yVel+=grav;
    player.y+=yVel;
    var jumpable = false;
    for(i = 0; i<level.length;i++){
        if(player.getRect(this).intersects(level[i])){
            if(yVel>0){
                player.y = level[i].top-player.height/2;
                yVel = 0;
                jumpable = true;
            }
            if(yVel<0){
                player.y = level[i].bottom+player.height/2;
                yVel*=-0.5;
            }
        }
    }
    if(upKeyDown&&jumpable){
        jump();
    }
    this.x = -player.x+(stage.stageWidth/2);
    this.y = -player.y+(stage.stageHeight/2);
}

function jump(){
    yVel-=jumpHeight;   
}

Where I think the problem occurs

player.x+=xVel;
    for(i = 0; i<level.length;i++){
        if(player.getRect(this).intersects(level[i])){
            if(xVel>0){
                player.x = level[i].left-player.width/2;
            }
            if(xVel<0){
                player.x = level[i].right+player.width/2;
            }
            xVel = 0;
        }
    }

    yVel+=grav;
    player.y+=yVel;
    var jumpable = false;
    for(i = 0; i<level.length;i++){
        if(player.getRect(this).intersects(level[i])){
            if(yVel>0){
                player.y = level[i].top-player.height/2;
                yVel = 0;
                jumpable = true;
            }
            if(yVel<0){
                player.y = level[i].bottom+player.height/2;
                yVel*=-0.5;
            }
        }
    }

The picture!

A visual description

Extra information:

The platforms are movie clip symbols, all originating from the same symbol. They are dragged onto the canvas and re sized. The platform symbol has an AS linkage called 'platform' which is how the child is identified as a platform in the code

The player is a rectangle with no animations

Both the platforms and player have an orientation in the center of the object.


Solution

  • What you need to to is test the ceiling collision first and adjust accordingly before the horizontal check. If you don't, then you player is colliding with the bottom of the platform when you do the horizontal check.