I am creating an endless runner game called Petnapped, and have run into a minor error. The user receives three lives at the beginning, and when he/she hits an obstacle, it decreases by one, which is great. Once the lives count reaches zero, the game transitions to a losing scene, with the option to go back to the main menu and try again. However, when the game starts for the second time, the lives decrease by two when the obstacle is hit. If it is played a third time, it decreases by three, and so on, until I close and restart Corona itself with ctrl-r. Any ideas on how to fix this? Everything else works fine, it’s just the lives counting when an obstacle is hit. I have tried composer.removeScene( dog ) but that has not worked.
Hi @aec13a,
I assume you are using physics for collision detection? You probably will need to post some of your code, specifically where you are creating the object(s)… however, this issue suggests that you are adding multiple collision listeners to one of the objects (or all of them), so that on each re-run, you are getting multiple detections of the same event.
If you post code, please surround it with “lua” tags for clarity:
[lua] ... [/lua]
Best regards,
Brent
Thanks Brent! The code that follows are the parts where I display one obstacle and where the collision function happens. There is only one level, and if you have any more questions just let me know.
[lua]
–code for display obstacle (blueball) and character (dog)
local blueball = display.newImage( “BlueBall.png”)
blueball.x, blueball.y = 1240, 660
–blueball.alpha = 1
–blueball:scale(3,3)
physics.addBody( blueball, “kinematic”, {friction = 0.5, bounce = 0.3} )
blueball.myName = “blueball”
sceneGroup:insert(blueball)
local dog = display.newImage(“Dog1.png”)
dog.x = display.contentCenterX
dog.y = 660
physics.addBody( dog, “dynamic”, { friction = 0.5, bounce = 0.3} )
dog.myName = “dog”
–dog.rotation = 0
–clubhouse:play()
–transition.to(clubhouse, {x = display.contentWidth, y = display.contentHeight, time=8000})
sceneGroup:insert( dog )
–code for collision function and displaying lives
_G.lives = 3
local livestext = display.newText( "Lives: "… lives, display.contentCenterX, 100, “Imprint MT Shadow”, 60 )
livestext:setFillColor( 1, 0, 1 )
sceneGroup:insert( livestext )
hit = false
local function onCollision( event )
if (event.phase == “began” ) then
hit = true
print( "began: " … event.object1.myName … " and " … event.object2.myName )
elseif ( event.phase == “ended” ) then
print( "ended: " … event.object1.myName … " and " … event.object2.myName )
return true
end
if ( hit == true ) then
lives = lives - 1
print(“hit”)
livestext.text = "Lives: " … lives
end
end
Runtime:addEventListener( “collision”, onCollision )
[/lua]
Hi @aec13a,
As a general practice when using physics/collisions, I suggest that you don’t manage them using a Runtime collision listener. Typically that is “overkill” and will give you too many collision events to handle.
Is one of your physics objects somewhat of a common object that is used once, but might collide with many things? For example, a player in a game would be such a thing, or in your case, perhaps your “dog” is the main character which will collide with many different things (platforms, balls, cats, etc.). If this is the case, it’s much better to apply a collision listener only on the dog, and then manage collisions with other things upon it. This is more efficient than listening for collisions in Runtime and it will give you much better control on handling what the dog has collided with.
If you need help in doing this, let me know. It’s covered in the guide, however, under “Local Collisions”.
http://docs.coronalabs.com/guide/physics/collisionDetection/index.html
Brent
Hi @Brent Sorrentino,
I read through the article that you suggested and somewhat understood it, so I was able to change my code to match the onLocalCollision() function. Corona now runs it twice, when the dog collides with one object. Do I need to have three separate collision functions for my three different obstacles? Here’s the new function…
[lua]
_G.lives = 3
local livestext = display.newText( "Lives: "… lives, display.contentCenterX, 100, “Imprint MT Shadow”, 60 )
livestext:setFillColor( 1, 0, 1 )
sceneGroup:insert( livestext )
hit = false
local function onLocalCollision( self, event )
if (event.phase == “began” ) then
hit = true
print( self.myName … ": collision began with " … event.other.myName )
elseif ( event.phase == “ended” ) then
print( self.myName … " : collision ended with " … event.other.myName )
end
if ( hit == true ) then
lives = lives - 1
print(“hit”)
livestext.text = "Lives: " … lives
end
end
dog.collision = onLocalCollision
dog:addEventListener( “collision”, dog )
blueball.collision = onLocalCollision
blueball:addEventListener( “collision”, blueball)
tire.collision = onLocalCollision
tire:addEventListener( “collision”, tire )
tntbox.collision = onLocalCollision
tntbox:addEventListener( “collision”, tntbox )
[/lua]
Hi @aec13a,
The main idea is that you do not have multiple collision listeners… only one, on the main object which will be detecting collisions (in this case, it seems that your dog will be colliding with various objects, so that should be the only object you put a collision listener on). Then, when the dog collides with anything else, you detect what that “other” object is, and take the appropriate action. Very efficient, and it won’t trigger redundant collision events which you don’t care about.
Brent
Hi @aec13a,
I assume you are using physics for collision detection? You probably will need to post some of your code, specifically where you are creating the object(s)… however, this issue suggests that you are adding multiple collision listeners to one of the objects (or all of them), so that on each re-run, you are getting multiple detections of the same event.
If you post code, please surround it with “lua” tags for clarity:
[lua] ... [/lua]
Best regards,
Brent
Thanks Brent! The code that follows are the parts where I display one obstacle and where the collision function happens. There is only one level, and if you have any more questions just let me know.
[lua]
–code for display obstacle (blueball) and character (dog)
local blueball = display.newImage( “BlueBall.png”)
blueball.x, blueball.y = 1240, 660
–blueball.alpha = 1
–blueball:scale(3,3)
physics.addBody( blueball, “kinematic”, {friction = 0.5, bounce = 0.3} )
blueball.myName = “blueball”
sceneGroup:insert(blueball)
local dog = display.newImage(“Dog1.png”)
dog.x = display.contentCenterX
dog.y = 660
physics.addBody( dog, “dynamic”, { friction = 0.5, bounce = 0.3} )
dog.myName = “dog”
–dog.rotation = 0
–clubhouse:play()
–transition.to(clubhouse, {x = display.contentWidth, y = display.contentHeight, time=8000})
sceneGroup:insert( dog )
–code for collision function and displaying lives
_G.lives = 3
local livestext = display.newText( "Lives: "… lives, display.contentCenterX, 100, “Imprint MT Shadow”, 60 )
livestext:setFillColor( 1, 0, 1 )
sceneGroup:insert( livestext )
hit = false
local function onCollision( event )
if (event.phase == “began” ) then
hit = true
print( "began: " … event.object1.myName … " and " … event.object2.myName )
elseif ( event.phase == “ended” ) then
print( "ended: " … event.object1.myName … " and " … event.object2.myName )
return true
end
if ( hit == true ) then
lives = lives - 1
print(“hit”)
livestext.text = "Lives: " … lives
end
end
Runtime:addEventListener( “collision”, onCollision )
[/lua]
Hi @aec13a,
As a general practice when using physics/collisions, I suggest that you don’t manage them using a Runtime collision listener. Typically that is “overkill” and will give you too many collision events to handle.
Is one of your physics objects somewhat of a common object that is used once, but might collide with many things? For example, a player in a game would be such a thing, or in your case, perhaps your “dog” is the main character which will collide with many different things (platforms, balls, cats, etc.). If this is the case, it’s much better to apply a collision listener only on the dog, and then manage collisions with other things upon it. This is more efficient than listening for collisions in Runtime and it will give you much better control on handling what the dog has collided with.
If you need help in doing this, let me know. It’s covered in the guide, however, under “Local Collisions”.
http://docs.coronalabs.com/guide/physics/collisionDetection/index.html
Brent
Hi @Brent Sorrentino,
I read through the article that you suggested and somewhat understood it, so I was able to change my code to match the onLocalCollision() function. Corona now runs it twice, when the dog collides with one object. Do I need to have three separate collision functions for my three different obstacles? Here’s the new function…
[lua]
_G.lives = 3
local livestext = display.newText( "Lives: "… lives, display.contentCenterX, 100, “Imprint MT Shadow”, 60 )
livestext:setFillColor( 1, 0, 1 )
sceneGroup:insert( livestext )
hit = false
local function onLocalCollision( self, event )
if (event.phase == “began” ) then
hit = true
print( self.myName … ": collision began with " … event.other.myName )
elseif ( event.phase == “ended” ) then
print( self.myName … " : collision ended with " … event.other.myName )
end
if ( hit == true ) then
lives = lives - 1
print(“hit”)
livestext.text = "Lives: " … lives
end
end
dog.collision = onLocalCollision
dog:addEventListener( “collision”, dog )
blueball.collision = onLocalCollision
blueball:addEventListener( “collision”, blueball)
tire.collision = onLocalCollision
tire:addEventListener( “collision”, tire )
tntbox.collision = onLocalCollision
tntbox:addEventListener( “collision”, tntbox )
[/lua]
Hi @aec13a,
The main idea is that you do not have multiple collision listeners… only one, on the main object which will be detecting collisions (in this case, it seems that your dog will be colliding with various objects, so that should be the only object you put a collision listener on). Then, when the dog collides with anything else, you detect what that “other” object is, and take the appropriate action. Very efficient, and it won’t trigger redundant collision events which you don’t care about.
Brent