Here's a little library I wrote to perform pixel perfect sprite collisions.
I've attached the actual source file to be included in projects, but I'll also paste the code below:
remstart
Library for Pixel Perfect Sprite Collision v0.9
by Kira Vakaan
Functions:
InitSpriteCollision()
-This function sets up the dummy sprite used in sprite point collision detection as well as the transparent color
used in all collisions. Call this command before any other.
SpritePointCollide(x,y,spr)
-Returns a one if the screen point (x,y) is colliding with sprite spr. If spr is set to zero, the number of the sprite
the point collides with is returned. Supports sprite scaling and offsetting.
SpriteCollide(spr1,spr2)
-Intended to replace the built-in command: sprite collision(spr1,spr2). Currently does NOT support sprite scaling but
DOES support sprite offsetting.
SetTransparentColor(color as dword)
-Sets the color to be ignored during collision detection.
GetTransparentColor()
-...really..?
In the future (maybe):
- Support for sprite scaling during sprite on sprite collision detection.
- Any suggestions from people.
remend
end
function InitSpriteCollision()
#constant DUMMY 1000
global Transparent as dword : Transparent=0
create bitmap DUMMY,1,1
get image DUMMY,0,0,1,1
delete bitmap DUMMY
set current bitmap 0
sprite DUMMY,0,0,DUMMY
hide sprite DUMMY
endfunction
function SpritePointCollide(x,y,spr)
sprite DUMMY,x,y,DUMMY
Collision=sprite collision(DUMMY,spr)
if not Collision then exitfunction 0
if not spr then spr=Collision
dec x,sprite x(spr)
dec y,sprite y(spr)
x=(x/(sprite scale x(spr)/100.0))+sprite offset x(spr)
y=(y/(sprite scale y(spr)/100.0))+sprite offset y(spr)
make memblock from image 255,sprite image(spr)
Width=memblock dword(255,0)
Height=memblock dword(255,4)
if x<0 or y<0 or x=Width or y=Height then exitfunction 0
if memblock dword(255,12+4*((x%%Width)+((y%%Width)*Width)))=Transparent then exitfunction 0
endfunction Collision
function SpriteCollide(spr1,spr2)
Collision=sprite collision(spr1,spr2)
if not Collision then exitfunction 0
Color1 as dword
Color2 as dword
if not spr2 then spr2=Collision
XPos1=sprite x(spr1)-sprite offset x(spr1) : YPos1=sprite y(spr1)-sprite offset y(spr1)
XPos2=sprite x(spr2)-sprite offset x(spr2) : YPos2=sprite y(spr2)-sprite offset y(spr2)
if XPos2<XPos1
OverlapX=XPos1
OverlapWidth=XPos2+sprite width(spr2)-XPos1
else
OverlapX=XPos2
OverlapWidth=XPos1+sprite width(spr1)-XPos2
endif
if YPos2<YPos1
OverlapY=YPos1
OverlapHeight=YPos2+sprite height(spr2)-YPos1
else
OverlapY=YPos2
OverlapHeight=YPos1+sprite height(spr1)-YPos2
endif
Spr1X=OverlapX-XPos1
Spr1Y=OverlapY-YPos1
Spr2X=OverlapX-XPos2
Spr2Y=OverlapY-YPos2
make memblock from image 255,sprite image(spr1)
make memblock from image 256,sprite image(spr2)
Spr1Width=memblock dword(255,0)
Spr1Height=memblock dword(255,4)
Spr2Width=memblock dword(256,0)
Spr2Height=memblock dword(256,4)
for y=1 to OverlapHeight
for x=1 to OverlapWidth
if Spr1X<0 or Spr1Y<0 or Spr1X>=Spr1Width or Spr1Y>=Spr1Height then goto continue
if Spr2X<0 or Spr2Y<0 or Spr2X>=Spr2Width or Spr2Y>=Spr2Height then goto continue
Color1=memblock dword(255,12+4*((Spr1X%%Spr1Width)+((Spr1Y%%Spr1Width)*Spr1Width)))
Color2=memblock dword(256,12+4*((Spr2X%%Spr2Width)+((Spr2Y%%Spr2Width)*Spr2Width)))
if Color1<>Transparent and Color2<>Transparent then exitfunction Collision
continue:
inc Spr1X
inc Spr2X
next x
dec Spr1X,OverlapWidth
dec Spr2X,OverlapWidth
inc Spr1Y
inc Spr2Y
next y
endfunction 0
function SetTransparentColor(color as dword)
Transparent=color
endfunction
function GetTransparentColor()
endfunction Transparent
The library is pretty simple to use. Just call InitSpriteCollision() before using any of the other commands.
You are given the option of setting a transparent color by using SetTransparentColor(color as dword).
To test collision between two sprites, use SpriteCollide(spr1,spr2). There's also the option of checking a single point for collision with SpritePointCollide(x,y,spr). Currently, sprite on sprite collision does not support the scaling or offsetting of either sprite whereas point on sprite collision should be fine.
There are comments at the top of the library.
Edit: I've revised the library slightly. Now sprite on sprite collision detection supports sprite offsetting. The code snippet and attachment are updated as well.