Here's that example I promised...
sync on : sync rate 0
autocam off
`screen size
global scrn_w scrn_h scrn_mx scrn_my
scrn_w=desktop width()
scrn_h=desktop height()
scrn_mx=scrn_w/2
scrn_my=scrn_h/2
set display mode scrn_w,scrn_h,32
set camera range 0.001,24.0
fog on
fog distance 10.0,20.0
fog color 0
color backdrop 0
set ambient light 1.0
for l=1 to 2
make light l
set spot light l,90,150
set light range l,8.0
next l
global elapsed#
global tim lasttim
type playertype
x as float
y as float
z as float
ax as float
ay as float
az as float
key_f
key_b
key_l
key_r
view_l view_r view_t view_b
endtype
`Player array
dim player(2) as playertype
`Simple map array
dim map(64,64)
`Make random maze
for y=0 to 63
for x=0 to 63
if x=0 or y=0 or x=63 or y=63 or rnd(6)=1 then map(x,y)=1
next x
next y
`Clear space for players
for x=1 to 4
for y=1 to 4
map(x,y)=0
map(63-x,63-y)=0
next x
next y
obj=100
`Build random maze
for y=0 to 63
for x=0 to 63
make object cube obj,1
`Wall or floor?
if map(x,y)=1
position object obj,x+0.5,0.5,y+0.5
else
position object obj,x+0.5,-0.5,y+0.5
color object obj,rgb(16,16,0)
endif
inc obj,1
next x
next y
`Players objects
make object sphere 1,0.6 : color object 1,rgb(255,0,0) : set object ambient 1,0
make object sphere 2,0.6 : color object 2,rgb(0,255,0) : set object ambient 2,0
`Player start settings and controls
curplayer=0
player(curplayer).x=2.0 : player(curplayer).z=2.0 : player(curplayer).y=0.45
player(curplayer).view_l=0 : player(curplayer).view_r=scrn_mx-1 : player(curplayer).view_t=0 : player(curplayer).view_b=scrn_h
player(curplayer).key_f=17 `Forward key W
player(curplayer).key_b=31 `Backward key S
player(curplayer).key_l=30 `Left key A
player(curplayer).key_r=32 `Right key D
curplayer=1
player(curplayer).x=61.0 : player(curplayer).z=61.0 : player(curplayer).y=0.45
player(curplayer).view_l=scrn_mx+1 : player(curplayer).view_r=scrn_w : player(curplayer).view_t=0 : player(curplayer).view_b=scrn_h
player(curplayer).key_f=200 `Forward key
player(curplayer).key_b=208 `Backward key
player(curplayer).key_l=203 `Left key
player(curplayer).key_r=205 `Right key
set camera aspect (scrn_w/2.0)/scrn_h
`main loop
tim=timer()
do
updateplayer(0)
updateplayer(1)
curplayer=1-curplayer
setplayerview(curplayer)
`work out timer movement multiplier
lasttim=tim
tim=timer()
elapsed#=(tim-lasttim)/20.0
text 0,0,"FPS:"+str$(screen fps())
sync
loop
`--------------------------------
function updateplayer(p)
`Store last positions for sliding collision
lx#=player(p).x
lz#=player(p).z
`Work out movement and turn controls
mv=keystate(player(p).key_f)-keystate(player(p).key_b)
turn=keystate(player(p).key_r)-keystate(player(p).key_l)
player(p).ay=wrapvalue(player(p).ay+(turn*elapsed#*3.0))
if mv<>0
player(p).x=newxvalue(player(p).x,player(p).ay,(mv*0.1)*elapsed#)
player(p).z=newzvalue(player(p).z,player(p).ay,(mv*0.1)*elapsed#)
player(p).y=0.45
`Sliding wall collision
if collision(player(p).x,player(p).z)=1
if collision(player(p).x,lz#)=1 then player(p).x=lx#
if collision(lx#,player(p).z)=1 then player(p).z=lz#
endif
endif
position object p+1,player(p).x,player(p).y,player(p).z
position light p+1,player(p).x,player(p).y,player(p).z
rotate light p+1,player(p).ax,player(p).ay,player(p).az
endfunction
`--------------------------------
function setplayerview(p)
set camera view player(p).view_l,player(p).view_t,player(p).view_r,player(p).view_b
position camera player(p).x,player(p).y,player(p).z
rotate camera player(p).ax,player(p).ay,player(p).az
endfunction
`--------------------------------
function collision(x#,z#)
col=0
for xx=-1 to 1
for zz=-1 to 1
xx#=x#+(xx*0.3)
zz#=z#+(zz*0.3)
if safecolcheck(xx#,zz#)=1 then exitfunction 1
next xx
next yy
endfunction 0
`--------------------------------
function safecolcheck(x#,y#)
x=x# : y=y#
if x<0 or x>63 or y<0 or y>63 then exitfunction 1
if map(x,y)=1 then exitfunction 1
endfunction 0
`--------------------------------
I did what mobiius has just said, swap between 'players' and update only one view per loop - update both players controls etc though. Have fun finding your balls in the dark...