Advertisement
Krystman

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

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