Perspective Virtual Camera library issue Corona SDK - lua

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.

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.

The output on console twice and the lanes overlap the player

The output I should get are the chick can jump right when i tap right and vice versa. But the two problems that I can't solve here are when I tap it will output in console like I tap twice. The second problem is the lanes are in array and keep on overlap everything, even the chick which is the player.
For this i include 2 lua files and 3 png.
This is my main.lua
display.setStatusBar( display.HiddenStatusBar )
local composer = require( "composer" )
print("entering gotoScene")
composer.gotoScene( "game2" )
print("out from gotoScene")
This is my game2.lua
---REQUIRES
local composer = require( "composer" )
local scene = composer.newScene()
local widget = require( "widget" )
local physics = require "physics"
physics.start()
physics.setGravity(0,0)
local lanes = {}
local laneID = 1
scroll = 2
---SIZE PHONE DECLARATION
local screenW = display.contentWidth --640
local screenH = display.contentHeight --1136
local halfX = display.contentWidth * 0.5 --half width 320
local halfY = display.contentHeight * 0.5 --half height 568
----------------------
----------------------
---WHEN TAP CHICK MOVE
local function tapListener( event )
local object = event.target
if object.name == "Right Side" then
print( object.name.." TAPPED!" )
if laneID < 3 then
laneID = laneID + 1;
transition.to(chick, {x=lanes[laneID].x,time=50})
print( "At lane "..laneID.." to the right")
end
return true
end
if object.name == "Left Side" then
print( object.name.." TAPPED!" )
if laneID > 1 then
laneID = laneID - 1;
transition.to(chick, {x=lanes[laneID].x,time=50})
print( "At lane "..laneID.." to the left")
end
return true
end
end
----------------------
---CREATE
-- Initialize the scene here.
-- Example: add display objects to "sceneGroup", add touch listeners, etc.
function scene:create( )
local group = self.view
---TAP BACKGROUND
RightSide = display.newRect(500,halfY, halfX+50, screenH + 100 )
RightSide.alpha = 0.1
RightSide.name = "Right Side"
LeftSide = display.newRect(140, halfY,halfX+50, screenH + 100)
LeftSide.alpha = 0.1
LeftSide.name = "Left Side"
----------------------
---TAP LABEL
rightLabel = display.newText({ text = "", x = 0, y = 0 , fontSize = 50 } )
rightLabel:setTextColor( 0 ) ; rightLabel.x = 500 ;rightLabel.y = halfY
leftLabel = display.newText({ text = "", x = 0, y = 0, fontSize = 50 } )
leftLabel:setTextColor( 0 ) ; leftLabel.x = 150 ; leftLabel.y = halfY
----------------------
---PATHWAY (BACKGROUND)
path1 = display.newImageRect("road.png",screenW,screenH)
path1.x = halfX
path1.y = halfY
path2 = display.newImageRect("road.png",screenW,screenH)
path2.x = halfX
path2.y = halfY - screenH
----------------------
---LANES
for i=1,3 do -- loop 3 times to create 3 lanes for our game
--myGroup=display.newGroup()
laneimg = display.newImageRect("lanesroad.png", 150, 1300)
lanes[i] = laneimg
lanes[i].x = (display.contentCenterX - 140*2) + (i*140)
lanes[i].y = display.contentCenterY
lanes[i].id = i
end
----------------------
---CHICK
chick = display.newImageRect("chick.png",100,100)
chick.anchorY = 1
chick.x = lanes[2].x
chick.y = 1000
physics.addBody(chick)
chick.bodyType = "dynamic"
----------------------
path1:toBack();
path2:toBack();
group:insert( RightSide )
group:insert( LeftSide )
group:insert( rightLabel )
group:insert( leftLabel )
group:insert( laneimg)
group:insert( chick )
end
----------------------
---BACKGROUND SCROLL
function pathScroll (self,event)
path1.y = path1.y + scroll
path2.y = path2.y + scroll
if path1.y == screenH * 1.5 then
path1.y = screenH * -.5
end
if path2.y == screenH * 1.5 then
path2.y = screenH * -.5
end
end
----------------------
---SHOW --that will show in scene
function scene:show (event)
---FOR ROAD TO SCROLL
path1.enterFrame = pathScroll
Runtime:addEventListener("enterFrame", pathScroll)
path2.enterFrame = pathScroll
Runtime:addEventListener("enterFrame", pathScroll)
----------------------
---WHEN TAP TO RIGHT
RightSide:addEventListener( "tap", tapListener )
rightLabel.text = "right"
----------------------
---WHEN TAP TO LEFT
LeftSide:addEventListener( "tap", tapListener )
leftLabel.text = "left"
----------------------
end
----------------------
---HIDE
function scene:hide (event)
end
----------------------
scene:addEventListener( "create", scene )
scene:addEventListener( "show", scene )
scene:addEventListener( "hide", scene )
return scene
enter image description here
enter image description here
The method scene:show is called twice. Once with event.phase paramater equal to will and second time with event.phase paramater equal to did. It also apply to scene.hide method. Code below check that.
At botom I put scene template from Corona documentation. It can be used as start point for new scene.
I commented out line with Runtime:addEventListener("enterFrame", pathScroll). You have two but one is enough.
More information you find with these links
Composer Library
Introducing the Composer API
Tap / Touch / Multitouch
Try (tested)
...
---SHOW --that will show in scene
function scene:show (event)
local phase = event.phase
if ( phase == 'will' ) then
elseif ( phase == 'did' ) then
---FOR ROAD TO SCROLL
path1.enterFrame = pathScroll
Runtime:addEventListener("enterFrame", pathScroll)
path2.enterFrame = pathScroll
--Runtime:addEventListener("enterFrame", pathScroll)
----------------------
---WHEN TAP TO RIGHT
RightSide:addEventListener( "tap", tapListener )
rightLabel.text = "right"
----------------------
---WHEN TAP TO LEFT
--LeftSide:addEventListener( "tap", tapListener )
leftLabel.text = "left"
----------------------
end
end
----------------------
...
Scene template
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()"
-- -----------------------------------------------------------------------------------
-- -----------------------------------------------------------------------------------
-- 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
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
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

Error : attempt to index global " cloud"

why i cant see the cloud image and is says a nil value when i put x and y coordinate and lastly how could i make in go up and repaswn itself randomly?
local storyboard = require("storyboard")
local scene = storyboard.newScene()
local physics = require "physics"
physics.start( )
physics.setGravity(0, 0)
--physics.setDrawMode( "hybrid" )
local LEFT = 100
local CENTER = display.contentCenterX
local RIGHT = display.contentWidth - 100
the problem is around here. i tried to change imges and a variety of coding yet it failed
function scene:createScene(event)
local screenGroup = self.view
cloud = display.newImage( "cloud.jpeg")
cloud.x = 200
cloud.y = 900
back = display.newImage( "sky.png" )
back.x = display.contentWidth/2
back.y = display.contentHeight/2
screenGroup:insert(back)
end
local function handleSwipe( event )
if event.phase == "moved" then
local dX = event.x - event.xStart
print(event.x, event.xStart, dX)
if dX > 10 then
local spot = RIGHT
if event.target.x == LEFT then
spot = CENTER
end
transition.to( event.target, {time=350, x = spot } )
elseif dX < -10 then
local spot = LEFT
if event.target.x == RIGHT then
spot = CENTER
end
transition.to( event.target, {time=350, x = spot } )
end
end
return true
end
function scene:enterScene(event)
object = display.newImage( "diver.png", display.contentCenterX, display.contentHeight/1.7, 25 )
object:addEventListener( "touch", handleSwipe )
end
function scene:exitScene( event )
end
function scene:destroyScene( event )
end
scene:addEventListener( "createScene", scene )
scene:addEventListener( "enterScene", scene )
scene:addEventListener( "exitScene", scene )
scene:addEventListener( "destroyScene", scene )
return scene
anyone can help?
I think you don't have "cloud.jpeg" in a folder where main.lua is. Otherwise tell me which line bug is related to.

corona + collision not working

I am learning Corona and I am trying to use the collision event.
The target of the following program is that the rock is moving towards to the car using transition.to. And print a line to report the collision where it occurs.
However, it does not work. Moreover, I even cannot receive the message "enterenter", what is the reason why the program cannot even get into the enter function?
My code is as follow. Thank you in advance.
local composer = require( "composer" )
local scene = composer.newScene()
local physics = require "physics"
physics.start(); physics.pause()
local function onLocalCollision( self, event )
if ( event.phase == "began" ) then
print( self.myName .. ": collision began with " .. event.other.myName )
elseif ( event.phase == "ended" ) then
print( self.myName .. ": collision ended with " .. event.other.myName )
end
end
local widget = require "widget"
function scene:create( event )
print("entercreate")
local sceneGroup = self.view
local backgrd = display.newImage("background2.png",0,260)
backgrd:scale(3,3)
local car = display.newImage("car2.png",80,270)
physics.addBody(car,"static")
car.myName="Car"
local rock = display.newImage("rock.jpg",520,280)
rock:scale(0.05,0.05)
physics.addBody(rock,"static")
rock.myName="rock"
sceneGroup:insert(backgrd)
sceneGroup:insert(car)
sceneGroup:insert(rock)
transition.to(backgrd,{time=24000, x=-1800,onComplete=endScroll})
transition.to(rock,{time=4000, delay=2500,x=-40})
end
function scene:enter( event )
print("enterenter")
physics.start()
local sceneGroup = self.view
Runtime:addEventListener( "collision", onLocalCollision )
end
scene:addEventListener( "create", scene )
scene:addEventListener( "enter", scene )
return scene
Working code with a local and a global (Runtime) listener:
local widget = require "widget"
local composer = require( "composer" )
local scene = composer.newScene()
local physics = require "physics"
physics.start()
physics.setGravity( 0,0 )
local function onGlobalCollision( event )
local target = event.object1
local other = event.object2
if ( event.phase == "began" ) then
print( "GLOBAL: " .. target.name .. ": collision began with " .. other.name )
elseif ( event.phase == "ended" ) then
print( "GLOBAL: " .. target.name .. ": collision ended with " .. other.name )
end
end
local function onLocalCollision( event )
local target = event.target
local other = event.other
if ( event.phase == "began" ) then
print( "LOCAL: " .. other.name .. ": collision began with " .. target.name )
elseif ( event.phase == "ended" ) then
print( "LOCAL: " .. other.name .. ": collision ended with " .. target.name )
end
end
function scene:create( event )
print("scene:create")
local sceneGroup = self.view
local car = display.newRect( 100, 100, 100, 100 )
car.name = "car"
physics.addBody( car )
local rock = display.newRect( 250, 250, 100, 100 )
rock.name = "rock"
rock:setFillColor( 0.5, 0.5, 0.5 )
physics.addBody( rock )
rock:addEventListener( "collision", onLocalCollision )
sceneGroup:insert(car)
sceneGroup:insert(rock)
transition.to(rock,{time=4000, x = -40, y = -100})
Runtime:addEventListener( "collision", onGlobalCollision )
end
function scene:enter( event )
print("scene:enter")
local sceneGroup = self.view
end
scene:addEventListener( "create", scene )
scene:addEventListener( "enter", scene )
return scene
The problem that you have with your code is that the two bodies are static and two static bodies can't collide with each other and that there is nothing called scene:enter in composer (so that's why it doesn't gets called and therefor not the onLocalListener).
Some body types will — or will not — collide with other body types. In
a collision between two physical objects, at least one of the objects
must be dynamic, since this is the only body type which collides with
any other type. See the Physics Bodies guide for details on body
types.
https://docs.coronalabs.com/daily/guide/physics/collisionDetection/index.html
Here is some information about the Composer API and you'll that you should probably use scene:show:
https://coronalabs.com/blog/2014/01/21/introducing-the-composer-api-plus-tutorial/

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