ok and now an fps version of it
(also forgot to mention that holding shift runs)
a,s,d,w =move
rightmouseclick in = look/turn
space =jump
// fast tile engine fps version
setvirtualresolution(1024,600)
setorientationallowed(0,0,1,0)
setvsync(1)
//fyi your maps can be way bigger now but change this to 128x5x128 if you want smaller maps
global tilemax_x=1024
global tilemax_y=5
global tilemax_z=1024
global resetscene=0
global oldmousex#
global oldmousey#
global newmousex#
global newmousey#
global firstclick=0
global look#=200.0
// total size of map
global map_xtotal, map_ytotal, map_ztotal as integer
map_xtotal = tilemax_x
map_ytotal = tilemax_y
map_ztotal = tilemax_z
// draw size for map radius
global map_xsize, map_ysize, map_zsize as integer
global map_xhalf, map_yhalf, map_zhalf, map_xymul as integer
//if your fps can handle it ... make the view area bigger ... or smaller if it cant
//these numbers below
map_xsize = 12
map_zsize = 12
//leave this y value at 5 or you will need to modify some other code
map_ysize = 5
//#############################################
map_xhalf = map_xsize >> 1
map_yhalf = map_ysize >> 1
map_zhalf = map_zsize >> 1
map_xymul = map_xsize * map_ysize
// map objects offset
global map_objects, object_total as integer
//what do you want to use for the starting object for 3d background
// i generally set it up high and all the players..n tiles lower
map_objects = 2000
//###########################
object_total = map_xymul * map_zsize
global tilecount, totalcount as integer
//tile engine assumes your using 100x100x100 tiles
//but i will tell you what needs to be changed if its different
//ok lets make some dummy tiles
createobjectbox(1,100,100,100)
setobjectcolor(1,0,100,0,255)
setobjectvisible(1,0)
//ok lets make some dummy tiles
createobjectbox(2,100,100,100)
setobjectcolor(2,0,150,0,255)
setobjectvisible(2,0)
//ok lets make some dummy tiles
createobjectbox(3,100,100,100)
setobjectcolor(3,150,50,50,255)
setobjectvisible(3,0)
//ok lets make some dummy tiles
createobjectbox(4,100,100,100)
setobjectcolor(4,150,150,50,255)
setobjectvisible(4,0)
//now our map
dim world#[tilemax_x,tilemax_y,tilemax_z]
setcamerarange(1,1,5000)
//create a solid floor layer
//################################################
for x=1 to tilemax_x step 1
for z=1 to tilemax_z step 1
world#[x,1,z]=random(1,2)
//lets randomly throw some height blocks in
a=random(1,100)
if a=1 then world#[x,2,z]=random(2,3)
if a=2
world#[x,2,z]=random(2,3)
world#[x,3,z]=random(2,3)
endif
//ceiling tile
//if you dont need to render a ceiling....its faster not to
//if you need it then cut down on the distance tile sizes eg..12x5x12
//if you want in your options you can specify different map sizes if the machine can handle it for the user to choose.
world#[x,4,z]=random(1,3)
next z
next x
//#################################################
//lets make a few walls for experiment
for t=1 to 10 step 1
world#[t,2,1]=random(1,4)
world#[t,3,1]=random(1,4)
next t
//lets make a few walls for experiment
for t=1 to 10 step 1
world#[t,2,10]=random(1,4)
world#[t,3,10]=random(1,4)
next t
//lets make a few walls for experiment
for t=1 to 10 step 1
world#[1,2,t]=random(1,4)
world#[1,3,t]=random(1,4)
next t
//lets make us a dummy box
createobjectbox(500,50,100,50)
setobjectcolor(500,50,50,50,255)
//now lets hold player data somewhere
dim players#[1,20]
players#[1,1]=500
players#[1,2]=200
players#[1,3]=500
setobjectposition(500,players#[1,1],players#[1,2],players#[1,3])
playerx#=players#[1,1]
playery#=players#[1,2]
playerz#=players#[1,3]
playera#=players#[1,4]
old_PosX# = playerx#
old_PosY# = playery#
old_PosZ# = playerz#
new_PosX# = playerx#
new_PosY# = playery#
new_PosZ# = playerz#
//main process
do
print("fps="+str(screenfps()))
print("click right mouse to look / wasd to move")
print("space to jump")
updateplayer()
updatescene()
sync()
loop
function updatescene()
//centered method
//grab players position to update the background properly
//ply_xpos#=players#[1,1]+100
//ply_ypos#=players#[1,2]
//ply_zpos#=players#[1,3]+100
//change that if needed
//nx=((ply_xpos#-50)/100)
//nz=((ply_zpos#-50)/100)
//new_xmin=nx-map_xhalf
//new_xmax=nx+map_xhalf-1
//new_zmin=nz-map_zhalf
//new_zmax=nz+map_zhalf-1
// get centre from players position (focal point)
x#=getcameraanglex(1)
y#=getcameraangley(1)
z#=getcameraanglez(1)
setcamerarotation(1,0,y#,0)
//movecameralocalz(1,100)
ply_xpos# = getcamerax(1)
ply_ypos# = getcameray(1)
ply_zpos# = getcameraz(1)
ply_yang# = getcameraangley(1)
//movecameralocalz(1,-100)
setcamerarotation(1,x#,y#,z#)
ply_xpos# = ( ply_xpos# + ( sin( ply_yang# ) * map_xhalf * 100.0 ) +50) / 100.0
ply_ypos# = ( ply_ypos# / 100.0 )
ply_zpos# = ( ply_zpos# + ( cos( ply_yang# ) * map_zhalf * 100.0 )+50 ) / 100.0
// cast to integers
new_xpos = ply_xpos# : new_ypos = ply_ypos# : new_zpos = ply_zpos#
// get new map extents
new_xmin = new_xpos - map_xhalf : new_xmax = new_xmin + map_xsize -1
new_ymin = 1: new_ymax = 5
new_zmin = new_zpos - map_zhalf : new_zmax = new_zmin + map_zsize -1
//note
//since y is small we should render all of y in the display area
//code to update screen
for z = new_zmin to new_zmax
for x = new_xmin to new_xmax
for y = 1 to 5
if resetscene=0 then update_tile( x, y, z, 1) else update_tile( x, y, z, 0)
next
next
next
//screen updated
// Update players last map position
map_oldxmin = new_xmin
map_oldxmax = new_xmax
map_oldymin = new_ymin
map_oldymax = new_ymax
map_oldzmin = new_zmin
map_oldzmax = new_zmax
resetscene=0
//endif
endfunction
function update_tile(x,y,z,flag)
cond1=0
cond3=0
` get extents conditional values first
if ( x >= map_oldxmin ) AND ( x <= map_oldxmax ) then cond1=1
//cond2 = ( y >= map_oldymin ) AND ( y <= map_oldymax )
if ( z >= map_oldzmin ) AND ( z <= map_oldzmax ) then cond3=1
` don't update if all conditions are true
if cond1 AND cond3 AND flag = 1 then exitfunction
// If we're out of map bounds then leave the old tile in the scene
if x < 0 or x > map_xtotal then exitfunction
//if y < 0 or y > map_ytotal then exitfunction
if z < 0 or z > map_ztotal then exitfunction
// find the object ID to use
xmod = x MOD map_xsize
ymod = y MOD map_ysize
zmod = z MOD map_zsize
obj = ( zmod * map_xymul ) + ( ymod * map_xsize ) + xmod
obj = obj + map_objects // this was what the starting object is for 3d map generation
// get main tile...this is the new tile to load
main_tile = readtile( x, y, z )
//need to delete old one to update new one
if getobjectexists( obj )=1 then deleteobject(obj)
if main_tile = 0 then exitfunction //no need to load anything as its mt
//this can be a range if you only want x amount of tiles drawn this way
if main_tile>0
if getobjectexists(main_tile)=1
instanceobject(obj,main_tile)
setobjectposition(obj,(x*100),(y*100)-100,(z*100))
setobjectvisible(obj,1)
endif
//you can do other settings here.... eg transparency on certain object numbers etc....
ENDIF
endfunction
function readtile(x,y,z)
if x<1 then exitfunction 0.0
if x>tilemax_x then exitfunction 0.0
if y<0 then exitfunction 0.0
if y>tilemax_y then exitfunction 0.0
if z<1 then exitfunction 0.0
if z>tilemax_z then exitfunction 0.0
ret#=world#[x,y,z]
endfunction ret#
function writetile(x,y,z,v#)
if x<1 then exitfunction
if x>tilemax_x then exitfunction
if y<0 then exitfunction
if y>tilemax_y then exitfunction
if z<1 then exitfunction
if z>tilemax_z then exitfunction
world#[x,y,z]=v#
endfunction
function getdistance#(x1#,y1#,z1#,x2#,y2#,z2#)
dx# = x2#-x1#
dy# = y2#-y1#
dz# = z2#-z1#
d#=sqrt(dx#*dx# + dy#*dy# + dz#*dz#)
endfunction d#
function updateplayer()
playerx#=players#[1,1]
playery#=players#[1,2]
playerz#=players#[1,3]
playera#=players#[1,4]
maxspeed#=12
playergravity#=players#[1,5]
playeronground=players#[1,6]
speedx#=players#[1,7]
speedz#=players#[1,8]
//look angle
look#=players#[1,9]
//gravity code here
playergravity#=playergravity#-2.0
//player movement
//keyboard on pc
movez=0
movex=0
//w
if GetRawKeyState(87)=1
speedz#=speedz#+1.5
movez=1
endif
//s
if GetRawKeyState(83)=1
speedz#=speedz#-1.5
movez=1
endif
//strafe
//a
if GetRawKeyState(65)=1
speedx#=speedx#-1.5 //RotateobjectglobalY(500,-8.0)
movex=1
endif
//d
if GetRawKeyState(68)=1
speedx#=speedx#+1.5 //RotateobjectglobalY(500,8.0)
movex=1
endif
//jump code
//32=spacekey [jump]
if getrawkeystate(32)=1 and playeronground=1
playergravity#=(20)
playeronground=0
endif
//run code
if getrawkeystate(16)=1 then maxspeed#=20.0
//adjust player
//slow down
if speedz#>maxspeed# then speedz#=speedz#-1.5
if speedz#<-(maxspeed#) then speedz#=speedz#+1.5
if speedz#>0 then speedz#=speedz#-0.5
if speedz#<0 then speedz#=speedz#+0.5
if speedz#<1.0 and speedz#>-1.0 and movez=0 then speedz#=0.0
//slow down
if speedx#>maxspeed# then speedx#=speedx#-1.5
if speedx#<-(maxspeed#) then speedx#=speedx#+1.5
if speedx#>0 then speedx#=speedx#-0.5
if speedx#<0 then speedx#=speedx#+0.5
if speedx#<1.0 and speedx#>-1.0 and movex=0 then speedx#=0.0
moveobjectlocalz(500,speedz#)
//capture mouse y
newmousex#=getrawmousex()
newmousey#=getrawmousey()
//setrawmouseposition(512,300)
//f=getrawmousex()
//f=getrawmousey()
if getrawmouserightstate()=0 then firstclick=0
if getrawmouserightstate()=1
//check to see if its just clicked
if firstclick=1
if newmousex#<oldmousex#
playera#=playera#-((oldmousex#-newmousex#)/2.0)
oldmousex#=newmousex#
endif
if newmousex#>oldmousex#
playera#=playera#+((newmousex#-oldmousex#)/2.0)
oldmousex#=newmousex#
endif
if newmousey#<oldmousey#
look#=look#-((oldmousey#-newmousey#)*.5)
oldmousey#=newmousey#
endif
if newmousey#>oldmousey#
look#=look#+((newmousey#-oldmousey#)*.5)
oldmousey#=newmousey#
endif
endif
firstclick=1
setrawmouseposition(512,300)
oldmousex#=getrawmousex()
oldmousey#=getrawmousey()
endif
moveobjectlocalx(500,speedx#)
setobjectrotation(500,0,playera#,look#)
//reset onground to perform check
playeronground=0
setobjectposition(500,getobjectx(500),getobjecty(500)+playergravity#,getobjectz(500))
//ok lets do collision check and gravity
a=0.0
tilex1=((getobjectx(500)+50)/100)-1
tilez1=((getobjectz(500)+50)/100)-1
tiley1=(((getobjecty(500)+50)-a)/100)-1
floortile=readtile((getobjectx(500)/100),1,(getobjectz(500)/100))
//max and limit y check
tiley1=1
//if tiley1>7 then tiley1=7
//look for sliding
for x1=tilex1-1 to tilex1+2 step 1
for z1=tilez1-1 to tilez1+2 step 1
for y1=1 to 5 step 1
tile=readtile(x1,y1,z1)
//collision for this stile of block
//change range if applicable
if tile>0
objx#=(x1*100)
objz#=(z1*100)
objy#=(y1*100)+readtile(x1,0,z1)-100
ox1#=getobjectx(500)
oy1#=getobjecty(500)
oz1#=getobjectz(500)
//ground / roof check
floordist#=50
test=0
if objy#+150>oy1# and objy#-150<oy1# and objz#+55>oz1# and objz#-55<oz1# and objx#+55>ox1# and objx#-55<ox1# then test=1
//collision confirmed
if test=1
//floor collision
if test=1 and objy#+floordist#<oy1# and objy#+floordist#+59>oy1#
playeronground=1
setobjectposition(500,getobjectx(500),objy#+floordist#+58,getobjectz(500))
test=0
players#[1,2]=getobjecty(500)
if playergravity#=<0.0 then playergravity#=0.0
endif
//up collision
if objy#-50>oy1# and objy#-100<oy1#
playeronground=0
setobjectposition(500,getobjectx(500),objy#-100,getobjectz(500))
test=0
if playergravity#>0.0 then playergravity#=0.0
players#[1,2]=getobjecty(500)
endif
endif
//walls check
ox1#=getobjectx(500)
oy1#=getobjecty(500)
oz1#=getobjectz(500)
test=0
floordist#=90
//if crouch=1 then floordist#=50
if objy#+floordist#>oy1# and objy#-100<oy1# and objz#+75>oz1# and objz#-75<oz1# and objx#+75>ox1# and objx#-75<ox1# then test=1
//collision confirmed
if test=1
//check for bigger digits
if objx#>ox1# then d1#=objx#-ox1#
if ox1#>objx# then d1#=ox1#-objx#
if objz#>oz1# then d2#=objz#-oz1#
if oz1#>objz# then d2#=oz1#-objz#
if d1#>d2# then order=1 else order=0
if d1#=d2# then test=0
if order=0
if test=1 and objz#+25<oz1# and objz#+75>oz1#
test=0
setobjectposition(500,getobjectx(500),getobjecty(500),objz#+75)
endif
if test=1 and objz#-25>oz1# and objz#-75<oz1#
test=0
setobjectposition(500,getobjectx(500),getobjecty(500),objz#-75)
endif
if test=1 and objx#+25<ox1# and objx#+75>ox1#
test=0
setobjectposition(500,objx#+75,getobjecty(500),getobjectz(500))
endif
if test=1 and objx#-25>ox1# and objx#-75<ox1#
test=0
setobjectposition(500,objx#-75,getobjecty(500),getobjectz(500))
endif
endif
if order=1
if test=1 and objx#+25<ox1# and objx#+75>ox1#
test=0
setobjectposition(500,objx#+75,getobjecty(500),getobjectz(500))
endif
if test=1 and objx#-25>ox1# and objx#-75<ox1#
test=0
setobjectposition(500,objx#-75,getobjecty(500),getobjectz(500))
endif
if test=1 and objz#+25<oz1# and objz#+75>oz1#
test=0
setobjectposition(500,getobjectx(500),getobjecty(500),objz#+75)
endif
if test=1 and objz#-25>oz1# and objz#-75<oz1#
test=0
setobjectposition(500,getobjectx(500),getobjecty(500),objz#-75)
endif
endif
endif
ENDIF
NEXT y1
NEXT z1
NEXT x1
//catch fall
if players#[1,2]<0.0
players#[1,2]=0.0
setobjectposition(500,getobjectx(500),players#[1,2],getobjectz(500))
playergravity#=0.0
playeronground=1
endif
//setobjectrotation(500,0,playera#+1,0)
//save vars
players#[1,1]=getobjectx(500)
players#[1,2]=getobjecty(500)
players#[1,3]=getobjectz(500)
players#[1,4]=getobjectangley(500)
players#[1,5]=playergravity#
players#[1,6]=playeronground
players#[1,7]=speedx#
players#[1,8]=speedz#
players#[1,9]=look#
//temporary
//handle camera
setcameraposition(1,playerx#,playery#+25,playerz#)
setcamerarotation(1,look#,playera#,0)
setobjectvisible(500,0)
//movecameralocalz(1,-350)
//setcameralookat(1,playerx#,playery#,playerz#,0)
endfunction
if ya like....I can change it to 10x10x10 tile sizes but give this stuff a try anyways to see whats happening
also make note: the current map size is set to 1024x5x1024 to show you it can be done.
edit: also there is no look restriction coded...so if you keep looking up or down your controls will reverse when you flip upsidedown.
I will do an example for ouya next....