Lunar lander: a classic in a new dress
Posted: Sun May 26, 2013 8:00 am
option base 1 ! option angle degrees
dim lander_x(15),lander_y(15),lx(15),ly(15)
gosub init_prog
fuel=select_level(bmin)
create_gauges(fuel,height,velocity,gas)
draw_poly(14,lx,ly,120,910-3*height/10,0,0,0,0,2)
button "start" title "start" at 324,80 size 120,40
start:
if button_pressed("start")=0 then start
button "start" delete
decending: ' check controls
tx=touch_x(0)
if tx>-1 then
ty=touch_y(0)
gas=slider("throttle",600,280,400,tx,ty,0)
end if
if button_pressed("real") then ttt=1000
if button_pressed("fast") then ttt=ttt/2
if timer()<ttt then decending
reset timer
' flight model (time step is fixed on 1 second)
thrust=gas*maxthrust/100 ! if fuel=0 then thrust=0
df=thrust/2000 ! fuel=fuel-df ! if fuel<0 then fuel=0
fv=thrust-weight-fuel ! acc=fv*gravity/(weight+fuel)
dv=acc ! velocity=velocity+dv
dh=velocity-dv/2 ! height=height+dh ! if height<0 then height=0
' update gauges
rmeter("fuel","g",384,260,120,0,400,fuel,0)
rmeter("meter","r",384,520,120,0,4000,height,0)
rmeter("m/sec","b",384,780,120,-200,200,velocity,0)
' update moon module
draw_poly(14,lx,ly,120,910-3*height/10,velocity,0,0,0,2)
' check on landing
if height>0 then goto decending else landed(velocity)
end
def select_level(bmin)
draw text "select difficulty level" at 260,10
button "easy" title "easy" at 200,40 size 120,30
button "medi" title "medium" at 340,40 size 120,30
button "diff" title "difficult" at 480,40 size 120,30
loop1: level=0
if button_pressed("easy") then level=1
if button_pressed("medi") then level=2
if button_pressed("diff") then level=3
if level=0 then loop1
button "easy" delete ! button "medi" delete ! button "diff" delete
fill rect 260,10 to 560,32
if level=1 then
draw text "easy level" at 320,40 ! select_level=1.6*bmin
else
if level=2 then
draw text "medium level" at 310,40 ! select_level=1.3*bmin
else
draw text "difficult level" at 290,40 ! select_level=1.1*bmin
end if
end if
end def
def create_gauges(b,h,v,gas)
rmeter("fuel","g",384,260,120,0,400,b,1)
rmeter("meter","r",384,520,120,0,4000,h,1)
rmeter("m/sec","b",384,780,120,-200,200,v,1)
slider ("throttle",600,280,400,0,0,1)
draw text "sim-speed" at 590,100
button "real" title "real time" at 525,130 size 100,30
button "fast" title "x2" at 645,130 size 100,30
fill color 0,0,0
fill rect 90,957.5 to 170,970 ! fill rect 110,947.5 to 150,958
fill color .8,.8,.8
end def
def landed(v)
draw font size 15
if v<-20 then
draw text "You made a mess of it! All destroyed and dead." at 180,930
return
end if
if v<-15 then
draw text "You crashed! Module destroyed, you severely wounded (and alone!)" at 180,930
return
end if
if v<-10 then
draw text "bad landing. Module is damaged, you are lightly wounded." at 180,930
return
end if
if v<-5 then
draw text "Fair landing! At least you are able to return." at 180,930
return
end if
if v<-2 then
draw text "You're an ace! Return to earth to recieve Medal of Honour!" at 180,930
return
end if
end def
def slider (tit$,xt,yt,hgt,xtouch,ytouch,ind)
xb=xt+70 ! if hgt<120 then hgt=120 ! yb=yt+hgt+70 ! dy=hgt/10
if ind=-1 then
fill rect xt-2,yt-2 to xb+2,yb+2 ! return
end if
if ind=1 then
draw size 3 ! draw font size 14
draw rect xt,yt to xb,yb
draw line xt,yt+20 to xb,yt+20
draw text tit$ at xt+(68-8*len(tit$))/2,yb-20
' ys=yb-30 ! ys=560
else
if xtouch<xt or xtouch>xb or ytouch<yt or ytouch>yb then
slider=-1
return
end if
ys=ytouch
if ys<yt+40 then ys=yt+40 ! if ys>yb-30 then ys=yb-30
end if
draw size 2
graphics lock
fill color .8,.8,.8 ! draw font size 14
fill rect xt+2,yt+33 to xb-2,yb-25
draw rect xt+28,yt+40 to xt+32,yb-30
y=yb-30+dy
for i=0 to 100 step 10
y=y-dy ! i$=i
draw line xt+24,y to xt+36,y
draw text i$ at xt+40,y-9
next i
fill color 0,0,.6 ! fill alpha .6
fill rect xt+6,ys-4 to xt+54,ys+4
fill color .8,.8,.8 ! fill alpha 1
tt=(yb-ys-30)*100/(yb-yt-70)
fill rect xt+8,yt+2 to xb-2,yt+15
draw text n2a$(tt,5,1) at xt+8,yt
graphics unlock
draw font size 20
slider=tt
end def
def set_col(col$)
if col$="r" or col$="R" then
draw color 1,0,0 ! fill color 1,0,0
end if
if col$="g" or col$="G" then
draw color 0,.7,0 ! fill color 0,.7,0
end if
if col$="b" or col$="B" then
draw color 0,0,1 ! fill color 0,0,1
end if
if col$="n" or col$="N" then
draw color 0,0,0 ! fill color .8,.8,.8
end if
enddef
def rmeter(tit$,col$,xc,yc,rad,minval,maxval,val,mode)
if mode=-1 then
fill circle xc,yc size rad+2
return
end if
graphics lock
if mode=0 then mode_0
set_col("n")
draw size 3 ! draw circle xc,yc size rad
draw size 4 ! draw circle xc,yc size rad-6
set_col(col$)
draw size 3 ! draw circle xc,yc size rad-3
set_col("n")
draw arc xc,yc,rad-50,130,410
draw size 3
for a=130 to 410 step 28
xs=xc+(rad-50)*cos(a) ! ys=yc+(rad-50)*sin(a)
xe=xc+(rad-42)*cos(a) ! ye=yc+(rad-42)*sin(a)
draw line xs,ys to xe,ye
next a
draw size 1
for a=130 to 410 step 7
xs=xc+(rad-50)*cos(a) ! ys=yc+(rad-50)*sin(a)
xe=xc+(rad-44)*cos(a) ! ye=yc+(rad-44)*sin(a)
draw line xs,ys to xe,ye
next a
delta=(maxval-minval)/10 ! sval=minval
draw font size 15
for a=130 to 410 step 28
xs=xc+(rad-28)*cos(a)-22 ! ys=yc+(rad-28)*sin(a)-10
draw text n2a$(sval,3,0) at xs,ys
sval=sval+delta
next a
draw font size 20
mode_0:
fill circle xc,yc size rad-52
xs=xc+(rad-80)*cos(112) ! ys=yc+(rad-80)*sin(112)
set_col(col$)
fill circle xc,yc size 10 ! draw text tit$ at xs-12,ys
set_col("n")
if val<minval then val=minval
if val>maxval then val=maxval
beta=130+280*(val-minval)/(maxval-minval)
xs=xc-30*cos(beta) ! ys=yc-30*sin(beta)
xe=xc+(rad-54)*cos(beta) ! ye=yc+(rad-54)*sin(beta)
draw size 6 ! draw line xs,ys to xe,ye
graphics unlock
end def
def draw_poly(n,x(),y(),x_pos,y_pos,v,r,g,b,thick)
draw color r,g,b ! draw size thick
graphics lock
if v<0 then v=0
fill rect x_pos-1,y_pos+38+v to x_pos+21,y_pos-60
n=n+1 ! x(n)=x(1) ! y(n)=y(1)
xs=x(1)+x_pos ! ys=y(1)+y_pos
for i=2 to n
xe=x(i)+x_pos ! ye=y(i)+y_pos
draw line xs,ys to xe,ye ! xs=xe ! ys=ye
next i
graphics unlock
end def
def n2a$(num,lang,dec)
b$=" "
fac=10^dec
num$=int(fac*num+.5)/fac
tot=lang-len(num$)
if tot<1 then tot=1
a$=substr$(b$,1,tot) & num$
n2a$=a$
end def
def test (in$,in)
fill rect 30,900 to 400,940
a$="test " & in$ & in
draw text a$ at 30,900
button "cont" title "doorgaan ?" at 440,890
loopje:
if button_pressed("cont")=0 then goto loopje
button "cont" delete
fill rect 30,900 to 400,940
end def
init_prog:
randomize
graphics ! fill color .8,.8,.8 ! draw color 0,0,0
graphics clear .8,.8,.8
height=2300+rnd(700) ! velocity=-rnd(40)
fac=.5 ! np=14
for i=1 to np
read lander_x(i),lander_y(i)
lx(i)=fac*lander_x(i) ! ly(i)=fac*(75-lander_y(i))
next i
data 20,0, 30,0, 30,25, 40,15, 40,0, 30,5, 30,55
data 20,75, 10,55, 10,5, 0,0, 0,15, 10,25, 10,0
read weight,fuel,gravity,maxthrust,gas
data 2000,100,1.6,4000,50
bmin=maxthrust*(weight+100)*sqrt(1.6*height+.5*velocity^2)
bmin=bmin/3200/(maxthrust-weight-100)
ttt=1000 ! reset timer
return
dim lander_x(15),lander_y(15),lx(15),ly(15)
gosub init_prog
fuel=select_level(bmin)
create_gauges(fuel,height,velocity,gas)
draw_poly(14,lx,ly,120,910-3*height/10,0,0,0,0,2)
button "start" title "start" at 324,80 size 120,40
start:
if button_pressed("start")=0 then start
button "start" delete
decending: ' check controls
tx=touch_x(0)
if tx>-1 then
ty=touch_y(0)
gas=slider("throttle",600,280,400,tx,ty,0)
end if
if button_pressed("real") then ttt=1000
if button_pressed("fast") then ttt=ttt/2
if timer()<ttt then decending
reset timer
' flight model (time step is fixed on 1 second)
thrust=gas*maxthrust/100 ! if fuel=0 then thrust=0
df=thrust/2000 ! fuel=fuel-df ! if fuel<0 then fuel=0
fv=thrust-weight-fuel ! acc=fv*gravity/(weight+fuel)
dv=acc ! velocity=velocity+dv
dh=velocity-dv/2 ! height=height+dh ! if height<0 then height=0
' update gauges
rmeter("fuel","g",384,260,120,0,400,fuel,0)
rmeter("meter","r",384,520,120,0,4000,height,0)
rmeter("m/sec","b",384,780,120,-200,200,velocity,0)
' update moon module
draw_poly(14,lx,ly,120,910-3*height/10,velocity,0,0,0,2)
' check on landing
if height>0 then goto decending else landed(velocity)
end
def select_level(bmin)
draw text "select difficulty level" at 260,10
button "easy" title "easy" at 200,40 size 120,30
button "medi" title "medium" at 340,40 size 120,30
button "diff" title "difficult" at 480,40 size 120,30
loop1: level=0
if button_pressed("easy") then level=1
if button_pressed("medi") then level=2
if button_pressed("diff") then level=3
if level=0 then loop1
button "easy" delete ! button "medi" delete ! button "diff" delete
fill rect 260,10 to 560,32
if level=1 then
draw text "easy level" at 320,40 ! select_level=1.6*bmin
else
if level=2 then
draw text "medium level" at 310,40 ! select_level=1.3*bmin
else
draw text "difficult level" at 290,40 ! select_level=1.1*bmin
end if
end if
end def
def create_gauges(b,h,v,gas)
rmeter("fuel","g",384,260,120,0,400,b,1)
rmeter("meter","r",384,520,120,0,4000,h,1)
rmeter("m/sec","b",384,780,120,-200,200,v,1)
slider ("throttle",600,280,400,0,0,1)
draw text "sim-speed" at 590,100
button "real" title "real time" at 525,130 size 100,30
button "fast" title "x2" at 645,130 size 100,30
fill color 0,0,0
fill rect 90,957.5 to 170,970 ! fill rect 110,947.5 to 150,958
fill color .8,.8,.8
end def
def landed(v)
draw font size 15
if v<-20 then
draw text "You made a mess of it! All destroyed and dead." at 180,930
return
end if
if v<-15 then
draw text "You crashed! Module destroyed, you severely wounded (and alone!)" at 180,930
return
end if
if v<-10 then
draw text "bad landing. Module is damaged, you are lightly wounded." at 180,930
return
end if
if v<-5 then
draw text "Fair landing! At least you are able to return." at 180,930
return
end if
if v<-2 then
draw text "You're an ace! Return to earth to recieve Medal of Honour!" at 180,930
return
end if
end def
def slider (tit$,xt,yt,hgt,xtouch,ytouch,ind)
xb=xt+70 ! if hgt<120 then hgt=120 ! yb=yt+hgt+70 ! dy=hgt/10
if ind=-1 then
fill rect xt-2,yt-2 to xb+2,yb+2 ! return
end if
if ind=1 then
draw size 3 ! draw font size 14
draw rect xt,yt to xb,yb
draw line xt,yt+20 to xb,yt+20
draw text tit$ at xt+(68-8*len(tit$))/2,yb-20
' ys=yb-30 ! ys=560
else
if xtouch<xt or xtouch>xb or ytouch<yt or ytouch>yb then
slider=-1
return
end if
ys=ytouch
if ys<yt+40 then ys=yt+40 ! if ys>yb-30 then ys=yb-30
end if
draw size 2
graphics lock
fill color .8,.8,.8 ! draw font size 14
fill rect xt+2,yt+33 to xb-2,yb-25
draw rect xt+28,yt+40 to xt+32,yb-30
y=yb-30+dy
for i=0 to 100 step 10
y=y-dy ! i$=i
draw line xt+24,y to xt+36,y
draw text i$ at xt+40,y-9
next i
fill color 0,0,.6 ! fill alpha .6
fill rect xt+6,ys-4 to xt+54,ys+4
fill color .8,.8,.8 ! fill alpha 1
tt=(yb-ys-30)*100/(yb-yt-70)
fill rect xt+8,yt+2 to xb-2,yt+15
draw text n2a$(tt,5,1) at xt+8,yt
graphics unlock
draw font size 20
slider=tt
end def
def set_col(col$)
if col$="r" or col$="R" then
draw color 1,0,0 ! fill color 1,0,0
end if
if col$="g" or col$="G" then
draw color 0,.7,0 ! fill color 0,.7,0
end if
if col$="b" or col$="B" then
draw color 0,0,1 ! fill color 0,0,1
end if
if col$="n" or col$="N" then
draw color 0,0,0 ! fill color .8,.8,.8
end if
enddef
def rmeter(tit$,col$,xc,yc,rad,minval,maxval,val,mode)
if mode=-1 then
fill circle xc,yc size rad+2
return
end if
graphics lock
if mode=0 then mode_0
set_col("n")
draw size 3 ! draw circle xc,yc size rad
draw size 4 ! draw circle xc,yc size rad-6
set_col(col$)
draw size 3 ! draw circle xc,yc size rad-3
set_col("n")
draw arc xc,yc,rad-50,130,410
draw size 3
for a=130 to 410 step 28
xs=xc+(rad-50)*cos(a) ! ys=yc+(rad-50)*sin(a)
xe=xc+(rad-42)*cos(a) ! ye=yc+(rad-42)*sin(a)
draw line xs,ys to xe,ye
next a
draw size 1
for a=130 to 410 step 7
xs=xc+(rad-50)*cos(a) ! ys=yc+(rad-50)*sin(a)
xe=xc+(rad-44)*cos(a) ! ye=yc+(rad-44)*sin(a)
draw line xs,ys to xe,ye
next a
delta=(maxval-minval)/10 ! sval=minval
draw font size 15
for a=130 to 410 step 28
xs=xc+(rad-28)*cos(a)-22 ! ys=yc+(rad-28)*sin(a)-10
draw text n2a$(sval,3,0) at xs,ys
sval=sval+delta
next a
draw font size 20
mode_0:
fill circle xc,yc size rad-52
xs=xc+(rad-80)*cos(112) ! ys=yc+(rad-80)*sin(112)
set_col(col$)
fill circle xc,yc size 10 ! draw text tit$ at xs-12,ys
set_col("n")
if val<minval then val=minval
if val>maxval then val=maxval
beta=130+280*(val-minval)/(maxval-minval)
xs=xc-30*cos(beta) ! ys=yc-30*sin(beta)
xe=xc+(rad-54)*cos(beta) ! ye=yc+(rad-54)*sin(beta)
draw size 6 ! draw line xs,ys to xe,ye
graphics unlock
end def
def draw_poly(n,x(),y(),x_pos,y_pos,v,r,g,b,thick)
draw color r,g,b ! draw size thick
graphics lock
if v<0 then v=0
fill rect x_pos-1,y_pos+38+v to x_pos+21,y_pos-60
n=n+1 ! x(n)=x(1) ! y(n)=y(1)
xs=x(1)+x_pos ! ys=y(1)+y_pos
for i=2 to n
xe=x(i)+x_pos ! ye=y(i)+y_pos
draw line xs,ys to xe,ye ! xs=xe ! ys=ye
next i
graphics unlock
end def
def n2a$(num,lang,dec)
b$=" "
fac=10^dec
num$=int(fac*num+.5)/fac
tot=lang-len(num$)
if tot<1 then tot=1
a$=substr$(b$,1,tot) & num$
n2a$=a$
end def
def test (in$,in)
fill rect 30,900 to 400,940
a$="test " & in$ & in
draw text a$ at 30,900
button "cont" title "doorgaan ?" at 440,890
loopje:
if button_pressed("cont")=0 then goto loopje
button "cont" delete
fill rect 30,900 to 400,940
end def
init_prog:
randomize
graphics ! fill color .8,.8,.8 ! draw color 0,0,0
graphics clear .8,.8,.8
height=2300+rnd(700) ! velocity=-rnd(40)
fac=.5 ! np=14
for i=1 to np
read lander_x(i),lander_y(i)
lx(i)=fac*lander_x(i) ! ly(i)=fac*(75-lander_y(i))
next i
data 20,0, 30,0, 30,25, 40,15, 40,0, 30,5, 30,55
data 20,75, 10,55, 10,5, 0,0, 0,15, 10,25, 10,0
read weight,fuel,gravity,maxthrust,gas
data 2000,100,1.6,4000,50
bmin=maxthrust*(weight+100)*sqrt(1.6*height+.5*velocity^2)
bmin=bmin/3200/(maxthrust-weight-100)
ttt=1000 ! reset timer
return