finds a direction (as defined by the xd and yd increments) which will lead to a clear tile. It assigns that tile as filled to prevent the next sprite choosing it as well. They then start moving by adding the xd and yd increments. (They must be increments of one pixel in this example because of how the position of the next tile is calculated). They keep moving until they are on the next tile. When all sprites are on the their next tile they can clear that tile and then check to see if the next tile is clear so they can keep moving in the same direction. If the next tile in the current direction is filled they choose another set of increments that will lead to a clear tile.
on a tile. They move pixel by pixel between tiles. Essentially it is the same as having the collision logic of sprites that jump from tile to tile. A collision means the next tile is filled with something. It could be another sprite.
The border tiles were filled to avoid having to check for out of boundary conditions.
Code: Select all
screenres 640,480,32
color rgb(0,0,0),rgb(255,255,255):cls
dim shared as integer world(20,15)
for j as integer = 0 to 14
for i as integer = 0 to 19
read world(i,j)
next i
next j
dim shared as any ptr tinyWalker
tinyWalker = imagecreate(256,256,rgb(255,0,255))
'bload "tinyWalker.bmp",tinyWalker
'fill with green frames
for j as integer = 0 to 7
for i as integer = 0 to 7
line tinyWalker,(i*32,j*32)-(i*32+31,j*32+31),rgb(0,255,0),b
next i
next j
type AGENT
as integer x
as integer y
as integer w
as integer h
as integer xd
as integer yd
as integer d 'direction flag
as integer f 'current animation frame
as any ptr img 'image block
end type
dim shared as AGENT ag(0 to 4)
'initialize agents
for i as integer = 0 to 4
ag(i).x = i*64+128
ag(i).y = 5*32
ag(i).w = 32
ag(i).h = 32
ag(i).xd = int(rnd(1)*3)-1
ag(i).yd = int(rnd(1)*3)-1
while ag(i).xd = 0 and ag(i).yd=0
ag(i).xd = int(rnd(1)*3)-1
ag(i).yd = int(rnd(1)*3)-1
wend
world(ag(i).x\32+ag(i).xd,ag(i).y\32+ag(i).yd) = 1 'set destination tile as taken
ag(i).x = ag(i).x + ag(i).xd 'make first move off this tile
ag(i).y = ag(i).y + ag(i).yd 'so as not to set on onTile flag
ag(i).img = tinyWalker
next i
sub drawWorld()
screenlock
cls
'draw world
for j as integer = 0 to 14
for i as integer = 0 to 19
if world(i,j)=0 then
line (i*32,j*32)-(i*32+32,j*32+32),rgb(0,0,0),b
else
line (i*32,j*32)-(i*32+32,j*32+32),rgb(100,100,255),bf
end if
next i
next j
'draw sprites
for i as integer = 0 to 4
line (ag(i).x,ag(i).y)-(ag(i).x+ag(i).w,ag(i).y+ag(i).h),rgb(0,255,0),b
next i
for i as integer = 0 to 4
if ag(i).xd = 0 and ag(i).yd = 0 then ag(i).f = 1
draw string (ag(i).x,ag(i).y),str(i)
put (ag(i).x,ag(i).y), ag(i).img, (ag(i).f*32,ag(i).d*32) - (ag(i).f*32+31,ag(i).d*32+31),trans
next i
screenunlock
end sub
sub upDateFrame(ag as AGENT)
If ag.xd = 0 and ag.yd = 0 then
ag.f = 0 'not moving
else
ag.f = ag.f + 1
if ag.f = 7 then ag.f = 0
end if
end sub
function onTile(ag as AGENT) as boolean
if ag.x = int(ag.x\32)*32 and ag.y = int(ag.y\32)*32 then
return TRUE
else
return FALSE
end if
end function
drawWorld()
'move agents off chosen tile
for i as integer = 0 to 4
ag(i).x = ag(i).x + ag(i).xd
ag(i).y = ag(i).y + ag(i).yd
next i
sub moveAgents()
dim as integer flag
flag = 0 'flags ALL agent on center of their next selected tile
for i as integer = 0 to 4
if onTile(ag(i))=FALSE then 'keep moving
ag(i).x = ag(i).x + ag(i).xd
ag(i).y = ag(i).y + ag(i).yd
flag = 1
end if
next i
if flag = 0 then 'all on center of next tile so we can check if next tile is free
for i as integer = 0 to 4
if world(ag(i).x\32+ag(i).xd,ag(i).y\32+ag(i).yd)=0 then 'next tile clear?
world(ag(i).x\32,ag(i).y\32)=0 'clear current tile
world(ag(i).x\32+ag(i).xd,ag(i).y\32+ag(i).yd)=1 'set next tile
else
do 'find another direction to move and if it is to a clear tile
ag(i).xd = int(rnd(1)*3)-1
ag(i).yd = int(rnd(1)*3)-1
while ag(i).xd = 0 and ag(i).yd=0
ag(i).xd = int(rnd(1)*3)-1
ag(i).yd = int(rnd(1)*3)-1
wend
loop until world(ag(i).x\32+ag(i).xd,ag(i).y\32+ag(i).yd)=0 'loop until found clear next tile
world(ag(i).x\32,ag(i).y\32)=0 'clear current tile
world(ag(i).x\32+ag(i).xd,ag(i).y\32+ag(i).yd) = 1 'set destination tile
end if
ag(i).x = ag(i).x + ag(i).xd 'make first move off tile
ag(i).y = ag(i).y + ag(i).yd 'so not to trigger onTile next loop
next i
end if
end sub
dim as integer count
drawWorld()
do
moveAgents()
drawWorld()
count = count + 1
if count > 4 then
count = 0
for i as integer = 0 to 4
upDateFrame(ag(i))
next i
end if
sleep 20
loop until multikey(&H01)
sleep
data 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
data 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1
data 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1