00:00
00:00
Newgrounds Background Image Theme

Ryor just joined the crew!

We need you on the team, too.

Support Newgrounds and get tons of perks for just $2.99!

Create a Free Account and then..

Become a Supporter!

AS3 collision with walls

1,412 Views | 3 Replies
New Topic

AS3 collision with walls 2015-10-02 00:46:42


So I am working on a top-down style game (think Zelda), and I need my character to come to a stop when he hits a wall. Here is what I have for character movement

// I'll use comments to save space
// Here the necessary statements are imported

char.addEventListener(Event.ENTER_FRAME, charWalk);
stage.addEventListener(KeyboardEvent.KEY_DOWN, kDown);
stage.addEventListener(KeyboardEvent.KEY_UP, kUp);

char.gotoAndStop('idledown');
var charSpeed:int = 5;

// this array holds references to all the keys
var keys:Array = [];

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

// Actual code for movement
function charWalk(e:Event):void
{
	if (keys[Keyboard.RIGHT])
	{
		char.x += charSpeed;
		char.gotoAndStop('walkright');
	}
// Repeated for the different directions
}

// Return to idle animations
function kUp(e:KeyboardEvent):void
{
    keys[e.keyCode] = false;
    if(e.keyCode == Keyboard.LEFT)
    {
        char.gotoAndStop('idleleft');
    }
// Again, this is repeated for all directions
}

I have been scouring the internet for some help with this. But everything either assumes I just want to return an integer on collision, or that the character dies or something.

I had code that set the charSpeed to 0 on collision, but then he was stuck to the wall, because from that point on he was never, not touching it!
How can I stop him from moving through a wall, but still let him move!?


GAH!

BBS Signature

Response to AS3 collision with walls 2015-10-03 02:13:51 (edited 2015-10-03 02:16:05)


Hi again Noodle : P

The way I usually handle stuff like this is to check for a collision after making changes to an objects position and if there is a collision revert to the old position.
Additionally it's best to perform the x & y changes separately. That way if your object is trying to move diagonally into a wall it will slide along it instead of not moving at all.

Basic Example:

var xSpeed = 0;
if(left key is down){
 xSpeed -= 4;
}
if(right key is down){
 xSpeed += 4;
}
//Attempt x movement
obj.x += xSpeed;
if(obj collides with something){
 //Undo x movement
 obj.x -= xSpeed;
}

//Same thing for y-component

Generic example you can wrap around any movement-modifying code:

var oldX = obj.x;
var oldY = obj.y;

//Code that might change the position

//Save target values
var newX = obj.x;
var newY = obj.y;

//Attempt x-component of movement (by undoing y-component)
obj.y = oldY;
if(obj collides with something){
 //Undo x-component
 obj.x = oldX;
}

//Attempt y-component of movement
obj.y = newY;
if(obj collides with something){
 //Undo y-component
 obj.y = oldY;
}

Depending on the situation you might also want to move the main object as close to the solid object as possible.
This is a bit trickier to get right. Ideally, if your shapes are fairly simple or predictable, you can just mathematically calculate the position the main object should be in (if both shapes are non-rotated rectangles, this is pretty easy).
Otherwise you can get a decent approximation by moving the main object forward in small increments until a collision occurs (only use small increments once you know large increments cause a collision).


You forgot to use code tags, didn't you?

Response to AS3 collision with walls 2015-10-03 11:47:33


At 10/3/15 02:13 AM, theCodeCat wrote: The way I usually handle stuff like this is to check for a collision after making changes to an objects position and if there is a collision revert to the old position.

That's not a good idea. Using that method will make the character go inside of the wall and then quickly jump out, producing an odd and jerky type of animation that will look like a glitch. It would also possibly make the character stop moving before they actually touch the wall, as their old position is more likely to outside of the wall's bounds.

A better way of doing it is to check if the character will collide with the wall before moving: if it does not collide, then move the character; if it will collide, then move the character right next to the wall but not touching it—in other words, move it the regular movement distance minus the amount that the character would "move into" the wall.

Also, this thread would be more appropriate in the Game Development forum. You can re-post this thread there if you need any further help or clarification.

Response to AS3 collision with walls 2015-10-03 17:19:33


I received a PM from theCodeCat which made me realise that I should have been a wee bit more clear in my post as to when/how the undesired behaviour I described could occur. If you were to operate directly with the DisplayObject's public x and y properties every time then it won't happen, but if you were to instead calculate the position before applying it—which can be useful in several situations, because it would keep the object's position not dependant on the object itself, allowing you to, for example, store the object's position even if the object is destroyed or easily swap the position of two objects—the problem would indeed occur.

This is a contrived example that will show the behaviour I described.