REM Project: breakout
REM Created: 4/10/2005 8:23:57 PM
REM by Coding Fodder
REM ***** Main Source File *****
REM
sync on:sync rate 0
set display mode 1024,768,32
backdrop on
color backdrop 0
hide mouse
 
type brick
   kind as integer
   strength as integer
endtype
 
type ball
   kind as integer
   strength as integer
   captured as boolean
   vx as float
   vy as float
   x as float
   y as float
   t0 as integer
endtype
 
type paddles
   kind as string
   width as float
   angle as float
   xpos as float
endtype
 
type item
   kind as string
   x as float
   y as float
   t0 as float
endtype
 
type particle
   color as integer
   x as float
   y as float
   vx as float
   vy as float
   t0 as integer
endtype
 
type events
   ball as integer
   kind as integer
   time as integer
   dx as integer
   dy as integer
endtype
 
#Constant G=0.0002
 
Global Number_of_paddles
Global Number_of_balls
Global Number_of_items
Global Number_of_bricks
Global Number_of_particles
Global Score
global paddle as paddles
global event as events
global game_time
global start_time
global event_time
global level_done
 
dim bricks(15,20) as brick
dim balls(10) as ball
dim items(10) as item
dim particles(10000) as particle
start_time=timer()
game_time=timer()
 
create_brick(1,1,1,0)
create_brick(2,0,1,0)
create_brick(3,0,0,1)
create_brick(4,1,1,1)
 
 
create_paddle()
add_paddle()
add_paddle()
add_paddle()
create_ball()
add_ball(0,0,0,0)
for i=1 to 4
add_paddle()
level_done=0
create_level(i)
balls(1).captured=1
balls(1).kind=1
DO
   game_clock()
   if check_for_event()=1
      execute_event()
      calculate_next_event()
   endif
   draw_bricks()
   get_inputs()
   draw_paddle()
   draw_balls()
   draw_particles()
   draw_items()
   text 1,1,str$(screen fps())
   text 500,1,"SCORE "+str$(score)
   sync
   if level_done=1 then exit
LOOP
next t
 
function draw_items()
   for i=1 to number_of_items
      y#=arc_move(game_time,items(i).t0,items(i).y,0.0)
      x#=items(i).x-4
      text x#,y#,items(i).kind
      if y#>768 then remove_item(i)
      if y#>695
         left#=mousex()-paddle.width/2-5
         right#=mousex()+paddle.width/2+5
         if x#>left# and x#<right#
            if items(i).kind="T"
               for j=1 to number_of_balls
                  balls(j).kind=2
               next i
            endif
            if items(i).kind="P"
               for j=1 to number_of_balls
                  balls(j).kind=3
               next i
            endif
            if items(i).kind="B" then `add_ball(0,0,0,0)
            if items(i).kind="L" then paddle.width=paddle.width+20
            remove_item(i)
         endif
      endif
   next i
endfunction
 
function draw_particles()
   lock pixels
      for i=1 to number_of_particles
         x#=lin_move(game_time,particles(i).t0,particles(i).x,particles(i).vx)
         y#=arc_move(game_time,particles(i).t0,particles(i).y,particles(i).vy)
 
         if y#>0
            if y#<768 and x#>0 and x#<1024
               set_locked_pixel(x#,y#,rgb(255,255,0))
            else
               remove_particle(i)
            endif
         endif
      next i
   unlock pixels
endfunction
 
function execute_event()
chx=1
chy=1
   if event.dy=700
      left#=mousex()-paddle.width/2-5
      right#=mousex()+paddle.width/2+5
      balls(event.ball).x=lin_move(event.time,balls(event.ball).t0,balls(event.ball).x,balls(event.ball).vx)
      balls(event.ball).y=lin_move(event.time,balls(event.ball).t0,balls(event.ball).y,balls(event.ball).vy)
      balls(event.ball).t0=event.time
      if balls(event.ball).x>left# and balls(event.ball).x<right#
         angle#=(mousex()-balls(event.ball).x)/paddle.width*85.0
         balls(event.ball).vx=-sin(angle#)*0.3
         balls(event.ball).vy=-cos(angle#)*0.3
         score=score-10
      else
         remove_ball(event.ball)
      endif
   endif
   if balls(event.ball).kind=2 and event.dx>0 then event.kind=-1
   if event.kind=1
      balls(event.ball).x=lin_move(event.time,balls(event.ball).t0,balls(event.ball).x,balls(event.ball).vx)
      balls(event.ball).y=lin_move(event.time,balls(event.ball).t0,balls(event.ball).y,balls(event.ball).vy)
      balls(event.ball).t0=event.time
      balls(event.ball).vx=-balls(event.ball).vx
      chx=-1
   endif
   if event.kind=2
      balls(event.ball).x=lin_move(event.time,balls(event.ball).t0,balls(event.ball).x,balls(event.ball).vx)
      balls(event.ball).y=lin_move(event.time,balls(event.ball).t0,balls(event.ball).y,balls(event.ball).vy)
      balls(event.ball).t0=event.time
      balls(event.ball).vy=-balls(event.ball).vy
      chy=-1
   endif
   if balls(event.ball).kind=3 and event.dx>0 then event.kind=-2
   if event.dx>0
      if event.kind<0 and event.dx>0 and event.dx<16 and event.dy>0 and event.dy<21
         score=score+(bricks(event.dx,event.dy).strength-1)*10
         bricks(event.dx,event.dy).strength=1
      endif
      if bricks(event.dx,event.dy).strength<4
         dec bricks(event.dx,event.dy).strength
         score=score+10
      endif
      if bricks(event.dx,event.dy).strength=0
         remove_brick(event.dx,event.dy)
         score=score+90
         for i= 1 to 15
            for j=1 to 20
               if bricks(i,j).kind>0 and bricks(i,j).kind<4 then inc bricksleft
            next j
         next i
         if bricksleft=0 then level_done=1
         lock pixels
         for i=(event.dx-1)*68 to event.dx*68 step 3
            for j=(event.dy-1)*20 to event.dy*20 step 3
               add_particle(rgb(255,255,0),i,j,balls(event.ball).vx*((rnd(150)/100.0)+0.5)*chx,balls(event.ball).vy*((rnd(150)/100.0)+0.5)*chy)
            next j
         next i
         if event.kind=-2
            for u=event.dx-1 to event.dx+1
               for v=event.dy-1 to event.dy+1
                  if u>0 and u<16 and v>0 and v<21
                     if bricks(u,v).strength>0
                        score=score+(bricks(u,v).strength-1)*10+100
                        remove_brick(u,v)
                     endif
                  endif
               next v
            next u
         endif
         unlock pixels
      endif
   endif
 
endfunction
 
function lin_move(t,t0,x0#,vx#)
   x#=vx#*(t-t0)+x0#
endfunction x#
 
function arc_move(t,t0,x0#,vx#)
   x#=vx#*(t-t0)+g*(t-t0)^2.0+x0#
endfunction x#
 
function calculate_next_event()
   time=20000
   time3=20000
   event.ball=0
   event.kind=-1
   event.dx=0
   event.dy=0
   for i=1 to number_of_balls
      if balls(i).vx<0
         time2=balls(i).t0+(5.0-balls(i).x)/balls(i).vx
         if time2-game_time<time
            time=time2-game_time
            event.kind=1
            event.ball=i
         endif
         for j=15 to 1 step -1
 
         next j
      endif
      if balls(i).vx>0
         time2=balls(i).t0+(1019.0-balls(i).x)/balls(i).vx
         if time2-game_time<time
            time=time2-game_time
            event.kind=1
            event.ball=i
         endif
      endif
      if balls(i).vy<0
         time2=balls(i).t0+(5.0-balls(i).y)/balls(i).vy
         if time2-game_time<time
            time=time2-game_time
            event.kind=2
            event.ball=i
         endif
      endif
      if balls(i).vy>0
         time2=balls(i).t0+(695.0-balls(i).y)/balls(i).vy
         if time2-game_time<time
            time=time2-game_time
            event.kind=-1
            event.ball=i
            event.dy=700
         endif
      endif
 
      for j=1 to 15
         if balls(i).vx>0.0
            time2=balls(i).t0+(j*68-5-balls(i).x)/balls(i).vx
            if time2-game_time>0 and time2-game_time<time and time2-game_time<time3
               x#=j*68-5
               y#=lin_move(time2,balls(i).t0,balls(i).y,balls(i).vy)
               x=j+1
               y=int(y#/20)+1
               if x<16 and x>0 and y>0 and y<21
               if bricks(x,y).kind>0
                  time3=time2-game_time
                  event.dx=x
                  event.dy=y
                  event.kind=1
               endif
               endif
            endif
         endif
         if balls(i).vx<0.0
            time2=balls(i).t0+(j*68+5-balls(i).x)/balls(i).vx
            if time2-game_time>0 and time2-game_time<time and time2-game_time<time3
               x#=j*68-5
               y#=lin_move(time2,balls(i).t0,balls(i).y,balls(i).vy)
               x=j
               y=int(y#/20)+1
               if x<16 and x>0 and y>0 and y<21
               if bricks(x,y).kind>0
                  time3=time2-game_time
                  event.dx=x
                  event.dy=y
                  event.kind=1
               endif
               endif
            endif
         endif
      next j
      for j=1 to 20
         if balls(i).vy>0.0
            time2=balls(i).t0+(j*20-5-balls(i).y)/balls(i).vy
            if time2-game_time>0 and time2-game_time<time and time2-game_time<time3
               y#=j*20-5
               x#=lin_move(time2,balls(i).t0,balls(i).x,balls(i).vx)
               y=j+1
               x=int(x#/68)+1
               if x<16 and x>0 and y>0 and y<21
               if bricks(x,y).kind>0
                  time3=time2-game_time
                  event.dx=x
                  event.dy=y
                  event.kind=2
               endif
               endif
            endif
         endif
         if balls(i).vy<0.0
            time2=balls(i).t0+(j*20+5-balls(i).y)/balls(i).vy
            if time2-game_time>0 and time2-game_time<time and time2-game_time<time3
               y#=j*20-5
               x#=lin_move(time2,balls(i).t0,balls(i).x,balls(i).vx)
               y=j
               x=int(x#/68)+1
               if x<16 and x>0 and y>0 and y<21
               if bricks(x,y).kind>0
                  time3=time2-game_time
                  event.dx=x
                  event.dy=y
                  event.kind=2
               endif
               endif
            endif
         endif
      next j
   next i
   if time3<time then time=time3
   event.time=time+game_time
endfunction
 
function check_for_event()
   if event.kind<>0
   if game_time>=event.time
      out=1
      game_time=event.time
   endif
   endif
endfunction out
 
function game_clock()
   time=timer()
   if time<start_time then time=time+86400000
   game_time=time-start_time
endfunction
 
function draw_balls()
   for i=1 to number_of_balls
      if balls(i).captured=1
         paste sprite 11,balls(i).x-5,balls(i).y-5
      else
         x#=lin_move(game_time,balls(i).t0,balls(i).x,balls(i).vx)-5
         y#=lin_move(game_time,balls(i).t0,balls(i).y,balls(i).vy)-5
         paste sprite 11,x#,y#
         if y#>780 then remove_ball(i)
      endif
   next i
endfunction
 
function create_ball()
   cls
   lock pixels
   for i=1 to 10
      for j=1 to 10
         if (5-i)^2+(5-j)^2<=25 then set_locked_pixel(i,j,rgb(150,150,150))
      next j
   next i
   unlock pixels
   get image 11,1,1,10,10
   sprite 11,20,20,11
   hide sprite 11
endfunction
 
function get_inputs()
   `angle=paddle.angle+mousemovez()/10.0
   if angle<45 and angle>-45 then paddle.angle=angle
   for i=1 to number_of_balls
      if balls(i).captured=1
         balls(i).x=mousex()+(5*(sin(paddle.angle)))
         balls(i).y=695+abs(5*(sin(paddle.angle)))
         if mouseclick()>0
            balls(i).captured=0
            balls(i).t0=game_time
            balls(i).vx=sin(paddle.angle)*0.3
            balls(i).vy=-cos(paddle.angle)*0.3
            calculate_next_event()
         endif
      endif
   next i
endfunction
 
function draw_paddle()
   rotate sprite 10,paddle.angle
   stretch sprite 10,paddle.width/50.0*100.0,100
   paste sprite 10,mousex()-paddle.width/2+(paddle.width/2*(1-cos(paddle.angle))),700-(paddle.width/2*(sin(paddle.angle)))
endfunction
 
function create_paddle()
   cls
   lock pixels
   for i=1 to 50
      for j=1 to 10
         set_locked_pixel(i,j,rgb(200,0,0))
      next j
   next i
   unlock pixels
   get image 10,1,1,50,10
   sprite 10,20,20,10
   hide sprite 10
   paddle.width=50
endfunction
 
function create_level(difficulty)
   for i=1 to 15
      for j=1 to 20
         add_brick(rnd(difficulty),i,j)
      next j
   next i
endfunction
 
Function Add_Brick(kind,x,y)
   `if bricks(x,y).kind=0
      inc number_of_bricks
      bricks(x,y).kind=kind
      select kind
         case 1:bricks(x,y).strength=1:endcase
         case 2:bricks(x,y).strength=2:endcase
         case 3:bricks(x,y).strength=3:endcase
         case 4:bricks(x,y).strength=4:endcase
      endselect
   `endif
endfunction
 
function Add_ball(x#,y#,vx#,vy#)
   if number_of_balls<10
      inc number_of_balls
      balls(number_of_balls).kind=1
      balls(number_of_balls).x=x#
      balls(number_of_balls).y=y#
      balls(number_of_balls).vx=vx#
      balls(number_of_balls).vy=vy#
      if x#=0 and y#=0 then balls(number_of_balls).captured=1
   endif
endfunction
 
function Add_item(kind,x#,y#)
   if number_of_items<10
   inc number_of_items
   items(number_of_items).t0=game_time
   items(number_of_items).x=x#
   items(number_of_items).y=y#
   if kind=1 then items(number_of_items).kind="T"
   if kind=2 then items(number_of_items).kind="P"
   if kind=3 then items(number_of_items).kind="B"
   if kind=4 then items(number_of_items).kind="L"
   endif
endfunction
 
function remove_item(num)
   dec number_of_items
   for i=num to number_of_items
      items(i).t0=items(i+1).t0
      items(i).x=items(i+1).x
      items(i).y=items(i+1).y
      items(i).kind=items(i+1).kind
   next i
endfunction
 
function add_paddle()
   inc number_of_paddles
endfunction
 
function add_particle(color,x#,y#,vx#,vy#)
   if number_of_particles<10000
   inc number_of_particles
   particles(number_of_particles).color=color
   particles(number_of_particles).x=x#
   particles(number_of_particles).y=y#
   particles(number_of_particles).vx=vx#
   particles(number_of_particles).vy=vy#
   particles(number_of_particles).t0=game_time
   endif
endfunction
 
function remove_brick(x,y)
   bricks(x,y).kind=0
   if rnd(10)=5 then add_item(rnd(4),(x-1)*68+34.0,y*20+10.0)
endfunction
 
function remove_ball(num)
   dec number_of_balls
   if number_of_balls>=num
      for i=num to number_of_balls
         balls(i).kind=balls(i+1).kind
         balls(i).t0=balls(i+1).t0
         balls(i).x=balls(i+1).x
         balls(i).y=balls(i+1).y
         balls(i).vx=balls(i+1).vx
         balls(i).vy=balls(i+1).vy
      next i
   endif
   if number_of_balls<=0 then remove_paddle()
endfunction
 
function remove_paddle()
   dec number_of_paddles
   paddle.width=50
   if number_of_paddles=0 then endgame()
   add_ball(0,0,0,0)
endfunction
 
function remove_particle(num)
   dec number_of_particles
   for i=num to number_of_particles
      particles(i).color=particles(i+1).color
      particles(i).x=particles(i+1).x
      particles(i).y=particles(i+1).y
      particles(i).vx=particles(i+1).vx
      particles(i).vy=particles(i+1).vy
      particles(i).t0=particles(i+1).t0
   next i
endfunction
 
function draw_bricks()
   for i=1 to 15
      for j=1 to 20
         if bricks(i,j).kind=1 then paste sprite 1,(i-1)*68,(j-1)*20
         if bricks(i,j).kind=2 then paste sprite 2,(i-1)*68,(j-1)*20
         if bricks(i,j).kind=3 then paste sprite 3,(i-1)*68,(j-1)*20
         if bricks(i,j).kind=4 then paste sprite 4,(i-1)*68,(j-1)*20
      next j
   next i
endfunction
 
function create_brick(num,red,green,blue)
   lock pixels
   for i=1 to 67
      for j=1 to 19
         set_locked_pixel(i,j,rgb(red*(200+abs(34-i)+abs(10-j)),green*(200+abs(34-i)+abs(10-j)),blue*(200+abs(34-i)+abs(10-j))))
      next j
   next i
   unlock pixels
   get image num,1,1,68,20
   sprite num,20,20,num
   hide sprite num
endfunction
 
function endgame()
   end
endfunction
 
function get_locked_pixel(x,y)
   start=get pixels pointer()
   repeat_number=get pixels pitch()
   bits_per_pixel=bitmap depth(num)/8
   pointer=start+y*repeat_number+x*bits_per_pixel
   result=*pointer
endfunction result
 
function set_locked_pixel(x,y,color_value)
   start=get pixels pointer()
   repeat_number=get pixels pitch()
   bits_per_pixel=bitmap depth(num)/8
   pointer=start+y*repeat_number+x*bits_per_pixel
   *pointer=color_value
endfunction