Krystman

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

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