I'm working on a game in which I have a bunch of overlays and one scene which is called game.lua. I wanted to make it, when I press back button (hardware button on Android device), game would, if there's an overlay, close the overlay and if there's no overlay (just game.lua scene), it would show exitmenu.lua(simple pop-up menu).
function onKeyEvent( event )
if(event.keyName == "back") then
local CurrentScene = composer.getSceneName("current")
local CurrentOverlay = composer.getSceneName("overlay")
if CurrentScene == "Scenes.game" and CurrentOverlay == nil then
composer.showOverlay("Scenes.exitmenu", {isModal = true})
return true
elseif CurrentOverlay ~= nil and CurrentOverlay ~= "Scenes.exitmenu" then
composer.hideOverlay("fade", 500)
return true
end
end
end
Runtime:addEventListener("key", onKeyEvent)
What happens is, when I press back button while overlay is on, function hides the overlay and also shows exitmenu.lua overlay. I have no idea what is wrong with my code, any advice is highly appreciated.
EDIT: I've fixed it! I needed to add and event.phase == "down", which makes my button press do function only once. That was the fix.
Related
This code in scene1...
local composer = require ( "composer")
local scene = composer.newScene()
local function showScene2()
local options = {
effect = "slideLeft",
time = 130,
}
composer.gotoScene("scene2", options)
end
...is overriding this code, also in scene1...
local object = display.newImage("images/goBackBtn.png", 240, 250)
object.name = "button object"
local function onObjectTap( self, event )
composer.gotoScene( "firstBar1" )
return true
end
object.tap = onObjectTap
object:addEventListener( "tap", object )
sceneGroup:insert( object )
The back button works. It shows the firstBar1 scene, but only for an instant.
Then the next scene, scene2, comes on screen and the slideshow continues. (The order is firstBar1, scene1, scene2, scene3 and so on). All the scenes have a back button to firstBar1.
Why won't the slideshow go back to firstBar1 and stop there? How can I correct it?
This is related to a previous query which one commentator suggested I clarify: "Back button does not navigate to required scene".
Thanks.
Maybe because you have a timer performed on the firstBar scene ..If so, every time you show the firstBar1 scene, you call the showScene2 function() .. so every time you go back to the scene the timer is performed ..
I suggest you pass a param when tapping the back button to stop the timer, or even to decide to use the timer or not.
so I would add to the back button
local function onObjectTap( self, event )
composer.gotoScene( "firstBar1",{params = {timer = "stop"} )
return true
end
on the firstBar scene
local params = event.params
if (params.timer ~="stop") then
timer.performWithDelay(2000, showScene2 )
end
I am currently making a jumping game where there is an object at the left side of the screen, on a platform. Once the object successfully jumps and lands on the platform on the right, it does the following:
1) the platform on the right moves to the left
2) the platform on the left (that you JUST jumped off from) moves off-screen.
3) a new platform is supposed to appear at the right side of the screen, thus continuing the loop.
I have already made the functions where it allows the object to jump and show if the collision is successful or not. My problem is, the 3 things I have mentioned above happens, but it keeps on going and does not stop for the object to make the next jump. This makes the object go off screen as well, since the platforms keep moving towards the left. After debugging, I feel like the problem lies where the collision happens. This is because, once it touches the platform, the collision keeps on happening until the object is off of the platform. I was wondering if you guys can help me with this!
Here is part of my code that is relevant:
local onPlatform = false
local gameStarted = false
function playerCollision( self, event )
if ( event.phase == "began" ) then
--if hit bottom column, u get points
if event.target.type == "player" and event.other.type == "bottomColumn" then
print ("hit column")
onPlatform = true
else
--if hit anything else, gameOver
--composer.gotoScene( "restart" )
print ("hit ground")
end
end
end
function moveColumns()
for a = elements.numChildren,1,-1 do
--speed of columns moving
--if greater than -100, keep moving it to left
--puts platform at the right and stops
if (elements[a].x > display.contentWidth/1.1) then
elements[a].x = elements[a].x - 12
end
--moves platform to left after it successfully lands
if (onPlatform == true) then
if (elements[a].x > display.contentWidth/3 and elements[a].x < display.contentWidth/1.11) then
elements[a].x = elements[a].x - 12
end
end
--moves left platform to off-screen and deletes after it passes a certain X-axis
if (onPlatform == true) then
if(elements[a].x > -100 and elements[a].x < display.contentWidth/2.99) then
elements[a].x = elements[a].x - 12
--adds score if it goes past a certain X-axis at left side
elseif(elements[a].x < -100) then
mydata.score = mydata.score + 1
tb.text = mydata.score
elements[a].scoreAdded = true
elements:remove(elements[a])
elements[a] = nil
end
end
end
end
When are you calling moveColumns?? Could you just call it from within playerCollision and remove the onPlatform variable? Probably need a bit more code to help properly.
I have three Composer Scene and I like to navigate between them by swiping left or right. What I have tried to do in my listener is to check
if( event.phase == "moved" ) then
local dx = (event.x - event.xStart)
if(dx > 20) then
composer.removeScene("level", false)
composer.gotoScene("wlc", {effect = "slideRight",time = 5000} )
end
end
but in this case when I swipe the scene will be replaced and I can't stop it or go back
and what I need is to control sliding by my finger like ViewPger in android
any way to achieve this?
With Composer, once you start the scene transition, there is no way to abort.
local held = false
local function jumperTap ()
jumper:applyForce( 0, 200, jumper.x, jumper.y )
return false
end
Runtime:addEventListener( "tap", jumperTap )
local function holdListener(event)
held = true
jumper:applyForce( 0, 250, jumper.x, jumper.y )
return true
end
local function jumperTouch(event)
if (event.phase == "began") then
display.getCurrentStage():setFocus(jumper)
holdTimer = timer.performWithDelay( 500, holdListener )
elseif (event.phase == "moved") then
timer.cancel(holdTimer)
elseif (event.phase == "ended" or event.phase == "cancelled") then
display.getCurrentStage():setFocus(nil)
timer.cancel(holdTimer)
held = false
end
end
Runtime:addEventListener( "touch", jumperTouch )
I'm trying to have a tap and a touch and hold. When the touch and hold happens, the jumper will have more force applied to him so he can jump higher when the screen is touched and held. When the screen is tapped, he will have a shorter jump.
When I tap, the expected thing happens. When I tap and hold, the expected thing happens. I do have a few glaring issues though due to my novice-ness in Corona. They are...
- When I tap and hold, all goes well, but when I release, it glitches and what is performed is what seems to be a the tap event. Not sure why this is happening
- When I perform the tap event, I am able to perform it again while the object is in the air--this brings him down to the ground and the tap event seems to be performed again, but with less force.
Any and all help is greatly appreciated!
EDIT: I put return true and return false in just to try something different, but it didn't affect anything.
I recommend testing out a debounce in order to prevent the tap/tap+hold events from doubling up. By passing the functions through a global boolean you can make it so they can only tap while no tap events are occuring. Because based on your events it seems they happen regardless if they are currently in 'jump' mode or not.
Example:
debounce = false
function func1()
if debounce == false then
debounce = true
//event script
end
end
function event_ended()
debounce = false
end
--up in the level1.lua
local target
--in the enter frame function of scene
function target:touch(event)
if event.phase=="began" then
local target=display.newImage("target.png",event.x,event.y)
return true
end
end
function target:touch(event)
You have not created target yet. You cannot assign a touch handler to an object that doesn't exist yet.
It sounds like what you need to do is add a touch handler to the stage. I would pre-create the image and just hide it using .isVisible = true. Then in your touch handler, show and hide the object. But regardless you have to put the touch handler on the whole screen and not an individual small image.
Remove the "local" in target:touch: it hides the module local, using a variable local to target:touch(). Also, if you want image to disappear after touch done, use the "ended" and "cancelled" phases of touch event. Finally, I'm assuming that you initialized target to something but if not, you must add that too, otherwise how can you define touch:event (thanks to Rob for noticing this btw):
-- first create the target, but don't show it:
local target = display.newImage("target.png", 0, 0)
target.isVisible = false
--in the enter frame function of scene
function target:touch(event)
if event.phase=="began" then
target.x = event.x
target.y = event.y
return true
else if event.phase == "ended" or event.phase == "cancelled" then
if target ~= nil then
target:removeSelf()
target = nil
end
return true
end
end