I have come up with this code for pixel perfect collision
set display mode 1280,1024,32:sync on:sync rate 0
load image "player.bmp",1,1
load image "enemy.bmp",2,1
x=20
y=20
do
if upkey()=1 then y=y-1
if downkey()=1 then y=y+1
if leftkey()=1 then x=x-1
if rightkey()=1 then x=x+1
sprite 1,x,y,1
offset sprite 1,-200,-200
sprite 2,150,160,2
sprhit=sprite hit(1,0)
if sprhit>0
ink rgb(255,0,0),0
`comment these lines back in to see collision rectangle
` bx1=max(x,sprite x(sprhit))
` by1=max(y,sprite y(sprhit))
` bx2=min(x+sprite width(1),sprite x(sprhit)+sprite width(sprhit))
` by2=min(y+sprite height(1),sprite y(sprhit)+sprite height(sprhit))
` box bx1,by1,bx2,by2
`Sprite 1 is the player sprite, Sprite to is the sprite collided with
coll=pixelcol(1,sprhit)
endif
text 0,0,"screen fps()="+str$(screen fps())
if coll>0 then text 0,15,"Collision"
sync
loop
function pixelcol(sp1,sp2)
`load sprite images into memory
make memblock from image 1,sprite image(sp1)
make memblock from image 2,sprite image(sp2)
`store image sizes
sw1=memblock dword(1,0)
sh1=memblock dword(1,4)
sw2=memblock dword(2,0)
sh2=memblock dword(2,4)
`store image positions
x1=sprite x(sp1)-sprite offset x(sp1)
y1=sprite y(sp1)-sprite offset y(sp1)
x2=sprite x(sp2)-sprite offset x(sp2)
y2=sprite y(sp2)-sprite offset y(sp2)
`calculate collision rectangle
rx1=max(x1,x2)
ry1=max(y1,y2)
rx2=min(x1+sw1-1,x2+sw2-1)
ry2=min(y1+sh1-1,y2+sh2-1)
`calculate area of first sprite that has overlapped second
sx1=rx1-x1
sy1=ry1-y1
ex1=rx2-x1
ey1=ry2-y1
`calculate area of second sprite that has overlapped first
sx2=rx1-x2
sy2=ry1-y2
ex2=rx2-x2
ey2=ry2-y2
`check through both sprites to see if any pixels collide
for row=0 to ey1-sy1
for col=0 to ex1-sx1
bit1=memblock dword(1,12+((row+sy1)*(sw1*4))+((col+sx1)*4))
bit2=memblock dword(2,12+((row+sy2)*(sw2*4))+((col+sx2)*4))
` AND bits together to see if a collision has occured
if bit1&&bit2
`Collision has occured
collision=1
`Clean up memblocks and return
delete memblock 1
delete memblock 2
exitfunction 1
endif
next col
next row
`no collision clean up memblocks and return
delete memblock 1
delete memblock 2
endfunction 0
function max(v1,v2)
`Calculate the larger of 2 numbers
if v1>v2
exitfunction v1
else
exitfunction v2
endif
endfunction v1
function min(v1,v2)
`calculate the smaller of 2 numbers
if v1<v2
exitfunction v1
else
exitfunction v2
endif
endfunction v1
It first checks for a normal sprite collision and then does a bit by bit check on the areas that have collided to see if any pixels have collided.
It could be speeded up by pre loading memblocks with sprite images as the make memblock from image takes a little time. When I tested preloading the images the overhead was negligable. As it is the slowdown is not too bad.
Any comments/Questions are welcome.
Cloggy