Code archives/Graphics/Collision2.0 - Motion based, very accurate.

This code has been declared by its author to be Public Domain code.

Download source code

Collision2.0 - Motion based, very accurate. by AntonyWells2004
This lib lets you check for collisions with much greater accuracy than blitz's current method.
As it will register collisions even if images pass over each wholey. (I.e if you're ship as moving at 25 pixels and in one frames goes over a 12 pixel image completely, this lib will still register the collision)

It does this by generating(In hardware) motion maps for each collision object, and then performing just the single col check as per normal for a standard test.

InitCol(res) lets you set the resolution of the motion maps. Smaller =less accurate but faster.
id=CreateCol(image) creates a collision object. Create one for every image.

Then to update it, just call moveCol(col,x,y) once per frame.

And that's it, just checkCol(col1,col2) and it'll return true if they have collided, even if they moved 600 pixels in one frame.

CheckCol has a skip rate...The higher the skip rate the faster the motion map generation, but the less accurate it'll be.

The example code will work with any image, but just delete it when you need the lib for your project.

there's a little demo in there..just hit left mouse button..it draws the two motion maps on the top left hand corner of the screen. And it tells when a collision has occured.
;-quick example

initcol(64) ;init system with 64pixel motion map

col1=createCol(myImage) create a col image.call this once for each unique image.

moveCol(col1,20,20) ;move it. call this once per frame.

and finally,

checkCol(col1,col2,rate) to check for a collision.
rate= skip rate, see above.


;-[=-]
Type cSys
	Field mRes,iRes
	Field xs#,ys#
	Field gw#,gh#
End Type
Type col
	Field id,mMap ;low res version and motion map.
	Field lx#,ly#,x#,y#
End Type


Global cSys.cSys
Function initCols(mRes=256)
	cSys=New cSys
	csys\mRes=mRes
	cSys\iRes=iRes
	cSys\gw=GraphicsWidth()
	cSys\gh=GraphicsHeight()
	TFormFilter False
End Function
Function createCol(image)
	col.col=New col
	col\id=CopyImage(image)
	col\mMap=CreateImage(csys\mRes,csys\mres)
	wd#=Float(ImageWidth(image))/Float(GraphicsWidth())
	hd#=Float(ImageHeight(image))/Float(GraphicsHeight())
	nw#=csys\mres*wd 
	nh#=csys\mres*hd
	ResizeImage col\id,nw,nh
	Return Handle(col)
End Function

Function moveCol(col,x#,y#) ;move it to the same x,y as the image
	in.col=Object.col(col)
	in\lx=in\x
	in\ly=in\y
	in\x=x
	in\y=y
End Function

Function checkCol(col1,col2,skipRate=5) ;higher skip rate = faster but less accurate.Play with it, diff shapes will fair differantly
	c1.col=Object.col(col1)
	If c1=Null Return
	c2.col=Object.col(col2)
	If c2=Null Return 
	;-
	;-[ Generate motion maps]
	genMotionMap(c1,skipRate)
	genMotionMap(c2,skipRate)
	Return ImagesCollide(c1\mmap,0,0,0,c2\mmap,0,0,0)
End Function

Function genMotionMap(in.col,skip=1) ;INTERNAL FUNCTION - 
	ax#=in\x
	ay#=in\y
	ex#=in\lx
	ey#=in\ly 
	ax=csys\mres*(ax/csys\gw)
	ay=csys\mres*(ay/csys\gh)
	ex=csys\mres*(ex/csys\gw)
	ey=csys\mres*(ey/csys\gh) ;scale coords into the res of the motion map
	
	xd#=ex-ax
	yd#=ey-ay
	If Abs(xd)>Abs(yd) steps#=Abs(xd) Else steps#=Abs(yd)
	xi#=xd/Steps
	yi#=yd/Steps
	SetBuffer ImageBuffer(in\mMap)
	sImg=in\id
	xi=xi*Float(skip)
	yi=yi*Float(skip)
	Cls
	If steps<1 steps=1
	Repeat
			;-
			DrawImage sImg,ax,ay
			ax=ax+xi
			ay=ay+yi
		;-
		steps=steps-skip
	Until steps<1
End Function

Comments

Rck2005
missing comment statements dude, run your code first then do a clean copy-paste next time


Q2005
^

What he said.


Code Archives Forum