MrColdfish
MrColdfish

Reputation: 123

ActionScript 2 Wall Collision

I am making my Flash game but... the collisions are my very big problem. I tried every single website, but nothing works.

The code of the player is this:

    onClipEvent(enterFrame){
        if(Key.isDown(Key.RIGHT)) {
            this._x+=3
        }
            if(Key.isDown(Key.LEFT)) {
            this._x-=3
        }
            if(Key.isDown(Key.UP)) {
            this._y-=3
        }
            if(Key.isDown(Key.DOWN)) {
            this._y+=3
        }

    }

Collision:

    if(cityhallLeftWall.hitTest(Player._x+Player._width/2, Player._y, true)){
    Player._x -=0
    }
    if(cityhallRightWall.hitTest(Player._x-Player._width/2, Player._y, true)){
    Player._x +=0
    }
    if(cityhallTopWall.hitTest(Player._x, Player._y+Player._height/2, true)){
    Player._y +=0
    }
    if(cityhallBottomWall.hitTest(Player._x, Player._y-Player._height/2, true)){
    Player._y -=0
    }

The movieclip of the player is named "Player". The movieclip of the building is named "cityhall". So, I want for example when the movieclip Player touches the movieclip cityhall, the y and x speed to get 0 or something like that. It's just impossible to find solution, so I decided to ask for help here.

Thanks :)

Upvotes: 0

Views: 660

Answers (4)

user3716469
user3716469

Reputation: 3

First the code, as most people aren't motivated to read without it(this in my test was placed in the movieclip Player or for me just movieclip P)

    onClipEvent(enterFrame){
    if(Key.isDown(Key.RIGHT)) {
        this._x+=3
    }
        if(Key.isDown(Key.LEFT)) {
        this._x-=3
    }
        if(Key.isDown(Key.UP)) {
        this._y-=3
    }
        if(Key.isDown(Key.DOWN)) {
        this._y+=3
    }
if(_root.cityhallLeftWall.hitTest(this._x-this._width/2, this._y, true)){
this._x +=3;
}
if(_root.cityhallRightWall.hitTest(this._x+this._width/2, this._y, true)){
this._x -=3;
}
if(_root.cityhallTopWall.hitTest(this._x, this._y-this._height/2, true)){
this._y +=3;
}
if(_root.cityhallBottomWall.hitTest(this._x, this._y+this._height/2, true)){
this._y -=3;
}
}

I tested this code and figured out your problems. This will get hard to understand in words so bear with me (don't have the reputation points to post images).

1.When testing for the right wall hit test you didn't use Player._x+Player._width/2 but Player._x-Player._width/2 this doesn't work as you tested the characters left edge against the right edged wall so the Player will be 'inside' the wall by the time he is pushed out.

2.You did the same mistake for the left wall, testing the right edge against it.

3.you aren't as mentioned by the other answers subtracting speed from the Player but subtracting 0 from the Player currents position this doesn't do anything,you have to subtract the amount the player is moving at in this case 3 in every direction(Up,Down,Left,Right).

4.Your collision checking lines aren't in the enter frame brackets and so would only be checked once at swf startup not every frame.

5.This isn't a mistake but a tip use while loops as with the current "if" you will notice if the player goes to the walls edge and manages to get inside somehow and is till pressing the directional key he can remain inside the wall but with while this can't happen.

Code for while loop:

     onClipEvent(enterFrame){
     if(Key.isDown(Key.RIGHT)) {
        this._x+=3
     }
        if(Key.isDown(Key.LEFT)) {
        this._x-=3
    }
        if(Key.isDown(Key.UP)) {
        this._y-=3
    }
        if(Key.isDown(Key.DOWN)) {
        this._y+=3
    }

while(_root.cityhallLeftWall.hitTest(this._x-this._width/2, this._y, true)){
this._x +=3;
}
while(_root.cityhallRightWall.hitTest(this._x+this._width/2, this._y, true)){
this._x -=3;
}
while(_root.cityhallTopWall.hitTest(this._x, this._y-this._height/2, true)){
this._y +=3;
}
while(_root.cityhallBottomWall.hitTest(this._x, this._y+this._height/2, true)){
this._y -=3;
}
}

hope this works and good luck.

Upvotes: 0

cameraman
cameraman

Reputation: 252

The problem lies in the Player's coordinates. They are not global.

Try this in your collision function:

// store player's new local position in an object
var playerGlobalPosition = {
    x:Player._x,
    y:Player._y
};

// translate local position to global
Player.localToGlobal(playerGlobalPosition);

Then test against those global coordinates:

if(cityhallLeftWall.hitTest(playerGlobalPosition.x + (Player._width/2), playerGlobalPosition.y, true)){
    Player._x -= 3; // as mentioned before, replace those 0 values with 3
}

Explanation:

In the hitTest method the x and y coordinates are defined in the global coordinate space. So if our coordinates (Player._x and Player._y) are local, we should translate them to the global space before applying the method. More here and here

Upvotes: 0

Neal Davis
Neal Davis

Reputation: 2008

It's been a while since I did anything in AS2, but I'll have a go at this.

first, set up a variable for the player's speed. It could look like this:

var speedX:Number = 0;

Now,in your enterFrame function, add this:

Player._x += speedX; //

Next, in each of your hitTest methods, do like this:

if(cityhallLeftWall.hitTest(Player._x+Player._width/2, Player._y, true)){
    speedX = 0;
}

You'll need to do likewise for the y direction. I'm sure you can figure it out from here. Cheers!

Upvotes: 0

King Dedede
King Dedede

Reputation: 1010

You should have the += be an equal repelling force to the player's speed, I.E. if your player hits a wall at x speed of 5 pixels per frame, the wall should add 5 pixels of speed to player in the opposite direction so you get a net movement of zero.

Upvotes: 0

Related Questions