attempt to index global 'playButton' (a nil value) - lua

I have just started a LUA a few weeks ago. I was able to create a simple character jumping with a score and then running this with the Corona Simulator. But I wanted to create a menu system so from main.lua which loads up menu.lua and from here it will go to Start (i.e. start the game i.e. to game.lua) and therefore I can play the game. But it doesn't appear. I have tried to add the eventListeners as shown below o
function scene:show( event )
local sceneGroup = self.view
local phase = event.phase
if ( phase == "will" ) then
-- Code here runs when the scene is still off screen (but is about to come on screen)
elseif ( phase == "did" ) then
-- Code here runs when the scene is entirely on screen
startButton:addEventListener( "tap", gotoGame )
highScoresButton:addEventListener( "tap", gotoHighScores )
end
end
Other than that I dont understand why the menu system won't go to Game.lua therefore I can play the game. Also I don't understand why there are errors when loading menu.lua I have used scenes and the composer management library and in theory it should work.
Image files are in one folder
main.lua File 1
local composer = require( "composer" )
-- Hide status bar
display.setStatusBar( display.HiddenStatusBar )
-- Seed the random number generator
math.randomseed( os.time() )
-- Go to the menu screen
composer.gotoScene("menu")
Menu.lua File 2
local composer = require( "composer" )
local scene = composer.newScene()
-- -----------------------------------------------------------------------------------
-- Code outside of the scene event functions below will only be executed ONCE unless
-- the scene is removed entirely (not recycled) via "composer.removeScene()"
-- -----------------------------------------------------------------------------------
local function gotoGame()
composer.gotoScene( "game" )
end
local function gotoHighScores()
composer.gotoScene( "highscores" )
end
-- -----------------------------------------------------------------------------------
-- Scene event functions
-- -----------------------------------------------------------------------------------
-- create()
function scene:create( event )
local sceneGroup = self.view
-- Code here runs when the scene is first created but has not yet appeared on screen
local background = display.newImageRect( sceneGroup, "background.png", 800, 1400 )
background.x = display.contentCenterX
background.y = display.contentCenterY
local title = display.newImageRect( sceneGroup, "title.png", 500, 80 )
title.x = display.contentCenterX
title.y = 200
local startButton = display.newText( sceneGroup, "Start", display.contentCenterX, 700, native.systemFont, 44 )
startButton:setFillColor( 0.82, 0.86, 1 )
local highScoresButton = display.newText( sceneGroup, "High Scores", display.contentCenterX, 810, native.systemFont, 44 )
highScoresButton:setFillColor( 0.75, 0.78, 1 )
startButton:addEventListener( "tap", gotoGame )
highScoresButton:addEventListener( "tap", gotoHighScores )
end
-- show()
function scene:show( event )
local sceneGroup = self.view
local phase = event.phase
if ( phase == "will" ) then
-- Code here runs when the scene is still off screen (but is about to come on screen)
elseif ( phase == "did" ) then
-- Code here runs when the scene is entirely on screen
startButton:addEventListener( "tap", gotoGame )
highScoresButton:addEventListener( "tap", gotoHighScores )
end
end
-- hide()
function scene:hide( event )
local sceneGroup = self.view
local phase = event.phase
if ( phase == "will" ) then
-- Code here runs when the scene is on screen (but is about to go off screen)
elseif ( phase == "did" ) then
-- Code here runs immediately after the scene goes entirely off screen
end
end
-- destroy()
function scene:destroy( event )
local sceneGroup = self.view
-- Code here runs prior to the removal of scene's view
end
-- -----------------------------------------------------------------------------------
-- Scene event function listeners
-- -----------------------------------------------------------------------------------
scene:addEventListener( "create", scene )
scene:addEventListener( "show", scene )
scene:addEventListener( "hide", scene )
scene:addEventListener( "destroy", scene )
-- -----------------------------------------------------------------------------------
return scene
game.lua File 3
local composer = require("composer")
local scene = composer.newScene()
display.setStatusBar(display.HiddenStatusBar)
local physics = require "physics"
function updateScore()
score=score+1
scoreText.text = "Score: "..score
scoreText.x, scoreText.y=80,40
end
function onTouch(event)
if(event.phase=="began") then
if(event.x<player.x) then
player:setLinearVelocity(-30,-200)
updateScore()
else
player:setLinearVelocity(30,-200)
updateScore()
end
end
end
-- create()
function scene:create( event )
local sceneGroup = self.view
-- Code here runs when the scene is first created but has not yet appeared
physics.pause()
score=0
local scoreText
local ground = display.newImage("ground.jpg")
local player = display.newImage("player.png")
end
-- show()
function scene:show( event )
local sceneGroup = self.view
local phase = event.phase
if ( phase == "will" ) then
-- Code here runs when the scene is still off screen (but is about to come on screen)
elseif ( phase == "did" ) then
-- Code here runs when the scene is entirely on screen
physics.start()
scoreText=display.newText("Score:0",0,0,native.systemFont,40)
scoreText.x, scoreText.y=80,40
ground.x=460
ground.y=1300
physics.addBody(ground, "static")
player.x=360
player.y=120
physics.addBody(player)
Runtime:addEventListener("touch", onTouch)
end
end
-- hide()
function scene:hide( event )
local sceneGroup = self.view
local phase = event.phase
if ( phase == "will" ) then
-- Code here runs when the scene is on screen (but is about to go off screen)
elseif ( phase == "did" ) then
-- Code here runs immediately after the scene goes entirely off screen
end
end
-- destroy()
function scene:destroy( event )
local sceneGroup = self.view
-- Code here runs prior to the removal of scene's view
end
-- -----------------------------------------------------------------------------------
-- Scene event function listeners
-- -----------------------------------------------------------------------------------
scene:addEventListener( "create", scene )
scene:addEventListener( "show", scene )
scene:addEventListener( "hide", scene )
scene:addEventListener( "destroy", scene )
-- -----------------------------------------------------------------------------------
return scene

When you create the scene with
function scene:create( event )
You always want to insert the objects (locals) into the sceneGroup doing this
sceneGroup:insert( object )
sceneGroup:insert( object2 )
Also I have the doubt that the event listener goes with touch and not tap (by looking on the doumentation):
startButton:addEventListener( "touch", gotoGame )
highScoresButton:addEventListener( "touch", gotoHighScores )
Anyway I suggest you to visit the documentation: it covers everything and it's euxhastive.

Related

Add Listener to an Image in Corona APK

I created a new project in CoronaLabs Studio with Physics-Based Game starting options and everything loaded up as a beginner I don't get where should I put addEventListener() so I can make the box to be clickable or to be destroyed on click?
I tried a bunch of different ways to just place this line of code inside the script to make the box clickable virus:applyLinearImpulse( 0, -0.25, virus.x, virus.y )
Here is the level1.lua script.
In this case, I have
require("toast")
local composer = require( "composer" )
local scene = composer.newScene()
-- include Corona's "physics" library
local physics = require("physics")
--------------------------------------------
tapCount = 0
tapText = display.newText( tapCount, display.contentCenterX, 20, native.systemFont, 40 )
--------------------------------------------
local screenW, screenH, halfW = display.actualContentWidth, display.actualContentHeight, display.contentCenterX
function scene:create( event )
-- Called when the scene's view does not exist.
-- INSERT code here to initialize the scene e.g. add display objects to 'sceneGroup', add touch listeners, etc.
local sceneGroup = self.view
physics.start()
physics.pause()
local background = display.newImageRect("game-background.png", 1170, 658)
background.x = display.contentCenterX
background.y = display.contentCenterY
-- OFFSCREEN BOX, position it, and rotate slightly
local box = display.newImageRect( "box.png", 40, 40 )
box.x, box.y = 160, -100
box.rotation = 33
-- add physics
physics.addBody( box, { density=1.0, friction=0.3, bounce=0.2 } )
-- create a grass object and add physics (with custom shape)
local grass = display.newImageRect( "grass.png", screenW, 82 )
grass.anchorX = 0
grass.anchorY = 1
-- draw the grass at the very bottom of the screen
grass.x, grass.y = display.screenOriginX, display.actualContentHeight + display.screenOriginY
local grassShape = { -halfW,-34, halfW,-34, halfW,34, -halfW,34 }
physics.addBody( grass, "static", { friction=0.3, shape=grassShape } )
sceneGroup:insert( background )
sceneGroup:insert( grass )
sceneGroup:insert( box )
end
function scene:show( event )
local sceneGroup = self.view
local phase = event.phase
if phase == "will" then
-- Called when the scene is still off-screen and is about to move on screen
elseif phase == "did" then
-- Called when the scene is now on-screen
physics.start()
end
end
function scene:hide( event )
local sceneGroup = self.view
local phase = event.phase
if event.phase == "will" then
-- Called when the scene is on-screen and is about to move off-screen
physics.stop()
elseif phase == "did" then
-- Called when the scene is now off-screen
end
end
function scene:destroy( event )
-- Called prior to the removal of scene's "view" (sceneGroup)
local sceneGroup = self.view
package.loaded[physics] = nil
physics = nil
end
---------------------------------------------------------------------------------
-- Listener setup
scene:addEventListener( "create", scene )
scene:addEventListener( "show", scene )
scene:addEventListener( "hide", scene )
scene:addEventListener( "destroy", scene )
-----------------------------------------------------------------------------------------
return scene
If I have understood your question correctly,here's an example where you can click a box and destroy it.
function scene:create(event)
local function destroyMe(event)
display.remove(event.target)
event.target=nil
end
local box = display.newImageRect( "box.png", 40, 40 )
box.x, box.y = 160, 100
box.rotation = 33
-- add physics
physics.addBody( box, { density=1.0, friction=0.3, bounce=0.2 } )
box:addEventListener("tap",destroyMe)
end
If you're using touch event,then that event will have three phases.Hence be cautious.

Cannot get functions to work in Corona SDK (With TabButton)

I am completely new to Corona SDK and I am just looking at the example projects just to see how things work. I am looking at the TAB example however I have a problem.
I have a page like so (this is page2)
local composer = require( "composer" )
local scene = composer.newScene()
function scene:create( event )
local sceneGroup = self.view
-- Called when the scene's view does not exist.
--
-- INSERT code here to initialize the scene
-- e.g. add display objects to 'sceneGroup', add touch listeners, etc.
-- create a white background to fill screen (things go in here like pictures etc)
local bg = display.newRect( 0, 0, display.contentWidth, display.contentHeight )
bg.anchorX = 0
bg.anchorY = 0
bg:setFillColor( 0 ) -- white
-- this will create the thing that you drag (the function is after)
local tracker = display.newRect( 568, 340, 50, 50 )
tracker:setFillColor( 1 )
-- all objects must be added to group (e.g. self.view)
sceneGroup:insert( bg )
sceneGroup:insert( tracker )
end
function scene:show( event )
local sceneGroup = self.view
local phase = event.phase
if phase == "will" then
-- Called when the scene is still off screen and is about to move on screen
elseif phase == "did" then
-- Called when the scene is now on screen
--
-- INSERT code here to make the scene come alive
-- e.g. start timers, begin animation, play audio, etc.
end
end
function scene:hide( event )
local sceneGroup = self.view
local phase = event.phase
if event.phase == "will" then
-- Called when the scene is on screen and is about to move off screen
--
-- INSERT code here to pause the scene
-- e.g. stop timers, stop animation, unload sounds, etc.)
elseif phase == "did" then
-- Called when the scene is now off screen
end
end
function scene:destroy( event )
local sceneGroup = self.view
-- Called prior to the removal of scene's "view" (sceneGroup)
--
-- INSERT code here to cleanup the scene
-- e.g. remove display objects, remove touch listeners, save state, etc.
end
function tracker:touch( event )
if event.phase == "began" then
self.markX = self.x --stores x location
self.markY = self.y --stores y location
elseif event.phase == "moved" then
local x = (event.x - event.xStart) + self.markX
local y = (event.y - event.yStart) + self.markY
self.x, self.y = x, y -- moves the object from things above
end
end
---------------------------------------------------------------------------------
-- Listener setup
scene:addEventListener( "create", scene )
scene:addEventListener( "show", scene )
scene:addEventListener( "hide", scene )
scene:addEventListener( "destroy", scene )
tracker:addEventListneer( "touch", tracker)
-----------------------------------------------------------------------------------------
return scene
Anyway to simplify things the changes I have done are:
local tracker = display.newRect( 568, 340, 50, 50 )
tracker:setFillColor( 1 )
This will create a new box which I am trying to make so you can drag it around the screen (I have used this function):
function tracker:touch( event )
if event.phase == "began" then
self.markX = self.x --stores x location
self.markY = self.y --stores y location
elseif event.phase == "moved" then
local x = (event.x - event.xStart) + self.markX
local y = (event.y - event.yStart) + self.markY
self.x, self.y = x, y -- moves the object from things above
end
end
So overall it creates a box and I am trying to add a function to it so that you can drag it around the screen. However it does not work and gives me an error saying that tracker on that start of the function line function tracker:touch( event ) is wrong? Any help, because I think that this is in the wrong place.
P.S I also have a tracker:addEventListneer( "touch", tracker) listener.
-Thanks
You are creating the local tracker as a local variable inside your scene:create function. This means this variable will only be available within the scope of said function.
You need to move the function tracker:touch(event) inside the scene:create function for the tracker to be reachable.
And you need to move the listener to the bottom of the scene:create function.
Never mind. I have fixed it. I should always check my spelling xD (I spelled the tracker:addEventListener( "touch", tracker) wrong). Such a noob mistake. Thanks for the help guys.

Perspective Virtual Camera library issue Corona SDK

Hello all I am currently developing an application that I am going to use the perspective library with. I have imported the library and have written the correct code it seems but to no avail my camera is not working properly. I am attempting to get the camera to follow the main character you are moving around with the buttons. I added him and the background and a "tree" to the camera and set him as the focus but it still will not follow him. Here is my code please tell me what I have done wrong here and how to fix it.
local storyboard = require( "storyboard" )
local scene = storyboard.newScene()
local perspective = require( "perspective" )
local camera = perspective.createView()
local physics = require( "physics" )
--physics.setDrawMode( "hybrid" )
local function start( event )
if( event.phase == "ended" ) then
end
end
local bg
local floor
local leftwall
local rightwall
local player
local button1
local button2
local pausebtn
local tree
local function b1( event )
if( event.phase == "ended" ) then
player:applyLinearImpulse( -.01, -.1 )
end
end
local function b2( event )
if( event.phase == "ended" ) then
player:applyLinearImpulse( .01, -.1 )
end
end
local function playerCollision( event )
if( event.phase == "began" ) then
storyboard.gotoScene( "gameover" )
end
end
local function pause( event )
if( event.phase == "ended" ) then
storyboard.showOverlay( "pause" )
physics.pause()
end
end
function scene:createScene( event )
local group = self.view
physics.start()
bg = display.newImage( "bg.png", display.contentWidth/2, display.contentHeight/2, display.contentWidth, display.contentHeight )
camera:add(bg, 3, false)
player = display.newImage( "player.png", display.contentWidth/2, display.contentHeight/2, display.contentWidth, display.contentHeight )
player.collision = playerCollision
camera:add(player, 1, true)
tree = display.newImage( "tree.png", 200, 200)
camera:add(tree, 2, false)
floor = display.newRect( 285, 375, 570, 1 )
button1 = display.newImage( "button1.png", 50, 275 )
button2 = display.newImage( "button2.png", 515, 275 )
leftwall = display.newRect( 0, -1000, 1, 5000 )
rightwall = display.newRect( 570, 300, 1, 5000 )
pausebtn = display.newImage( "pausebtn.png", 540, 30 )
-- Physics
physics.addBody( player )
physics.addBody( floor )
floor.bodyType = "static"
physics.addBody( rightwall )
rightwall.bodyType = "static"
physics.addBody( leftwall )
leftwall.bodyType = "static"
group:insert(bg)
group:insert(player)
group:insert(floor)
group:insert(button1)
group:insert(button2)
group:insert(rightwall)
group:insert(leftwall)
group:insert(pausebtn)
group:insert(tree)
end
function scene:enterScene( event )
print( "game" )
button1:addEventListener( "touch", b1 )
button2:addEventListener( "touch", b2 )
player:addEventListener( "collision", playerCollision )
pausebtn:addEventListener( "touch", pause )
end
function scene:exitScene()
player = nil
camera:cancel()
end
function scene:destroyScene( event )
end
scene:addEventListener( "createScene", scene )
scene:addEventListener( "enterScene", scene )
scene:addEventListener( "exitScene", scene )
scene:addEventListener( "destroyScene", scene )
return scene
Looks like you are missing the call to camera:track() (which should probably go in the enterScene handler). You might also need camera:setBounds(false).
If this still doesn't fix issue, remove all code from your post that is not required in order to duplicate the problem. If you can boil it down to a small example that I can run, I can try and post update.

Corona test project Works at emulator but not on the Device

I have this weird situation. I have 2 scenes. I can go from 1 to the other in the simulator but it crashes when I do the same on the device...
This is the code of the first scene (menu)
menu.lua
local storyboard = require( "storyboard" )
local scene = storyboard.newScene()
-- include Corona s "widget" library
local widget = require ("widget")
-- forward declarations and other locals
local playBtn
local optsBtn
local helpBtn
-- Levels Menu
local function onPlayBtnRelease()
-- ads.hide()
storyboard.gotoScene( "levels", "fade", 500 )
return true -- indicates successful touch
end
-- Options
local function onOptionsBtnRelease()
storyboard.gotoScene( "options", "fade", 500 )
return true -- indicates successful touch
end
-- Help
local function onHelpBtnRelease()
storyboard.gotoScene( "help", "fade", 500 )
return true -- indicates successful touch
end
-----------------------------------------------------------------------------------------
-- BEGINNING OF YOUR IMPLEMENTATION
--
-- NOTE: Code outside of listener functions (below) will only be executed once,
-- unless storyboard.removeScene() is called.
--
-----------------------------------------------------------------------------------------
-- Called when the scene s view does not exist:
function scene:createScene( event )
local group = self.view
-- display a background image
local background = display.newImageRect( "background.jpg", display.contentWidth, display.contentHeight )
background:setReferencePoint( display.TopLeftReferencePoint )
background.x, background.y = 0, 0
-- create/position logo/title image on upper-half of the screen
local titleLogo = display.newImageRect( "title.png", 264, 42 )
titleLogo:setReferencePoint( display.CenterReferencePoint )
titleLogo.x = display.contentWidth * 0.5
titleLogo.y = display.contentHeight / 5
-- create a widget button (which will loads levels.lua on release)
playBtn = widget.newButton{
label="Play Now",
labelColor = { default={255}, over={128} },
defaultFile="button.png",
overFile="button-over.png",
width=154, height=40,
onRelease = onPlayBtnRelease -- event listener function
}
playBtn:setReferencePoint( display.CenterReferencePoint )
playBtn.x = display.contentWidth*0.5
playBtn.y = display.contentHeight * 2 / 5
-- button for options (options.lua)
optsBtn = widget.newButton{
label="Options",
labelColor = { default={255}, over={128} },
defaultFile="button.png",
overFile="button-over.png",
width=154, height=40,
onRelease = onOptionsBtnRelease -- event listener function
}
optsBtn:setReferencePoint( display.CenterReferencePoint )
optsBtn.x = display.contentWidth*0.5
optsBtn.y = display.contentHeight * 3 / 5
-- button for options (help.lua)
helpBtn = widget.newButton{
label="Help",
labelColor = { default={255}, over={128} },
defaultFile="button.png",
overFile="button-over.png",
width=154, height=40,
onRelease = onHelpBtnRelease -- event listener function
}
helpBtn:setReferencePoint( display.CenterReferencePoint )
helpBtn.x = display.contentWidth*0.5
helpBtn.y = display.contentHeight * 4 / 5
-- Load Configurations
local utili = require( "utility" )
mySettings = utili.loadTable("BlastsOptions.json")
-- all display objects must be inserted into group
group:insert( background )
group:insert( titleLogo )
group:insert( playBtn )
group:insert( optsBtn )
group:insert( helpBtn )
end
-- Called immediately after scene has moved onscreen:
function scene:enterScene( event )
local group = self.view
-- INSERT code here (e.g. start timers, load audio, start listeners, etc.)
-- Audio ***
local menusound = audio.loadStream("sounds/menusback.mp3")
if mySettings.musicOn == true then
audio.play (menusound, {loop=-1})
end
end
-- Called when scene is about to move offscreen:
function scene:exitScene( event )
local group = self.view
-- INSERT code here (e.g. stop timers, remove listenets, unload sounds, etc.)
audio.stop()
end
-- If scene s view is removed, scene:destroyScene() will be called just prior to:
function scene:destroyScene( event )
local group = self.view
--if playBtn then
-- playBtn:removeSelf() -- widgets must be manually removed
-- playBtn = nil
--end
end
-----------------------------------------------------------------------------------------
-- END OF YOUR IMPLEMENTATION
-----------------------------------------------------------------------------------------
-- "createScene" event is dispatched if scene s view does not exist
scene:addEventListener( "createScene", scene )
-- "enterScene" event is dispatched whenever scene transition has finished
scene:addEventListener( "enterScene", scene )
-- "exitScene" event is dispatched whenever before next scene s transition begins
scene:addEventListener( "exitScene", scene )
-- "destroyScene" event is dispatched before view is unloaded, which can be
-- automatically unloaded in low memory situations, or explicitly via a call to
-- storyboard.purgeScene() or storyboard.removeScene().
scene:addEventListener( "destroyScene", scene )
-----------------------------------------------------------------------------------------
return scene
And this is the code of the second one:
Can you help me to find what could be wrong?
levels.lua
local storyboard = require( "storyboard" )
local scene = storyboard.newScene()
-- include Corona s "widget" library
local widget = require ("widget")
--------------------------------------------
local function onKeyEvent( event )
if (event.keyName == "back") and (system.getInfo("platformName") == "Android") then
storyboard.gotoScene( "menu", "fade", 500 )
return true
end
return false
end
Runtime:addEventListener( "key", onKeyEvent );
-- forward declarations and other locals
local play1Btn
local play2Btn
local menuBtn
-- 'onRelease' event listener for playBtn
local function onLeve1BtnRelease()
-- go to level1.lua scene
audio.stop ()
storyboard.gotoScene( "level1", "fade", 500 )
return true -- indicates successful touch
end
local function onLeve2BtnRelease()
-- go to level1.lua scene
-- ads.hide()
storyboard.gotoScene( "level1", "fade", 500 )
return true -- indicates successful touch
end
local function onMenuBtnRelease()
-- go to level1.lua scene
storyboard.gotoScene( "menu", "fade", 500 )
return true -- indicates successful touch
end
-- Called when the scene s view does not exist:
function scene:createScene( event )
local group = self.view
-- display a background image
local background = display.newImageRect( "background.jpg", display.contentWidth, display.contentHeight )
background:setReferencePoint( display.TopLeftReferencePoint )
background.x, background.y = 0, 0
-- create/position logo/title image on upper-half of the screen
local titleLogo = display.newImageRect( "select-Level.png", 264, 42 )
titleLogo:setReferencePoint( display.CenterReferencePoint )
titleLogo.x = display.contentWidth * 0.5
titleLogo.y = display.contentHeight / 5
-- create a widget button (which will loads level1.lua on release)
play1Btn = widget.newButton{
label="Level 1",
labelColor = { default={255}, over={128} },
defaultFile="button.png",
overFile="button-over.png",
width=154, height=40,
onRelease = onLeve1BtnRelease -- event listener function
}
play1Btn:setReferencePoint( display.CenterReferencePoint )
play1Btn.x = display.contentWidth*0.5
play1Btn.y = display.contentHeight * 2 / 5
-- button for options (options.lua)
play2Btn = widget.newButton{
label="Level 2",
labelColor = { default={255}, over={128} },
defaultFile="button.png",
overFile="button-over.png",
width=154, height=40,
onRelease = onLeve2BtnRelease -- event listener function
}
play2Btn:setReferencePoint( display.CenterReferencePoint )
play2Btn.x = display.contentWidth*0.5
play2Btn.y = display.contentHeight * 3 / 5
-- button for options (help.lua)
menuBtn = widget.newButton{
label="Return",
labelColor = { default={255}, over={128} },
defaultFile="button.png",
overFile="button-over.png",
width=154, height=40,
onRelease = onMenuBtnRelease -- event listener function
}
menuBtn:setReferencePoint( display.CenterReferencePoint )
menuBtn.x = display.contentWidth*0.5
menuBtn.y = display.contentHeight * 4 / 5
-- all display objects must be inserted into group
group:insert( background )
group:insert( titleLogo )
group:insert( play1Btn )
group:insert( play2Btn )
group:insert( menuBtn )
end
-- Called immediately after scene has moved onscreen:
function scene:enterScene( event )
local group = self.view
-- INSERT code here (e.g. start timers, load audio, start listeners, etc.)
end
-- Called when scene is about to move offscreen:
function scene:exitScene( event )
local group = self.view
end
-- If scene s view is removed, scene:destroyScene() will be called just prior to:
function scene:destroyScene( event )
local group = self.view
end
-----------------------------------------------------------------------------------------
-- END OF YOUR IMPLEMENTATION
-----------------------------------------------------------------------------------------
-- "createScene" event is dispatched if scene s view does not exist
scene:addEventListener( "createScene", scene )
-- "enterScene" event is dispatched whenever scene transition has finished
scene:addEventListener( "enterScene", scene )
-- "exitScene" event is dispatched whenever before next scene s transition begins
scene:addEventListener( "exitScene", scene )
-- "destroyScene" event is dispatched before view is unloaded, which can be
-- automatically unloaded in low memory situations, or explicitly via a call to
-- storyboard.purgeScene() or storyboard.removeScene().
scene:addEventListener( "destroyScene", scene )
-----------------------------------------------------------------------------------------
return scene
Very very Thanks. I'm new on Corona and I'm stuck on this :(
krs is correct!
I have disrespected the resource naming convention.
I put "-" in the name of the images files and it is not allowed.
Problem was solved changing the name of the images.

enterScene event does not triggered

I am trying to create a game using gyroscope and I am facing a very strange problem. I have the following two scene's
I want when the ball in the first scene collide with the door to move to the second scene.
When the ball move slowly and collide with the door everything works fine and the next scene starts normaly, but if the ball in the first scene move very fast and collide with the door with great force the next scene starts frοsted, it seems like the enterscene event is not triggered. Any Idea?
My code:
Scene1:
---------------------------------------------------------------------------------
--
-- scene1.lua
--
---------------------------------------------------------------------------------
local storyboard = require( "storyboard" )
local scene = storyboard.newScene()
system.setIdleTimer( false )
local physics = require "physics"
local physicsData = (require "myphysics").physicsData(1.0)
---------------------------------------------------------------------------------
-- BEGINNING OF IMPLEMENTATION
---------------------------------------------------------------------------------
local displayTime,background,ball,maze,maze2,borders,exitscn
local startTime=0
local levelTime = 20
local function onGyroscopeDataReceived( event )
local deltaRadiansX = event.xRotation * event.deltaTime
local deltaDegreesX = deltaRadiansX * (180 / math.pi)
local deltaRadiansY = event.yRotation * event.deltaTime
local deltaDegreesY = deltaRadiansY * (180 / math.pi)
ball:applyForce( -deltaDegreesX*6, -deltaDegreesY*6, ball.x, ball.y )
end
function nextScene()
storyboard.gotoScene( "loadscene2")
end
local function onCollision( event )
if ( event.phase == "ended" ) then
if(event.object1.name=="exitscn" or event.object2.name=="exitscn") then
timer.performWithDelay ( 500, nextScene )
end
end
end
local function gameOver()
storyboard.gotoScene( "menu", "fade", 300)
end
local function checkTime(event)
local now = os.time()
displayTime.text = levelTime - (now - startTime)
if ( levelTime - (now - startTime)==0) then
gameOver()
end
end
-- Called when the scene's view does not exist:
function scene:createScene( event )
local screenGroup = self.view
physics.start();
physics.setGravity( 0,0 )
displayTime = display.newText(levelTime, 0, 0, "Helvetica", 20)
displayTime.isVisible=false
background=display.newImage("bcklevel1.png")
background.x=display.contentCenterX
background.y=display.contentCenterY
ball=display.newImage("ball1.png")
ball.x=30
ball.y=display.contentCenterY
ball.name="ball"
maze=display.newImage( "maze1.png" )
maze.x=display.contentCenterX
maze.y=display.contentCenterY
maze.name="maze"
maze2=display.newImage( "maze1.png" )
maze2.x=display.contentCenterX
maze2.y=display.contentCenterY
maze2.name="maze2"
borders=display.newImage( "borders.png" )
borders.x=display.contentCenterX
borders.y=display.contentCenterY
borders.name="borders"
borders.alpha=0.1
exitscn=display.newImage("exit.png")
exitscn.x=display.contentWidth-30
exitscn.y=display.contentCenterY
exitscn.name="exitscn"
physics.addBody (ball, "dynamic",physicsData:get("ball"))
physics.addBody (maze, "static",physicsData:get("mazelevel1_1"))
physics.addBody (maze2, "static",physicsData:get("mazelevel1_2"))
physics.addBody (borders, "static",physicsData:get("borders"))
physics.addBody (exitscn, "dynamic",physicsData:get("exitscn"))
--ball:addEventListener ( "touch", nextScene )
Runtime:addEventListener("enterFrame", checkTime)
Runtime:addEventListener( "gyroscope", onGyroscopeDataReceived )
Runtime:addEventListener( "collision", onCollision )
screenGroup:insert( background )
screenGroup:insert(displayTime)
screenGroup:insert( ball )
screenGroup:insert( maze )
screenGroup:insert( maze2 )
screenGroup:insert( borders )
screenGroup:insert( exitscn )
print( "\n1: createScene event")
end
-- Called immediately after scene has moved onscreen:
function scene:enterScene( event )
print( "1: enterScene event" )
physics.start()
startTime = os.time()
displayTime.isVisible=true
end
-- Called when scene is about to move offscreen:
function scene:exitScene( event )
print( "1: exitScene event" )
physics.stop( )
Runtime:removeEventListener( "enterFrame", checkTime )
Runtime:removeEventListener( "gyroscope", onGyroscopeDataReceived )
Runtime:removeEventListener( "collision", onCollision )
end
-- Called prior to the removal of scene's "view" (display group)
function scene:destroyScene( event )
print( "((destroying scene 1's view))" )
package.loaded[physics] = nil
physics = nil
end
---------------------------------------------------------------------------------
-- END OF YOUR IMPLEMENTATION
---------------------------------------------------------------------------------
-- "createScene" event is dispatched if scene's view does not exist
scene:addEventListener( "createScene", scene )
-- "enterScene" event is dispatched whenever scene transition has finished
scene:addEventListener( "enterScene", scene )
-- "exitScene" event is dispatched before next scene's transition begins
scene:addEventListener( "exitScene", scene )
-- "destroyScene" event is dispatched before view is unloaded, which can be
-- automatically unloaded in low memory situations, or explicitly via a call to
-- storyboard.purgeScene() or storyboard.removeScene().
scene:addEventListener( "destroyScene", scene )
---------------------------------------------------------------------------------
return scene
Scene2:
---------------------------------------------------------------------------------
--
-- scene2.lua
--
---------------------------------------------------------------------------------
local storyboard = require( "storyboard" )
local scene = storyboard.newScene()
system.setIdleTimer( false )
local physics = require "physics"
local physicsData = (require "myphysics").physicsData(1.0)
---------------------------------------------------------------------------------
-- BEGINNING OF IMPLEMENTATION
---------------------------------------------------------------------------------
local displayTime,background,ball,maze,maze2,borders,exitscn
local startTime=0
local levelTime = 20
local function onGyroscopeDataReceived( event )
local deltaRadiansX = event.xRotation * event.deltaTime
local deltaDegreesX = deltaRadiansX * (180 / math.pi)
local deltaRadiansY = event.yRotation * event.deltaTime
local deltaDegreesY = deltaRadiansY * (180 / math.pi)
ball:applyForce( -deltaDegreesX*6, -deltaDegreesY*6, ball.x, ball.y )
end
function nextScene()
storyboard.gotoScene( "menu", "fade", 1000 )
end
local function onCollision( event )
if ( event.phase == "ended" ) then
if(event.object1.name=="exitscn" or event.object2.name=="exitscn") then
timer.performWithDelay ( 500, nextScene )
end
end
end
local function gameOver()
storyboard.gotoScene( "menu", "fade", 300)
end
local function checkTime(event)
local now = os.time()
displayTime.text = levelTime - (now - startTime)
if ( levelTime - (now - startTime)==0) then
gameOver()
end
end
-- Called when the scene's view does not exist:
function scene:createScene( event )
local screenGroup = self.view
physics.start();
physics.setGravity( 0,0 )
displayTime = display.newText(startTime, 0, 0, "Helvetica", 20)
displayTime.isVisible=false
background=display.newImage("bcklevel1.png")
background.x=display.contentCenterX
background.y=display.contentCenterY
ball=display.newImage("ball1.png")
ball.x=30
ball.y=display.contentCenterY
ball.name="ball"
maze=display.newImage( "maze2.png" )
maze.x=display.contentCenterX
maze.y=display.contentCenterY
maze.name="maze"
maze2=display.newImage( "maze2.png" )
maze2.x=display.contentCenterX
maze2.y=display.contentCenterY
maze2.name="maze2"
borders=display.newImage( "borders.png" )
borders.x=display.contentCenterX
borders.y=display.contentCenterY
borders.name="borders"
borders.alpha=0.1
exitscn=display.newImage("exit.png")
exitscn.x=display.contentWidth-30
exitscn.y=display.contentCenterY
exitscn.name="exitscn"
physics.addBody (ball, "dynamic",physicsData:get("ball"))
physics.addBody (maze, "static",physicsData:get("mazelevel2_1"))
physics.addBody (maze2, "static",physicsData:get("mazelevel2_2"))
physics.addBody (borders, "static",physicsData:get("borders"))
physics.addBody (exitscn, "dynamic",physicsData:get("exitscn"))
--ball:addEventListener ( "touch", nextScene )
Runtime:addEventListener("enterFrame", checkTime)
Runtime:addEventListener( "gyroscope", onGyroscopeDataReceived )
Runtime:addEventListener( "collision", onCollision )
screenGroup:insert( background )
screenGroup:insert(displayTime)
screenGroup:insert( ball )
screenGroup:insert( maze )
screenGroup:insert( maze2 )
screenGroup:insert( borders )
screenGroup:insert( exitscn )
print( "\n1: createScene event")
end
-- Called immediately after scene has moved onscreen:
function scene:enterScene( event )
print( "1: enterScene event" )
physics.start()
startTime = os.time()
displayTime.isVisible=true
end
-- Called when scene is about to move offscreen:
function scene:exitScene( event )
print( "1: exitScene event" )
physics.stop( )
Runtime:removeEventListener( "enterFrame", checkTime )
Runtime:removeEventListener( "gyroscope", onGyroscopeDataReceived )
Runtime:removeEventListener( "collision", onCollision )
end
-- Called prior to the removal of scene's "view" (display group)
function scene:destroyScene( event )
print( "((destroying scene 2's view))" )
package.loaded[physics] = nil
physics = nil
end
---------------------------------------------------------------------------------
-- END OF YOUR IMPLEMENTATION
---------------------------------------------------------------------------------
-- "createScene" event is dispatched if scene's view does not exist
scene:addEventListener( "createScene", scene )
-- "enterScene" event is dispatched whenever scene transition has finished
scene:addEventListener( "enterScene", scene )
-- "exitScene" event is dispatched before next scene's transition begins
scene:addEventListener( "exitScene", scene )
-- "destroyScene" event is dispatched before view is unloaded, which can be
-- automatically unloaded in low memory situations, or explicitly via a call to
-- storyboard.purgeScene() or storyboard.removeScene().
scene:addEventListener( "destroyScene", scene )
---------------------------------------------------------------------------------
return scene
In the second file, i bet there is something spooky about
function nextScene()
storyboard.gotoScene( "menu", "fade", 1000 )
end
local function onCollision( event )
if ( event.phase == "ended" ) then
if(event.object1.name=="exitscn" or event.object2.name=="exitscn") then
timer.performWithDelay ( 500, nextScene )
end
end
end
first you delay with 500 ms and then an additional 1000 ms delays the transition to the next scene. Maybe you are aware of this, but you are not handling this transition the same way here as in the first file.
I think code is proper. there is some problem of grouping things in enter scene and memory reload for storyboard scenes. Please try with below solutions:
I think you written whole code in create scene and this will call once a time for a storyboard scene. You should try to implement reusable code in enterScene and should use local group = self.view for enter scene objects.
You should try to refresh or release memory of current storyboard scene either on DOOR collision with ball OR from exit scene of current storyboard.
I think the problem is the collision event gets triggered more than once while you delay to call nextScene.
Try doing something like this:
local hasNextSceneEventHappened = false
local function onCollision( event )
if ( event.phase == "ended" ) then
-- Ignore the call if we have already collided for next level
if(event.object1.name=="exitscn" or event.object2.name=="exitscn") then
if (hasNextSceneEventHappened == true ) then return end
hasNextSceneEventHappened = true
timer.performWithDelay ( 500, nextScene )
end
end
end
This code will ensure that you dont spam the goToScene() function and get undesired behavior.
I hope it works for you.
use a flag like didGo.
init this flag on your file body to false and write something like this:
-- body of your file:
local didGo = false
-- when you want to go to another scene
if ( not didGo) then
didGo = true
storyboard.gotoScene...
end

Resources