Page 1 of 1
Collision, need help.
Posted: Tue Oct 30, 2012 2:14 pm
by rokit boy
Ok so I'm making collision in my game, here it is:
Code: Select all
function leftcollide(x1,y1,w1,h1,x2,y2,w2,h2)
local i
for i = 0, h1 - 1 do
if y1 + i > y2 and y1 + i < y2 + h2 and x1 > x2 and x1 < x2 + w2 then
return true
end
end
return false
end
function rightcollide(x1,y1,w1,h1,x2,y2,w2,h2)
local i
for i = 0, h1 - 1 do
if y1 + i > y2 and y1 + i < y2 + h2 and x1 + w1 > x2 and x1< x2 then
return true
end
end
return false
end
function upcollide(x1,y1,w1,h1,x2,y2,w2,h2)
local i
for i = 0, h1 - 1 do
if x1 + i > x2 and y1 > y2 and y1 < y2 + h2 then
return true
end
end
return false
end
function downcollide(x1,y1,w1,h1,x2,y2,w2,h2)
local i
for i = 0, h1 - 1 do
if x1 + i > x2 and y1 < y2 and y2 < y1 + h2 then
return true
end
end
return false
end
right and down work like a charm, but when I do left it also returns down and up, and up also returns left and right, can anyone help me?
Re: Collision, need help.
Posted: Tue Oct 30, 2012 4:29 pm
by Roland_Yonaba
Are you trying to make a bounding-box collision checks (AABB versus AABB) ?
Isn't
this enough.
Re: Collision, need help.
Posted: Tue Oct 30, 2012 4:55 pm
by rokit boy
No, because i need to check which side is touched, this is the extra bit:
Code: Select all
if CheckCollision(self.x-16,self.y-16,32,32,ax,ay,32,32) and rightcollide(self.x-16,self.y-16,32,32,ax,ay,32,32) == true and self.x < ax then
rightcollision = true
leftcollision = false
--print("right")
end
if CheckCollision(self.x-16,self.y-16,32,32,ax,ay,32,32) and upcollide(self.x-16,self.y-16,32,32,ax,ay,32,32) == true and self.y > ay then
upcollision = true
downcollision = false
--print("up")
end
if CheckCollision(self.x-16,self.y-16,32,32,ax,ay,32,32) and downcollide(self.x-16,self.y-16,32,32,ax,ay,32,32) == true and self.y < ay then
downcollision = true
upcollision = false
--print("down")
end
if CheckCollision(self.x-16,self.y-16,32,32,ax,ay,32,32) and leftcollide(self.x-16,self.y-16,32,32,ax,ay,32,32) == true and self.x > ax then
leftcollision = true
rightcollision = false
--print("left")
end
Re: Collision, need help.
Posted: Tue Oct 30, 2012 5:16 pm
by kikito
You may want to use a displacement vector then:
viewtopic.php?f=4&t=9341&p=57738
On the demo attached there, when the two boxes collide, a vector (the white line that appears in the screen) is generated. This vector can be used to check whether the collision was up,down,left or right, in a single operation.
Re: Collision, need help.
Posted: Tue Oct 30, 2012 9:14 pm
by Roland_Yonaba
Well, just a silly idea...
How's that working for you ?
Code: Select all
-- Bounding-box collision check
function CheckCollision(ax1,ay1,aw,ah, bx1,by1,bw,bh)
local ax2,ay2,bx2,by2 = ax1 + aw, ay1 + ah, bx1 + bw, by1 + bh
return ax1 < bx2 and ax2 > bx1 and ay1 < by2 and ay2 > by1
end
-- Gets sides where collision occurs, from the perspective of object placed at ax1,ay1
local function GetSides(ax1,ay1,aw,ah, bx1,by1,bw,bh)
if ChekCollision(ax1,ay1,aw,ah, bx1,by1,bw,bh) then
local onx = ax1 < bx1 and 'right' or (ax1 > bx1 and 'left' or 'superposed')
local ony = ay1 < by1 and 'down' or (ay1 > by1 and 'up' or 'superposed')
return onx,ony
end
end
Kikito's proposal is more robust, though.
Re: Collision, need help.
Posted: Tue Oct 30, 2012 10:40 pm
by Qcode
Not sure if this is any help for you, but I started learning collisions off of this tutorial:
http://www.opentk.com/node/869. It's written in C# (I think) but I managed to translate it to Lua. The function ends up like this.
Code: Select all
function calculatemtd(v1, v2)
local v1minx = v1.x --Min = top left
local v1miny = v1.y
local v2minx = v2.x
local v2miny = v2.y
local v1maxx = v1.x + v1.width -- Max = bottom right
local v1maxy = v1.y + v1.height
local v2maxx = v2.x + v2.width
local v2maxy = v2.y + v2.height
--K, we got our first set of values.
local mtd = {} --Make our mtd table.
local left = v2minx - v1maxx
local right = v2maxx - v1minx
local up = v2miny - v1maxy
local down = v2maxy - v1miny
if left > 0 or right < 0 or up > 0 or down < 0 then --Not colliding. This is the easy part.
return false
end
if math.abs(left) < right then --Determine the collision on both axises? Axis'? I give up. On the x and y axis
mtd.x = left
else
mtd.x = right
end
if math.abs(up) < down then
mtd.y = up
else
mtd.y = down
end
if math.abs(mtd.x) < math.abs(mtd.y) then
mtd.y = 0
else
mtd.x = 0
end
return mtd
end
(Of course you can specify the x, y, width, and height of each object in the parameters, but I prefer to just use 2 tables.)
Then you can do your colliding like this.
(For aabb it's just a bounding box check)
Code: Select all
function collide(v1, v2)
local collision = aabb(v1, v2)
local horizontal, vertical
local mtd
if collision then
mtd = calculatemtd(v1, v2)
end
if mtd then
if mtd.x ~= 0 then
horizontal = true
end
if mtd.y ~= 0 then
vertical = true
end
end
if horizontal then
v1.x = v1.x + mtd.x
--At this point you should set your vertical speed to zero as well. For me it's xSpeed
v1.xSpeed = 0
end
if vertical then
v1.y = v1.y + mtd.y
v1.ySpeed = 0
end
Re: Collision, need help.
Posted: Thu Jun 22, 2017 8:22 pm
by Le Codex
Roland_Yonaba wrote: ↑Tue Oct 30, 2012 9:14 pm
Code: Select all
-- Gets sides where collision occurs, from the perspective of object placed at ax1,ay1
local function GetSides(ax1,ay1,aw,ah, bx1,by1,bw,bh)
if ChekCollision(ax1,ay1,aw,ah, bx1,by1,bw,bh) then
local onx = ax1 < bx1 and 'right' or (ax1 > bx1 and 'left' or 'superposed')
local ony = ay1 < by1 and 'down' or (ay1 > by1 and 'up' or 'superposed')
return onx,ony
end
end
I don't quite understand what you're doing here. Why are there strings in if-statements ? What value do they represent? Are they always
true ?
Re: Collision, need help.
Posted: Thu Jun 22, 2017 8:26 pm
by Nixola
Dude. That's a 4+ years necropost. Check the date of the last post before replying.
Re: Collision, need help.
Posted: Thu Jun 22, 2017 9:03 pm
by zorg
This is like the third time too... If you have a question, open a new thread.