Krystman

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

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