Page 1 of 1

### [bump] how to detect side collision

Posted: Sat Aug 24, 2019 4:50 pm
Hi, I use bump.lua, the collision library, and i have a small issue :

I can detect when a collision is happening on the down side of my cube, the print is working ->

Code: Select all

``````player.x, player.y, cols, len = world:move(player, player.x, player.y + player.vy)
for i = 1, len do
local col = cols[i]
if col.normal.y == -1 then
print('DOWN')
end
end
``````
But i can't detect any other collision like on the left or right side of my cube, the print is not working ->

Code: Select all

``````player.x, player.y, cols, len = world:move(player, player.x, player.y + player.vy)
for i = 1, len do
local col = cols[i]
if col.normal.x == -1 then
print('LEFT')
end
end
``````
I am new to bump so I am sure it's easy...
If you have any ideas it could help me a lot! thanks!!

### Re: [bump] how to detect side collision

Posted: Sat Aug 24, 2019 5:33 pm
What value do you get for col.normal.x when you expected a collision?

### Re: [bump] how to detect side collision

Posted: Sun Aug 25, 2019 1:08 am
everytime i expected a collision the value of col.normal.x stay at 0

### Re: [bump] how to detect side collision

Posted: Sun Aug 25, 2019 11:13 am
Works for me. Can you post your project? Or at least a trimmed down version that still shows the problem, but that we can run.

Here's my test (it doesn't require LÖVE, it can be run with the command-line LuaJIT):

Code: Select all

``````local bump = require 'bump'
local world = bump.newWorld()

local A = {name = 'A'}
local B = {name = 'B'}
local C = {name = 'B'}
local x, y = 32, 0

local function moveA(xd, yd)
local xf, yf, coll, len = world:move(A, xd, yd)
print(string.format("A is now at %.17g, %.17g", xf, yf))
for i = 1, len do
local normal = coll[i].normal
print(string.format("Normal is %.17g, %.17g", normal.x, normal.y))
end
x = xf
y = yf
end

moveA(x, y+1) -- collision down (negative y)
moveA(x-1, y) -- collision left (positive x)
--[[
Output:

A is now at 32, 0
Normal is 0, -1
A is now at 32, 0
Normal is 1, 0
--]]
``````

### Re: [bump] how to detect side collision

Posted: Sun Aug 25, 2019 11:32 am
Here is the entire code, sorry i don't know how to attach a file. You can focus on the 'playerf' functions. I don't know why but col.normal.y seems to work but col.normal.x doesn't work.

Code: Select all

`````` io.stdout:setvbuf('no')
love.graphics.setDefaultFilter("nearest")

local bump = require('bump')
local world = bump.newWorld()

-- listes fonctions --
local tween = {}
local transition = {}
local cubes = {liste={}}
local playerf = {}
local game = {}
---
local gravity = 7
local gameScreen = 'game'

function setColor(r,g,b,a) return love.graphics.setColor((r or 255)/255, (g or 255)/255, (b or 255)/255, (a or 255)/255) end

-- TWEEN --
if in_or_out == 'in' then
local s = t/d
return c*s*s + b
elseif in_or_out == 'out' then
local i = t/d
return -c * i*(i-2) + b
end
end
---

-- TRANSITION --
transition.alpha = 0
transition.alphaMax = 1.2
transition.vitesse = 4
transition.state = 1
transition.play = false
transition.goal = nil
end

function transition.to(goal_screen)
transition.play = true
transition.goal = goal_screen
end

function transition.update(dt)
if transition.play == true then
if transition.state == 1 then
transition.alpha = transition.alpha + transition.vitesse*dt
if transition.alpha > transition.alphaMax then
transition.state = 2
end
elseif transition.state == 2 then
gameScreen = transition.goal
transition.alpha = transition.alpha - transition.vitesse*dt
if transition.alpha <= 0 then
transition.state = 1
transition.play = false
end
end
end
end

function transition.draw()
love.graphics.setColor(67/255,109/255,118/255,transition.alpha)
love.graphics.rectangle('fill', 0, 0, largeurScreen, hauteurScreen)
love.graphics.setColor(1,1,1)
end
---

-- CUBES --
local cube = {x=x,y=y,w=w,h=h}
cubes.liste[#cubes.liste+1] = cube
end

function cubes.draw()
for _,cube in ipairs(cubes.liste) do
setColor()
love.graphics.rectangle("line", cube.x, cube.y, cube.w, cube.h)
end
end
---

end

end

end

end
---

-- PLAYER --
player = {x=120,y=100,vx=0,vy=0,w=30,h=30,acceleration=60,decceleration=50,max_speed=8,jump1=false,jump2=false,max_height=12.5}
end

function playerf.resetVelocity()
for i = 1, len do
local col = cols[i]
if col.normal.y == -1 or col.normal.y == 1 then
player.vy = 0
print('up and down collision detection ok')
end
if col.normal.y == -1 then
player.jump1 = false
player.jump2 = false
end

if col.normal.x == -1 or col.normal.x == 1 then
print('SIDE COLLISION OK') -- doesn't print anything
end
end
end

function playerf.gravity(dt)
player.x, player.y, cols, len = world:move(player, player.x, player.y + player.vy)
playerf.resetVelocity()
end

function playerf.movements(dt)
if love.keyboard.isDown('right') then
if player.vx > player.max_speed then
player.vx = player.max_speed
end
elseif love.keyboard.isDown('left') then
if player.vx < -player.max_speed then
player.vx = -player.max_speed
end
else
if player.vx > 0 then
player.vx = player.vx - (player.decceleration*dt)
if player.vx < 0 then
player.vx = 0
end
elseif player.vx < 0 then
player.vx = player.vx + (player.decceleration*dt)
if player.vx > 0 then
player.vx = 0
end
end
end

player.x, player.y, cols, len = world:move(player, player.x+(player.vx or 0), player.y+(player.vy or 0))
end

function playerf.update(dt)
playerf.movements(dt)
playerf.gravity(dt)
end

function playerf.draw()
love.graphics.rectangle('fill',player.x,player.y,player.w,player.h)

love.graphics.print(player.vx)
end

function playerf.keypressed(key)
if key == 'up' then
if player.jump1 == false then
player.jump1 = true
player.vy = -player.max_height
elseif player.jump1 == true and player.jump2 == false then
player.jump2 = true
player.vy = -player.max_height/1.5
end
end
end
---

-- GAME --
end

function game.update(dt)
playerf.update(dt)
end

function game.draw()
cubes.draw()
playerf.draw()
end

function game.keypressed(key)
playerf.keypressed(key)
end
---

-- MAIN FUNCTIONS --
love.window.setMode(810, 600)
largeurScreen, hauteurScreen = love.window.getMode()
love.graphics.setBackgroundColor(0,0,0)

end

function love.update(dt)
if gameScreen == 'game' then
game.update(dt)
else
end

transition.update(dt)
end

function love.draw()
if gameScreen == 'game' then
game.draw()
else
end

transition.draw()
end

function love.keypressed(key)
if gameScreen == 'game' then
game.keypressed(key)
else
end
end
---
``````
I want to detect side collisions in order to create wall jumping effects.

### Re: [bump] how to detect side collision

Posted: Sun Aug 25, 2019 1:21 pm
For wall-jumps, in my game I simply use bump's queryRect method: When player presses the jump button while in mid-air, query a couple pixels wide rectangle on either side of the player's collision box for tiles (remember to use an appropriate filter), check if there is a surface the player can jump off of (simply check if len > 0), and act accordingly. This works well enough for a simple quick implementation, unless you want to integrate the wall detection into the regular physics upates for objects.

### Re: [bump] how to detect side collision

Posted: Sun Aug 25, 2019 2:42 pm
maxtrautwein wrote:
Sun Aug 25, 2019 11:32 am
Here is the entire code, sorry i don't know how to attach a file.
You can't attach files in "quick reply" mode. You have to press press "Full editor and preview" to get the interface that allows you to submit attachments. Anyway, the code you posted helped because it's self-contained. Thanks.

maxtrautwein wrote:
Sun Aug 25, 2019 11:32 am
You can focus on the 'playerf' functions. I don't know why but col.normal.y seems to work but col.normal.x doesn't work.
The collision you expect is happening, but in playerf.movements(), and you don't detect it there.

In a certain sense, Bump doesn't report collisions that are already resolved. More specifically, when the objects are touching but one of the objects is not moving towards the other, you don't get a collision. So, the resolution in playerf.movements() detects the contact and places the object touching the wall, but there's no code that checks the resulting collision at that point. When execution reaches playerf.gravity(), the wall and the player are already touching and you don't get the collision for it.

To avoid a problem such as the one you're having, you should call world:move() only once per frame, and check collisions there.