End Game and Collision Help !

Hi,

I got a really big problem and I don’t know how to resolve it … so I really need your help !

I am creating a simple game for a school project.

I would like to finalize my game by adding an end when the armadillo touch a meteorite, however I don’t know how. Ideally when the armadillo creates a meteor collision, the game stops, displays the score and brings up the button “play again” which allows you to replay, but I really do not know how to do that … At the end of the program, I put  a green text what I had found on another program I made, I don’t know if it is really helpful, but you never know …

I’ll be very grateful if you can help me finish my game.

I joined you my program, any help will help me.

Thank you already for your great help.

Lucas

[lua] --Game scene
local composer = require(“composer”)
local scene = composer.newScene()

–Physic function
local physics = require (“physics”)
physics.start ()
physics.setGravity(0, 0)
–physics.setDrawMode(“hybrid”)

local leftWall = display.newRect(0, display.contentCenterY, 1, 700)
local rightWall = display.newRect(320, display.contentCenterY, 1, 700)
local flooring = display.newRect (display.contentCenterX, 520, 500, 1 )
local ceiling = display.newRect(display.contentCenterX, -44, 500, 1 )
physics.addBody(leftWall, “static”, { bounce = 0.1})
physics.addBody(rightWall, “static”, { bounce = 0.1})
physics.addBody(ceiling, “static”, { bounce = 0.1})
physics.addBody(flooring, “static”, { bounce = 0.1})

–createMeteor()

function scene:create(event)
–Background
local background = display.newImage(“fond.png”, 200, 250, 480, 70)

–Player
local armadillo = display.newImage (“arm.png”, 160, 200, 30)
physics.addBody(armadillo, “dynamic”,{ bounce =0.8,friction = 1.0})
armadillo.gravityScale = 0
armadillo.isFixedRotation = true
armadillo.ID = “arma”

_W = display.contentWidth;
_H = display.contentHeight;
motionx = 0;
motiony = 0
speed = 3;

–create button
local gauche = display.newImage(“boutongauche.png”)
gauche.x = 50; gauche.y = 460;
local droit = display.newImage(“boutondroit.png”)
droit.x = 150; droit.y = 460
local bas = display.newImage(“boutonbas.png”)
bas.x = 100; bas.y = 460
local haut = display.newImage(“boutonhaut.png”)
haut.x = 100; haut.y = 410

–move character
function gauche:touch()
motionx = -speed;
end
gauche:addEventListener(“touch”,gauche)

function droit:touch()
motionx = speed;
end
droit:addEventListener(“touch”,droit)

function haut:touch()
motiony = -speed;
end
haut:addEventListener(“touch”, haut)

function bas:touch()
motiony = speed;
end
bas:addEventListener(“touch”, bas)

local function movearmadillo (event)
armadillo.x = armadillo.x + motionx;
armadillo.y = armadillo.y + motiony
local function stop (event)
if event.phase ==“ended” then
motionx = 0;
motiony = 0
end

end
Runtime:addEventListener(“touch”, stop )
end
Runtime:addEventListener(“enterFrame”, movearmadillo)

local function spawn( objectType, x, y )
local meteor
local sizeXY = math.random( 20, 100 )
local collisionFilter = { categoryBits = 4, maskBits = 2 }
local body = { filter=collisionFilter, isSensor=true }
local meteor = display.newImage(“meteor.png”)
physics.addBody(meteor, “dynamic”,{friction = 1.0, radius={200}})
meteor.x = math.random (5, 315)
meteor.y = math.random (-40, 515)
function moveMeteor()
transition.to(meteor, {time=2000, x=math.random(5, 315), y=math.random(-40,515), onComplete=moveMeteor})
end
moveMeteor()
end

local meteor = spawn (“meteor.png”)

local function spawn2( objectType, x, y )
local meteor2
local sizeXY = math.random( 20, 100 )
local collisionFilter = { categoryBits = 4, maskBits = 2 }
local body = { filter=collisionFilter, isSensor=true }
local meteor2 = display.newImage(“meteor.png”)
physics.addBody(meteor2, “dynamic”,{friction = 1.0, radius={200}})
meteor2.x = math.random (5, 315)
meteor2.y = math.random (-40, 515)
function moveMeteor2()
transition.to(meteor2, {time=2000, x=math.random(5, 315), y=math.random(-40,515), onComplete=moveMeteor2})
end
moveMeteor2()
end

local meteor2 = spawn2 (“meteor.png”)

–Score
local score = 0

local scoreTxt = display.newText(score, 300, 30, font, 50)
scoreTxt.x = 160
scoreTxt.y = -23
local function updateScore()
score = score + 1
scoreTxt.text = score
end

local scoreTimer = timer.performWithDelay(1000, updateScore, -1)

–collision

–end game

–function endGame ()
–armadillo:removeEventListener( “collision”, armadillo)
–Runtime:removeEventListener (“enterFrame”, onUpdate)
–background:removeEventListener (“touch”, flapBird)
–local promptEnd = display.newText (“You Lost !”, 160, 100, font, 32)
–promptEnd:setFillColor (0,0,0)
–local promptReplay = display.newText (“Play Again”, 160, 240, font, 32)
–promptReplay:setFillColor(0,0,0)
–sceneGroup:insert (promptEnd)
–sceneGroup:insert (promptReplay)
–local function replay(event)
–if (event.phase == “began”) then
–composer.gotoScene (“mainMenu”, {effect = “fade”, time = 1000})
–end
–end
–promptReplay:addEventListener (“touch”, replay)
–end

–armadillo.collision = onLocalCollision
–armadillo:addEventListener(“collision”, armadillo)

end

scene:addEventListener(“create”, scene)
return scene[/lua]

That’s very hard to read. You’ll get better and quicker replies if you format things properly.

Have a look here: https://coronalabs.com/blog/2015/06/09/tutorial-the-value-of-well-formatted-code/

You’re using composer, so why not create a gameover scene?

When the collision happens, you’d just need to call composer.gotoScene(“gameover”).

Your gameover scene could then have a button that when tapped uses composer.gotoScene() to go back to the game.

Hi !

I did what you say and thats good, thank you ! But I have an other problem … when i relaunch the playGame scene or the mainMenu scene the physics of my player and the meteor doesn’t dissappear … so when i play for the second time i have 2 players and 4 meteors but only one player and 2 meteor are visible … i noticed this when i write “physics.setDrawMode(“hybrid”)” …

How can I do to destroy these physics or can I relaunch the entire game if I clic on a button as if i start the game for the first time ?

Thank you for your answers !

Lucas

I’m not sure exactly what the behaviour you’re describing is, but I can make a couple of important points. First of all, when you use composer, every object needs to be inserted into its scene. Have a look at the templatefor a composer scene. Notice that inside each method is the line

 local sceneGroup = self.view

You need to use sceneGroup:insert(yourObject) on every object in the scene so that composer will control it properly as you move between different scenes.

Secondly, composer scenes have show and hide methods as you can see in the template. The show method would be a good place to add physics to objects, and the hide method would be a good place to remove the physics.

Hi Hasty,

I’m really sorry but I don’t understand what you said … I think it’s the good thing to resolve my problem but i don’t find the lines code I had to put on my program … it would be very nice if you could give me the code to write, I will find where to place them. If you do that, I would be saved because I have to give the project finish to my profesor in 2 weeks …

I still search but if you do that I will be very happy !

Thank you !

Lucas

I’d hate to give too much away and get you in trouble with your professor. I’ll show you a small project though, that shows how to properly insert objects into scenes, change between scenes, and use scene:show() and scene:hide() to control what happens in your game:

-- menu.lua local composer = require( "composer" ) local scene = composer.newScene() local function startTap(event) composer.gotoScene("game") end function scene:create( event ) local sceneGroup = self.view local background = display.newRect(display.contentCenterX, display.contentCenterY, display.contentWidth, display.contentHeight ) background:setFillColor(0.1, 0, 0.1) local startButton = display.newText( "START", display.contentCenterX, display.contentCenterY) startButton:addEventListener("tap", startTap) -- objects should be inserted into the sceneGroup sceneGroup:insert( background ) sceneGroup:insert( startButton ) end scene:addEventListener( "create", scene ) return scene

-- game.lua local composer = require( "composer" ) local scene = composer.newScene() local myCrate -- Im forward declaring myCrate here, so that I can access it in the functions below -- if I only declared it inside scene:create() then I would not be able to do anything with it -- in scene:show() or scene:hide() local function menuTap(event) composer.gotoScene("menu") end function scene:create( event ) local sceneGroup = self.view local background = display.newRect(display.contentCenterX, display.contentCenterY, display.contentWidth, display.contentHeight ) background:setFillColor(0.1, 0.1, 0) myCrate = display.newImage("crate.png") -- note that I do not use "local" here; myCrate is declared above so that -- it is in scope for each scene function. local menuButton = display.newText( "MENU", 250, 25) menuButton:addEventListener("tap", menuTap) -- objects should be inserted into the sceneGroup sceneGroup:insert(background) sceneGroup:insert(myCrate) sceneGroup:insert(menuButton) end function scene:show( event ) local phase = event.phase if ( phase == "will" ) then -- Called when the scene is still off screen (but is about to come on screen). myCrate.x, myCrate.y = display.contentCenterX, display.contentCenterY -- this will put myCrate back to the middle every time you go to this scene elseif ( phase == "did" ) then -- Called when the scene is now on screen. -- Insert code here to make the scene come alive. -- Example: start timers, begin animation, play audio, etc. transition.to(myCrate, {x = 0, y = 0, time = 5000, tag = "mc"}) -- this will make myCrate move to top left every time you start the scene. end end function scene:hide( event ) local phase = event.phase if ( phase == "will" ) then -- Called when the scene is on screen (but is about to go off screen). -- Insert code here to "pause" the scene. -- Example: stop timers, stop animation, stop audio, etc. transition.cancel("mc") -- this will cancel myCrates transition when you go to another scene. elseif ( phase == "did" ) then -- Called immediately after scene goes off screen. end end scene:addEventListener( "create", scene ) scene:addEventListener( "show", scene ) scene:addEventListener( "hide", scene ) return scene

I may be a bit stupid or I do not understand anything but I did led me to an even worse result than what I had before … meteor pictures and armadillo not s’ appear more and meteorites do not move. Also the score is no longer displayed … I really feel like you wasting your time I’m sorry but I really need help!

I think my only problem comes from poor provision of the code, not the code itself …

Moreover, there is no problem with my teacher this is just an option and is professor of computer science, he knew absolutely no corona sdk before I will make him discover.

Thank you again for your help, I will seal my code.

--Game scene local composer = require("composer") local scene = composer.newScene() --Physic function local physics = require ("physics") physics.start () physics.setGravity(0, 0) physics.setDrawMode("hybrid") local leftWall = display.newRect(0, display.contentCenterY, 1, 700) local rightWall = display.newRect(320, display.contentCenterY, 1, 700) local flooring = display.newRect (display.contentCenterX, 520, 500, 1 ) local ceiling = display.newRect(display.contentCenterX, -44, 500, 1 ) physics.addBody(leftWall, "static", { bounce = 0.1}) physics.addBody(rightWall, "static", { bounce = 0.1}) physics.addBody(ceiling, "static", { bounce = 0.1}) physics.addBody(flooring, "static", { bounce = 0.1}) --createMeteor() function scene:create(event) --Background local background = display.newImage("fond.png", 200, 250, 480, 70) end function scene:show (event) local phase = event.phase if (phase == "will") then local sceneGroup = self.view \_W = display.contentWidth; \_H = display.contentHeight; motionx = 0; motiony = 0 speed = 3; local armadillo = display.newImage ("arm.png", 160, 280) physics.addBody(armadillo, "dynamic",{ bounce =0.8,friction = 1.0}) armadillo.gravityScale = 0 armadillo.x = 160 armadillo.y = 200 armadillo.isFixedRotation = true armadillo.ID = "arma" armadillo.myName = "player" sceneGroup:insert(armadillo) local function movearmadillo (event) armadillo.x = armadillo.x + motionx; armadillo.y = armadillo.y + motiony local function stop (event) if event.phase =="ended" then motionx = 0; motiony = 0 end end Runtime:addEventListener("touch", stop ) end Runtime:addEventListener("enterFrame", movearmadillo) elseif (phase =="did") then local sceneGroup = self.view local gauche = display.newImage("boutongauche.png") gauche.x = 50; gauche.y = 460; local droit = display.newImage("boutondroit.png") droit.x = 150; droit.y = 460 local bas = display.newImage("boutonbas.png") bas.x = 100; bas.y = 460 local haut = display.newImage("boutonhaut.png") haut.x = 100; haut.y = 410 --move character function gauche:touch() motionx = -speed; end gauche:addEventListener("touch",gauche) function droit:touch() motionx = speed; end droit:addEventListener("touch",droit) function haut:touch() motiony = -speed; end haut:addEventListener("touch", haut) function bas:touch() motiony = speed; end bas:addEventListener("touch", bas) local function spawn( objectType, x, y ) local meteor local sizeXY = math.random( 20, 100 ) local collisionFilter = { categoryBits = 4, maskBits = 2 } local body = { filter=collisionFilter, isSensor=true } local meteor = display.newImage("meteor.png") meteor.x = math.random (5, 315) meteor.y = math.random (-40, 515) meteor.myName = "meteor" physics.addBody(meteor, "dynamic",{friction = 1.0, radius={200}}) sceneGroup:insert(meteor) end local meteor = spawn ("meteor.png") local function spawn2( objectType, x, y ) local meteor2 local sizeXY = math.random( 20, 100 ) local collisionFilter = { categoryBits = 4, maskBits = 2 } local body = { filter=collisionFilter, isSensor=true } local meteor2 = display.newImage("meteor.png") meteor2.x = math.random (5, 315) meteor2.y = math.random (-40, 515) meteor2.myName = "meteor2" physics.addBody(meteor2, "dynamic",{friction = 1.0, radius={200}}) sceneGroup:insert(meteor2) end local meteor2 = spawn2 ("meteor.png") function moveMeteor() transition.to(meteor, {time=2000, x=math.random(5, 315), y=math.random(-40,515), onComplete=moveMeteor}) end moveMeteor() function moveMeteor2() transition.to(meteor2, {time=2000, x=math.random(5, 315), y=math.random(-40,515), onComplete=moveMeteor2}) end moveMeteor2() local score = 0 local scoreTxt = display.newText(score, 300, 30, font, 50) scoreTxt.x = 160 scoreTxt.y = -23 sceneGroup:insert(scoreTxt) local function updateScore() score = score + 1 scoreTxt.text = score end local scoreTimer = timer.performWithDelay(1000, updateScore, -1) end end function scene:hide (event) local phase = event.phase if(phase == "will") then function onCollision(event) if(event.object1.myName == "player" and event.object2.myName == "meteor") or (event.object1.myName == "meteor" and event.object2.myName == "player") or (event.object1.myName == "player" and event.object2.myName == "meteor2") or (event.object1.myName == "meteor2" and event.object2.myName == "player") then timer.cancel(scoreTimer) moveMeteor = false moveMeteor2 = false end end Runtime:addEventListener("collision", onCollision) elseif (phase == "did") then composer.gotoScene ( "gameOver", {effect = "fade", time = 200}) end end scene:addEventListener("show", scene) scene:addEventListener("create", scene) return scene

I don’t think you understand how composer works. You should read and re-read this tutorial until you get it: https://coronalabs.com/blog/2014/01/21/introducing-the-composer-api-plus-tutorial/.

I’ll summarise here, though.

When you first go to a scene with composer.newScene(), that is the one and only time that scene:create() will be called (unless the scene is destroyed). This is where you should generally create your objects and insert them into sceneGroup.

scene:show() will executed twice whenever you use composer.gotoScene() to go to the scene. It executes first when composer.gotoScene() is called, when the previous scene is still on the screen. It is called a second time when the scene is fully on screen. event.phase will have different values to distinguish between the two: “will” and “did”.

scene:show() will be called twice every time you go to the scene. So this is where you’ll want to reposition objects, reset scores, etc.

scene:hide() is similarly called twice when you leave the scene. The first time is when composer.gotoScene() is called and the scene is still on screen. The second time is when the scene is fully off screen, and has been replaced by the new scene. These are also distinguished by event.phase being either “will” or “did”.

I’m not sure how familiar you are with the concept of scope. If you’re unsure about it, you should read here: https://coronalabs.com/blog/2015/06/16/tutorial-scope-for-beginners/

You might want to create your armadillo, for example, in the scene:create() function, and then reposition it with scene:show() every time the scene restarts. To do this, you can forward-declare your armadillo. All you need to do is put this code:

local armadillo

before the scene:create() function and the scene:show() function. This will keep a spot in memory called armadillo that is in scope for the scene functions. So in scene:create() you just need to create the armadillo with:

armadillo = display.newImage(...)

Then in scene:show(), when you want to put the armadillo back to its starting position (assuming you want to do that), you can just put:

armadillo.x = 160 armadillo.y = 200

You can treat the meteors in a similar manner.

Using a spawn function for your meteors is a perfectly fine thing to do, but using one for each meteor is very redundant. I would suggest you have one spawn function, before scene:create(), something like this:

local spawnMeteor() local meteor = display.newImage("meteor.png") meteor.x, meteor.y = ... metoer.width, meteor.height = ... return meteor end

Inside scene:create() you could then make your meteors:

meteor1 = spawnMeteor() meteor2 = spawnMeteor() sceneGroup:insert(meteor1) sceneGroup:insert(meteor2)

I didn’t use local for the meteors there, so these will be global variables, unless you forward declare them near the top of the file (recommended).

scene:show() would next be a good place to start your meteors moving.

Don’t forget to insert your buttons into the sceneGroup as well, and remember that the order you insert things affects which objects appear on top. This is why you almost always want to insert the background first, so that it will be behind everything else.

Also, you are calling composer.gotoScene() inside of scene:hide(). You never want to do that. composer.gotoScene() is used to change scene. While changing scene, scene:hide() is called on the previous scene, and scene:show() on the next scene you are going to. To put composer.gotoScene() in either function is to try and change scene while you’re in the middle of changing scenes. That’s sure to mess things up, and perhaps result in an unwelcome visit from xZibit.

Hi,

I think I understand a lot of things, thank you ! But I don’t finish because I had some little problems … In my scene:create() when I insert things in the sceneGroup they doesn’t appear on the screen, their physics body are on the screen, i see them whit the hybrid mode but the image is not on the screen. :confused:

And my second problem is, I couldn’t go to the scene:hide() … i tried to put the collision function at the end of the scene:show() but the scene hide doesn’t launch …

Then, in my scene hide, can I create a button to relaunch the game and another to go to the menu or did I had to do this in another scene ?

A few small effort and I’ll eventually get there … at least I hope! (I’ll send you half of my mark :wink: )

  1. Did you make sure to insert objects into the scene in the order you want them layered? For example:

    sceneGroup:insert(background) sceneGroup:insert(armadillo)

That will place the background down first, with the armadillo then on top of it. But if you do this:

sceneGroup:insert(armadillo) sceneGroup:insert(background)

then the background will be on top of the armadillo and you won’t see it ( the armadillo).

  1. The scene:hide() function isn’t launching as you haven’t added the listener like you’ve done for scene:show() and scene:create() on lines 188 and 189. You just need to do the same for scene:hide() also.

  2. Don’t create a new button in scene:hide(). Remember that this function is called while changing scenes. It’s just useful for stopping timers and animations, and things like that… a bit of tidying up as you leave the scene. You definitely want to add new buttons in another scene, like in the example I showed you.

As for your collision function, I would create it before the scene:create() function and then either:

    - add the listener in scene:create()

    - or add the listener in scene:show() and remove it in scene:hide()

All since good but i can’t end my game on collision … I don’t understand how to do this !

Can you help me for the collision function and add the listener in scene:show and how to remove it in scene:hide() ?

This is my actually code :

--Game scene local composer = require("composer") local scene = composer.newScene() --Physic function local physics = require ("physics") physics.start () physics.setGravity(0, 0) physics.setDrawMode("hybrid") local leftWall = display.newRect(0, display.contentCenterY, 1, 700) local rightWall = display.newRect(320, display.contentCenterY, 1, 700) local flooring = display.newRect (display.contentCenterX, 520, 500, 1 ) local ceiling = display.newRect(display.contentCenterX, -44, 500, 1 ) physics.addBody(leftWall, "static", { bounce = 0.1}) physics.addBody(rightWall, "static", { bounce = 0.1}) physics.addBody(ceiling, "static", { bounce = 0.1}) physics.addBody(flooring, "static", { bounce = 0.1}) local armadillo local function spawnMeteor() local meteor = display.newImage("meteor.png") physics.addBody(meteor, "dynamic",{friction = 1.0, radius={200}}) meteor.x, meteor.y = math.random (5, 315), math.random (-40, 515) return meteor end function onCollision(event) if(event.object1.myName == "player" and event.object2.myName == "meteor") or (event.object1.myName == "meteor" and event.object2.myName == "player") or (event.object1.myName == "player" and event.object2.myName == "meteor2") or (event.object1.myName == "meteor2" and event.object2.myName == "player") then timer.cancel(scoreTimer) end end Runtime:addEventListener("collision", onCollision) function scene:create(event) local sceneGroup = self.view --Background local background = display.newImage("fond.png", 200, 250, 480, 70) armadillo = display.newImage("arm.png") meteor1 = spawnMeteor() meteor2 = spawnMeteor() gauche = display.newImage("boutongauche.png") droit = display.newImage("boutondroit.png") bas = display.newImage("boutonbas.png") haut = display.newImage("boutonhaut.png") score = 0 scoreTxt = display.newText(score, 300, 30, font, 50) scoreTxt.x = 160 scoreTxt.y = -23 sceneGroup:insert(background) sceneGroup:insert(scoreTxt) sceneGroup:insert(meteor1) sceneGroup:insert(meteor2) sceneGroup:insert(gauche) sceneGroup:insert(droit) sceneGroup:insert(bas) sceneGroup:insert(haut) sceneGroup:insert(armadillo) end function scene:show (event) local phase = event.phase if (phase == "will") then local sceneGroup = self.view \_W = display.contentWidth; \_H = display.contentHeight; motionx = 0; motiony = 0 speed = 3; armadillo.x = 160 armadillo.y = 200 physics.addBody(armadillo, "dynamic",{ bounce =0.8,friction = 1.0}) armadillo.gravityScale = 0 armadillo.isFixedRotation = true armadillo.ID = "arma" armadillo.myName = "player" gauche.x = 50; gauche.y = 460; droit.x = 150; droit.y = 460 bas.x = 100; bas.y = 460 haut.x = 100; haut.y = 410 local meteor1 local meteor2 elseif (phase =="did") then local sceneGroup = self.view local function movearmadillo (event) armadillo.x = armadillo.x + motionx; armadillo.y = armadillo.y + motiony local function stop (event) if event.phase =="ended" then motionx = 0; motiony = 0 end end Runtime:addEventListener("touch", stop ) end Runtime:addEventListener("enterFrame", movearmadillo) function gauche:touch() motionx = -speed; end gauche:addEventListener("touch",gauche) function droit:touch() motionx = speed; end droit:addEventListener("touch",droit) function haut:touch() motiony = -speed; end haut:addEventListener("touch", haut) function bas:touch() motiony = speed; end bas:addEventListener("touch", bas) function moveMeteor() transition.to(meteor1, {time=2000, x=math.random(5, 315), y=math.random(-40,515), onComplete=moveMeteor}) end moveMeteor() function moveMeteor2() transition.to(meteor2, {time=2000, x=math.random(5, 315), y=math.random(-40,515), onComplete=moveMeteor2}) end moveMeteor2() local function updateScore() score = score + 1 scoreTxt.text = score end local scoreTimer = timer.performWithDelay(1000, updateScore, -1) if event.onCollision == true then composer.gotoScene("hide") end end end function scene:hide (event) local phase = event.phase if(phase == "will") then timer.cancel(scoreTimer) moveMeteor = false moveMeteor2 = false elseif (phase == "did") then composer.gotoScene ( "gameOver", {effect = "fade", time = 200}) end end scene:addEventListener("show", scene) scene:addEventListener("create", scene) scene:addEventListener("hide", scene) return scene

Your onCollision function should work as it is. Put this inside it to see what’s going wrong:

print(event.object1.myName, event.object2.myName, scoreTimer)

I have found the problem but now when the collision occure i couldn’t go to the sceneHide … a special code exist for this ? :confused:

Sorry, I think my problem is here : 

function endGame (event) if event.onCollision == true then composer.gotoScene("hide") local option = {effect = "fade", time = 200} print("okay !") end end Runtime:addEventListener("enterFrame", endGame)

I think it’s not the good code to enter the collision function on the scene:show(). The print desn’t appear so the function doesn’t work and I don’t know if I have to use “composer.gotoScene” or “local option”. And the Runtime:addEventListener(“enterFrame”, endGame) may be wrong …

There is no onCollision property in the enterfame event table, so event.onCollision will always be nil. An enterFrame event table has no details about collisions, so this is the wrong way to do this. You need a collision listener. You were on the right track before. 

I don’t understand … I’ve tryied many things but when tu collision occure i don’t know why but I can’t go to the scene:hide() … what did I have to do please ?  :frowning:

--Game scene local composer = require("composer") local scene = composer.newScene() local musicGame = audio.loadStream("musicGame.wav") audio.play( musicGame , {loops=200 }) --audio.stop(musicMenu) --Physic function local physics = require ("physics") physics.start () physics.setGravity(0, 0) --physics.setDrawMode("hybrid") local leftWall = display.newRect(0, display.contentCenterY, 1, 700) local rightWall = display.newRect(320, display.contentCenterY, 1, 700) local flooring = display.newRect (display.contentCenterX, 520, 500, 1 ) local ceiling = display.newRect(display.contentCenterX, -44, 500, 1 ) physics.addBody(leftWall, "static", { bounce = 0.1}) physics.addBody(rightWall, "static", { bounce = 0.1}) physics.addBody(ceiling, "static", { bounce = 0.1}) physics.addBody(flooring, "static", { bounce = 0.1}) local armadillo local function spawnMeteor() local meteor = display.newImage("meteor.png") physics.addBody(meteor, "dynamic",{friction = 1.0, radius={200}}) meteor.x, meteor.y = math.random (5, 315), math.random (-40, 515) meteor.myName = "meteor" return meteor end function scene:create(event) local sceneGroup = self.view --Background local background = display.newImage("fond.png", 200, 250, 480, 70) armadillo = display.newImage("arm.png") meteor1 = spawnMeteor() meteor2 = spawnMeteor() gauche = display.newImage("boutongauche.png") droit = display.newImage("boutondroit.png") bas = display.newImage("boutonbas.png") haut = display.newImage("boutonhaut.png") score = 0 scoreTxt = display.newText(score, 300, 30, font, 50) scoreTxt.x = 160 scoreTxt.y = -23 sceneGroup:insert(background) sceneGroup:insert(scoreTxt) sceneGroup:insert(meteor1) sceneGroup:insert(meteor2) sceneGroup:insert(gauche) sceneGroup:insert(droit) sceneGroup:insert(bas) sceneGroup:insert(haut) sceneGroup:insert(armadillo) end function scene:show (event) local phase = event.phase if (phase == "will") then local sceneGroup = self.view \_W = display.contentWidth; \_H = display.contentHeight; motionx = 0; motiony = 0 speed = 3; armadillo.x = 160 armadillo.y = 200 physics.addBody(armadillo, "dynamic",{ bounce =0.8,friction = 1.0}) armadillo.gravityScale = 0 armadillo.isFixedRotation = true armadillo.ID = "arma" armadillo.myName = "player" gauche.x = 50; gauche.y = 460; droit.x = 150; droit.y = 460 bas.x = 100; bas.y = 460 haut.x = 100; haut.y = 410 local meteor1 local meteor2 elseif (phase =="did") then local sceneGroup = self.view local function movearmadillo (event) armadillo.x = armadillo.x + motionx; armadillo.y = armadillo.y + motiony local function stop (event) if event.phase =="ended" then motionx = 0; motiony = 0 end end Runtime:addEventListener("touch", stop ) end Runtime:addEventListener("enterFrame", movearmadillo) function gauche:touch() motionx = -speed; end gauche:addEventListener("touch",gauche) function droit:touch() motionx = speed; end droit:addEventListener("touch",droit) function haut:touch() motiony = -speed; end haut:addEventListener("touch", haut) function bas:touch() motiony = speed; end bas:addEventListener("touch", bas) function moveMeteor() transition.to(meteor1, {time=2000, x=math.random(5, 315), y=math.random(-40,515), onComplete=moveMeteor}) end moveMeteor() function moveMeteor2() transition.to(meteor2, {time=2000, x=math.random(5, 315), y=math.random(-40,515), onComplete=moveMeteor2}) end moveMeteor2() local function updateScore() score = score + 1 scoreTxt.text = score end scoreTimer = timer.performWithDelay(1000, updateScore, -1) --function endGame () --if (event.onCollision == "began") then --composer.gotoScene("hide") --local option = {effect = "fade", time = 200} --print("okay !") --elseif (event.onCollision == "ended") then --print("non") --end --end --Runtime:addEventListener("collision", endGame) --end function onCollision(event) if(event.object1.myName == "player" and event.object2.myName == "meteor") or (event.object1.myName == "meteor" and event.object2.myName == "player") or (event.object1.myName == "player" and event.object2.myName == "meteor2") or (event.object1.myName == "meteor2" and event.object2.myName == "player") then print(event.object1.myName, event.object2.myName, score) timer.cancel(scoreTimer) composer.loadScene("hide") end end Runtime:addEventListener("collision", onCollision) end end function scene:hide (event) local sceneGroup = self.view local phase = event.phase if(phase == "will") then print ("yes !!!") moveMeteor = false moveMeteor2 = false elseif (phase == "did") then composer.gotoScene ( "gameOver", {effect = "fade", time = 200}) end end scene:addEventListener("show", scene) scene:addEventListener("create", scene) scene:addEventListener("hide", scene) return scene

scene:hide() gets called automatically when you use composer.gotoScene(). “hide” is not a scene you tell composer to go to. Instead of your collision function having composer.loadScene(“hide)”, just use composer.gotoScene(“nameofscene”). This will change the scene and scene:hide() will be called as automatically as the scene changes. You don’t need to call composer.gotoScene() inside the scene:hide() function, as you are already changing scene.

Oh YES ! Thank you !!!

I think it’s the last problem that I have to resolve :

when I change scene to go to GameOver.lua , this message appear :

playGame.lua96: attempt to perform arithmetic on field ‘x’ (a nil value) stack traceback:

 

I haven’t this problem before and I can’t do whithout ‘x’ for my code … what I have to do please ? :confused:

I can’t see what would be causing that. Are you at some point removing armadillo or setting it equal to something else? The error suggests that armadillo is a table that does not have an ‘x’ property, so I assume you’ve made some kind of change to it that isn’t in your code above.

I don’t change anything … the problem occure when I supposed to go to the next scene so that’s strange … :confused:

And the problem is at the second : armadillo.x, not the first and its the same problem with the second armadillo.y !

I don’t understand …