That's okay, I needed to re-do the deque() function anyway... Don't know why it claimed the error however. Like we've noticed, there seem to be problems with nesting if..endif and such like that.
Anyway, try this one out and see if it helps. It doesn't solve all the problems as yet however, in that multiple objects can collide on a particular matrix location and one will "over-ride" the other in an unpredictable way, but it's a start. Providing you can get it working for you that is...
So give it a try and we'll see.
S.
Rem Project: subtanks
Rem Created: 2004-06-05 21:29:49
Rem ***** Main Source File *****
rem setup
set display mode 1024, 768, 32
sync on
sync rate 60
rem master variables made global
dim worldwidth(1)
dim worldheight(1)
dim xsize(1)
dim ysize(1)
dim zsize(1)
dim objoffset(1)
worldwidth(1) = 240
worldheight(1) = 240
max_players = 2
objoffset(1) = 19 : rem object # offset
dim head(1)
rem following used to define arrays
xsize(1) = worldwidth(1) / 12
ysize(1) = 5 : rem 5 layers for now
zsize(1) = worldheight(1) / 12
a = xsize(1) + 1
b = zsize(1) + 1
d = ysize(1)
c = a * b / 2 : ` only half the objects can move
rem object/world arrays
dim pos_x(c)
dim pos_y(c)
dim pos_z(c)
dim direction(c)
dim moving(c)
dim speed(c)
dim tilestatus(a, d, b)
dim tileobj(a, d, b)
dim camvariant(1)
camvariant(1) = 1
dim b(1)
dim lim(1)
lim(1) = c
rem LOAD
load_level()
rem ========= main loop =========
DO
player_input(1)
move()
arrivals()
update_cam()
print_status(1)
SYNC
LOOP
rem -----------------------------------------
function update_cam()
camdistance = 50
if scancode() = 16 then camvariant(1) = 1
if scancode() = 17 then camvariant(1) = 2
rem place camera
if camvariant(1) = 1
position camera object position x(1), object position y(1) + camdistance, object position z(1) - camdistance
point camera object position x(1), object position y(1), object position z(1)
endif
if scancode() = 14
for y = 0 to zsize(1)
set cursor 150, (22 - y) * 20
for x = 0 to xsize(1) + 1
print " ",tilestatus(x, 1, y);
next x
next y
endif
if scancode() = 43
for aa = 1 to 10
set cursor 150, aa*20
print moving(aa)," ",direction(aa)," ",speed(aa)," ",pos_x(aa)," ",pos_y(aa)," ",pos_z(aa)," ";
next aa
endif
rem place camera, variant 2
if camvariant(1) = 2
position camera 105, 30, 100
point camera object position x(1), object position y(1), object position z(1)
endif
endfunction
rem -----------------------------------------
function print_status(q)
set cursor 0,0
x = object position x(q) / 12
y = object position y(q) / 12
z = object position z(q) / 12
y = y + 1
print "moving: "; active(q)
print "direction: "; direction(b(1))
print "speed: "; speed(b(1))
print "pos_x: "; object position x(q)
print "pos_y: "; object position y(q)
print "pos_z: "; object position z(q)
print "grid X: "; x
print "grid Y: "; y
print "grid Z: "; z
print " ";head(1)
print "Tilestatus forward: ";ismoveable(1, x, y, z)
print "Tilestatus right: ";ismoveable(2, x, y, z)
print "Tilestatus backward: ";ismoveable(3, x, y, z)
print "Tilestatus left: ";ismoveable(4, x, y, z)
print "Tilestatus up: ";ismoveable(5, x, y, z)
print "Tilestatus down: ";ismoveable(6, x, y, z)
endfunction
rem -----------------------------------------
rem create world -- currently only loads layer one!
function load_level()
rem make world matrix
make matrix 1, worldwidth(1), worldheight(1), worldwidth(1) / 12, worldheight(1) / 12
position matrix 1, 6, -6, 6
update matrix 1
block = objoffset(1)
for mazex = 1 to xsize(1)
for mazez = 1 to zsize(1)
read maze
rem if a block was found
if (maze = 1) or (maze = 2)
inc block
make object box block, 12, 12, 12
color object block, rgb(15,60,15)
position object block, mazex * 12, groundheight, mazez * 12
tilestatus(mazex, 1, mazez) = maze
tileobj(mazex, 1, mazez) = block
endif
if maze = 3
inc block
make object sphere block, 15
color object block, rgb(40,15,15)
position object block, mazex * 12, groundheight, mazez * 12
tilestatus(mazex, 1, mazez) = maze
tileobj(mazex, 1, mazez) = block
endif
if maze = 0
tilestatus(mazex, 1, mazez) = 0
tileobj(mazex, 1, mazez) = 0
endif
next mazez
next mazex
rem set hidden double border
for x = 0 to xsize(1) + 1
tilestatus(x, 1, 0) = 1
tilestatus(x, 1, zsize(1) + 1) = 1
next x
for z = 0 to zsize(1) + 1
tilestatus(0, 1, z) = 1
tilestatus(xsize(1) + 1, 1, z) = 1
next y
rem set lower level solid
for z = 0 to zsize(1) + 1
for x = 0 to xsize(1) + 1
tilestatus(x, 0, z) = 1
next x
next z
rem --- player 1 init ---
rem make temp player char
make object box 1, 12, 12, 12
position object 1, 24, 0, 24
color object 1, rgb(0,60,80)
tilestatus(2, 1, 2) = -1
tileobj(2, 1, 2) = 1
rem scratch pad value below
tileobj(0, 1, 0) = 1
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,2,2,0,0,0,0,0,0,0,0,0,1
data 1,0,0,0,0,0,0,2,0,0,2,0,0,0,0,0,0,0,0,1
data 1,0,0,0,0,0,0,0,2,2,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,3,0,0,0,0,0,0,0,0,0,0,1,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
endfunction
rem -----------------------------------------
remstart check player input
direction codes
forward - 1
right - 2
back - 3
left - 4
up - 5
down - 6
remend
function player_input(object)
rem fetch object position locally... (in grid values)
x = object position x(object) / 12
y = object position y(object) / 12
z = object position z(object) / 12
y = y + 1
if active(object) = 0
if upkey() = 1
if ismoveable(1, x, y, z)
destination(1, x, y, z, 2)
else
if ismoveable(1, x, y, z + 1)
destination(1, x, y, z + 1, 1)
destination(1, x, y, z, 1)
endif
endif
endif
if rightkey() = 1
if ismoveable(2, x, y, z)
destination(2, x, y, z, 2)
else
if ismoveable(2, x + 1, y, z)
destination(2, x + 1, y, z, 1)
destination(2, x, y, z, 1)
endif
endif
endif
if downkey() = 1
if ismoveable(3, x, y, z)
destination(3, x, y, z, 2)
else
if ismoveable(3, x, y, z - 1)
destination(3, x, y, z - 1, 1)
destination(3, x, y, z, 1)
endif
endif
endif
if leftkey() = 1
if ismoveable(4, x, y, z)
destination(4, x, y, z, 2)
else
if ismoveable(4, x - 1, y, z)
destination(4, x - 1, y, z, 1)
destination(4, x, y, z, 1)
endif
endif
endif
endif
endfunction
rem -----------------------------------------
rem add object to moving que...
function que(dire, x, y, z, obj, spd)
head(1) = head(1) + 1
moving(head(1)) = obj
pos_x(head(1)) = x
pos_y(head(1)) = y
pos_z(head(1)) = z
speed(head(1)) = spd
direction(head(1)) = dire
endfunction
rem -----------------------------------------
rem pull object from movement que
function deque(obj)
a = 0
b = head(1) + 2
for top = 1 to b
if abs(moving(top)) = obj then a = 1
if a = 1
moving(top - 1) = moving(top)
pos_x(top - 1) = pos_x(top)
pos_y(top - 1) = pos_y(top)
pos_z(top - 1) = pos_z(top)
speed(top - 1) = speed(top)
direction(top - 1) = direction(top)
endif
next top
head(1) = head(1) - 1
if head(1) < 0 then head(1) = 0
endfunction
rem -----------------------------------------
rem test for object in movement que
function active(obj)
ret = 0
if head(1)
for w = 1 to head(1)
if abs(moving(w)) = obj
b(1) = w
ret = 1
endif
next w
endif
endfunction ret
rem -----------------------------------------
rem compute object destination point and que it
function destination(dire, x, y, z, spd)
q = tileobj(x, y, z)
dx = object position x(q)
dy = object position y(q)
dz = object position z(q)
if dire = 1 then dz = dz + 12
if dire = 2 then dx = dx + 12
if dire = 3 then dz = dz - 12
if dire = 4 then dx = dx - 12
if dire = 5 then dy = dy + 12
if dire = 6 then dy = dy - 12
que(dire, dx, dy, dz, q, spd)
endfunction
rem -----------------------------------------
rem test that an object can be moved
function ismoveable(dire, x, y, z)
rem I'm lazy, so I use locals....
a = tilestatus(x, y, z + 1) : rem forward 1
b = tilestatus(x + 1, y, z) : rem right 2
c = tilestatus(x, y, z - 1) ; rem backward 3
d = tilestatus(x - 1, y, z) : rem left 4
e = tilestatus(x, y + 1, z) : rem up 5
f = tilestatus(x, y - 1, z) : rem down
stat = 0
p = tilestatus(x, y, z)
select p
case -1 : if dire = 1 and a = 0 then stat = 1
if dire = 2 and b = 0 then stat = 1
if dire = 3 and c = 0 then stat = 1
if dire = 4 and d = 0 then stat = 1
if dire = 5 and e = 0 then stat = 1
if dire = 6 and f = 0 then stat = 1
endcase
case 2 : if dire = 1 and a = 0 then stat = 1
if dire = 2 and b = 0 then stat = 1
if dire = 3 and c = 0 then stat = 1
if dire = 4 and d = 0 then stat = 1
if dire = 5 and e = 0 then stat = 1
if dire = 6 and f = 0 then stat = 1
endcase
case 3 : if dire = 1 and a = 0 then stat = 1
if dire = 2 and b = 0 then stat = 1
if dire = 3 and c = 0 then stat = 1
if dire = 4 and d = 0 then stat = 1
if dire = 5 and e = 0 then stat = 1
if dire = 6 and f = 0 then stat = 1
endcase
case default : stat = 0 : endcase
endselect
endfunction stat
rem -----------------------------------------
rem move the world... but only those that count!
function move()
if head(1)
for w = 1 to head(1)
rem if its moving....
if moving(w) > 0
q = moving(w)
rem forward
if pos_z(w) > object position z(q)
position object q, object position x(q), object position y(q), object position z(q) + speed(w)
endif
rem right
if pos_x(w) > object position x(q)
position object q, object position x(q) + speed(w), object position y(q), object position z(q)
endif
rem backward
if pos_z(w) < object position z(q)
position object q, object position x(q), object position y(q), object position z(q) - speed(w)
endif
rem left
if pos_x(w) < object position x(q)
position object q, object position x(q) - speed(w), object position y(q), object position z(q)
endif
rem up
if pos_y(w) > object position y(q)
position object q, object position x(q), object position y(q) + speed(w), object position z(q)
endif
rem down
if pos_y(w) < object position y(q)
position object q, object position x(q), object position y(q) - speed(w), object position z(q)
endif
rem arrived...
if (object position z(q) = pos_z(w)) and (object position x(q) = pos_x(w)) and (object position y(q) = pos_y(w))
moving(w) = 0 - moving(w)
endif
endif
next w
endif
endfunction
rem -----------------------------------------
rem update the arrays after movement is done
function arrivals()
if (head(1) > 0)
for w = 1 to head(1)
if moving(w) < 0
q = abs(moving(w))
x = pos_x(w) / 12
y = pos_y(w) / 12
z = pos_z(w) / 12
y = y + 1
d = direction(w)
select d
case 1 : tileobj(x, y, z) = q
tileobj(x, y, z - 1) = 0
tilestatus(x, y, z) = tilestatus(x, y, z - 1)
selfmoving(w, x, y, z, d)
tilestatus(x, y, z - 1) = 0
endcase
case 2 : tileobj(x, y, z) = q
tileobj(x - 1, y, z) = 0
tilestatus(x, y, z) = tilestatus(x - 1, y, z)
selfmoving(w, x, y, z, d)
tilestatus(x - 1, y, z) = 0
endcase
case 3 : tileobj(x, y, z) = q
tileobj(x, y, z + 1) = 0
tilestatus(x, y, z) = tilestatus(x, y, z + 1)
selfmoving(w, x, y, z, d)
tilestatus(x, y, z + 1) = 0
endcase
case 4 : tileobj(x, y, z) = q
tileobj(x + 1, y, z) = 0
tilestatus(x, y, z) = tilestatus(x + 1, y, z)
selfmoving(w, x, y, z, d)
tilestatus(x + 1, y, z) = 0
endcase
case 5 : tileobj(x, y, z) = q
tileobj(x, y - 1, z) = 0
tilestatus(x, y, z) = tilestatus(x, y - 1, z)
selfmoving(w, x, y, z, d)
tilestatus(x, y - 1, z) = 0
endcase
case 6 : tileobj(x, y, z) = q
tileobj(x, y + 1, z) = 0
tilestatus(x, y, z) = tilestatus(x, y + 1, z)
selfmoving(w, x, y, z, d)
tilestatus(x, y + 1, z) = 0
endcase
endselect
endif
next w
endif
endfunction
function selfmoving(obj, x, y, z, d)
t = tilestatus(x, y, z)
select t
case 3 : s = speed(obj)
deque(obj)
if ismoveable(d, x, y, z)
destination(d, x, y, z, s)
endif
endcase
case default : deque(obj) : endcase
endselect
endfunction
Any truly great code should be indisguishable from magic.