Game End Discussion

I just wanted to start a discussion here. I have been having a lot of difficulties on creating a proper exit to games. I have a game with four mini games in it. Obviously I need to exit once game to get to the next one. This game has been rejected by Apple because they said the quality was not good enough. When I went in to do some extensive testing on the game I realized the exiting of the mini games is extremely fragile. For instance if you touch the exit button during a collision it freezes up the game. If you go into one game play through it for a while then leave the game and come back into it then it freezes up. If you lose at a mini game after playing through it for a long period of time it freezes up. I was just wondering if anyone else has encountered these issues and if they have any pointers for methods on fixing it. [import]uid: 49863 topic_id: 29840 reply_id: 329840[/import]

Are you using storyboard or directory? It sounds like your issues are related to not removing objects/timers/event listeners. Not properly managing this can cause some major headaches. [import]uid: 147305 topic_id: 29840 reply_id: 119702[/import]

I am using director. I thought I kept track of all objects, timers, and listeners. I don’t know what else could cause this though. [import]uid: 49863 topic_id: 29840 reply_id: 119783[/import]

Here is my code if it helps. I know there is a lot there but basically you just need to follow the things that need to be removed.

[lua]module(…, package.seeall)

–====================================================================–
– SCENE: TEMPLATE
–====================================================================–

–[[

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

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

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

  • Template

–]]

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 balloons = display.newGroup()

– start physics

local physics = require(“physics”)
physics.start()
physics.setGravity(0,9.18 )

–initialize variables
local currentLevel = 1
dartsLeft = 3
local gameState = “start”
local toRemove = {}
local toRemove2 = {}
local rotDirection = 1
local BALLOON_W = 41
local BALLOON_H = 21
local OFFSET = 23
local W_LEN = 12
–setup levels
local levels = {}
levels[1] = {{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,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,3,0,1,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,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,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},}

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

– Display Objects

local background = display.newImage(“balloonBackground.png”)
local statsBackground = display.newRect(0,0, display.contentWidth, 25)
local gameExitBtn = display.newImage(“game_exit_final.png”)

– BUTTONS

– Functions


-------creating collision detection--------------------------------------------

local function onCollision(self, event)
if self.name == “dart” and event.other.name == “balloon” then -----determine if the collision between dart and balloon happens
–score = score + 100 -----score increases if balloon is popped
–scoreNum.text = score -----print score to screen

audio.play(sounds.pop) -----play sound effect
sounds.pop = nil

table.insert(toRemove, event.other) ----put dart in table to be removed later

end

end


-------creating the scene------------------------------------------------------

local function createPlayer()

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

end

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

local function fireDart(event)

if dartsLeft ~= 0 then

dartsLeft = dartsLeft - 1
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)
localGroup:insert(dart)
dart.collision = onCollision
dart:addEventListener(“collision”, dart)

if event.phase == “ended” then

sounds.blow = nil
speed = nil
velocity = nil
dart = nil

end

if dart.isVisible == false then
dart:removeEventListener(“collision”, dart)
localGroup:remove(dart)
dart = nil

end
end

end


----------------draw level-----------------------------------------------------

local function spawnScreenDarts(dartsLeft)

dart2 = display.newImage(“dart.png”)
dart2.name = “dart2”
dart2:setReferencePoint(display.CenterReferencePoint)
dart2.x = 5
dart2.y = display.contentHeight - 25
fg:insert(dart2)

dart3 = display.newImage(“dart.png”)
dart3.name = “dart3”
dart3:setReferencePoint(display.CenterReferencePoint)
dart3.x = 15
dart3.y = display.contentHeight - 25
fg:insert(dart3)

dart4 = display.newImage(“dart.png”)
dart4.name = “dart4”
dart4:setReferencePoint(display.CenterReferencePoint)
dart4.x = 25
dart4.y = display.contentHeight - 25
fg:insert(dart4)
dartsLeft = 3
return dartsLeft
end

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_Base_Shadows.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_Base_Shadow.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_Base_Shadows.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_Base_Shadow.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(“Green_Base_Shadow.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


---------------change levels---------------------------------------------------

local createLevel = function(event)

currentLevel = currentLevel + 1
changeLevel2(levels[currentLevel])

end

function changeLevel2(level)

buildLevel(level)
dart2.isVisible = true
dart3.isVisible = true
dart4.isVisible = true
dartsLeft = 3
Runtime:addEventListener( “enterFrame”, changeLevel)

end

function changeLevel(event)

if balloons.numChildren == 0 and gameState == “removing balloons” and table.maxn(levels) ~= currentLevel then

timer.performWithDelay(5000, createLevel, 1)
Runtime:removeEventListener( “enterFrame”, changeLevel)

end

end


--------game ending functions--------------------------------------------------

local function endGame()

director:changeScene(“mainmenu”)

end

local function removeOverScreenObjects()

timer.performWithDelay(1000, endGame, 1)

end

local function removeObjects()

localGroup:remove(gun)
localGroup:remove(background)
localGroup:remove(gameExitBtn)
localGroup:remove(statsBackground)
localGroup:remove(balloon)
localGroup:remove(dart2)
localGroup:remove(dart3)
localGroup:remove(dart4)
dart2 = nil
dart3 = nil
dart4 = nil
balloon = nil
gun = nil
background = nil
gameExitBtn = nil
statsBackground = nil
rotDirection = nil
BALLOON_W = nil
BALLOON_H = nil
OFFSET = nil
W_LEN = nil
levels = nil
dartsLeft = nil
music = nil
sounds = nil
gameState = nil
timer.performWithDelay(1000, removeOverScreenObjects, 1)

end

local function removeListeners(event)
if event.phase == “ended” then
gameExitBtn:removeEventListener(“touch”, removeListeners)
gun:removeEventListener(“tap”, fireDart)
Runtime:removeEventListener( “enterFrame”, gunRotation)
Runtime:removeEventListener(“enterFrame”, update)
timer.performWithDelay(500, removeObjects(), 1)
end
end

local function removeListeners2(event)

gameState = “game over”
Runtime:removeEventListener(“enterFrame”, gameOver)
Runtime:removeEventListener(“enterFrame”, update)
gameExitBtn:removeEventListener(“touch”, removeListeners)
gun:removeEventListener(“tap”, fireDart)
Runtime:removeEventListener( “enterFrame”, gunRotation)
timer.performWithDelay(1000, removeObjects(), 1)

end

function gameOver(event)

if dartsLeft == 0 and balloons.numChildren ~= 0 and gameState ~= “game over” then

timer.performWithDelay(10000, removeListeners2, 1)

end

end


---------update function------------------------------------------------------

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

remove(toRemove2[i])
toRemove2[i] = nil

end

if dartsLeft == 2 then

dart4.isVisible = false

elseif dartsLeft == 1 then

dart3.isVisible = false

elseif dartsLeft == 0 then

dart2.isVisible = false

end

if balloons.numChildren == 0 then

if dart4.isVisible == true then
dart4.isVisible = false
end
if dart3.isVisible == true then
dart3.isVisible = false
end
if dart2.isVisible == true then
dart2.isVisible = false
end
dartsLeft = 0
gameState = “removing balloons”

end

end

– PARAMETERS

– Listener
– INITIALIZE
local initVars = function ()
– Inserts
bg:insert(background)
bg:insert(statsBackground)
fg:insert(gameExitBtn)
localGroup:insert(bg)
localGroup:insert(mg)
localGroup:insert(fg)
localGroup:insert(balloons)
– Positions
gameExitBtn:setReferencePoint(display.CenterReferencePoint)
gameExitBtn.xScale = 0.5
gameExitBtn.yScale = 0.5
gameExitBtn.x = display.contentWidth - 20
gameExitBtn.y = display.contentHeight - 15

– Colors

– Listeners
createPlayer()
buildLevel(levels[1])
spawnScreenDarts()
Runtime:addEventListener( “enterFrame”, gunRotation)
Runtime:addEventListener( “enterFrame”, changeLevel)
gun:addEventListener(“tap”, fireDart)
Runtime:addEventListener(“enterFrame”, update)
Runtime:addEventListener(“enterFrame”, gameOver)
gameExitBtn:addEventListener(“touch”, removeListeners)
end

– Initiate variables
initVars()

– MUST return a display.newGroup()
return localGroup

end [import]uid: 49863 topic_id: 29840 reply_id: 120083[/import]

bump
[import]uid: 49863 topic_id: 29840 reply_id: 120322[/import]

Are you using storyboard or directory? It sounds like your issues are related to not removing objects/timers/event listeners. Not properly managing this can cause some major headaches. [import]uid: 147305 topic_id: 29840 reply_id: 119702[/import]

I am using director. I thought I kept track of all objects, timers, and listeners. I don’t know what else could cause this though. [import]uid: 49863 topic_id: 29840 reply_id: 119783[/import]

OK the exit button works fine. It removes everything with no errors. For some reason the other exit method for losing the game doesn’t work. It’s weird because I do the same thing for the exit button press that I do if the player loses the game. [import]uid: 49863 topic_id: 29840 reply_id: 120691[/import]

I guess this is why all game developers require you to hit a button to exit a game and not just end it. I will just use this method only for exiting the game. [import]uid: 49863 topic_id: 29840 reply_id: 120717[/import]

Here is my code if it helps. I know there is a lot there but basically you just need to follow the things that need to be removed.

[lua]module(…, package.seeall)

–====================================================================–
– SCENE: TEMPLATE
–====================================================================–

–[[

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

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

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

  • Template

–]]

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 balloons = display.newGroup()

– start physics

local physics = require(“physics”)
physics.start()
physics.setGravity(0,9.18 )

–initialize variables
local currentLevel = 1
dartsLeft = 3
local gameState = “start”
local toRemove = {}
local toRemove2 = {}
local rotDirection = 1
local BALLOON_W = 41
local BALLOON_H = 21
local OFFSET = 23
local W_LEN = 12
–setup levels
local levels = {}
levels[1] = {{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,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,3,0,1,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,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,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},}

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

– Display Objects

local background = display.newImage(“balloonBackground.png”)
local statsBackground = display.newRect(0,0, display.contentWidth, 25)
local gameExitBtn = display.newImage(“game_exit_final.png”)

– BUTTONS

– Functions


-------creating collision detection--------------------------------------------

local function onCollision(self, event)
if self.name == “dart” and event.other.name == “balloon” then -----determine if the collision between dart and balloon happens
–score = score + 100 -----score increases if balloon is popped
–scoreNum.text = score -----print score to screen

audio.play(sounds.pop) -----play sound effect
sounds.pop = nil

table.insert(toRemove, event.other) ----put dart in table to be removed later

end

end


-------creating the scene------------------------------------------------------

local function createPlayer()

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

end

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

local function fireDart(event)

if dartsLeft ~= 0 then

dartsLeft = dartsLeft - 1
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)
localGroup:insert(dart)
dart.collision = onCollision
dart:addEventListener(“collision”, dart)

if event.phase == “ended” then

sounds.blow = nil
speed = nil
velocity = nil
dart = nil

end

if dart.isVisible == false then
dart:removeEventListener(“collision”, dart)
localGroup:remove(dart)
dart = nil

end
end

end


----------------draw level-----------------------------------------------------

local function spawnScreenDarts(dartsLeft)

dart2 = display.newImage(“dart.png”)
dart2.name = “dart2”
dart2:setReferencePoint(display.CenterReferencePoint)
dart2.x = 5
dart2.y = display.contentHeight - 25
fg:insert(dart2)

dart3 = display.newImage(“dart.png”)
dart3.name = “dart3”
dart3:setReferencePoint(display.CenterReferencePoint)
dart3.x = 15
dart3.y = display.contentHeight - 25
fg:insert(dart3)

dart4 = display.newImage(“dart.png”)
dart4.name = “dart4”
dart4:setReferencePoint(display.CenterReferencePoint)
dart4.x = 25
dart4.y = display.contentHeight - 25
fg:insert(dart4)
dartsLeft = 3
return dartsLeft
end

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_Base_Shadows.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_Base_Shadow.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_Base_Shadows.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_Base_Shadow.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(“Green_Base_Shadow.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


---------------change levels---------------------------------------------------

local createLevel = function(event)

currentLevel = currentLevel + 1
changeLevel2(levels[currentLevel])

end

function changeLevel2(level)

buildLevel(level)
dart2.isVisible = true
dart3.isVisible = true
dart4.isVisible = true
dartsLeft = 3
Runtime:addEventListener( “enterFrame”, changeLevel)

end

function changeLevel(event)

if balloons.numChildren == 0 and gameState == “removing balloons” and table.maxn(levels) ~= currentLevel then

timer.performWithDelay(5000, createLevel, 1)
Runtime:removeEventListener( “enterFrame”, changeLevel)

end

end


--------game ending functions--------------------------------------------------

local function endGame()

director:changeScene(“mainmenu”)

end

local function removeOverScreenObjects()

timer.performWithDelay(1000, endGame, 1)

end

local function removeObjects()

localGroup:remove(gun)
localGroup:remove(background)
localGroup:remove(gameExitBtn)
localGroup:remove(statsBackground)
localGroup:remove(balloon)
localGroup:remove(dart2)
localGroup:remove(dart3)
localGroup:remove(dart4)
dart2 = nil
dart3 = nil
dart4 = nil
balloon = nil
gun = nil
background = nil
gameExitBtn = nil
statsBackground = nil
rotDirection = nil
BALLOON_W = nil
BALLOON_H = nil
OFFSET = nil
W_LEN = nil
levels = nil
dartsLeft = nil
music = nil
sounds = nil
gameState = nil
timer.performWithDelay(1000, removeOverScreenObjects, 1)

end

local function removeListeners(event)
if event.phase == “ended” then
gameExitBtn:removeEventListener(“touch”, removeListeners)
gun:removeEventListener(“tap”, fireDart)
Runtime:removeEventListener( “enterFrame”, gunRotation)
Runtime:removeEventListener(“enterFrame”, update)
timer.performWithDelay(500, removeObjects(), 1)
end
end

local function removeListeners2(event)

gameState = “game over”
Runtime:removeEventListener(“enterFrame”, gameOver)
Runtime:removeEventListener(“enterFrame”, update)
gameExitBtn:removeEventListener(“touch”, removeListeners)
gun:removeEventListener(“tap”, fireDart)
Runtime:removeEventListener( “enterFrame”, gunRotation)
timer.performWithDelay(1000, removeObjects(), 1)

end

function gameOver(event)

if dartsLeft == 0 and balloons.numChildren ~= 0 and gameState ~= “game over” then

timer.performWithDelay(10000, removeListeners2, 1)

end

end


---------update function------------------------------------------------------

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

remove(toRemove2[i])
toRemove2[i] = nil

end

if dartsLeft == 2 then

dart4.isVisible = false

elseif dartsLeft == 1 then

dart3.isVisible = false

elseif dartsLeft == 0 then

dart2.isVisible = false

end

if balloons.numChildren == 0 then

if dart4.isVisible == true then
dart4.isVisible = false
end
if dart3.isVisible == true then
dart3.isVisible = false
end
if dart2.isVisible == true then
dart2.isVisible = false
end
dartsLeft = 0
gameState = “removing balloons”

end

end

– PARAMETERS

– Listener
– INITIALIZE
local initVars = function ()
– Inserts
bg:insert(background)
bg:insert(statsBackground)
fg:insert(gameExitBtn)
localGroup:insert(bg)
localGroup:insert(mg)
localGroup:insert(fg)
localGroup:insert(balloons)
– Positions
gameExitBtn:setReferencePoint(display.CenterReferencePoint)
gameExitBtn.xScale = 0.5
gameExitBtn.yScale = 0.5
gameExitBtn.x = display.contentWidth - 20
gameExitBtn.y = display.contentHeight - 15

– Colors

– Listeners
createPlayer()
buildLevel(levels[1])
spawnScreenDarts()
Runtime:addEventListener( “enterFrame”, gunRotation)
Runtime:addEventListener( “enterFrame”, changeLevel)
gun:addEventListener(“tap”, fireDart)
Runtime:addEventListener(“enterFrame”, update)
Runtime:addEventListener(“enterFrame”, gameOver)
gameExitBtn:addEventListener(“touch”, removeListeners)
end

– Initiate variables
initVars()

– MUST return a display.newGroup()
return localGroup

end [import]uid: 49863 topic_id: 29840 reply_id: 120083[/import]

bump
[import]uid: 49863 topic_id: 29840 reply_id: 120322[/import]

OK the exit button works fine. It removes everything with no errors. For some reason the other exit method for losing the game doesn’t work. It’s weird because I do the same thing for the exit button press that I do if the player loses the game. [import]uid: 49863 topic_id: 29840 reply_id: 120691[/import]

I guess this is why all game developers require you to hit a button to exit a game and not just end it. I will just use this method only for exiting the game. [import]uid: 49863 topic_id: 29840 reply_id: 120717[/import]