I am creating a game and going from the start screen into the game is no problem but when I go from restart into the game I get this error :
ERROR: Runtime error C:\Users\user\Documents\Corona Projects\app\game.lua:92: attempt to call method 'addEventListener' (a nil value)
This is my code :
player = display.newImage("player.png") player.x = 100 player.y = 300 player.myName = "player" physics.addBody(player, "static", {density=.1, bounce=0.2, friction=.2, radius=12}) function player:collision(event) if event.phase == "began" then transition.cancel() composer.gotoScene("restart", options) end end function scene:show(event) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then player:addEventListener("collision") Runtime:addEventListener("touch", onTouch) elseif ( phase == "did" ) then end end function scene:hide(event) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then display.remove( player ) display.remove( ball ) composer.removeScene( "start" ) player:removeEventListener("collision") Runtime:removeEventListener("touch", onTouch) elseif ( phase == "did" ) then print("hide removing objects") end end
This is where the error is :
player:addEventListener("collision")
I tried putting the player image in the create scene but the same thing happened . I made sure my image has the proper name . Please help .
This is because you removed the object in phase == will when the screen disappears. And since you created the player in scene:create(), it will only be displayed once. The error is saying that it is trying to add an eventListener to an object that does not exist.
EDIT: That was wrong, you need to have the player in scene:create().
function scene:show(event) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then elseif ( phase == "did" ) then player:addEventListener("collision") Runtime:addEventListener("touch", onTouch) end end function scene:hide(event) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then elseif ( phase == "did" ) then print("hide removing objects") composer.removeScene( "start" ) player:removeEventListener("collision") Runtime:removeEventListener("touch", onTouch) display.remove( ball ) display.remove( player ) end end
You should move the player code back into scene:create().
This was in the tutorial:
"The scene’s view is initialized and, if the view does not already exist, a create event is dispatched to the scene’s scene:create() function. At this point, the scene still resides “off screen,” so this is an opportune time to create user interface objects and other display objects needed for the scene, including buttons, text, graphics, and other objects that should show when the scene comes on screen."
Are you going to be needing the player for multiple levels? If you are, you should create a module that contains your player and its corresponding functions:
--player.lua local M = {} function M:new() --make character here function player:collision() --handles collision end function player:finalize() --Occurs when player is no longer needed (removes listeners) end end return M --scene.lua local player = require "player" player:new() --creates the player and attaches all of its listeners, it's that simple!
If you are not, then don’t do this, it is just extra work. However, if you are, consider this method, and if you want I can help you implement it.
You need to define player:collision after player has been created within the scene:create function.
Otherwise at the point player:collision is defined, player is still nil. Remember, code runs top to bottom but code inside functions will not run until that function is called. Scene:create is not run until the very end of the file, after you try to define player:function.
An alternative is to have a local function called playerCollision, defined above scene:create, that is then assigned to player.
No. I said to create your player as normal within scene:create. After that, either add the player:collision function within scene:create now that player is in scope, or use addEventListener to add a listener for playerCollision, which must be defined above scene:create for that to be in scope.
This is a good example of just trying random things until something works rather than understanding what you’re doing and why. If you think it through logically, why would you put the code to create the player inside its own collision function?
I just did what you told me to do and still got an error :
local function playerCollision( event ) if event.phase == "began" then end end function scene:create(event) local screenGroup = self.view local background = display.newImageRect("terrain.jpg",display.contentWidth,display.contentHeight) background.x = display.contentCenterX background.y = display.contentCenterY screenGroup:insert(background) ball = display.newImage("ball1.png") ball.x = 400 ball.y = 160 physics.addBody(ball, "dynamic") ball.myName = "ball" screenGroup:insert(ball) player = display.newImage("player.png") player.x = 100 player.y = 300 player.myName = "player" physics.addBody(player, "static", {density=.1, bounce=0.2, friction=.2, radius=12}) screenGroup:insert(player) function player:collision(event) if event.phase == "began" then transition.cancel() composer.gotoScene("restart", options) end end local function loopObject() local objectDown= function() transition.to(player, { time=600, y=20, onComplete=loopObject }) end transition.to(player, { time=600, y=300, onComplete=objectDown }) end loopObject() end
error :
game.lua:93: attempt to call method 'addEventListener' (a nil value)
The start screen goes into the game but then that problem shows up .