Advertisement
Krystman

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

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