Restarting a level

Hello,

I’m having an issue restarting a level. I have reinstated and reset all my variables, but i get a bunch of runtime errors. Do I have to reset all of my functions as well and if so, how do I do that? I am using Director class 1.2. I heard Director version 1.3 has a reload scene ability, but I don’t know how to use it. Any help would be much appreciated. [import]uid: 47722 topic_id: 12015 reply_id: 312015[/import]

Post some of your code that highlights the problem, and some examples of the errors you are receiving. It’ll make it easier to try and help you :slight_smile: [import]uid: 26769 topic_id: 12015 reply_id: 43852[/import]

On a side note, if you have Runtime listeners going and change scenes, it will fall over.

But yes - code would help.

Peach :slight_smile: [import]uid: 52491 topic_id: 12015 reply_id: 43872[/import]

Here is the function I am trying to use to restart the level.

[blockcode]
function changeScene(e)
if (e.phase == “ended”) then

play_again.isVisible = false
play_again.alpha = 0
back_to_menu.isVisible = false
play_again.alpha = 0

if(e.target.scene) then
– Load main menu
director:changeScene(e.target.scene);
else
– Load game again
SCORE_LRG = 20
SCORE_MED = 15
SCORE_SML = 10
_score = 0
HEALTH_LRG = 7
HEALTH_MED = 2
HEALTH_SML = 5
_health = 100
health_up = false

end
end
end

play_again:addEventListener(“touch”, changeScene);
back_to_menu:addEventListener(“touch”, changeScene);
[/blockcode]

And here is the function that drops my objects randomly

[blockcode]
function newBlock()
rand = math.random( 100 )

if (rand < 60) then
local smallblock = display.newImageRect(“images/s_boulder.png”, 21, 21);
smallblock.x = 60 + math.random( 160 )
smallblock.y = -100
physics.addBody(smallblock, {density = 0.3, friction = 0.3})
smallblock:setLinearVelocity(0,300)
smallblock.name = “small block”

smallblock:addEventListener(“touch”, removeSmall)

localGroup:insert(smallblock)

elseif (rand < 80) then
local mediumblock = display.newImageRect(“images/m_boulder.png”, 27, 25);
mediumblock.x = 60 + math.random( 160 )
mediumblock.y = -100
physics.addBody(mediumblock, {density = 1.0, friction = 0.3})
mediumblock:setLinearVelocity(0,1)
mediumblock.name = “medium block”

mediumblock:addEventListener(“touch”, removeMedium)

localGroup:insert(mediumblock)

else
local largeblock = display.newImageRect(“images/l_boulder.png”, 42, 41);
largeblock.x = 60 + math.random( 160 )
largeblock.y = -100
physics.addBody(largeblock, {density = 2.0, friction = 0.3, radius = 20.5})
largeblock:setLinearVelocity(0,1)
largeblock.name = “large block”

largeblock:addEventListener(“touch”, removeLarge)

localGroup:insert(largeblock)

end

end

local dropBlocks = timer.performWithDelay( 500, newBlock, 100 )
[/blockcode] [import]uid: 47722 topic_id: 12015 reply_id: 43894[/import]

Here is a terminal error

/Users/username/Documents/Apps/Corona Project/game.lua:239: attempt to call method ‘insert’ (a nil value)
stack traceback:
[C]: in function ‘insert’
/Users/username/Documents/Apps/Corona Project/game.lua:239: in function ‘_listener’
?: in function <?:441>
?: in function <?:214>
[import]uid: 47722 topic_id: 12015 reply_id: 43895[/import]

I do have runtime listeners going, but I’m not quite sure what you mean [import]uid: 47722 topic_id: 12015 reply_id: 43907[/import]

It’s trying to call something after the scene change.

On the scene change make sure no timers or Runtime listeners are still active; you need to cancel/remove them. They’ll get re-added when you reload the scene.

Make sense? [import]uid: 52491 topic_id: 12015 reply_id: 44007[/import]

I’m still having no luck with this. I’m still getting an error with the listener and an error in line 14 in the code in message #3 above. I can’t figure this out and I’m so determined to find a way to do this. Is there any other way to restart a level besides the method I’m using now? Please remember that I am new to Corona. Any help is always much appreciated.

[import]uid: 47722 topic_id: 12015 reply_id: 44115[/import]

i don’t think anybody can point the exact problem, because the lack of information you provided.

All i can do, is giving some general thoughts.

I think your way is completely wrong. You are not restarting anything, you are just changing some values and you hope it to keep going.

I suggest you to learn implementing object oriented programming in lua. Lua is not a real object oriented language, but with some tricks, it can “simulate” it.

If you would have - say - a “level” object, you could reinitialize it as “level = myLevel.new()”

that way you would know that everything is re-created from the beginning.

there is a simple/sample object oriented game framework in code exchange. check it out, and learn how to write “objectified” and “modular” code.

That way, you could keep your code organized.

Either do this (which i think is the right way), or just paste some more code, and hope someone catch the mistake… [import]uid: 46529 topic_id: 12015 reply_id: 44124[/import]

I have the buttons set up so that a loadlevel1 scene is called by the restart button and after a second, the level reloads (like Ghosts vs Monsters). Here is the error I’m still getting

[blockcode]/Users/username/Documents/Apps/Corona Project/game.lua:241: attempt to call method ‘insert’ (a nil value)
stack traceback:
[C]: in function ‘insert’
/Users/username/Documents/Apps/Corona Project/game.lua:241: in function ‘_listener’
?: in function <?:441>
?: in function <?:214>
[/blockcode]

I believe the error is talking about line 12 of this code

[blockcode]
function newBlock()
rand = math.random( 100 )

if (rand < 60) then
local smallblock = display.newImageRect(“images/s_boulder.png”, 21, 21);
smallblock.x = 60 + math.random( 160 )
smallblock.y = -100
physics.addBody(smallblock, {density = 0.3, friction = 0.3})
smallblock:setLinearVelocity(0,300)
smallblock.name = “small block”

localGroup:insert(smallblock)

smallblock:addEventListener(“touch”, removeSmall)
end
end
[/blockcode]

Here is the function is use to restart the level.

[blockcode]

function restartLevel(event)
if (event.phase == “ended”) then
Runtime:removeEventListener( “collision”, block1Collision )
Runtime:removeEventListener( “collision”, block2Collision )
Runtime:removeEventListener( “collision”, block3Collision )
director:changeScene(“loadlevel1”)
end
end

play_again:addEventListener(“touch”, restartLevel)
[/blockcode]

The level does eventually reload, but some of my collisions and touch events don’t work. I still have no idea what’s wrong. Do I really need to take my code and start over/rewrite it from scratch? [import]uid: 47722 topic_id: 12015 reply_id: 44379[/import]

One trick I used with restarting a level was to transition to another screen, that just said loading… Then, have that screen reload your level. This is simpler that trying to write reset routines on the current level.

  1. get your level setup and working.

  2. player dies, or level ends and you want to restart
    — remove all runtime listeners.
    — cancel all timers (you should actually do this when the player dies)
    — transition to your intermediate screen, then have it transtion back to your level (after a couple of sceonds. Transitioning too fast will generate erros or crash your game in some instances) [import]uid: 55144 topic_id: 12015 reply_id: 44400[/import]

Thats what I set it up to do! I will try your suggestions, support47 and see if they work! [import]uid: 47722 topic_id: 12015 reply_id: 44407[/import]

One question…my timer looks like this
[blockcode] local dropBlocks = timer.performWithDelay( 500, newBlock, 100 ) [/blockcode]

How do I cancel it if it looks like that?

Do I use dropblocks = timer.cancel or do I use dropblocks = nil;

Thanks [import]uid: 47722 topic_id: 12015 reply_id: 44408[/import]

Try stay away from from hardcoding howmany time your time runs. Instead you can use ( 500, newBlock, 0) which will make your timer runs until you cancel them. But, either way I do believe you should still be able to cancel your timers whenever you want. In your case dropBlocks.cancel() should work. Also, I normally use cancel, and nil.

Also, one issue with this timer function is they can not be pause during a game. If you want to design your game so it can be paused and resume, then check out the link below, for a great add-on module from Jonathon Beebe.

http://jonbeebe.tumblr.com/post/2439016279/how-to-use-the-new-time-functions
[import]uid: 55144 topic_id: 12015 reply_id: 44426[/import]

Ok well I have no more errors, but when I press my play again button, only one of my three collisions are working. Could it be that the runtime listeners are not being added again upon scene reload? If so, how do I fix this?

Thanks. [import]uid: 47722 topic_id: 12015 reply_id: 44431[/import]

are all your collision listeners runtime. Do you have any that are object based (i.e. ship:addEventListener(“collision”, shipCollision) for example.) [import]uid: 55144 topic_id: 12015 reply_id: 44438[/import]

Yes they are all runtime. I have touch listeners that are object based, but all my collision listeners are runtime listeners. Should I try and change them to object based listeners?

Thanks [import]uid: 47722 topic_id: 12015 reply_id: 44441[/import]

I have experience unpredictable result when using multiple runtime listeners for the same event. I assign the collision event to each object, which helps with memory management. I used walls and floor off screen. so that if the object hit each other you can handle those event by check what objects are involve in the collision. Then in my case if the object hit the walls or floor, they need to be remove from game/memory [import]uid: 55144 topic_id: 12015 reply_id: 44485[/import]

Well I tried to change all my runtime listeners to object based listeners and I got nothing. I’m still getting the same issue with my play again or back to menu buttons. The large block collision always works but the other two don’t work consistently, The terminal reports no errors. I don’t know what to do at this point. I think I’m going to rewrite my entire set of code. If anyone can give me a clear example of using object based listeners and how to remove an object upon collision with these listeners, I would really appreciate it. I’ve looked at numerous collision examples and they have really confused me. [import]uid: 47722 topic_id: 12015 reply_id: 44618[/import]

Hopefully this will help. This is working code straight from my game, that show how to attached even listeners to objects when they are created/spawned.


local function spawnAliens()

local alienMissile = display.newImageRect(“images/alienprobe.png”, 40, 40)
alienMissile.name = “alienmissile”
physics.addBody(alienMissile, {friction=0.0, bounce=0})
alienMissile.x = myRandom(40, _W - 40); alienMissile.y = 10;

local alienMissileCollision = function(event)

if (event.other.name == “motherShip”) then
return
end

if (event.other.name == “shot”) then

display.remove(alienMissile)
alienMissile = nil

end
if (event.other.name == “floor”) then

display.remove(alienMissile)
alienMissile = nil

end
end

alienMissile:addEventListener(“collision”, alienMissileCollision)

end


p.s. you probably already know this, but just in case, check out the object.name = “name”. This is what allows me to figure out what objects are part of the collision.
[import]uid: 55144 topic_id: 12015 reply_id: 44639[/import]