This code shows how a player in a 2D environment can walk on top of an uneven terrain image.
It makes use of a function by Cloggy for pixel-perfect collision.
`Basic setup...
sync on : sync rate 60
set display mode 1024,768,screen depth()
color backdrop rgb(200,200,255)
`Load the terrain image (needs transparency)
load image "Terrain.png",1
`Make it into a sprite and position in properly
sprite 1,0,screen height()-image height(1),1
`Load character image
load image "Player.png",2
`Make the character sprite
sprite 2,500,0,2
`=== MAIN LOOOOOOP =====================================
DO
`Apply basic gravity to the player
inc SpriteVelocity#,0.1
`Position player properly according to gravity
sprite 2,sprite x(2),sprite y(2)+SpriteVelocity#,2
`Check to see if the player collides with the terrain and move if they do
`First checks to see if the standard box collision occurs
sprhit=sprite collision(1,2)
if sprhit>0
`If it does, check pixel collision
while pixelcol(1,2)=1
`If pixel collision occurs, move player up
sprite 2,sprite x(2),sprite y(2)-1,2
`Also reset their falling speed (because they've hit the ground)...
SpriteVelocity#=0
`And allow them to jump
if upkey()=1 then SpriteVelocity#=-5
endwhile
endif
`Control player with arrowkeys
if leftkey() then sprite 2,sprite x(2)-2,sprite y(2),2
if rightkey() then sprite 2,sprite x(2)+2,sprite y(2),2
SYNC
LOOP
`=======================================================
`==== PIXEL-PERFECT SPRITE COLLISION BY CLOGGY =========
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=getmax(x1,x2)
ry1=getmax(y1,y2)
rx2=getmin(x1+sw1-1,x2+sw2-1)
ry2=getmin(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))
bit1=memblock byte(1,12+((row+sy1)*(sw1*4))+((col+sx1)*4)+3)
bit2=memblock byte(2,12+((row+sy2)*(sw2*4))+((col+sx2)*4)+3)
` AND bits together to see if a collision has occured
if bit1>0 and bit2>0
`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 getmax(v1,v2)
`Calculate the larger of 2 numbers
if v1>v2
exitfunction v1
else
exitfunction v2
endif
endfunction v1
function getmin(v1,v2)
`calculate the smaller of 2 numbers
if v1<v2
exitfunction v1
else
exitfunction v2
endif
endfunction v1
The media you'll need to test it is attached.
Please post questions or comments!