set display mode 800,600,32
sync on
sync rate 60
 
Start:
 
 
 
Scroll as float = 0
 
rem *** Airplane ***
type AirplaneType
   X as float
   Y as float
   Speed as float
   MinSpeed as float
   MaxSpeed as float
   SpeedX as float
   SpeedY as float
   Angle as float
endtype
global Airplane as AirplaneType
CreateAirplane()
 
rem Level/Score
global Level as integer = 1
global Score as integer = 0
 
ResetAirplane()
BuildLevel()
 
 
do
   cls
 
   ink 0xFFFFFFFF, 0
   print "FPS: ", screen fps()
   print "Scroll: ", str$(Scroll,0)
   print "Level: ", Level
   print "Rings: ", RingsPassed
   print
   print "SCORE: ", Score
 
   ControlAirplane()
   UpdateAirplane()
   DrawAirplane(Scroll)
 
   Scroll = Airplane.X-300
 
   ShowMatrix(Scroll)
   ShowRings(Scroll)
 
   sync
loop
 
 
 
 
 
 
 
 
 
 
 
 
function CreateRings(Rings,MaxY)
   rem Variables
   global RingCount as integer : RingCount = Rings
   global RingHeight as integer = 50
   global RingsPassed as integer = 0
   rem Array
   dim Ring(Rings) as RingType
   for r = 1 to Rings
      Ring(r).X = 500 + rnd(MaxPosX-500)
      Ring(r).Y = 100 + rnd(MaxY-100)
      Ring(r).C = rnd(0xFFFFFF)
      Ring(r).Passed = 0
      Ring(r).Size = RingHeight
   next r
endfunction
 
   type RingType
      X as integer
      Y as integer
      C as dword `Color
      Passed as boolean `if the airplane already scrolled out of the screen
      Size as integer `Size increases when a ring is hit
   endtype
 
function CreateMatrix(Segments,Min,Max,SegSizeX)
   rem Variables
   global SegmentSizeX as integer : SegmentSizeX = SegSizeX
   global SegmentCount as integer : SegmentCount = Segments
   global MaxPosX as integer : MaxPosX = Segments*SegSizeX
   rem Create Terrain
   dim Matrix(Segments) as integer
   Matrix(0) = Max
   Height = (Min + Max)/2
   MaxDif = (Max - Min)/10
   for s = 1 to Segments
      Height = Height + MaxDif - rnd(MaxDif*2)
      if Height < Min then Height = Min
      if Height > Max then Height = Max
      Matrix(s) = Height
   next s
   Matrix(Segments)=Max
endfunction
 
function ShowRings(Scroll)
   sw = screen width()
   for r = 1 to RingCount
      xp = Ring(r).X - Scroll
      if xp>-20 or sp<sw+20
         ink Ring(r).C, 0
         ellipse xp, Ring(r).Y, Ring(r).Size*0.4, Ring(r).Size
      endif
   next r
endfunction
 
function ShowMatrix(Scroll)
   pos2 = -Scroll
   sw = screen width()
   for s = 1 to SegmentCount
      pos1 = pos2
      pos2 = s*SegmentSizeX - Scroll
      if pos2 > 0 and pos1 < sw
         line pos1,Matrix(s-1),pos2,Matrix(s)
      endif
   next s
endfunction
 
function UpdateAirplaneSpeed()
   Airplane.SpeedX = sin(Airplane.Angle)*Airplane.Speed
   Airplane.SpeedY = cos(Airplane.Angle)*Airplane.Speed
endfunction
 
function ControlAirplane()
   rl = rightkey()-leftkey()
   ud = upkey()-downkey()
   if rl<>0
      Airplane.Angle = wrapvalue(Airplane.Angle-rl*2.3)
   endif
   if ud<>0
      Airplane.Speed = Airplane.Speed + ud*0.1
      if Airplane.Speed < Airplane.MinSpeed then Airplane.Speed = Airplane.MinSpeed
      if Airplane.Speed > Airplane.MaxSpeed then Airplane.Speed = Airplane.MaxSpeed
   endif
   if ud or rl then UpdateAirplaneSpeed()
endfunction
 
function UpdateAirplane()
   rem Gravity
   AirPlane.Angle = wrapvalue(AirPlane.Angle - (180-AirPlane.Angle)/360.0)
   UpdateAirplaneSpeed()
   rem Position
   inc Airplane.X, Airplane.SpeedX
   inc Airplane.Y, Airplane.SpeedY
   rem Rings
   for r = 1 to RingCount
      if Ring(r).Passed=0
         xdis = Airplane.X - Ring(r).X
         ydis = Airplane.Y - Ring(r).Y
         if abs(xdis)<20
            Ring(r).Passed=1
            if abs(ydis)<RingHeight
               inc RingsPassed
               inc Score, Airplane.Speed*10
               inc Ring(r).Size
            endif
         endif
      else
         if Ring(r).Size>RingHeight and Ring(r).Size<RingHeight*3
            inc Ring(r).Size
         endif
      endif
   next r
   rem Win
   if Airplane.X > MaxPosX+100
      Nextlevel()
   endif
   rem Crash
   ycol = GetMatrixHeight(Airplane.X)-20
   if Airplane.Y > ycol then PlayerLost(1)
endfunction
 
function GetMatrixHeight(X)
   for s = 1 to SegmentCount
      if s*SegmentSizeX > X then h = Matrix(s) : exitfunction h
   next s
   sh = screen height()
endfunction sh
 
function DrawAirplane(Scroll)
   xp = Airplane.X - Scroll
   yp = Airplane.Y
   rotate sprite 1, 90-Airplane.Angle
   paste sprite 1, xp, yp
endfunction
 
function NextLevel()
   rem Defeat
   if RingsPassed < RingCount/2
      PlayerLost(0)
   endif
   rem Victory
   cls rgb(0,0,90)
   ink 0xFFFFFF00,0
   x = screen width()/2
   center text x, 100, "You successfuly finished Level "+str$(Level)+"!"
   center text x, 140, "Rings hit: "+str$(RingsPassed)+"/"+str$(RingCount)
   center text x, 180, "Your score: "+str$(Score)
   center text x, 300, "- Press spacekey to continue -"
   sync
   wait 1000
   repeat : until spacekey()=1
   rem New level
   inc Level
   ResetAirplane()
   BuildLevel()
   inc Airplane.MinSpeed, 0.5
   inc Airplane.MaxSpeed, 0.5
endfunction
 
function PlayerLost(Crash as boolean)
   cls rgb(90,0,0)
   ink 0xFF00FFFF,0
   x = screen width()/2
   if Crash
      center text x, 100, "You crashed into the terrain!"
   else
      center text x, 100, "You didn't hit enough rings!"
   endif
   center text x, 140, "Rings hit: "+str$(RingsPassed)+"/"+str$(RingCount)
   center text x, 180, "Your score: "+str$(Score)
   center text x, 300, "- Press spacekey to end, return to restart -"
   sync
   wait 1000
   do
      if spacekey()=1 then end
      if returnkey()=1 then goto Start
   loop
endfunction
 
 
function ResetAirplane()
   AirPlane.X = 0
   Airplane.Y = 200
   Airplane.Angle = 90 `Angle clockwise from top -> 90 = to the right side
   Airplane.MaxSpeed = 6.5
   Airplane.MinSpeed = 2.8
   Airplane.Speed = (Airplane.MaxSpeed+Airplane.MinSpeed)/2
   UpdateAirplaneSpeed()
   rotate sprite 1, 0
endfunction
 
function BuildLevel()
   CreateMatrix(50+10*Level,300+100/Level,600,60)
   CreateRings(10+3*Level,320)
endfunction
 
 
function CreateAirplane()
   cls 0
   ink rgb(255,255,255),0
   line 10,10,70,10
   line 10,10, 8, 8
   line  8, 8, 6, 2
   line  6, 2, 4, 1
   line  4, 1, 2, 1
   line  2, 1, 1, 4
   line  1, 4, 1,15
   line  1,15, 3,17
   line  3,17, 7,18
   line  7,18,10,19
   line  7,18,5,20
   circle 3,22,3
   line 10,19,30,23
   line 30,23,40,25
   line 40,25,65,20
   line 65,20,69,15
   line 69,15,71,12
   line 71,12,70,10
   rem Seat-Thing
   line 30,10,36, 7
   line 36, 7,38,10
   rem Wings
   line 34, 4,54, 4
   line 34,28,54,28
   line 39, 4,39,28
   line 50, 4,50,28
   rem Wheel
   line 55,23,60,28
   circle 60,28,3
   rem Rotor
   line 71,12,73,12
   line 73, 3,73,21
   rem Get image
   get image 1, 0,0,75,35, 1
   sprite 1, 0,0, 1
   hide sprite 1
   offset sprite 1, sprite width(1)/2, sprite height(1)/2
   set sprite 1, 0,1
endfunction