Why does my player bounce back and forth when colliding?
Forum rules
Before you make a thread asking for help, read this.
Before you make a thread asking for help, read this.
Why does my player bounce back and forth when colliding?
When the player in my game collides with either the left or top wall of a game, the player begins bouncing up and down or back and forth. Anyone know why? The player collision detection is located in player.lua, line 92 until line 155.
- Attachments
-
- game.love
- (11.57 KiB) Downloaded 50 times
Re: Why does my player bounce back and forth when colliding?
As opposed to using keypressed and keyreleased, I would use isDown within the update function.
Code: Select all
function updatePlayer(dt)
local tx, ty = nil, nil
if love.keyboard.isDown("up") then
ty = player.y - player.speed * dt
elseif love.keyboard.isDown("down") then
ty = player.y + player.speed * dt
end
if love.keyboard.isDown("left") then
tx = player.x - player.speed * dt
elseif love.keyboard.isDown("right") then
tx = player.x + player.speed * dt
end
if tx ~= nil or ty ~= nil then
tx, ty = tx or player.x, ty or player.y
for i, obj in ipairs(objs) do -- Table of objects to check
local collide = checkColl(tx, ty, player.w, player.h, obj.x, obj.y, obj.w, obj.h)
if not collide then
player.x, player.y = tx, ty
end
end
end
end
-- AABB Collision Check
function checkColl(x1, y1, w1, h1, x2, y2, w2, h2)
local collided = false
if x1 <= x2+ w2 and
x2 <= x1 + w1 and
y1 <= y2 + h2 and
y2 <= y1 + h1 then
collided = true
end
return collided
end
Re: Why does my player bounce back and forth when colliding?
I only see problems when going right.
I think you've got your loops wrong.
This works for me (for the right direction only):
When going in any direction, there are only one or two squares to check. In case of going right or left, if the Y coordinate is grid-aligned, there's only one square to check; otherwise, there are two.
In both cases, the X coordinate to check for collision is the one that is at a distance of less than a unit from the player.
You could fix the other loops similarly. Try to check only one or two squares every time (from floor to ceil). It should work.
I think you've got your loops wrong.
This works for me (for the right direction only):
Code: Select all
local i = math.floor(player.x / 16)+2 -- only one X coordinate to check, no need for a loop
for j = math.floor(player.y / 16)+1, math.ceil(player.y / 16)+1 do
In both cases, the X coordinate to check for collision is the one that is at a distance of less than a unit from the player.
You could fix the other loops similarly. Try to check only one or two squares every time (from floor to ceil). It should work.
Re: Why does my player bounce back and forth when colliding?
I'd rather not use isDown for moving, for example, if you are moving right you cannot move left if you press the left arrow key, but with this system using keypressed and keyreleased, the player changes direction every time a directional key is pressed.Beelz wrote:As opposed to using keypressed and keyreleased, I would use isDown within the update function.
Code: Select all
function updatePlayer(dt) local tx, ty = nil, nil if love.keyboard.isDown("up") then ty = player.y - player.speed * dt elseif love.keyboard.isDown("down") then ty = player.y + player.speed * dt end if love.keyboard.isDown("left") then tx = player.x - player.speed * dt elseif love.keyboard.isDown("right") then tx = player.x + player.speed * dt end if tx ~= nil or ty ~= nil then tx, ty = tx or player.x, ty or player.y for i, obj in ipairs(objs) do -- Table of objects to check local collide = checkColl(tx, ty, player.w, player.h, obj.x, obj.y, obj.w, obj.h) if not collide then player.x, player.y = tx, ty end end end end -- AABB Collision Check function checkColl(x1, y1, w1, h1, x2, y2, w2, h2) local collided = false if x1 <= x2+ w2 and x2 <= x1 + w1 and y1 <= y2 + h2 and y2 <= y1 + h1 then collided = true end return collided end
Re: Why does my player bounce back and forth when colliding?
It works, but the problem persists. The player still shakes back and forth when colliding with a wall from the top and from the left.pgimeno wrote:I only see problems when going right.
I think you've got your loops wrong.
This works for me (for the right direction only):When going in any direction, there are only one or two squares to check. In case of going right or left, if the Y coordinate is grid-aligned, there's only one square to check; otherwise, there are two.Code: Select all
local i = math.floor(player.x / 16)+2 -- only one X coordinate to check, no need for a loop for j = math.floor(player.y / 16)+1, math.ceil(player.y / 16)+1 do
In both cases, the X coordinate to check for collision is the one that is at a distance of less than a unit from the player.
You could fix the other loops similarly. Try to check only one or two squares every time (from floor to ceil). It should work.
Re: Why does my player bounce back and forth when colliding?
I think you need to fix the other loops similarly. I don't see the shake here.Kasperelo wrote:It works, but the problem persists. The player still shakes back and forth when colliding with a wall from the top and from the left.pgimeno wrote:I think you've got your loops wrong.
[...]
You could fix the other loops similarly. Try to check only one or two squares every time (from floor to ceil). It should work.
Re: Why does my player bounce back and forth when colliding?
I think I see now what you mean.
The cause seems to be that you check the tiles based on current player's position, not in the future player's position.
So it's again because of the loops. Instead of math.floor(player.x / 16) ... it should be using math.floor((player.x + dt * player.speed) / 16) ... etc.
I strongly advise you to put these tentative positions in variables, e.g.
EDIT: This made it work for me:
The cause seems to be that you check the tiles based on current player's position, not in the future player's position.
So it's again because of the loops. Instead of math.floor(player.x / 16) ... it should be using math.floor((player.x + dt * player.speed) / 16) ... etc.
I strongly advise you to put these tentative positions in variables, e.g.
Code: Select all
local newX, newY = player.x, player.y
if --[[going right]] then
newX = newX + dt * player.speed
--[[check collision with tiles for newX, newY]]
etc.
Code: Select all
function player.move(dt)
local newX, newY = player.x, player.y
local offset = player.speed * dt
if player.moving then
if player.moving:sub(1, 1) == "r" then
newX = newX + offset
local i = math.floor(newX / 16) + 2
for j = math.floor(newY / 16) + 1, math.ceil(newY / 16) + 1 do
if collision.rectangle(newX, newY, 16, 16, (i - 1) * 16, (j - 1) * 16, 16, 16) and map.tilemap[i][j] == 1 then
newX = (i - 1) * 16 - 16
end
end
elseif player.moving:sub(1, 1) == "l" then
newX = newX - offset
local i = math.ceil(newX / 16)
for j = math.floor(newY / 16) + 1, math.ceil(newY / 16) + 1 do
if collision.rectangle(newX, newY, 16, 16, (i - 1) * 16, (j - 1) * 16, 16, 16) and map.tilemap[i][j] == 1 then
newX = (i - 1) * 16 + 16
end
end
end
if player.moving:sub(2, 2) == "d" then
newY = newY + offset
for i = math.floor(newX / 16) + 1, math.ceil(newX / 16) + 1 do
local j = math.floor(newY / 16) + 2
if collision.rectangle(newX, newY, 16, 16, (i - 1) * 16, (j - 1) * 16, 16, 16) and map.tilemap[i][j] == 1 then
newY = (j - 1) * 16 - 16
end
end
elseif player.moving:sub(2, 2) == "u" then
newY = newY - offset
for i = math.floor(newX / 16) + 1, math.ceil(newX / 16) + 1 do
local j = math.ceil(newY / 16)
if collision.rectangle(newX, newY, 16, 16, (i - 1) * 16, (j - 1) * 16, 16, 16) and map.tilemap[i][j] == 1 then
newY = (j - 1) * 16 + 16
end
end
end
player.x, player.y = newX, newY
end
end
Last edited by pgimeno on Sat Dec 19, 2015 7:03 pm, edited 1 time in total.
Re: Why does my player bounce back and forth when colliding?
I've tried different things, and nothing worked, so I just set the player to draw at math.floor(player.x) and math.floor(player.y), so if the player teleports into a block for a frame, it won't show, because the player moves almost nothing in just one frame. Lazy, I know, but whatever
Re: Why does my player bounce back and forth when colliding?
Yeah, I see what you mean, but I was already doing that. That is why the player doesn't bounce back and forth all the time, but it stills does that sometimes.
Who is online
Users browsing this forum: No registered users and 53 guests