Advertisement
Krystman

Pico-8 Hero - Breakout - End of Ep. 19

Mar 10th, 2017
854
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 9.14 KB | None | 0 0
  1. --goals
  2. -- todo: explosions do not
  3. --       trigger combos!
  4.  
  5. -- 6. (powerups)
  6. -- 7. juicyness
  7. --     arrow anim
  8. --     text blinking
  9. --     particles
  10. --     screenshake
  11. -- 8. high score
  12.  
  13. function _init()
  14.  cls()
  15.  mode="start"
  16.  level=""
  17.  debug=""
  18.  levelnum = 1
  19.  levels={}
  20.  --levels[1] = "x5b"
  21.  levels[2] = "x4b"
  22.  --levels[1] = "hxixsxpxbxbxbxbxbxbxbxbxbxbxbxbxbxbxbxbxbxbxbxbxbxbxbxbxbxbxbxbxbxbxbxbxb"
  23.  levels[1] = "////x4b/s9s"
  24. end
  25.  
  26. function _update60()
  27.  if mode=="game" then
  28.   update_game()
  29.  elseif mode=="start" then
  30.   update_start()
  31.  elseif mode=="gameover" then
  32.   update_gameover()
  33.  elseif mode=="levelover" then
  34.   update_levelover()
  35.  end
  36. end
  37.  
  38. function update_start()
  39.  if btnp(4) then
  40.   startgame()
  41.  end
  42. end
  43.  
  44. function startgame()
  45.  mode="game"
  46.  ball_r=2
  47.  ball_dr=0.5
  48.  
  49.  pad_x=52
  50.  pad_y=120
  51.  pad_dx=0
  52.  pad_w=24
  53.  pad_h=3
  54.  pad_c=7
  55.  
  56.  brick_w=9
  57.  brick_h=4
  58.  
  59.  levelnum = 1
  60.  level = levels[levelnum]
  61.  buildbricks(level)
  62.  --brick_y=20
  63.  
  64.  lives=3
  65.  points=0
  66.  
  67.  sticky=true
  68.  
  69.  chain=1 --combo chain multiplier
  70.  
  71.  serveball()
  72. end
  73.  
  74. function nextlevel()
  75.  mode="game"
  76.  pad_x=52
  77.  pad_y=120
  78.  pad_dx=0
  79.  
  80.  levelnum+=1
  81.  if levelnum > #levels then
  82.   -- we've beaten the gane
  83.   -- we need some kind of special
  84.   -- screen here
  85.   mode="start"
  86.   return
  87.  end
  88.  level=levels[levelnum]
  89.  buildbricks(level)
  90.  
  91.  sticky=true
  92.  chain=1
  93.  
  94.  serveball()
  95. end
  96.  
  97. function buildbricks(lvl)
  98.  local i,j,o,chr,last
  99.  brick_x={}
  100.  brick_y={}
  101.  brick_v={}
  102.  brick_t={}
  103.  
  104.  j=0
  105.  -- b = normal brick
  106.  -- x = empty space
  107.  -- i = indestructable brick
  108.  -- h = hardened brick
  109.  -- s = sploding brick
  110.  -- p = powerup brick
  111.  
  112.  for i=1,#lvl do
  113.   j+=1
  114.   chr=sub(lvl,i,i)  
  115.   if chr=="b"
  116.   or chr=="i"
  117.   or chr=="h"
  118.   or chr=="s"
  119.   or chr=="p" then
  120.    last=chr
  121.    addbrick(j,chr)  
  122.   elseif chr=="x" then
  123.    last="x"
  124.   elseif chr=="/" then
  125.    j=(flr((j-1)/11)+1)*11
  126.   elseif chr>="1" and chr<="9" then
  127.    for o=1,chr+0 do
  128.     if last=="b"
  129.     or last=="i"
  130.     or last=="h"
  131.     or last=="s"
  132.     or last=="p" then
  133.         addbrick(j,last)
  134.     elseif last=="x" then
  135.      --nothing
  136.     end
  137.     j+=1
  138.    end
  139.    j-=1
  140.   end
  141.  end
  142. end
  143.  
  144. function addbrick(_i,_t)
  145.  add(brick_x,4+((_i-1)%11)*(brick_w+2))
  146.  add(brick_y,20+flr((_i-1)/11)*(brick_h+2))
  147.  add(brick_v,true)
  148.  add(brick_t,_t)
  149. end
  150.  
  151. function levelfinished()
  152.  if #brick_v == 0 then return true end
  153.  
  154.  for i=1,#brick_v do
  155.   if brick_v[i] == true and brick_t[i] != "i" then
  156.    return false
  157.   end
  158.  end
  159.  return true
  160. end
  161.  
  162. function serveball()
  163.  ball_x=pad_x+flr(pad_w/2)
  164.  ball_y=pad_y-ball_r
  165.  ball_dx=1
  166.  ball_dy=-1
  167.  ball_ang=1
  168.  chain=1
  169.  
  170.  sticky=true
  171.  --0.50
  172.  --1.30
  173. end
  174.  
  175. function setang(ang)
  176.  ball_ang=ang
  177.  if ang==2 then
  178.   ball_dx=0.50*sign(ball_dx)
  179.   ball_dy=1.30*sign(ball_dy)  
  180.  elseif ang==0 then
  181.   ball_dx=1.30*sign(ball_dx)
  182.   ball_dy=0.50*sign(ball_dy)
  183.  else
  184.   ball_dx=1*sign(ball_dx)
  185.   ball_dy=1*sign(ball_dy)
  186.  end
  187. end
  188.  
  189. function sign(n)
  190.  if n<0 then
  191.   return -1
  192.  elseif n>0 then
  193.   return 1
  194.  else
  195.   return 0
  196.  end
  197. end
  198.  
  199. function gameover()
  200.  mode="gameover"
  201. end
  202.  
  203. function levelover()
  204.  mode="levelover"
  205. end
  206.  
  207. function update_gameover()
  208.  if btnp(4) then
  209.   startgame()
  210.  end
  211. end
  212.  
  213. function update_levelover()
  214.  if btnp(4) then
  215.   nextlevel()
  216.  end
  217. end
  218.  
  219. function update_game()
  220.  local buttpress=false
  221.  local nextx,nexty,brickhit
  222.  
  223.  if btn(0) then
  224.   --left
  225.   pad_dx=-2.5
  226.   buttpress=true
  227.   --pad_x-=5
  228.   if sticky then
  229.    ball_dx=-1
  230.   end
  231.  end
  232.  if btn(1) then
  233.   --right
  234.   pad_dx=2.5
  235.   buttpress=true
  236.   --pad_x+=5
  237.   if sticky then
  238.    ball_dx=1
  239.   end
  240.  end
  241.  if sticky and btnp(4) then
  242.   sticky=false
  243.  end
  244.  
  245.  if not(buttpress) then
  246.   pad_dx=pad_dx/1.3
  247.  end
  248.  pad_x+=pad_dx
  249.  pad_x=mid(0,pad_x,127-pad_w)
  250.  
  251.  if sticky then
  252.   ball_x=pad_x+flr(pad_w/2)
  253.   ball_y=pad_y-ball_r-1
  254.  else
  255.   --regular ball physics
  256.   nextx=ball_x+ball_dx
  257.   nexty=ball_y+ball_dy
  258.  
  259.   if nextx > 124 or nextx < 3 then
  260.    nextx=mid(0,nextx,127)
  261.    ball_dx = -ball_dx
  262.    sfx(0)
  263.   end
  264.   if nexty < 10 then
  265.    nexty=mid(0,nexty,127)
  266.    ball_dy = -ball_dy
  267.    sfx(0)
  268.   end
  269.  
  270.   -- check if ball hit pad
  271.   if ball_box(nextx,nexty,pad_x,pad_y,pad_w,pad_h) then
  272.    -- deal with collision
  273.    if deflx_ball_box(ball_x,ball_y,ball_dx,ball_dy,pad_x,pad_y,pad_w,pad_h) then
  274.     --ball hit paddle on the side
  275.     ball_dx = -ball_dx
  276.     if ball_x < pad_x+pad_w/2 then
  277.      nextx=pad_x-ball_r
  278.     else
  279.      nextx=pad_x+pad_w+ball_r
  280.     end
  281.    else
  282.     --ball hit paddle on the top/bottom
  283.     ball_dy = -ball_dy
  284.     if ball_y > pad_y then
  285.      --bottom
  286.      nexty=pad_y+pad_h+ball_r
  287.     else
  288.      --top
  289.      nexty=pad_y-ball_r
  290.      if abs(pad_dx)>2 then
  291.       --change angle
  292.       if sign(pad_dx)==sign(ball_dx) then
  293.        --flatten angle
  294.        setang(mid(0,ball_ang-1,2))
  295.       else
  296.        --raise angle
  297.        if ball_ang==2 then
  298.         ball_dx=-ball_dx
  299.        else
  300.         setang(mid(0,ball_ang+1,2))
  301.        end
  302.       end
  303.      end
  304.     end
  305.    end
  306.    sfx(1)
  307.    chain=1
  308.   end
  309.  
  310.   brickhit=false
  311.   for i=1,#brick_x do
  312.    -- check if ball hit brick
  313.    if brick_v[i] and ball_box(nextx,nexty,brick_x[i],brick_y[i],brick_w,brick_h) then
  314.     -- deal with collision
  315.     if not(brickhit) then
  316.      if deflx_ball_box(ball_x,ball_y,ball_dx,ball_dy,brick_x[i],brick_y[i],brick_w,brick_h) then
  317.       ball_dx = -ball_dx
  318.      else
  319.       ball_dy = -ball_dy
  320.      end
  321.     end
  322.     brickhit=true
  323.     hitbrick(i)
  324.    
  325.     if levelfinished() then
  326.      _draw()
  327.      levelover()
  328.     end
  329.    end
  330.   end
  331.   ball_x=nextx
  332.   ball_y=nexty
  333.  
  334.   checkexplosions()
  335.  
  336.   if nexty > 127 then
  337.    sfx(2)
  338.    lives-=1
  339.    if lives<0 then
  340.     gameover()
  341.    else
  342.     serveball()
  343.    end
  344.   end
  345.  end
  346.  
  347. end
  348.  
  349. function hitbrick(_i)
  350.  if brick_t[_i]=="b" then
  351.   sfx(2+chain)
  352.   brick_v[_i]=false
  353.   points+=10*chain
  354.   chain+=1
  355.   chain=mid(1,chain,7)
  356.  elseif brick_t[_i]=="i" then
  357.   sfx(10)
  358.  elseif brick_t[_i]=="h" then
  359.   sfx(10)
  360.   brick_t[_i]="b"
  361.  elseif brick_t[_i]=="p" then
  362.   sfx(2+chain)
  363.   brick_v[_i]=false
  364.   points+=10*chain
  365.   chain+=1
  366.   chain=mid(1,chain,7)
  367.   --todo trigger powerup
  368.  elseif brick_t[_i]=="s" then
  369.   sfx(2+chain)
  370.   brick_t[_i]="zz"
  371.   points+=10*chain
  372.   chain+=1
  373.   chain=mid(1,chain,7)
  374.   --todo trigger powerup
  375.  end
  376. end
  377.  
  378. function checkexplosions()
  379.  for i=1,#brick_x do
  380.   if brick_t[i] == "zz" then
  381.    brick_t[i]="z"
  382.   end
  383.  end
  384.  
  385.  for i=1,#brick_x do
  386.   if brick_t[i] == "z" then
  387.    explodebrick(i)
  388.   end
  389.  end
  390.  
  391.  for i=1,#brick_x do
  392.   if brick_t[i] == "zz" then
  393.    brick_t[i]="z"
  394.   end
  395.  end
  396. end
  397.  
  398. function explodebrick(_i)
  399.  brick_v[_i]=false
  400.  for j=1,#brick_x do
  401.   if j!=_i
  402.   and brick_v[j]
  403.   and abs(brick_x[j]-brick_x[_i]) <= (brick_w+2)
  404.   and abs(brick_y[j]-brick_y[_i]) <= (brick_h+2)
  405.   then
  406.    hitbrick(j)
  407.   end  
  408.  end
  409.  
  410. end
  411.  
  412. function _draw()
  413.  if mode=="game" then
  414.   draw_game()
  415.  elseif mode=="start" then
  416.   draw_start()
  417.  elseif mode=="gameover" then
  418.   draw_gameover()
  419.  elseif mode=="levelover" then
  420.   draw_levelover()
  421.  end
  422. end
  423.  
  424. function draw_start()
  425.  cls()
  426.  print("pico hero breakout",30,40,7)
  427.  print("press — to start",32,80,11)
  428. end
  429.  
  430. function draw_gameover()
  431.  rectfill(0,60,128,75,0)
  432.  print("game over",46,62,7)
  433.  print("press — to restart",27,68,6)
  434. end
  435.  
  436. function draw_levelover()
  437.  rectfill(0,60,128,75,0)
  438.  print("stage clear!",46,62,7)
  439.  print("press — to continue",27,68,6)
  440. end
  441.  
  442. function draw_game()
  443.  local i
  444.  
  445.  cls(1)
  446.  circfill(ball_x,ball_y,ball_r, 10)
  447.  if sticky then
  448.   -- serve preview
  449.   line(ball_x+ball_dx*4,ball_y+ball_dy*4,ball_x+ball_dx*6,ball_y+ball_dy*6,10)
  450.  end
  451.  
  452.  rectfill(pad_x,pad_y,pad_x+pad_w,pad_y+pad_h,pad_c)
  453.  
  454.  --draw bricks
  455.  for i=1,#brick_x do
  456.   if brick_v[i] then
  457.    if brick_t[i] == "b" then
  458.     brickcol = 14
  459.    elseif brick_t[i] == "i" then
  460.     brickcol = 6
  461.    elseif brick_t[i] == "h" then
  462.     brickcol = 15
  463.    elseif brick_t[i] == "s" then
  464.     brickcol = 9
  465.    elseif brick_t[i] == "p" then
  466.     brickcol = 12
  467.    elseif brick_t[i] == "z" or brick_t[i] == "zz" then
  468.     brickcol = 8
  469.    end
  470.    rectfill(brick_x[i],brick_y[i],brick_x[i]+brick_w,brick_y[i]+brick_h,brickcol)
  471.   end
  472.  end
  473.  
  474.  rectfill(0,0,128,6,0)
  475.  if debug!="" then
  476.   print(debug,1,1,7)
  477.  else
  478.   print("lives:"..lives,1,1,7)
  479.   print("score:"..points,40,1,7)
  480.   print("chain:"..chain.."x",100,1,7)
  481.  end
  482. end
  483.  
  484. function ball_box(bx,by,box_x,box_y,box_w,box_h)
  485.  -- checks for a collion of the ball with a rectangle
  486.  if by-ball_r > box_y+box_h then return false end
  487.  if by+ball_r < box_y then return false end
  488.  if bx-ball_r > box_x+box_w then return false end
  489.  if bx+ball_r < box_x then return false end
  490.  return true
  491. end
  492.  
  493. function deflx_ball_box(bx,by,bdx,bdy,tx,ty,tw,th)
  494.     local slp = bdy / bdx
  495.     local cx, cy
  496.     if bdx == 0 then
  497.         return false
  498.     elseif bdy == 0 then
  499.         return true
  500.     elseif slp > 0 and bdx > 0 then
  501.         cx = tx - bx
  502.         cy = ty - by
  503.         return cx > 0 and cy/cx < slp
  504.     elseif slp < 0 and bdx > 0 then
  505.         cx = tx - bx
  506.         cy = ty + th - by
  507.         return cx > 0 and cy/cx >= slp
  508.     elseif slp > 0 and bdx < 0 then
  509.         cx = tx + tw - bx
  510.         cy = ty + th - by
  511.         return cx < 0 and cy/cx <= slp
  512.     else
  513.         cx = tx + tw - bx
  514.         cy = ty - by
  515.         return cx < 0 and cy/cx >= slp
  516.     end
  517. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement