Thursday, December 26, 2013

Pop The Bubbles





How many bubbles you can burst in 60 seconds? This game is for relaxing in free time.

Why kids will love?
+ Very easy to play! Touch and Broken, that's it!
+ Entertaining

Credits to Nightmares Within

Using existing code modified for Corona SDK 2013.2109
BubbleMaker_Lib.lua

-- 2013 Nightmares Within
-- http://www.nightmareswithin.com
-- @NightmaresWithn
-- http://www.facebook.com/NightmaresWithin
-- You are free to Distribute, just keep my header :)
-- ==================================================
local bubbleMakerLib = {}
local bubbleMakerLib_mt = { __index = bubbleMakerLib }

local Random = math.random

function bubbleMakerLib.New(inGFXGroup, advancePopCounter, gameOverHandler)
 local bubLib = {}
 
 bubLib.blowerPick = nil
 bubLib.blowRoundTimer = nil
 bubLib.blowTimer = nil
 bubLib.bubbleGroup = inGFXGroup
 bubLib.blowSpeed = nil
 bubLib.blowerX = nil
 bubLib.blowerY = nil
 bubLib.advancePopCounter = advancePopCounter
 bubLib.gameOverHandler = gameOverHandler
 
 return setmetatable(bubLib, bubbleMakerLib_mt)
end

function bubbleMakerLib:MakeBlower(inX, inY, bubbleCount, blowSpeed, blowPauseTime)
 self.blowSpeed = blowSpeed
 self.blowerX = inX
 self.blowerY = inY
 self.bubbleCount = bubbleCount
 self.blowSpeed = blowSpeed
 self.blowPauseTime = blowPauseTime
 
 self.blowerPick = display.newImageRect(self.bubbleGroup, "Blower.png", 80, 219)
 self.blowerPick.x = inX
 self.blowerPick.y = inY - 65
 
 local blower = display.newCircle(self.bubbleGroup, inX, inY - 40, 20)
 blower.alpha = 0
end

function bubbleMakerLib:BlowBubbles(inAmount)
 self.blowTimer = timer.performWithDelay(self.blowSpeed, function()
  local bubble = self:NewBubble()
  bubble:setLinearVelocity(Random(-80, 80), Random(1,4))
 end, inAmount)
end

function bubbleMakerLib:StartBlower() 
 self:BlowBubbles(self.bubbleCount)
 
 self.blowRoundTimer = timer.performWithDelay(self.blowPauseTime, function()
  self:BlowBubbles(self.bubbleCount)
 end, 0)
end

function bubbleMakerLib:StopBlower()
 if(self.blowRoundTimer)then
  timer.cancel(self.blowRoundTimer)
 end
 if(self.blowTimer)then
  timer.cancel(self.blowTimer)
 end
 
 for i=self.bubbleGroup.numChildren,1,-1 do
  if(self.bubbleGroup[i].Pop)then
   if(self.bubbleGroup[i].alive)then
    self.bubbleGroup[i]:Pop()
   end
  end
 end
end

function bubbleMakerLib:MakeBubbleCollisionHandler(inSelf)
 local self = inSelf
 
 return function(obj,event)
  if(event.phase == "began")then
   if(event.other.name == "grass")then
    if(obj.alive)then
     obj.alive = false
     timer.performWithDelay(1, function()
      obj:Pop()
     end)  
     --timer.performWithDelay(10, function()
     -- self.gameOverHandler()
     --end)
    end
   end
  end 
  return true
 end
end

function bubbleMakerLib:MakeBubbleTouchHandler(inSelf)
 local self = inSelf
 
 return function(obj,event)
  if (event.phase == "began") then
   if(obj.alive)then
    obj.alive = false
    timer.performWithDelay(10, function()
     obj:Pop()
    end)
    self.advancePopCounter()
   end
  end
  return true
 end
end
 
function bubbleMakerLib:NewBubble()
 local bubble = nil
 
 bubbleSize = Random(40, 80)
 
 bubble = display.newImageRect(self.bubbleGroup, "Bubble.png", bubbleSize, bubbleSize)
 bubble.x = self.blowerX
 bubble.y = self.blowerY 
 physics.addBody(bubble, "dynamic", {density=0.1, friction=0.0, bounce=0.5, radius=bubbleSize * .45})
 bubble.alive = true
 bubble.gfxGroup = self.bubbleGroup
 bubble.collision = self:MakeBubbleCollisionHandler(self)
 bubble:addEventListener("collision", bubble)

 bubble.touch = self:MakeBubbleTouchHandler(self)
 bubble:addEventListener("touch", bubble)
 
 function bubble:Pop()
  if(self.collision)then
   self:removeEventListener("collision", self)
  end
  if(self.touch)then
   self:removeEventListener("touch",self)
  end
  
  local bubblePop = display.newImageRect(self.gfxGroup, "BubblePop.png", 250, 250)
  bubblePop.x = self.x
  bubblePop.y = self.y
  bubblePop.xScale = .01
  bubblePop.yScale = .01
  transition.to(bubblePop, {time=150, xScale = 1, yScale = 1, alpha = 0, onComplete = function()
   display.remove(bubblePop)
   bubblePop = nil
  end})
  
  display.remove(self)
  self = nil
 end

 return bubble
end

return bubbleMakerLib

main.lua

-- 2013 Nightmares Within
-- http://www.nightmareswithin.com
-- @NightmaresWithn
-- http://www.facebook.com/NightmaresWithin
-- You are free to Distribute, just keep my header :)
-- ==================================================
display.setStatusBar( display.HiddenStatusBar )

physics = require("physics")

local function BubblePopper()
 physics.start()
 physics.setGravity(0, 9.8)
 physics.setDrawMode("normal")
 
 local screenW = display.contentWidth
 local screenH = display.contentHeight
 local screenHW = screenW *.5
 local screenHH = screenH *.5
 local Random = math.random
 local popSound = audio.loadStream("pop.wav")

 -- Require our Bubble Maker
 local bubbleMaker_Lib = require("BubbleMaker_Lib")
 bubbleMaker = nil
 
 
 -- Make some groups
 local levelGroup = display.newGroup()
 local backgroundGroup = display.newGroup()
 local hudGroup = display.newGroup()
 local groundGroup = display.newGroup()
 local bubbleGroup = display.newGroup()
 levelGroup:insert(backgroundGroup)
 levelGroup:insert(hudGroup)
 levelGroup:insert(groundGroup)
 levelGroup:insert(bubbleGroup)
 
 local popCounter = 0
 local blowerSpeed = 100
 local blowerPauseTime = 3000
 local blowerBubbleCount = 20
 local gameOverText = nil
 local StartGame = nil
 local number = 60
 
 -- Make a background gradient
 local function MakeBackground()
  local background = display.newImageRect(backgroundGroup, "Sky.png", screenW, screenH)
  background.x = display.contentCenterX
  background.y = display.contentCenterY
 end
 MakeBackground()
 
 local saveValue = function( strFilename, strValue )
        local theFile = strFilename
        local theValue = strValue
        local path = system.pathForFile( theFile, system.DocumentsDirectory )

        local file = io.open( path, "w+" )
        if file then
           file:write( theValue )
           io.close( file )
        end
      end
    
      local loadValue = function( strFilename )
        local theFile = strFilename
        local path = system.pathForFile( theFile, system.DocumentsDirectory )

        local file = io.open( path, "r" )
        if file then
           local contents = file:read( "*a" )
           io.close( file )
           return contents
        else
           file = io.open( path, "w" )
           file:write( "0" )
           io.close( file )
           return "0"
        end
      end
    
    local highScoreFilename = "highScore.data"
    local loadedHighScore = loadValue( highScoreFilename )
    local highScore = tonumber(loadedHighScore)

 local txt_counter = display.newText(hudGroup, number, 0, 0, native.systemFont, 40 )
 txt_counter.x = screenW/2
    txt_counter.y = screenH/2 - 185
 txt_counter:setFillColor(1, 1, 1 )
 
 local bubbleCounter = display.newText(hudGroup, "Score: "..popCounter, 0, 0, native.systemFont, 14)
 bubbleCounter.x = screenW/2 - 110
    bubbleCounter.y = screenH/2 - 220
 bubbleCounter:setFillColor(1, 1, 1 )
 
 local highCounter = display.newText(hudGroup, "High Score: "..highScore, 0, 0, native.systemFont, 14)
 highCounter.x = screenW/2 + 90
    highCounter.y = screenH/2 - 220
 highCounter:setFillColor(1, 1, 1 )
 
 local function RestartHandler(event)
  if(event.phase == "began")then
   gameOverText:removeEventListener("touch", gameOverText)
   display.remove(gameOverText)
   gameOverText = nil
   popCounter = 0
   number = 60
   bubbleCounter.text = "Score: "..popCounter
   txt_counter.alpha = 1
   txt_counter.text = number
   StartGame()
  end 
  return true
 end
 
 local function GameOver()
  bubbleMaker:StopBlower()
  
  gameOverText = display.newText(hudGroup, "Game Over", 0, 0, native.systemFontBold, 40)
  gameOverText.x = screenHW
  gameOverText.y = screenHH
  gameOverText:addEventListener("touch", RestartHandler)
    
 end
 
 function fn_counter()
    number = number - 1
    txt_counter.text = number
            if(number == 0) then
    txt_counter.alpha = 0
    GameOver()
            end
    end
    masa = timer.performWithDelay(1000, fn_counter, 0)
 
 local function AdvancePopCounter()
  audio.play(popSound)
  popCounter = popCounter + 1
  bubbleCounter.text = "Score: "..popCounter
  if popCounter > highScore then
              highScore = popCounter
              local highScoreFilename = "highScore.data"
              saveValue( highScoreFilename, tostring(highScore) )
        end
  highCounter.text = "High Score: "..highScore
 end
 
 
 --Simple, re-usable function to create physics boundaries on your device
 local function MakeCollisionBounds()
  local tRectTop = display.newRect(groundGroup, display.contentCenterX, 0, screenW, 10)
  physics.addBody(tRectTop, "static", {density = 1.0, friction = 1.0})
  local tRectBottom = display.newRect(groundGroup, display.contentCenterX, screenH - 10, screenW, 10)
  physics.addBody(tRectBottom,  "static", {density = 1.0, friction = 1.0})
  tRectBottom.name = "ground"
  local tRectLeft = display.newRect(groundGroup, 0, display.contentCenterY, 10, screenH)
  physics.addBody(tRectLeft, "static", {density = 1.0, friction = 1.0})
  local tRectRight = display.newRect(groundGroup, screenW, display.contentCenterY, 10, screenH)
  physics.addBody(tRectRight, "static", {density = 1.0, friction = 1.0})
  tRectTop.alpha = 0
  tRectTop.isHitTestable = true
  tRectBottom.alpha = 0
  tRectBottom.isHitTestable = true
  tRectLeft.alpha = 0
  tRectLeft.isHitTestable = true
  tRectRight.alpha = 0
  tRectRight.isHitTestable = true  
 end
 MakeCollisionBounds()
 
 local function MakeGrass()
  local grass = display.newImageRect(groundGroup, "Grass.png", screenW, 40)
  physics.addBody(grass, "static", {density = 1.0, friction = 1.0})
  grass.x = display.contentCenterX
  grass.y = screenH - 10
  grass.name = "grass"
 end
 MakeGrass()
 
 StartGame = function()
  bubbleMaker = bubbleMaker_Lib.New(bubbleGroup, AdvancePopCounter, GameOver)
  bubbleMaker:MakeBlower(display.contentCenterX, 50, blowerBubbleCount, blowerSpeed, blowerPauseTime)
  bubbleMaker:StartBlower()
 end
 StartGame()
 
end

BubblePopper()