[Resolved] Removing Balloons

I got a mini game here. The point is to shoot the balloons. With each balloon shot it removes balloons.numbChildren by one. Each balloon on the screen equals one. So when all of the numChildren are gone and the gametimer is not equal to 0 it loads the next level. If you get a few levels in and then lose. When you come back into the game after a level or two it reads that numbchildren is a greater number. So it loads the next level on screen before all of the balloons are gone. This causes several errors in the game. Namely balloons that are on the screen that never go away. Here’s the full code for the game. If I can get help on this I would greatly appreciate it. This is the last bug I have in this game and upon fixing it I will finally be able to release this game.

[code]
module(…, package.seeall)

–====================================================================–
– SCENE: BALLOON LEVEL
–====================================================================–

–[[

  • Version: 0.2
  • Made by Ninja Carnival Team @ 2011

******************

  • INFORMATION
    ******************

  • Balloon Level

–]]

new = function ( params )

– Imports
local ui = require ( “ui” )

– Groups
local localGroup = display.newGroup()
local bg = display.newGroup()
local mg = display.newGroup()
local fg = display.newGroup()
local lg = display.newGroup()
– start physics
local physics = require(“physics”)
physics.start()
physics.setGravity(0,0 )
– Variables
local levelTimer = 15
local BALLOON_W = 41
local BALLOON_H = 21
local OFFSET = 23
local W_LEN = 12
local balloons = display.newGroup()
local toRemove = {}
local toRemove2 = {}
gameIsActive = true
currentLevel = 1
local gameEvent = ‘’
local levelText
local levelTextNum
local statTextSize = 16
local score = 0
local scoreNum = display.newText(0, 0, 0, native.systemFontBold, statTextSize)
local scoreText = display.newText(“SCORE:”, 0, 0, native.systemFontBold, statTextSize)
local gameTimer = 20
local levelCounter = 1
local levelText = display.newText (“Lvl:”, 0, 0, native.systemFontBold, statTextSize)
local levelTextNum = display.newText(1, 0, 0, native.systemFontBold, statTextSize)
local gameTimerText = display.newText(“20”, 0, 0, native.systemFontBold, statTextSize)

–Pre-load sounds and music
music = audio.loadStream(“LevelOneSong.mp3”)
sounds = {
pop = audio.loadSound(“balloonPopFinal.mp3”),
blow = audio.loadSound(“BlowingIntoDartGunFinal.mp3”)
}

–setup levels 1 through 10
local levels = {}
levels[1] = {{0,0,0,0,0,0,0,0,0,0,0,0},
{0,1,0,0,0,3,4,5,4,3,0,0},
{0,0,0,0,1,0,0,0,0,0,1,0},
{0,2,0,0,0,3,0,1,0,3,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,3,0,0,0,0,0,2,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,4,0,0,0,0,0,1,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0},}

levels[2] = {{0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,1,2,4,5,4,3,1,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,2,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,2,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,3,4,5,4,2,1,2,0,0,0},}

levels[3] = {{0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,4,0,1,0,3,0,2,0,5,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,3,0,0,0,0,0,0,0,3,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,2,0,0,0,0,0,0,0,1,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,1,0,0,0,0,0,0,0,2,0,0},}

levels[4] = {{0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,1,0,0,0,0,5,0},
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,2,0,0,0,3,0,0,0,0,3,0},
{0,0,2,0,4,0,4,0,2,0,0,0},
{0,0,0,0,0,4,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,2,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0},}

levels[5] = {{0,0,0,0,0,0,0,0,0,0,0,0},
{0,1,0,0,0,0,0,0,0,1,0,0},
{0,0,2,0,0,0,0,0,2,0,0,0},
{0,0,0,3,0,0,0,3,0,0,0,0},
{0,0,0,0,4,0,4,0,0,0,0,0},
{0,0,0,0,0,5,0,0,0,0,0,0},
{0,0,0,0,4,0,4,0,0,0,0,0},
{0,0,0,3,0,0,0,3,0,0,0,0},
{0,0,2,0,0,0,0,0,2,0,0,0},}

– Display Objects
local background = display.newImage(“Level_1_BG.png”)
– Player Stats
local statsBackground = display.newRect(0,0,_W,scoreText.height + 2.5)
– Functions

local function onCollision(self, event)
if self.name == “dart” and event.other.name == “balloon” then
score = score + 100
scoreNum.text = score

audio.play(sounds.pop)
table.insert(toRemove, event.other)
balloons.numChildren = balloons.numChildren - 1
table.insert(toRemove2,self)

end

if event.phase == “began” then
if(balloons.numChildren == 0 and table.maxn(levels) ~= currentLevel) then
gameEvent = “win”
local timer2 = timer.performWithDelay(60, restart, 1)
end
end

if (balloons.numChildren == 0 and table.maxn(levels) == currentLevel) then
gameEvent = “finished”

end

end

local function spawnPlayer ( event )

gun = display.newImage(“blowgun_50X50__2.png”)
gun.name = “gun”
gun.x = display.contentWidth / 2
gun.y = display.contentHeight - 30
gun:setReferencePoint(display.CenterReferencePoint)
mg:insert(gun)
return gun
end

–rotate gun
local rotDirection = 1
local function gunRotation(event)

gun.rotation = gun.rotation + rotDirection
if gun.rotation > 90 then
rotDirection = -1
elseif gun.rotation < -80 then
rotDirection = 1
end

end

–function for firing the dart
local function fireDart(event)

local dart = display.newImage(“dart.png”)
dart.name = “dart”
dart:setReferencePoint(display.CenterReferencePoint)
dart.x = gun.x
dart.y = gun.y
dart.rotation = gun.rotation
physics.addBody(dart, “dynamic”, {density=1.0, friction=0.5, bounce=0.0, radius= 10})
dart.linearDamping = 0.3
dart.angularDamping = 0.8
dart.isBullet = true
dart.isSensor = false
local speed = 500
local velocity = {}
velocity.x = math.cos( math.rad( dart.rotation - 90 ) ) * speed
velocity.y = math.sin( math.rad( dart.rotation - 90 ) ) * speed
audio.play(sounds.blow)
dart:applyForce(velocity.x, velocity.y, dart.x, dart.y)
dart.collision = onCollision
dart:addEventListener(“collision”, dart)

end

–function for creating level
function buildLevel(level)

local len = table.maxn(level)
balloons:toFront()

for i = 1, len do
for j = 1, W_LEN do
if(level[i][j] == 1) then
local balloon = display.newImage(“Blue_Bln_Down.png”)
balloon.name = “balloon”
balloon.x = BALLOON_W * j - OFFSET
balloon.y = BALLOON_H * i
physics.addBody(balloon, {density = .5, friction = 0, bounce = 0, radius = 15})
balloon.bodyType = ‘static’
balloons.insert(balloons, balloon)
elseif(level[i][j] == 2) then
local balloon = display.newImage(“yellow_down.png”)
balloon.name = “balloon”
balloon.x = BALLOON_W * j - OFFSET
balloon.y = BALLOON_H * i
physics.addBody(balloon, {density = .5, friction = 0, bounce = 0, radius = 15})
balloon.bodyType = ‘static’
balloons.insert(balloons, balloon)
elseif(level[i][j] == 3) then
local balloon = display.newImage(“Red_Bln_Down.png”)
balloon.name = “balloon”
balloon.x = BALLOON_W * j - OFFSET
balloon.y = BALLOON_H * i
physics.addBody(balloon, {density = .5, friction = 0, bounce = 0, radius = 15})
balloon.bodyType = ‘static’
balloons.insert(balloons, balloon)
elseif(level[i][j] == 4) then
local balloon = display.newImage(“Pink_Down.png”)
balloon.name = “balloon”
balloon.x = BALLOON_W * j - OFFSET
balloon.y = BALLOON_H * i
physics.addBody(balloon, {density = .5, friction = 0, bounce = 0, radius = 15})
balloon.bodyType = ‘static’
balloons.insert(balloons, balloon)
elseif(level[i][j] == 5) then
local balloon = display.newImage(“Peach_Down.png”)
balloon.name = “balloon”
balloon.x = BALLOON_W * j - OFFSET
balloon.y = BALLOON_H * i
physics.addBody(balloon, {density = .5, friction = 0, bounce = 0, radius = 15})
balloon.bodyType = ‘static’
balloons.insert(balloons, balloon)
end
end
end
end

local updateTimer = function( event )

gameTimer = gameTimer - 1
if gameTimer <= 0 then gameTimer = 0
end
gameTimerText.text = gameTimer

end

– function for changing levels
function restart(e)
print(“restart”)

if(gameEvent == ‘win’ and table.maxn(levels) > currentLevel) then
currentLevel = currentLevel + 1
balloons.numChildren = 0
changeLevel(levels[currentLevel])
print(“next level”)
elseif(gameEvent == ‘win’ and table.maxn(levels) == currentLevel) then
gameEvent = ‘finished’
balloons.numChildren = 0
print(“you win”)

elseif(gameEvent == ‘finished’ or gameEvent == ‘lose’) then
currentLevel = 0
balloons.numChildren = 0
end
end

function changeLevel(level)
print(balloons.numChildren)
levelCounter = levelCounter + 1
levelTextNum.text = levelCounter
balloons.numChildren = 0
balloons = display.newGroup()
gameTimer = 20
buildLevel(level)
end

function gameEnd( event )

gameEvent = “lose”
overScreenTimer = timer.performWithDelay(1500, gameOverScreen, 1)

end

function gameOverScreen(event)

localGroup:remove(background)
background = nil
print(“removed background”)
localGroup:remove(statsBackground)
statsBackground = nil
print(“removed statsbackground”)
localGroup:remove(scoreText)
scoreText = nil
print (“removed scoreText”)
localGroup:remove(scoreNum)
scoreNum = nil
print (“removed scoreNum”)
localGroup:remove(levelText)
levelText = nil
print (“removed levelText”)
localGroup:remove(levelTextNum)
levelTextNum = nil
print (" removed levelTextNum")
gun:removeEventListener(“tap”, fireDart)
print (“fire dart removed”)
Runtime:removeEventListener( “enterFrame”, gunRotation)
print (“rotation removed”)
localGroup:remove(gun)
gun = nil
print(“removed gun”)
balloons:removeSelf()
print(“balloons removed”)

overScreen = display.newImage(“game_over.png”)
m = " Touch For Title Screen "
msg = display.newText(m, 0, 0, native.systemFont, 12)
msg:setTextColor(254,203,50)
msg:setReferencePoint(display.CenterReferencePoint)
msg.x = display.contentWidth * 0.5
msg.y = display.contentHeight * 0.75
msg:addEventListener(“touch”, titleScreen)
lg:insert(overScreen)
lg:insert(msg)
localGroup:insert(lg)
end

function titleScreen( event)

timer.cancel(overScreenTimer)
audio.pause(music)
gameEvent = nil
director:changeScene(“mainmenu”)
localGroup:remove(overScreen)
localGroup:remove(msg)

end

– INITIALIZE
local initVars = function ()
– Inserts
bg:insert(background)
spawnPlayer()
fg:insert(statsBackground)
fg:insert(scoreText)
fg:insert(gameTimerText)
fg:insert(scoreNum)
fg:insert(levelText)
fg:insert(levelTextNum)

localGroup:insert(bg)
localGroup:insert(mg)
localGroup:insert(fg)
print(localGroup.numChildren)
– score positions

scoreText.x = (scoreText.width * 0.5) + 10
scoreText.y = (scoreText.height * 0.5) + 5
scoreNum:setReferencePoint(display.CenterLeftReferencePoint)
scoreNum.x = scoreText.width + 30
scoreNum.y = scoreText.y
levelText.x = (display.contentWidth * 0.75) + 25
levelText.y = levelText.height * 0.5
levelTextNum.x = (display.contentWidth * 0.75) + 45
levelTextNum.y = levelTextNum.height * 0.5

– timer position
gameTimerText.x = _W * 0.5
gameTimerText.y = scoreText.y

– Colors
statsBackground:setFillColor(50,0,0)
scoreText:setTextColor(255,0,0)
scoreNum:setTextColor(255,0,0)
levelText:setTextColor(255,0,0)
levelTextNum:setTextColor(255,0,0)
gameTimerText:setTextColor(255,0,0)

– Listeners
Runtime:addEventListener( “enterFrame”, gunRotation)
gun:addEventListener(“tap”, fireDart)
buildLevel(levels[1])
local timer3 = timer.performWithDelay(1000, updateTimer, 60)–left off here

–audio.play(music, {loops = -1})

end

– Initiate variables
initVars()

– Update
local update = function ( event )

for i = #toRemove, 1, -1 do
toRemove[i].parent:remove(toRemove[i])
toRemove[i] = nil
end
for i = #toRemove2,1,-1 do
toRemove2[i].parent:remove(toRemove2[i])
toRemove2[i] = nil
end

if gameTimer == 0 and balloons.numChildren ~= 0 then
balloons.numChildren = 0
gameEvent = “lost”
print(“you lose”)
end

if gameEvent == “lost” then
gameEnd()
print(“game over”)
end

end

Runtime:addEventListener(“enterFrame”, update)
– MUST return a display.newGroup()
return localGroup

end
[import]uid: 49863 topic_id: 25018 reply_id: 325018[/import]

Bump. [import]uid: 49863 topic_id: 25018 reply_id: 101736[/import]

This is a little long to go over, though maybe someone will.

Are you using a loop to remove all remaining children immediately before the scene change and stopping new ones from spawning prior to that? That is normally where issues like this occur. [import]uid: 52491 topic_id: 25018 reply_id: 101777[/import]

Yeah sorry about the length wasn’t sure what to specifically post since this part of the code is used in a lot of places and I am not even sure where the issue occurs. Not really using a loop. Every time the numchildren becomes zero and the game timer is not equal to zero it calls the restart function since it is looking to go to the next level I put balloons.numchildren at 0 there. Actually throughout the process I put balloons.numchildren to 0 before the next level is created. With a print statement it is telling me before the level is created that numchildren is 0. So I am unsure if that is the bug now. I also put timers with delays in for firing the dart and before the next level is created and that still didn’t fix the problem. Still somehow when you lose the game and go back into it after a few levels the thing goes wacky and moves to the next level before the balloons are all gone on screen. Then they stay on there so the number off children becomes insane and starts processing the next levels immediately. [import]uid: 49863 topic_id: 25018 reply_id: 101878[/import]

OK this is resolved. I had to add the lose objectives in the collision detection method. [import]uid: 49863 topic_id: 25018 reply_id: 102278[/import]

Awesome, well done - this was obviously a lot to go back over and am very happy to hear you solved it :slight_smile: [import]uid: 52491 topic_id: 25018 reply_id: 102376[/import]

Thanks Peach, Yeah I think I got 3,000 or so lines of code in this game all together. I will never make another game with mini games ever lol. This should be done and I should be releasing it today. I want to thank everyone in these threads that helped me out. It really does mean a lot to a new game dev to have this kind of help. [import]uid: 49863 topic_id: 25018 reply_id: 102417[/import]

Happy to hear that, will keep an eye out on the showcase :wink:

It’s a great little community and I’m sure everyone was happy to help - it’s the circle of progress I think, new users are helped by the experienced, they become experienced, they help new users, etc. - it’s a nice system. [import]uid: 52491 topic_id: 25018 reply_id: 102422[/import]