Log In  


Hi folks,

I'm trying to get to grips with collision detection and have sussed it for simple single objects against each other, but now I'm trying to detect one object against many using tables.

I'm not sure why my code below isn't working. I think it's the final FOR-LOOP which goes through the position checking of the player and each of the blocks. The penultimate line that has RETURN TRUE is never reached (I've tried putting STOP() in there and it never executes) so is there something wrong with the IF statements above it that return false?

Note: If I place the RETURN TRUE within the loop directly above it (immediately following the position checks), collision with the first block works fine, just no others!

In my head, this should work - it just doesn't!

What am i doing wrong please?

function _init()
	initblocks()
	initplayer()
end

function _update()
--	if btn(4) then updateblocks() end
	moveplayer()
	if colcheck() then pl.col=11 
	 else
	 pl.col=7
	end
end

function _draw()
	cls()
	drawblocks()
	drawplayer()
end

-- user functions --

function initblocks()
	block={}
	for n=20,80,30 do
		for f=20,110,30 do
			add(block,{x=f,y=n,w=10,h=10,col=7})
		end
	end
end

function updateblocks()
	for f in all(block) do
		f.col = flr(rnd(15)+1)
	end
end

function drawblocks()
	for f in all(block) do
		rectfill(f.x,f.y,f.x+f.w,f.y+f.h,f.col)
	end
end

function initplayer()
	pl={}
	pl.x=10
	pl.y=110
	pl.w=10
	pl.h=10
	pl.col=7
end

function drawplayer()
	rect(pl.x,pl.y,pl.x+pl.w,pl.y+pl.h,pl.col)
end

function moveplayer()
	if btn(0) then pl.x-=1 end
	if btn(1) then pl.x+=1 end
	if btn(2) then pl.y-=1 end
	if btn(3) then pl.y+=1 end
end

function colcheck()
	for f in all(block) do
		if pl.x>f.x+f.w then return false end
		if pl.x+pl.w<f.x then return false end
		if pl.y>f.y+f.h then return false end
		if pl.y+pl.h<f.y then return false end
	end
	return true
end


Your collide function exits when the player misses any of the blocks - which is usually the case.
Fixed version:

function colcheck()
	for f in all(block) do
 	local outside=
 		(pl.x>f.x+f.w) or
 	 (pl.x+pl.w<f.x) or 
 		(pl.y>f.y+f.h) or 
 	 (pl.y+pl.h<f.y)
		-- inside?
 	if(not outside) return true
 	-- keep testing other blocks...
 end
 return false
end

Ah, yes of course! I didn’t see that - thank you.



[Please log in to post a comment]