Advertisement
Krystman

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

Mar 18th, 2017
520
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 10.31 KB | None | 0 0
  1. --goals
  2. -- 6. powerups
  3. --     - sound effect
  4. --     - pill types
  5.  
  6. --     - speed down
  7. --     - 1up
  8. --     - sticky
  9. --     - expand/reduct
  10. --     - megaball
  11. --     - multiball
  12.  
  13. -- 7. juicyness
  14. --     arrow anim
  15. --     text blinking
  16. --     particles
  17. --     screenshake
  18. -- 8. high score
  19.  
  20. function _init()
  21.  cls()
  22.  mode="start"
  23.  level=""
  24.  debug=""
  25.  levelnum = 1
  26.  levels={}
  27.  --levels[1] = "x5b"
  28.  levels[1] = "b9b/x4p"
  29.  --levels[1] = "hxixsxpxbxbxbxbxbxbxbxbxbxbxbxbxbxbxbxbxbxbxbxbxbxbxbxbxbxbxbxbxbxbxbxbxb"
  30.  --levels[1] = "////x4b/s9s"
  31. end
  32.  
  33. function _update60()
  34.  if mode=="game" then
  35.   update_game()
  36.  elseif mode=="start" then
  37.   update_start()
  38.  elseif mode=="gameover" then
  39.   update_gameover()
  40.  elseif mode=="levelover" then
  41.   update_levelover()
  42.  end
  43. end
  44.  
  45. function update_start()
  46.  if btnp(4) then
  47.   startgame()
  48.  end
  49. end
  50.  
  51. function startgame()
  52.  mode="game"
  53.  ball_r=2
  54.  ball_dr=0.5
  55.  
  56.  pad_x=52
  57.  pad_y=120
  58.  pad_dx=0
  59.  pad_w=24
  60.  pad_h=3
  61.  pad_c=7
  62.  
  63.  brick_w=9
  64.  brick_h=4
  65.  
  66.  levelnum = 1
  67.  level = levels[levelnum]
  68.  buildbricks(level)
  69.  --brick_y=20
  70.  
  71.  lives=3
  72.  points=0
  73.  
  74.  sticky=true
  75.  
  76.  chain=1 --combo chain multiplier
  77.  
  78.  serveball()
  79. end
  80.  
  81. function nextlevel()
  82.  mode="game"
  83.  pad_x=52
  84.  pad_y=120
  85.  pad_dx=0
  86.  
  87.  levelnum+=1
  88.  if levelnum > #levels then
  89.   -- we've beaten the gane
  90.   -- we need some kind of special
  91.   -- screen here
  92.   mode="start"
  93.   return
  94.  end
  95.  level=levels[levelnum]
  96.  buildbricks(level)
  97.  
  98.  sticky=true
  99.  chain=1
  100.  
  101.  serveball()
  102. end
  103.  
  104. function buildbricks(lvl)
  105.  local i,j,o,chr,last
  106.  brick_x={}
  107.  brick_y={}
  108.  brick_v={}
  109.  brick_t={}
  110.  
  111.  j=0
  112.  -- b = normal brick
  113.  -- x = empty space
  114.  -- i = indestructable brick
  115.  -- h = hardened brick
  116.  -- s = sploding brick
  117.  -- p = powerup brick
  118.  
  119.  for i=1,#lvl do
  120.   j+=1
  121.   chr=sub(lvl,i,i)  
  122.   if chr=="b"
  123.   or chr=="i"
  124.   or chr=="h"
  125.   or chr=="s"
  126.   or chr=="p" then
  127.    last=chr
  128.    addbrick(j,chr)  
  129.   elseif chr=="x" then
  130.    last="x"
  131.   elseif chr=="/" then
  132.    j=(flr((j-1)/11)+1)*11
  133.   elseif chr>="1" and chr<="9" then
  134.    for o=1,chr+0 do
  135.     if last=="b"
  136.     or last=="i"
  137.     or last=="h"
  138.     or last=="s"
  139.     or last=="p" then
  140.         addbrick(j,last)
  141.     elseif last=="x" then
  142.      --nothing
  143.     end
  144.     j+=1
  145.    end
  146.    j-=1
  147.   end
  148.  end
  149. end
  150.  
  151. function resetpills()
  152.  pill_x={}
  153.  pill_y={}
  154.  pill_v={}
  155.  pill_t={}
  156. end
  157.  
  158. function addbrick(_i,_t)
  159.  add(brick_x,4+((_i-1)%11)*(brick_w+2))
  160.  add(brick_y,20+flr((_i-1)/11)*(brick_h+2))
  161.  add(brick_v,true)
  162.  add(brick_t,_t)
  163. end
  164.  
  165. function levelfinished()
  166.  if #brick_v == 0 then return true end
  167.  
  168.  for i=1,#brick_v do
  169.   if brick_v[i] == true and brick_t[i] != "i" then
  170.    return false
  171.   end
  172.  end
  173.  return true
  174. end
  175.  
  176. function serveball()
  177.  ball_x=pad_x+flr(pad_w/2)
  178.  ball_y=pad_y-ball_r
  179.  ball_dx=1
  180.  ball_dy=-1
  181.  ball_ang=1
  182.  chain=1
  183.  resetpills()
  184.  
  185.  sticky=true
  186.  --0.50
  187.  --1.30
  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.   end
  324.  
  325.   brickhit=false
  326.   for i=1,#brick_x do
  327.    -- check if ball hit brick
  328.    if brick_v[i] and ball_box(nextx,nexty,brick_x[i],brick_y[i],brick_w,brick_h) then
  329.     -- deal with collision
  330.     if not(brickhit) then
  331.      if deflx_ball_box(ball_x,ball_y,ball_dx,ball_dy,brick_x[i],brick_y[i],brick_w,brick_h) then
  332.       ball_dx = -ball_dx
  333.      else
  334.       ball_dy = -ball_dy
  335.      end
  336.     end
  337.     brickhit=true
  338.     hitbrick(i,true)
  339.    end
  340.   end
  341.   ball_x=nextx
  342.   ball_y=nexty
  343.  
  344.   -- move pills
  345.   for i=1,#pill_x do
  346.    if pill_v[i] then
  347.     pill_y[i]+=0.7
  348.     if pill_y[i] > 128 then
  349.      pill_v[i]=false
  350.     end
  351.     if box_box(pill_x[i],pill_y[i],8,6,pad_x,pad_y,pad_w,pad_h) then
  352.      debug = "pickup!!"
  353.      pill_v[i]=false
  354.     end
  355.    end
  356.   end
  357.  
  358.   checkexplosions()
  359.  
  360.   if nexty > 127 then
  361.    sfx(2)
  362.    lives-=1
  363.    if lives<0 then
  364.     gameover()
  365.    else
  366.     serveball()
  367.    end
  368.   end
  369.  end
  370.  
  371.  if levelfinished() then
  372.   _draw()
  373.   levelover()
  374.  end
  375.  
  376. end
  377.  
  378. function hitbrick(_i,_combo)
  379.  if brick_t[_i]=="b" then
  380.   sfx(2+chain)
  381.   brick_v[_i]=false
  382.   if _combo then
  383.    points+=10*chain
  384.    chain+=1
  385.    chain=mid(1,chain,7)
  386.   end
  387.  elseif brick_t[_i]=="i" then
  388.   sfx(10)
  389.  elseif brick_t[_i]=="h" then
  390.   sfx(10)
  391.   brick_t[_i]="b"
  392.  elseif brick_t[_i]=="p" then
  393.   sfx(2+chain)
  394.   brick_v[_i]=false
  395.   if _combo then
  396.    points+=10*chain
  397.    chain+=1
  398.    chain=mid(1,chain,7)
  399.   end
  400.   spawnpill(brick_x[_i],brick_y[_i],1)
  401.  elseif brick_t[_i]=="s" then
  402.   sfx(2+chain)
  403.   brick_t[_i]="zz"
  404.   if _combo then
  405.    points+=10*chain
  406.    chain+=1
  407.    chain=mid(1,chain,7)
  408.   end
  409.  end
  410. end
  411.  
  412. function spawnpill(_x,_y,_t)
  413.  add(pill_x,_x)
  414.  add(pill_y,_y)
  415.  add(pill_v,true)
  416.  add(pill_t,_t)
  417.  
  418.  --pill_x[#pill_x+1]=_x
  419.  --pill_y[#pill_x]=_y
  420.  --pill_v[#pill_x]=true
  421.  --pill_t[#pill_x]=_t
  422. end
  423.  
  424. function checkexplosions()
  425.  for i=1,#brick_x do
  426.   if brick_t[i] == "zz" then
  427.    brick_t[i]="z"
  428.   end
  429.  end
  430.  
  431.  for i=1,#brick_x do
  432.   if brick_t[i] == "z" then
  433.    explodebrick(i)
  434.   end
  435.  end
  436.  
  437.  for i=1,#brick_x do
  438.   if brick_t[i] == "zz" then
  439.    brick_t[i]="z"
  440.   end
  441.  end
  442. end
  443.  
  444. function explodebrick(_i)
  445.  brick_v[_i]=false
  446.  for j=1,#brick_x do
  447.   if j!=_i
  448.   and brick_v[j]
  449.   and abs(brick_x[j]-brick_x[_i]) <= (brick_w+2)
  450.   and abs(brick_y[j]-brick_y[_i]) <= (brick_h+2)
  451.   then
  452.    hitbrick(j,false)
  453.   end  
  454.  end
  455.  
  456. end
  457.  
  458. function _draw()
  459.  if mode=="game" then
  460.   draw_game()
  461.  elseif mode=="start" then
  462.   draw_start()
  463.  elseif mode=="gameover" then
  464.   draw_gameover()
  465.  elseif mode=="levelover" then
  466.   draw_levelover()
  467.  end
  468. end
  469.  
  470. function draw_start()
  471.  cls()
  472.  print("pico hero breakout",30,40,7)
  473.  print("press — to start",32,80,11)
  474. end
  475.  
  476. function draw_gameover()
  477.  rectfill(0,60,128,75,0)
  478.  print("game over",46,62,7)
  479.  print("press — to restart",27,68,6)
  480. end
  481.  
  482. function draw_levelover()
  483.  rectfill(0,60,128,75,0)
  484.  print("stage clear!",46,62,7)
  485.  print("press — to continue",27,68,6)
  486. end
  487.  
  488. function draw_game()
  489.  local i
  490.  
  491.  cls(1)
  492.  circfill(ball_x,ball_y,ball_r, 10)
  493.  if sticky then
  494.   -- serve preview
  495.   line(ball_x+ball_dx*4,ball_y+ball_dy*4,ball_x+ball_dx*6,ball_y+ball_dy*6,10)
  496.  end
  497.  
  498.  rectfill(pad_x,pad_y,pad_x+pad_w,pad_y+pad_h,pad_c)
  499.  
  500.  --draw bricks
  501.  for i=1,#brick_x do
  502.   if brick_v[i] then
  503.    if brick_t[i] == "b" then
  504.     brickcol = 14
  505.    elseif brick_t[i] == "i" then
  506.     brickcol = 6
  507.    elseif brick_t[i] == "h" then
  508.     brickcol = 15
  509.    elseif brick_t[i] == "s" then
  510.     brickcol = 9
  511.    elseif brick_t[i] == "p" then
  512.     brickcol = 12
  513.    elseif brick_t[i] == "z" or brick_t[i] == "zz" then
  514.     brickcol = 8
  515.    end
  516.    rectfill(brick_x[i],brick_y[i],brick_x[i]+brick_w,brick_y[i]+brick_h,brickcol)
  517.   end
  518.  end
  519.  
  520.  for i=1,#pill_x do
  521.   if pill_v[i] then
  522.    spr(1,pill_x[i],pill_y[i])
  523.   end
  524.  end
  525.  
  526.  rectfill(0,0,128,6,0)
  527.  if debug!="" then
  528.   print(debug,1,1,7)
  529.  else
  530.   print("lives:"..lives,1,1,7)
  531.   print("score:"..points,40,1,7)
  532.   print("chain:"..chain.."x",100,1,7)
  533.  end
  534. end
  535.  
  536. function ball_box(bx,by,box_x,box_y,box_w,box_h)
  537.  -- checks for a collion of the ball with a rectangle
  538.  if by-ball_r > box_y+box_h then return false end
  539.  if by+ball_r < box_y then return false end
  540.  if bx-ball_r > box_x+box_w then return false end
  541.  if bx+ball_r < box_x then return false end
  542.  return true
  543. end
  544.  
  545. function box_box(box1_x,box1_y,box1_w,box1_h,box2_x,box2_y,box2_w,box2_h)
  546.  -- checks for a collion of the two boxes
  547.  if box1_y > box2_y+box2_h then return false end
  548.  if box1_y+box1_h < box2_y then return false end
  549.  if box1_x > box2_x+box2_w then return false end
  550.  if box1_x+box1_w < box2_x then return false end
  551.  return true
  552. end
  553.  
  554. function deflx_ball_box(bx,by,bdx,bdy,tx,ty,tw,th)
  555.     local slp = bdy / bdx
  556.     local cx, cy
  557.     if bdx == 0 then
  558.         return false
  559.     elseif bdy == 0 then
  560.         return true
  561.     elseif slp > 0 and bdx > 0 then
  562.         cx = tx - bx
  563.         cy = ty - by
  564.         return cx > 0 and cy/cx < slp
  565.     elseif slp < 0 and bdx > 0 then
  566.         cx = tx - bx
  567.         cy = ty + th - by
  568.         return cx > 0 and cy/cx >= slp
  569.     elseif slp > 0 and bdx < 0 then
  570.         cx = tx + tw - bx
  571.         cy = ty + th - by
  572.         return cx < 0 and cy/cx <= slp
  573.     else
  574.         cx = tx + tw - bx
  575.         cy = ty - by
  576.         return cx < 0 and cy/cx >= slp
  577.     end
  578. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement