Code for collisions

General discussion about LÖVE, Lua, game development, puns, and unicorns.
User avatar
osgeld
Party member
Posts: 303
Joined: Sun Nov 23, 2008 10:13 pm

Re: Code for collisions

Post by osgeld »

if your using simple shapes physics are the way to go, but in the case of mario up there it becomes much easier to mask it rather than plotting out all those points to a body
User avatar
osgeld
Party member
Posts: 303
Joined: Sun Nov 23, 2008 10:13 pm

Re: Code for collisions

Post by osgeld »

ok i didnt comprehend how much crap i had to do today heh

but heres a basic pbm image format reader, i dont really like a couple of things but ill fix that in masklib

issues
1) you have to manually set the image width, cause i didnt snag it out of the header info
2) it really only can deal with 1 image at a time, but this is more about showing how and not a final product
3) its slow, mainly because of the repeat loop

Code: Select all

-- simple binary pbm reader
-- 2007 - 2009 osgeld
-- ( osgeld@cheesefactory.us )
-- CC share alike
-- use, distrubute, remix ect
-- give credit, share updates

data        = love.filesystem.read("mario.pbm")
image_width = 439
mask        = {}

-- strip the pbm header
for i = 1, 3 do
	found = string.find(data, "\n")
	data = string.sub(data, found + 1, -1)
end
	
-- convert from binary to table 
local x = 0
local y = 0
for counter = 1, #data do
	byte = string.byte(string.sub(data, counter, counter))
	byte_value = 128 
		
	repeat 
		if (byte / byte_value) >= 1 then
			byte = byte - byte_value
		else
			table.insert(mask, {x, y})
		end
		
		if x < image_width then
			x = x + 1
		else 
			x = 0
			y = y + 1
		end
			
		byte_value = byte_value / 2

	until(byte_value < 1)
end
again its not the final product, but i hope it gives you a start
User avatar
Skofo
Party member
Posts: 146
Joined: Mon Dec 22, 2008 10:55 pm

Re: Code for collisions

Post by Skofo »

Oh man, pixel-perfect collision. While that looks really neat and I love the effort you put into it, wouldn't it be a lot more efficient most of the time to use vectors, even for complex things like spaceships?
Working on: Viator
Need a 64-bit Debian package for LÖVE? Here it is!
User avatar
osgeld
Party member
Posts: 303
Joined: Sun Nov 23, 2008 10:13 pm

Re: Code for collisions

Post by osgeld »

once the lib is done is a matter of 3 mouse clicks in the gimp to make a collision mask

vs even the asteroids ship is 6 cords to map

also to hammer this point home, you will not be checking pixel perfect every loop
osuf oboys
Party member
Posts: 215
Joined: Sun Jan 18, 2009 8:03 pm

Re: Code for collisions

Post by osuf oboys »

osgeld wrote:once the lib is done is a matter of 3 mouse clicks in the gimp to make a collision mask

vs even the asteroids ship is 6 cords to map

also to hammer this point home, you will not be checking pixel perfect every loop
For this solution to work reall well, I would preferably like to see that it is capable of handling scaled sprites as well as computing the normals of the collided surfaces (e.g. intrapolating from the nearby pixels).

Do you have an efficient bit-wise AND function that you use for this library? If not, here's one:

Code: Select all

booleanAndResult = {}
for i=0,255 do
	booleanAndResult[i] = {}
	for j=0,255 do
		booleanAndResult[i][j] = 0
		for k=0,7 do
			if (i % (2 * 2^k)) >= 2^k and (j % (2 * 2^k)) >= 2^k then
				booleanAndResult[i][j] = booleanAndResult[i][j] + 2^k 
			end
		end
	end
end
function bool32And(x1, x2)	
	return booleanAndResult[x1 % 256][x2 % 256] +
		256 * booleanAndResult[math.floor(x1 / 256) % 256][math.floor(x2 / 256) % 256] +
		65536 * booleanAndResult[math.floor(x1 / 65536) % 256][math.floor(x2 / 65536) % 256] +
		16777216 * booleanAndResult[math.floor(x1 / 16777216) % 256][math.floor(x2 / 16777216) % 256]
end
If I haven't written anything else, you may assume that my work is released under the LPC License - the LÖVE Community. See http://love2d.org/wiki/index.php?title=LPC_License.
User avatar
osgeld
Party member
Posts: 303
Joined: Sun Nov 23, 2008 10:13 pm

Re: Code for collisions

Post by osgeld »

ill see what i can do, and thanks for the bitwise AND, i have one but its not as smooth as yours
User avatar
counterfactual_jones
Prole
Posts: 24
Joined: Mon Feb 09, 2009 10:14 am

Re: Code for collisions

Post by counterfactual_jones »

Yes, but then you need to use their physics. Which is fine for some games, but hey, mario and every other arcade game don't use them, and if you're going for that kind of feel... Opening up the collision functions would be useful, at least for some simple cases I guess.
osuf oboys
Party member
Posts: 215
Joined: Sun Jan 18, 2009 8:03 pm

Re: Code for collisions

Post by osuf oboys »

osgeld wrote:ill see what i can do, and thanks for the bitwise AND, i have one but its not as smooth as yours
Taking modulus to ensure that the quotient remains an integer makes things considerably faster. And so, the following version is better. Still far from the machine instructions though.

Code: Select all

booleanAndResult = {}
for i=0,255 do
	booleanAndResult[i] = {}
	for j=0,255 do
		booleanAndResult[i][j] = 0
		for k=0,7 do
			if (i % (2 * 2^k)) >= 2^k and (j % (2 * 2^k)) >= 2^k then
				booleanAndResult[i][j] = booleanAndResult[i][j] + 2^k
			end
		end
	end
end
booleanXorResult = {}
for i=0,255 do
	booleanXorResult[i] = {}
	for j=0,255 do
		booleanXorResult[i][j] = 0
		for k=0,7 do
			if ((i % (2 * 2^k)) >= 2^k and (j % (2 * 2^k)) < 2^k) or
			((i % (2 * 2^k)) < 2^k and (j % (2 * 2^k)) >= 2^k)
			then
				booleanXorResult[i][j] = booleanXorResult[i][j] + 2^k
			end
		end
	end
end


function bnot32(x)
	return 4294967295 - x
end
function bnot64(x)
	return 18446744073709551615 - x
end 

function band32(x1, x2) 
	local	sum = 0
	local	a1, a2
	a1 = x1 % 16777216
	a2 = x2 % 16777216
	sum = sum + booleanAndResult[(x1 - a1) / 16777216][(x2 - a2) / 16777216]
	x1 = a1 % 65536
	x2 = a2 % 65536
	sum = sum + booleanAndResult[(a1 - x1) / 65536][(a2 - x2) / 65536]
	a1 = x1 % 256
	a2 = x2 % 256
	return sum + booleanAndResult[(x1 - a1) / 256][(x2 - a2) / 256] +
		booleanAndResult[a1][a2]
end

function bxor32(x1, x2) 
	local	sum = 0
	local	a1, a2
	a1 = x1 % 16777216
	a2 = x2 % 16777216
	sum = sum + booleanXorResult[(x1 - a1) / 16777216][(x2 - a2) / 16777216]
	x1 = a1 % 65536
	x2 = a2 % 65536
	sum = sum + booleanXorResult[(a1 - x1) / 65536][(a2 - x2) / 65536]
	a1 = x1 % 256
	a2 = x2 % 256
	return sum + booleanXorResult[(x1 - a1) / 256][(x2 - a2) / 256] +
		booleanXorResult[a1][a2]
end

If I haven't written anything else, you may assume that my work is released under the LPC License - the LÖVE Community. See http://love2d.org/wiki/index.php?title=LPC_License.
User avatar
bartbes
Sex machine
Posts: 4946
Joined: Fri Aug 29, 2008 10:35 am
Location: The Netherlands
Contact:

Re: Code for collisions

Post by bartbes »

I want to take the credits for that :P
sroccaserra
Prole
Posts: 7
Joined: Wed Feb 04, 2009 11:54 am

Re: Code for collisions

Post by sroccaserra »

About spaceships (as mentionned by Peter Hickman in this thread):

In many "modern" 2D shmups (i.e. post 1994), the hitbox of the spaceship and bullets are rectangles slightly smaller than their respective sprites, allowing them to slightly overlap without exploding.

This prevents the "exploding without touching anything" bug when using rectangles for collisions.

In Radiant Silvergun (a classic masterpiece) for instance, there is a cheat code to see these small rectangles. So you can make an awsome 2D game using only rectangles for collisions.

Note that bosses or big ennemies use several rectangle hitboxes that approximate their shape.

And yes, if you use rectangles I guess you can define corresponding bodies and use the LÖVE physic engine.
Post Reply

Who is online

Users browsing this forum: No registered users and 2 guests