I added collision to my game but I have a problem. But first I´ll give you some background.
I have this:
// Function that verifies if a point is inside a rectangle // point {x,y} // rectangle {x,y,w,h} function contains(point, rectangle) { return point.x > rectangle.x && ponto.x < rectangle.x + rectangle.w && ponto.y > rectangle.y && ponto.y < rectangle.y + rectangle.h; }
On update();
function
I have this:
//Save player´s position var xOld = xPlayer; var yOld = yPlayer;
That is used here:
// Detect collision with obstacles for(var i in obstacles1) { var rPlayer = {x:xPlayer, y:yPlayer, w:wPlayer, h:hPlayer}; if( contains({x:xPlayer, y:yPlayer}, obstacles1[i]) || contains({x:xPlayer+wPlayer, y:yPlayer}, obstacles1[i]) || contains({x:xPlayer, y:yPlayer+hPlayer}, obstacles1[i]) || contains({x:xPlayer+wPlayer, y:yPlayer+hPlayer}, obstacles1[i]) || contains({x:obstacles1[i].x, y:obstacles1[i].y}, rPlayer) || contains({x:obstacles1[i].x+obstacles1[i].w, y:obstacles1[i].y}, rPlayer) || contains({x:obstacles1[i].x, y:obstacles1[i].y+obstacles1[i].h}, rPlayer) || contains({x:obstacles1[i].x+obstacles1[i].w, y:obstacles1[i].y+obstacles1[i].h}, rPlayer) ){ xPlayer = xOld; yPlayer = yOld; } }
Note:
wPlayer
and hPlayer
are the width and height of the player, as the animation is done through a spritesheet.
xPlayer
and yPlayer
are the positions of the Player
This makes the player stop when going against an obstacle (kind of). With my code the player will constantly be running against that same obstacle (by getting teleported to its old positions) until the input stops.
The problem with this code is that when I´m pressing more than one key and the player is going into an obstacle he´ll get stuck on the wall even though he is performing another animation.
Is there a way to make him “slide” across the obstacles? I can´t think of anything…
Sorry for this big post and sorry if I didn´t explain myself well. If you have any questions I´ll be happy to make it clearer.
EDIT: Yes there are some typos.
Advertisement
Answer
The 5 laws of game collisions
Your problem is that you are breaking all the laws of game collisions.
Note this is all a little tongue in cheek but nevertheless valuable advice
The 5 laws.
- Never ever move to a position inside an obstacle… ever!
- To move from here to there you move over all the points between.
- You can only hit one thing at a time, and it will always be the closest to where you are.
- Every collision creates a new direction with a new destination.
- A journey takes time, always complete the journey.
Law 1;
If the object ends up inside something you are in an impossible situation, there is no mathematical solution, you can not move through solid mater. You must never break this law, all the other laws can be bent a little, but break the first law and you have a bug in the game.
Laws 2 & 3;
Think of the real world, when you move you move along a path. If something is in your way you can not move through it. In a game you render the scene as a sequence of frames, and when you move the character from one point to the next, you are using teleportation. You can’t do that, you must create a path and test if that path intersects any obstacles, if you skip an obstacle you may end up breaking the first law (you can’t do that).
The obstacle closest to the start of the path is the one you will always hit first.
Laws 4 & 5;
When you hit an obstacle you will bounce off of it, that will change the direction and the path you are traveling along. In the game you are animating at 60 frames a second. That means that the journey is 16,667 millisecond long, if you hit something it will be at some time between the frames. You must move to that point in time.
So now you have hit an obstacle at some time between the frames and have a new direction and a new destination. You also have the remaining time till the next frame. To complete the journey you must do it all again. To complete the journey you must do every collision until you have traveled the 16,667 millisecond in time to the next frame.
There can be many collisions between frames
From one frame to the next you can have many collisions, if you don’t do every one of them, in the correct order, you will end up getting stuck, or moving unnaturally, or worse and break the first law.
Some demos
Some posts with examples on collisions. The first two are what I think you are looking for.
AABB rectangle finding the first collision along a path to use the demo follow the instructions, but draw a small box at the start or there is no room to move.
Breaking the first law Unstoppable force meets unbreakable object. Though not applicable the demo can be used to illustrate how breaking the first law destroys the illusion that objects are solid.