G2A Many GEOs
SHARE
TWEET

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

Krystman Apr 3rd, 2017 255 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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
RAW Paste Data
Ledger Nano X - The secure hardware wallet
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Top