Advertisement
PlasmaPuffs

Bubble Gobble Source Code

Aug 3rd, 2024 (edited)
70
1
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 11.51 KB | Source Code | 1 0
  1. // Time used: 2h 56m 55s
  2.  
  3. random.choice = function(a) a[random.nextInt(a.length)] end
  4. random.shuffle = function(c)
  5.   c.sortList(function(a, b) random.next() - 0.5 end)
  6. end
  7.  
  8. reset = function()
  9.   depth = 0
  10.   air = 1
  11.   _air = 1
  12.  
  13.   x = 0
  14.   y = 0
  15.   a = 0
  16.  
  17.   vx = 0
  18.   vy = 0
  19.   can = true
  20.  
  21.   count = 0
  22.   bubbles = []
  23.   fizzes = []
  24.   creatures = []
  25.  
  26.   stretch = 1
  27.   squash = 1
  28.   roll = 0
  29.  
  30.   camera = 0
  31. end
  32.  
  33. gameOver = function()
  34.   state = "Game Over"
  35.   audio.playSound("hit", 1)
  36.  
  37.   local score = floor(camera / -16)
  38.   if score > highscore then
  39.     highscore = score
  40.     storage.set("highscore", score)
  41.   end
  42. end
  43.  
  44. init = function()
  45.   audio.playMusic("bubble_gobble", 0.2, true)
  46.   asset_manager.loadFont("font")
  47.   screen.setFont("font")
  48.   highscore = storage.get("highscore")
  49.   tick = 0
  50.   state = "Main Menu"
  51.   reset()
  52. end
  53.  
  54. update = function()
  55.   tick += 1
  56.  
  57.   if state == "Main Menu" then
  58.     if mouse.press then
  59.       audio.playSound("click", 0.5)
  60.       state = "Game"
  61.     end
  62.     return
  63.   elsif state == "Game Over" then
  64.     if mouse.press then
  65.       audio.playSound("click", 0.5)
  66.       state = "Main Menu"
  67.       reset()
  68.     end
  69.     return
  70.   end
  71.  
  72.   air -= 0.0005
  73.   _air += (air - _air) * 0.1
  74.  
  75.   stretch = 1 - (cos((tick + 30) / 30) / 8)
  76.   squash = 1 - (cos(tick / 30) / 8)
  77.   roll = sin(tick / 48) * 2
  78.  
  79.   if mouse.press and can then
  80.     audio.playSound("whoosh", 0.02)
  81.     can = false
  82.     air -= 0.1
  83.     after 0.2 seconds do can = true end
  84.    
  85.     vx += cosd(a) * 2
  86.     vy += sind(a) * 2
  87.   end
  88.  
  89.   vx *= 0.98
  90.   vy *= 0.98
  91.  
  92.   x += vx
  93.   y += vy
  94.  
  95.   if vx < 0 then
  96.     if x + 8 < screen.width / -2 then
  97.       x = (screen.width / 2) + 8
  98.     end
  99.   end
  100.  
  101.   if vx > 0 then
  102.     if x - 8 > screen.width / 2 then
  103.       x = (screen.width / -2) - 8
  104.     end
  105.   end
  106.  
  107.   y -= 1
  108.  
  109.   a = atan2d(mouse.y - (y - camera), mouse.x - x)
  110.  
  111.   for bubble in bubbles
  112.     if bubble.y - camera > (bubble.radius * 2) + (screen.height / 2) then
  113.       bubbles.removeElement(bubble)
  114.       continue
  115.     end
  116.    
  117.     if bubble.pop then
  118.       bubble.pop += 0.05
  119.       if bubble.pop >= 1 then bubbles.removeElement(bubble) end
  120.       continue
  121.     end
  122.    
  123.     local distance = sqrt(pow(bubble.x - x, 2) + pow(bubble.y - y, 2))
  124.     if distance < bubble.radius + 8 then
  125.       audio.playSound("bubble", 0.5)
  126.       bubble.pop += 0.05
  127.       air = 1
  128.     end
  129.   end
  130.  
  131.   if not (tick % 8) and random.next() < 0.8 then
  132.     fizz = object end
  133.     fizz.x = x + (random.next() * 12) - 6
  134.     fizz.y = y
  135.     fizz.vx = 0
  136.     fizz.vy = 0
  137.     fizz.pop = 0.2
  138.     fizz.radius = 1 + random.next()
  139.     fizzes.push(fizz)
  140.   end
  141.  
  142.   for fizz in fizzes
  143.     fizz.pop += 0.01
  144.     if fizz.pop >= 1 then
  145.       fizzes.removeElement(fizz)
  146.       continue
  147.     end
  148.    
  149.     fizz.vy += 0.02
  150.    
  151.     fizz.vx *= 0.95
  152.     fizz.vy *= 0.95
  153.    
  154.     fizz.x += fizz.vx
  155.     fizz.y += fizz.vy
  156.   end
  157.  
  158.   if y < camera - 20 then
  159.     distance = y - camera
  160.     camera += distance * 0.03
  161.    
  162.     if (camera / -50) > count then
  163.       count += 1
  164.      
  165.       local bubble = object end
  166.       bubble.radius = 20 + (random.next() * 10)
  167.       bubble.pop = 0
  168.      
  169.       position = false
  170.       while not position
  171.         position = [
  172.           (random.next() * screen.width) - (screen.width / 2)
  173.           camera - 200 + random.nextInt(100) - 50
  174.         ]
  175.        
  176.         intersection = false
  177.         for o in bubbles
  178.           if sqrt(
  179.             pow(o.x - position[0], 2) + pow(o.y - position[1], 2)
  180.           ) < bubble.radius + o.radius then
  181.             intersection = true
  182.             break
  183.           end
  184.         end
  185.        
  186.         if intersection then position = false end
  187.       end
  188.      
  189.       bubble.x = position[0]
  190.       bubble.y = position[1]
  191.       bubbles.push(bubble)
  192.      
  193.       local creature = object end
  194.       creature.x = (screen.width / 2) - position[0]
  195.       creature.y = position[1]
  196.      
  197.       local data = random.choice([
  198.         ["lunker", 64, 32, 0.1],
  199.         ["fish", 32, 16, 0.2],
  200.         ["fishling", 16, 8, 0.5],
  201.         ["fishy", 16, 8, 1],
  202.         ["fry", 8, 8, 2]
  203.       ])
  204.      
  205.       creature.name = data[0]
  206.       creature.width = data[1]
  207.       creature.height = data[2]
  208.       creature.beat = 1
  209.      
  210.       local r = random.next()
  211.       local a = r * (1 / 3)
  212.       local b = (r + 1) * (1 / 3)
  213.       local c = (r + 2) * (1 / 3)
  214.       local components = [a, b, c]
  215.       random.shuffle(components)
  216.       creature.color = (
  217.         "rgb(" +
  218.         min(components[0] * 500, 255) + ", " +
  219.         min(components[1] * 500, 255) + ", " +
  220.         min(components[2] * 500, 255) + ")"
  221.       )
  222.      
  223.       creature.flip = ((random.next() > 0.5) * 2) - 1
  224.       creature.speed = creature.flip * data[3]
  225.       creatures.push(creature)
  226.     end
  227.   end
  228.  
  229.   for creature in creatures
  230.     if creature.y - camera > creature.width + (screen.height / 2) then
  231.       creatures.removeElement(creature)
  232.       continue
  233.     end
  234.    
  235.     creature.beat += ((1 - creature.beat) * 0.05)
  236.     creature.x += creature.speed
  237.     local w = creature.width / 2
  238.    
  239.     if creature.speed < 0 then
  240.       if creature.x + w < screen.width / -2 then
  241.         creature.x = (screen.width / 2) + w
  242.       end
  243.     end
  244.    
  245.     if creature.speed > 0 then
  246.       if creature.x - w > screen.width / 2 then
  247.         creature.x = (screen.width / -2) - w
  248.       end
  249.     end
  250.    
  251.     if not (tick % 60) then creature.beat = 1.1 end
  252.     if not (tick % 8) and random.next() < 0.8 then
  253.       local o = (
  254.         (random.next() * creature.width * 0.75) - (creature.width - 0.375)
  255.       )
  256.      
  257.       fizz = object end
  258.       fizz.x = creature.x + o
  259.       fizz.y = creature.y
  260.       fizz.vx = 0
  261.       fizz.vy = random.next() * 4
  262.       fizz.pop = 0.2
  263.       fizz.radius = 1 + random.next()
  264.       fizzes.push(fizz)
  265.     end
  266.    
  267.     if (
  268.       creature.x - (creature.width / 2) < x + 8 and
  269.       creature.x + (creature.width / 2) > x - 8 and
  270.       creature.y - (creature.height / 2) < y + 8 and
  271.       creature.y + (creature.height / 2) > y - 8
  272.     ) then
  273.       gameOver()
  274.       return
  275.     end
  276.   end
  277.  
  278.   air = min(max(air, 0), 1)
  279.   if not air then gameOver() end
  280. end
  281.  
  282. draw = function()
  283.   if state == "Main Menu" then
  284.     screen.clear("rgb(127, 219, 255)")
  285.    
  286.     local s = sin(tick / 10)
  287.     local c = cos(tick / 20)
  288.    
  289.     screen.setDrawScale(1 + (sin(tick / 20) / 10), 1 + (cos(tick / 20) / 10))
  290.     screen.setLineWidth(16)
  291.     screen.setDrawRotation(c)
  292.     screen.drawTextOutline("Bubble Gobble", 0, s, 32, "rgb(0, 31, 51)")
  293.     screen.drawText("Bubble Gobble", 0, c, 32, 999)
  294.     screen.setLineWidth(1)
  295.     screen.setDrawScale(1, 1)
  296.     screen.setDrawRotation(0)
  297.    
  298.     local s = "Your highscore is: " + highscore + "m"
  299.     screen.setLineWidth(4)
  300.     screen.drawTextOutline(s, 0, -60, 8, "rgb(0, 31, 51)")
  301.     screen.drawText(s, 0, -60, 8, 999)
  302.     screen.setLineWidth(1)
  303.    
  304.     local help = "Controls and Description in the Project Description."
  305.     screen.setLineWidth(4)
  306.     screen.drawTextOutline(help, 0, -70, 8, "rgb(0, 31, 51)")
  307.     screen.drawText(help, 0, -70, 8, 999)
  308.     screen.setLineWidth(1)
  309.    
  310.     local play = "Click Anywhere on the Screen to Play!"
  311.     screen.setLineWidth(4)
  312.     screen.drawTextOutline(play, 0, -80, 8, "rgb(0, 31, 51)")
  313.     screen.drawText(play, 0, -80, 8, 999)
  314.     screen.setLineWidth(1)
  315.     return
  316.   elsif state == "Game Over" then
  317.     local color = waterColor(camera / -9999)
  318.     screen.clear("rgb(" + color[0] + ", " + color[1] + ", " + color[2] + ")")
  319.    
  320.     local s = sin(tick / 10)
  321.     local c = cos(tick / 20)
  322.    
  323.     screen.setDrawScale(1 + (sin(tick / 20) / 10), 1 + (cos(tick / 20) / 10))
  324.     screen.setLineWidth(16)
  325.     screen.setDrawRotation(c)
  326.     screen.drawTextOutline("Game Over!", 0, s, 32, "rgb(0, 31, 51)")
  327.     screen.drawText("Game Over!", 0, c, 32, 999)
  328.     screen.setLineWidth(1)
  329.     screen.setDrawScale(1, 1)
  330.     screen.setDrawRotation(0)
  331.    
  332.     local s = "Your highscore is: " + highscore + "m"
  333.     screen.setLineWidth(4)
  334.     screen.drawTextOutline(s, 0, -60, 8, "rgb(0, 31, 51)")
  335.     screen.drawText(s, 0, -60, 8, 999)
  336.     screen.setLineWidth(1)
  337.    
  338.     local score = "Your score is: " + floor(camera / -16) + "m!"
  339.     screen.setLineWidth(4)
  340.     screen.drawTextOutline(score, 0, -70, 8, "rgb(0, 31, 51)")
  341.     screen.drawText(score, 0, -70, 8, 999)
  342.     screen.setLineWidth(1)
  343.    
  344.     local proceed = "Click Anywhere on the Screen to Proceed."
  345.     screen.setLineWidth(4)
  346.     screen.drawTextOutline(proceed, 0, -80, 8, "rgb(0, 31, 51)")
  347.     screen.drawText(proceed, 0, -80, 8, 999)
  348.     screen.setLineWidth(1)
  349.     return
  350.   end
  351.  
  352.   local color = waterColor(camera / -9999)
  353.   screen.clear("rgb(" + color[0] + ", " + color[1] + ", " + color[2] + ")")
  354.  
  355.   screen.setTranslation(0, -camera)
  356.   screen.setRotation(roll)
  357.  
  358.   for o in creatures
  359.     screen.setDrawScale(o.flip * o.beat, o.beat)
  360.     local fill = new Image(o.width, o.height, true)
  361.     fill.drawSprite(o.name + "/fill", 0, 0, o.width, o.height)
  362.     fill.setBlending('source-in')
  363.     fill.fillRect(0, 0, o.width, o.height, o.color)
  364.     screen.drawImage(fill, o.x, o.y, o.width, o.height)
  365.     screen.drawSprite(o.name + "/outline", o.x, o.y, o.width, o.height)
  366.     screen.setDrawScale(1, 1)
  367.   end
  368.  
  369.   screen.setDrawRotation(a - 90)
  370.   screen.drawSprite(sprites["player"].frames[can] x, y, 16, 16)
  371.   screen.setDrawRotation(0)
  372.  
  373.   for o in bubbles + fizzes
  374.     local size = o.radius * 2
  375.     screen.setAlpha(1 - o.pop)
  376.     screen.setDrawScale(1 + o.pop, 1 + o.pop)
  377.     screen.setAlpha((1 - o.pop) / 5)
  378.     screen.fillRound(o.x, o.y, size * stretch, size * squash, 999)
  379.     screen.setAlpha(1 - o.pop)
  380.     screen.drawRound(o.x, o.y, size * stretch, size * squash, 999)
  381.     screen.setDrawScale(1, 1)
  382.     screen.setAlpha(1)
  383.   end
  384.  
  385.   screen.setRotation(0)
  386.   screen.setTranslation(0, 0)
  387.  
  388.   screen.setAlpha(0.4)
  389.   screen.setDrawAnchor(-1, 0)
  390.   screen.fillRect(-170, 80, 340 * _air, 20, 999)
  391.   screen.setDrawAnchor(0, 0)
  392.   screen.setAlpha(1)
  393.  
  394.   screen.setLineWidth(2)
  395.   screen.drawRect(0, 80, 340, 20, "rgb(0, 31, 51)")
  396.   screen.setLineWidth(1)
  397.  
  398.   screen.setLineWidth(4)
  399.   local airText = "Air: " + round(air * 100) + "%"
  400.   screen.drawTextOutline(airText, 0, 80, 8, "rgb(0, 31, 51)")
  401.   screen.drawText(airText, 0, 80, 8, 999)
  402.   screen.setLineWidth(4)
  403.  
  404.   screen.setLineWidth(8)
  405.   screen.setDrawAnchor(-1, -1)
  406.   local x = (screen.width / -2) + 8
  407.   local y = (screen.height / -2) + 8
  408.   local depthText = "Depth: " + floor(camera / -16) + "m"
  409.   screen.drawTextOutline(depthText, x, y, 16, "rgb(0, 31, 51)")
  410.   screen.drawText(depthText, x, y, 16, 999)
  411.   screen.setDrawAnchor(0, 0)
  412.   screen.setLineWidth(1)
  413. end
  414.  
  415. lerp = function(a, b, t) a + ((b - a) * t) end
  416. lerpColor = function(color1, color2, t)
  417.   [
  418.     lerp(color1[0], color2[0], t),
  419.     lerp(color1[1], color2[1], t),
  420.     lerp(color1[2], color2[2], t)
  421.   ]
  422. end
  423.  
  424. waterColor = function(depth)
  425.   depth = min(max(depth, 0), 1)
  426.  
  427.   local lightAqua = [127, 219, 255]
  428.   local aqua = [0, 116, 217]
  429.   local deepAqua = [0, 31, 63]
  430.   local navyBlue = [0, 31, 51]
  431.  
  432.   local stage = false
  433.   local t = false
  434.  
  435.   if depth < (1 / 3) then
  436.     stage = 1
  437.     t = depth * 3
  438.   elsif depth < (2 / 3) then
  439.     stage = 2
  440.     t = (depth - (1 / 3)) * 3
  441.   else
  442.     stage = 3
  443.     t = (depth - (2 / 3)) * 3
  444.   end
  445.  
  446.   if stage == 1 then return lerpColor(lightAqua, aqua, t)
  447.   elsif stage == 2 then return lerpColor(aqua, deepAqua, t)
  448.   else return lerpColor(deepAqua, navyBlue, t) end
  449. end
  450.  
  451.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement