`Global rotation functions by Lower Logic
 
set display mode 1024,768,32
sync on
sync rate 60
autocam off
hide mouse
fog off
position camera 0,25.0,20.0
 
`make textures
create bitmap 99,256,256
ink rgb(140,100,0),0
box 0,0,128,128
box 128,128,256,256
ink rgb(220,210,200),0
box 0,128,128,256
box 128,0,256,128
ink rgb(0,0,0),0
for x=126 to 130
line x,0,x,256
line 0,x,256,x
next x
for x=0 to 2
line x,0,x,256
line 0,x,256,x
next x
for x=254 to 256
line x,0,x,256
line 0,x,256,x
next x
get image 99,0,0,256,256,1
delete bitmap 99
create bitmap 1,256,256
ink rgb(20,80,140),0
box 0,0,128,128
box 128,128,256,256
ink rgb(200,210,220),0
box 0,128,128,256
box 128,0,256,128
ink rgb(0,0,0),0
x=128
line x,0,x,256
line 0,x,256,x
x=0
line x,0,x,256
line 0,x,256,x
x=256
line x,0,x,256
line 0,x,256,x
get image 1,0,0,256,256,1
delete bitmap 1
 
`make ball
make object sphere 99,5,64,64
texture object 99,99
set object specular 99,rgb(250,240,200)
set object specular power 99,25
set object emissive 99,rgb(30,20,0)
set object ambient 99,1
set object collision off 99
set object filter 99,0
 
`shadow
make object sphere 2,5,32,32
scale object 2,130,0.01,130
yrotate object 2,90
fix object pivot 2
color object 2,0
ghost object on 2,1
set object ambient 2,1
set object emissive 2,rgb(0,0,0)
set object specular 2,rgb(0,0,0)
set object specular power 2,100
set object collision off 2
 
`ground
   `ice
make object plain 3,100,100
pitch object down 3,-90
color object 3,rgb(0,0,0)
set reflection shading on 3
position object 3,0,7.5,50.0
set object transparency 3,5
 
 `normal
make object plain 6,100,100
pitch object down 6,-90
texture object 6,1
scale object texture 6,0.999,0.999
position object 6,0,0,-50.0
set object specular 6,rgb(230,210,200)
set object specular power 6,50
set object emissive 6,rgb(0,0,10)
set object filter 6,0
 
make object plain 45,100,100
position object 45,-100.0,-7.5,-50.0
 
make object plain 46,100,100
position object 46,-100.0,-17.5,-150.0
 
make object plain 47,100,5
position object 47,0.0,-17.5,-150.0
 
make object plain 48,5,50
position object 48,47.5,-17.5,-150.0-27.5
 
make object plain 49,25,50
position object 49,50.0,-10.0,-175.0-50.0/2.0-50.0
 
make object plain 50,25,50
position object 50,50.0,-10.0,-175.0-50.0/2.0-120.0
 
make object plain 51,50,25
position object 51,50.0,-20.0,-370.0
 
make object plain 53,50,25
position object 53,0.0,-27.0,-370.0
 
for x=45 to 53
if x<>52
pitch object down x,-90
texture object x,1
set object specular x,rgb(230,210,200)
set object specular power x,50
set object emissive x,rgb(0,0,10)
set object filter x,0
endif
next x
 
`walls
   `north
make object plain 8,100,7.5/2
texture object 8,1
scale object texture 8,1,0.5
position object 8,0,7.5/4,0
set object specular 8,rgb(230,210,200)
set object specular power 8,50
set object emissive 8,rgb(0,0,10)
set object filter 8,0
 
make object plain 9,100,7.5/2
texture object 9,1
scale object texture 9,-1,0.5
position object 9,0,(7.5/4)*3,0
set object specular 9,rgb(230,210,200)
set object specular power 9,50
set object emissive 9,rgb(0,0,10)
set object filter 9,0
set object collision off 9
 
make object plain 25,100,7.5
texture object 25,1
scale object texture 25,0.5,1
position object 25,0,7.5*1.5,100.0
 
make object plain 29,100,7.5
texture object 29,1
scale object texture 29,-0.5,1
position object 29,-100.0,7.5/-2,0
 
   `test
make object plain 30,100,25
texture object 30,1
xrotate object 30,-53.0
scale object texture 30,1,-1
position object 30,-100.0,-15.0,-110.0
 
make object plain 52,25,25
texture object 52,1
xrotate object 52,-73.0
yrotate object 52,-90.0
position object 52,13.1,-23.6,-370.0
 
   `south
make object plain 26,100,7.5
texture object 26,1
scale object texture 26,-0.5,-1
position object 26,0,7.5/2,-100.0
 
make object plain 31,50,7.5
texture object 31,1
position object 31,50.0,-20.0+7.5/2.0,-382.5
 
   `east
make object plain 27,100,7.5
yrotate object 27,90
texture object 27,1
scale object texture 27,0.5,1
position object 27,-50.0,7.5/-2,-50.0
 
make object plain 32,25.0,7.5
yrotate object 32,90
texture object 32,1
position object 32,75.0,-20.0+7.5/2.0,-370.0
 
   `west
make object plain 28,100,7.5
yrotate object 28,90
texture object 28,1
scale object texture 28,0.5,-1
position object 28,-150.0,7.5/-2,-50.0
 
 
for x=25 to 30
set object specular x,rgb(230,210,200)
set object specular power x,50
set object emissive x,rgb(0,0,10)
set object filter x,0
enable object zwrite x
enable object zread x
next x
 
 
 
`jump-pads
make object sphere 11,5,12,12
scale object 11,150,10,150
position object 11,0,7.52,8.0
 
make object sphere 12,5,12,12
scale object 12,150,10,150
position object 12,-8.0,0.02,-8.0
 
make object sphere 13,5,12,12
scale object 13,150,10,150
position object 13,8.0,0.02,-8.0
 
make object sphere 14,5,12,12
scale object 14,150,10,150
position object 14,-58.0,-7.48,-50.0
 
make object sphere 15,5,12,12
scale object 15,150,10,150
position object 15,-95.0,-7.48,-95.0
 
make object sphere 16,5,12,12
scale object 16,150,10,150
`position object 16,-100.0,-17.48,-110.0
position object 16,50.0,-17.5,-282.0
 
make object sphere 17,5,12,12
scale object 17,150,10,150
position object 17,47.5,-17.5,-207.0
 
make object sphere 18,5,12,12
scale object 18,150,10,150
position object 18,55.0,-17.5,-282.0
 
make object sphere 19,5,12,12
scale object 19,150,10,150
position object 19,45.0,-17.5,-282.0
 
`comic-outline
make object sphere 4,5.2,32,32
scale object 4,-100,-100,-100
color object 4,rgb(0,0,0)
set object ambient 4,0
set object collision off 4
 
`light
make light 1
color light 1,rgb(255,255,255)
position light 1,5,100,5
set light range 1,200
 
c_f=10
`background
cls : backdrop off
for x=0 to 32
ink rgb(111-x*c_f,222-x*c_f,255-x*c_f),0
line x,0,x,64
next x
for x=32 to 0 step -1
ink rgb(111-x*c_f,222-x*c_f,255-x*c_f),0
line abs(32-x)+32,0,abs(32-x)+32,64
next x
get image 5,0,0,64,64,4
backdrop on
make object sphere 5,10,32,32
scale object 5,8000,8000,8000 : texture object 5,5
scale object texture 5,4,4 : position object 5,-25,-5,-55
`set object 5,1,0,0,0,1,0,1
set object cull 5,0
set object filter 5,0
set object specular 5,rgb(155,205,255)
set object specular power 5,100
set object emissive 5,rgb(10,30,50)
set object collision off 5
 
`collision ball
make object sphere 7,5.1,32,32
hide object 7
scale object 7,50,100,50
 
 
 
state_50=1
start_50=object position z(50)
 
v#=0.01
vr#=0.1
xm#=0.0
zm#=0.0
 
camd#=30.0
camh#=20.0
cama#=90.0
cama_offset#=10.0
 
one=1
res_x#=0.0
res_y#=20.0
res_z#=50.0
fall#=-25.0
 
r=1 : b=1 : g=1
 
dim texts$(13)
texts$(1)=" "
texts$(2)="Move Ball with Arrowkeys."
texts$(3)=" "
texts$(4)="Rotate Cam with left-/rightclick"
texts$(5)=" "
texts$(6)="Zoom with mousewheel"
texts$(7)=" "
texts$(8)="Change Zoom with Button 3 (mousewheel)"
texts$(9)=" "
texts$(10)=" "
texts$(11)=" "
texts$(12)="Thanks to Lower Logic (global ball rotation) and Ric (setting up rotation functions)"
 
textx=25
set text font "Lucida console"
set text size 14
set text to bold
 
up as boolean
down as boolean
left as boolean
right as boolean
 
start_time=timer()
 
do
 
gosub move_platforms
 
remstart
ink rgb(200,210,220),0
set cursor 0,0
print "xm#=";xm#
print "zm#=";zm#
remend
oldx#=x#
oldy#=y#
oldz#=z#
 
if cama#=0.0
   up=downkey() or joystick down()
   down=upkey() or joystick up()
   left=rightkey() or joystick right()
   right=leftkey() or joystick left()
endif
if cama#=270.0
   up=leftkey() or joystick left()
   down=rightkey() or joystick right()
   left=downkey() or joystick down()
   right=upkey() or joystick up()
endif
if cama#=180.0
   up=upkey() or joystick up()
   down=downkey() or joystick down()
   left=leftkey() or joystick left()
   right=rightkey() or joystick right()
endif
if cama#=90.0
   up=rightkey() or joystick right()
   down=leftkey() or joystick left()
   left=upkey() or joystick up()
   right=downkey() or joystick down()
endif
 
ang#=360*(vr#^2)/2.5
 
`rotate for e/w-wall collision
zrotate object 7,object angle z(7)-90
 
`inc/dec speed depending on keys (e.g. v#*0=0 / v#*1=v# ) and collision
`east wall collision
if object collision(7,0)<>27 and object collision(7,0)<>32 then inc xm#,v#*right
if object collision(7,0)<>28 then dec xm#,v#*left
 
`wall collision east
if object collision(7,0)=27 or object collision(7,0)=32
   if abs(xm#)<0.045
      dec x#,abs(xm#)/10.0
   else
      xm#=xm#*-0.75
   endif
   if xm#>0.002 then dec xm#,xm#/10.0
endif
 
`wall collision west
if object collision(7,0)=28
   if abs(xm#)<0.045
      dec x#,abs(xm#)/10.0
   else
      xm#=xm#*-0.75
   endif
   if xm#<-0.002 then inc xm#,xm#/10.0
endif
 
`stop if low speed
if abs(xm#)<0.002 then xm#=0.0
 
`rotate back
zrotate object 7,object angle z(7)+90
 
`rotate for n/s-wall collision
xrotate object 7,object angle x(7)+90
`north wall collision
if object collision(7,0)<>8 and object collision(7,0)<>25 and object collision(7,0)<>29 then inc zm#,v#*up
`south wall collision
if object collision(7,0)<>26 and object collision(7,0)<>31 then dec zm#,v#*down
 
`wall collision north
if object collision(7,0)=8 or object collision(7,0)=25 or object collision(7,0)=29
   if abs(zm#)<0.05
      dec z#,abs(zm#)/10.0
   else
      zm#=zm#*-0.75
   endif
   if zm#>0.002 then dec zm#,zm#/10.0
endif
 
`wall collision south
if object collision(7,0)=26 or object collision(7,0)=31
   if abs(zm#)<0.05
      inc z#,abs(zm#)/10.0
   else
      zm#=zm#*-0.75
   endif
   if zm#<-0.002 then inc zm#,zm#/10.0
endif
 
`stop if low speed
if abs(zm#)<0.002 then zm#=0.0
 
`rotate back
xrotate object 7,object angle x(7)-90
 
`if moving then rotate ball depending on speed
if xm#>0.0 then rotate_gz(99,-ang#*(xm#*10.0))
if xm#<0.0 then rotate_gz(99,ang#*abs(xm#*10.0))
if zm#>0.0 then rotate_gx(99,ang#*(zm#*10.0))
if zm#<0.0 then rotate_gx(99,-ang#*abs(zm#*10.0))
 
 
`reset
if y#<fall# and time=0 then one=1: time=20
if one then x#=res_x# : y#=res_y# :  z#=res_z# : text 50,50,str$( mouseclick()) : one=0 : rotate object 99,rnd(360),rnd(360),rnd(360) : xm#=0.0 : zm#=0.0
if x#>-50.0 and z#<-145.0 and res_x#<>-50.0 and res_y#<>10.0 and res_z#<>-150.0 then checktime=500 : res_x#=-50.0 : res_y#=10.0 : res_z#=-150.0: fall#=-40.0
 
if checktime>0 then shadow_text(screen width()/2,screen height()/2+500-checktime,"Checkpoint",rgb(150+checktime/10,255,180+checktime/10),1) : dec checktime
 
`check different grounds and set resistance factor
`               object   3  =  icy/metal ground
if object collision(7,0)=3
   d#=6.0
else
   d#=2.0
   if object collision(7,0)=47 or object collision(7,0)=48 or object collision(7,0)=50 then d#=7.0
endif
 
`set ground resistance depending on speed
f#=((xm#*xm#)*100.0+(zm#*zm#)*100.0)/5.0
if f#<d# then f#=d#
f#=10.0-f#
`print f#
`f#=5.0
 
`decrease speed depending on speed
if xm#<0.0 then inc xm#,v#/f#
if xm#>0.0 then dec xm#,v#/f#
if zm#<0.0 then inc zm#,v#/f#
if zm#>0.0 then dec zm#,v#/f#
 
`gravity and ground collision
if object collision(7,0)=0
   if jump=0
      y#=y#-0.5
   endif
else
   if object collision(7,0)<>8
      if object collision(7,0)<25 or object collision(7,0)>46
         if object collision(7,0)<>52 and object collision(7,0)<>30 then y#=object size z(object collision(7,0))/2.0+object position y(object collision(7,0))+2.5
      endif
   endif
endif
 
`roll up ramp 2
if object collision(7,52)=1 then y#=y#+.15 : xm#=xm#-.006
 
`add movements to position
x#=x#+xm#
z#=z#+zm#
 
`re-position objects
position object 99,x#,y#,z#
position object 4,x#,y#,z#
`position shadow correct
if object collision(7,0)>0 and object collision(7,0)<>8
   if object collision(7,0)>25 or object collision(7,0)<11
      sy#=object size z(object collision(7,0))/2.0+object position y(object collision(7,0)+0.005)
   else
      if sy#=0 or sy#=0.0
         for for#=1.0 to 100.0
            position object 2,x#,object position y(2)-for#/10.0,z#
            if object collision(2,0)>0 then sy#=for#/10.0 : exit
         next for#
      endif
   endif
endif
`fix if falling
if sy#>y#-2.5 then sy#=y#-2.49
position object 2,x#,sy#+0.01,z#
position object 7,x#,y#,z#
scale object 2,100.0+(sy#-y#)*5.0+32.5,0.03,100.0+(sy#-y#)*5.0+32.5
if object collision(7,0)>0
   rotate object 2,object angle x(object collision(7,0)),0,object angle z(object collision(7,0))
else
   rotate object 2,0,0,0
endif
 
`fix jumpers
set object collision off 45
set object collision off 46
 
`roll up ramp 1
if object collision(7,0)=30 then y#=y#+.45 : zm#=zm#-.006
 
 
`jump-pads jumping
if object collision(7,0)>10 and object collision(7,0)<25
jump=30
y#=y#+0.05
endif
 
if jump>0 then y#=y#+jump/15 : jump=jump-1
 
 
`color jumpers
if object collision(7,0)>10 and object collision(7,0)<20 then ru=1 : gu=1 : bu=1 : r=0 : g=0 : b=255
for x=1 to 2
if ru=1 then inc r : if gu=1 then inc g : if bu<1 then inc b
`if ru=0 then dec r : if gu=0 then dec g : if bu<0 then dec b
if r=255 then ru=0 : if g=255 then gu=0 : if b=255 then bu=0
if r=0 then ru=1   : if g=0 then gu=1   : if b=0 then bu=1
next x
 
for x=11 to 19
if object collision(7,0)=x
   change=x
endif
if change=x
   color object x,rgb(r,g,b)
else
   color object x,rgb(255,255,255)
endif
next x
 
 
`fix jumpers
set object collision on 45
set object collision on 46
 
if object collision(7,0)=53 and wintime$="" then won=1
 
`if mousebutton 2 pressed -> rotate cam
if mouseclick()=2 and time2<=0 then cama#=wrapvalue(cama#-90) : time2=60
if mouseclick()=1 and time2<=0 then cama#=wrapvalue(cama#+90) : time2=60
 
camd#=abs(camd#-mousemovez()/100.0)
if mouseclick()=4 and time<=0
if camd#<>15.0
camd#=15.0
time=50
else
 camd#=30.0 : time=50
 endif
endif
 
`set cam
chase_cam(0,99,camd#,camh#+y#,cama#+cama_offset#)
 
`rotate bg-sphere
rotate object 5,object angle x(5)+0.1,object angle y(5)+0.1,object angle z(5)+0.1
 
gosub interface
gosub update_time
 
if time>0 then dec time
if time2>0 then dec time2
 
sync
loop
 
 
 
remstart Rotate_GX
   This function rotates the given object around the global (world) x axis by
   the given amount.
   Param    obj      The object to rotate
   Param    amount#  The angle to rotate the object by
remend
 
function rotate_GX(obj as integer,amount# as float)
   rem get normal vectors for X, Y, and Z axes of the object
   x#=object position x(obj):y#=object position y(obj):z#=object position z(obj)
   move object right obj,1
   xx#=object position x(obj)-x#:xy#=object position y(obj)-y#:xz#=object position z(obj)-z#
   move object left obj,1:move object up obj,1
   yx#=object position x(obj)-x#:yy#=object position y(obj)-y#:yz#=object position z(obj)-z#
   move object down obj,1:move object obj,1
   zx#=object position x(obj)-x#:zy#=object position y(obj)-y#:zz#=object position z(obj)-z#
   move object obj,-1
   rem rotate the vectors
   xx1#=xx#
   xy1#=xy#*cos(amount#)-xz#*sin(amount#)
   xz1#=xz#*cos(amount#)+xy#*sin(amount#)
   zx1#=zx#
   zy1#=zy#*cos(amount#)-zz#*sin(amount#)
   zz1#=zz#*cos(amount#)+zy#*sin(amount#)
   rem calculate angle z
   zr#=atanfull(xy1#,xx1#)
   rem calculate angle y
   xx2#=xx1#*cos(zr#)+xy1#*sin(zr#)
   xy2#=xy1#*cos(zr#)-xx1#*sin(zr#)
   xz2#=xz1#
   zx2#=zx1#*cos(zr#)+zy1#*sin(zr#)
   zy2#=zy1#*cos(zr#)-zx1#*sin(zr#)
   zz2#=zz1#
   yr#=atanfull(xx2#,xz2#)-90
   rem calculate angle x
   zx3#=zx2#*cos(yr#+90)-zz2#*sin(yr#+90)
   zy3#=zy2#
   xr#=atanfull(zy3#,zx3#)+180
   if xr#+1>xr# and yr#+1>yr# and zr#+1>zr#
      rotate object obj,xr#,yr#,zr#
   endif
endfunction
 
 
remstart Rotate_GZ
   This function rotates the given object around the global (world) z axis by
   the given amount.
   Param    obj      The object to rotate
   Param    amount#  The angle to rotate the object by
remend
function rotate_GZ(obj,amount#)
   rem Rotating around the global Z axis is trivial
   rem as it is the first rotation anyway in the default ZYX rotation order
   rotate object obj,object angle x(obj),object angle y(obj),object angle z(obj)+amount#
endfunction
 
 
function chase_cam(CamNum#,id,camDist,Height#,yAng#)
 
   `grab the cameras current position
   xPos#=object position x(id)
   yPos#=object position y(id)
   zPos#=object position z(id)
 
   `work out new position
   xCamPos#=newxvalue(xPos#,yAng#,camDist)
   zCamPos#=newzvalue(zPos#,yAng#,camDist)
 
   `work out camera height
   yCamPos#=Height#
   if Height#<yPos# then yCamPos#=yPos#
 
   s=20
   xCamPos#=curvevalue(xCamPos#,camera position x(CamNum#),s)
   yCamPos#=curvevalue(yCamPos#,camera position y(CamNum#),s)
   zCamPos#=curvevalue(zCamPos#,camera position z(CamNum#),s)
 
   `update camera position
   position camera CamNum#,xCamPos#,yCamPos#,zCamPos#
   point camera CamNum#,xPos#,yPos#,zPos#
 
endfunction
 
 
interface:
 
   shadow_text(screen width()-text width("FPS: "+str$(screen fps())),0,"FPS: "+str$(screen fps()),rgb(200,210,220),0)
   for x=1 to array count(texts$(0))
      shadow_text(textx,x*10,texts$(x),rgb(200,210,220),0)
   next x
 
return
 
function shadow_text(x#,y#,text$,color,center)
ink rgb(10,20,30),0
if center=0 then text x#+1,y#+2,text$
if center=1 then center text x#+1,y#+2,text$
ink color,0
if center=0 then text x#,y#,text$
if center=1 then center text x#,y#,text$
endfunction
 
move_platforms:
 
if state_50=1
   position object 50,object position x(50),object position y(50),object position z(50)-0.1
else
   position object 50,object position x(50),object position y(50),object position z(50)+0.1
endif
 
if state_50=1
   if object position z(50)<start_50-25.0 then state_50=0
else
   if object position z(50)>start_50+5.0 then state_50=1
endif
 
if object collision(7,0)=50
   if state_50=1 then zm#=zm#+.005
   if state_50=0 then zm#=zm#-.005
endif
 
return
 
update_time:
 
runtime=timer()-start_time
sec=runtime/1000
if sec>=60 then start_time=timer() : inc min
if sec<10 then sec$="0"+str$(sec) else sec$=str$(sec)
shadow_text(screen width()/2,0,str$(min)+":"+sec$,rgb(200,210,220),1)
 
if won=1 then wintime$="You won in "+str$(min)+":"+sec$+" Minutes!" :won=2
if won=0 then wintime$=""
shadow_text(screen width()/2,screen height()/2,wintime$,rgb(100,210,160),1)
 
return