When a player has completed a game, i would like for the scene to be restarted, i.e i want to reload the current scene. I have tried storyboard:reloadScene() without success.
I also tried to purge the scene and then reload it, also without any result.
local function onEveryFramePoop()
if(foodBalls) then
for i = foodBalls.numChildren, 1, -1 do
local ball = foodBalls[i]
if(ball.y > 200 and not(ball.isBeingPooped)) then
ball.isBeingPooped = true
local function tempRemove()
if(foodBalls.numChildren)then
ball:removeSelf()
ball = nil
print("removed")
end
end
physics.removeBody(ball)
transition.to(ball, {time = 2000, y = 400, onComplete = tempRemove})
audio.play(fartSound)
end
end
if(foodBalls.numChildren == 0 and food.numChildren == 2) then
reward.playRewardAnimation()
Runtime:removeEventListener("enterFrame", onEveryFramePoop)
timer.performWithDelay(2500, reloadSceneWithDelay)
end
end
end
function reloadSceneWithDelay()
storyboard.gotoScene("levels.levelDigestion") -- **HERE I WANT TO RESTART SCENE**
end
Nothing seems to happen at all. What am i missing here ?
I didn't use storyboard but, you can try this :
Create a black scene in storyboard
Then, when you want to restart, just go to black scene and afterwards to the scene where you want to go.
The problem may be about that you are trying to call a module from itself.
Related
I am trying to make a frame that bobs up and down when an event is triggered (already worked the event out and it works perfectly) however i have no idea how to work with frames and i would really like to make the frame do the effect mentioned above, an additional thing is can it then after another event is triggered slide down and off the screen?
Heyo, the Developer Hub has great tutorials for working with with Frames and Guis!
It sounds like TweenService is the thing that will solve your problem!
I don't know what signal you're tapping into but here's a simple example of the thing you want to do :
1) Create a ScreenGui in StarterGui.
2) Add a TextButton to the ScreenGui, we'll listen for clicks on this to toggle the frame open and close.
3) Add a Frame to the ScreenGui, add some stuff to it. Customize it, move it around.
4) Add a LocalScript to the ScreenGui. Add this to the script...
-- grab some UI Elements
local TweenService = game:GetService("TweenService")
local btn = script.Parent.TextButton
local testFrame = script.Parent.Frame
-- make some variables
local isVisible = false
local currentTween
local onscreenPos = testFrame.Position
local offscreenPos = UDim2.new(onscreenPos.X.Scale - 1,
onscreenPos.X.Offset,
onscreenPos.Y.Scale,
onscreenPos.Y.Offset)
-- make a helper function for animating the frame
local function tweenToPos(thing, target)
local tweenInfo = TweenInfo.new(0.5, -- how long should this play (seconds)
Enum.EasingStyle.Bounce, -- << This will give you the bounce in look
Enum.EasingDirection.Out,
0, -- number of times to repeat
false, -- reverses
0) -- how many seconds to delay the animation
local propertyTable = {
Position = target,
}
local tween = TweenService:Create(thing, tweenInfo, propertyTable)
return tween
end
-- move the frame off-screen to begin with
testFrame.Position = offscreenPos
-- connect to the button and toggle between on/offscreen
btn.Activated:Connect(function(inputObj)
-- if the tween is already running, cancel it
if currentTween then
if currentTween.PlaybackState == Enum.PlaybackState.Playing
or currentTween.PlaybackState == Enum.PlaybackState.Delayed
or currentTween.PlaybackState == Enum.PlaybackState.Paused then
currentTween:Cancel()
end
end
-- create a new tween to animate the frame
if isVisible then
currentTween = tweenToPos(testFrame, offscreenPos)
else
currentTween = tweenToPos(testFrame, onscreenPos)
end
-- play the animation
currentTween:Play()
-- toggle which tween to use next
isVisible = not isVisible
end)
This should have a nice bounce effect for going in and out. You can swap out the btn.Activated:Connect with whatever signal you were listening to and this should work just fine.
Hope this helped!
Heyo, since you're trying to animate when a user hovers over a frame, follow these steps...
1) Create a ScreenGui in StarterGui.
2) Add a Frame to the ScreenGui, change its name to HoverFrame, we'll listen for mouse events on this to toggle the animation states.
3) Add another Frame to the ScreenGui, change its name to TweenFrame, add some stuff to it. Customize it, move it around, this is what we'll animate around the screen.
4) Add a LocalScript to the ScreenGui. Double click to open it, and add this to the script...
-- grab some UI Elements
local hoverFrame = script.Parent.HoverFrame
local testFrame = script.Parent.TweenFrame
-- make some variables
local TweenService = game:GetService("TweenService")
local currentTween
local onscreenPos = UDim2.new(0,0,0.443,0)
local offscreenPos = UDim2.new(0,0,0.914,0)
-- make a helper function for animating the frame
local function tweenToPos(thing, target)
local tweenInfo = TweenInfo.new(0.5, -- how long should this play (seconds)
Enum.EasingStyle.Bounce, -- << This will give you the bounce in look
Enum.EasingDirection.Out,
0, -- number of times to repeat
false, -- reverses
0) -- how many seconds to delay the animation
local propertyTable = {
Position = target,
}
local tween = TweenService:Create(thing, tweenInfo, propertyTable)
return tween
end
-- make another helper function for handling the animation tween
local function cancelTweenIfPlaying()
if currentTween then
if currentTween.PlaybackState == Enum.PlaybackState.Playing
or currentTween.PlaybackState == Enum.PlaybackState.Delayed
or currentTween.PlaybackState == Enum.PlaybackState.Paused then
currentTween:Cancel()
end
end
end
-- listen for when the mouse hovers over the button, and animate the frame
hoverFrame.MouseEnter:Connect(function(x, y)
-- if there is an animation playing, cancel it.
cancelTweenIfPlaying()
-- animate the frame to center stage
currentTween = tweenToPos(testFrame, onscreenPos)
currentTween:Play()
end)
-- listen for when the mouse stops hovering over the button
hoverFrame.MouseLeave:Connect(function(x, y)
-- if the tween is already running, cancel it
cancelTweenIfPlaying()
-- animate to offscreen
currentTween = tweenToPos(testFrame, offscreenPos)
currentTween:Play()
end)
Hope this helped!
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'm new to Corona and Lua, so pleas be patient.
So i have a main screen, that I go to from my main file, and it works fine. Then i want to go back to that sceen from a diffrent sceen, and nothing happens (but the "win" is spaming my consol window).
The win function:
function win()
print("win!");
storyboard.gotoScene( "MSCREEN.mscreen" );
end
Function where i'm calling it:
function scene:enterFrame(inEvent)
--some other stuff
if (ball.x>display.contentWidth and failFlag==false) then
win();
end
end
and my main sceen:
local scene = storyboard.newScene();
local bg;
local text;
function scene:createScene(inEvent)
bg = display.newImage( "MSCREEN/bg.png");
bg.x = display.contentWidth / 2;
bg.y = display.contentHeight / 2;
text=display.newText( "Touch!", 0,0, fontName, 70);
text.x =display.contentWidth / 2 ;
text.y =display.contentHeight / 2 +230;
self.view:insert(bg);
self.view:insert(text);
end
function scene:enterFrame(inEvent)
tekstBujany(text);
end
function scene:touch(inEvent)
if inEvent.phase == "ended" then
storyboard.gotoScene( "JUMP.GJump" );
end
end
function scene:destroyScene(inEvent)
bg:removeSelf();
bg=nil;
text:removeSelf();
text=nil;
end -- End destroyScene().
scene:addEventListener("createScene", scene);
scene:addEventListener("destroyScene", scene);
Runtime:addEventListener("enterFrame", scene);
Runtime:addEventListener("touch",scene);
return scene;
SOLVED
so adding
storyboard.purgeOnSceneChange = true;
did the trick, not sure why.
Be careful with the win() function, it looks like it gets called a lot of times. Set another variable and change it in the method.
function win()
isNotWin = false -- so this method doesn't get called a lot of times.
print("win!")
storyboard.gotoScene( "MSCREEN.mscreen" )
end
function scene:enterFrame(inEvent)
--some other stuff
if (ball.x>display.contentWidth and failFlag==false and isNotWin == true) then
win();
end
end
The "enterFrame" event gets generated at every frame for the Runtime object, so about 30 to 60 times / sec. So win() will be called at every frame if possible. Since win() causes a transition to a new scene, if storyboard.purgeOnSceneChange = false then enterFrame gets called for each scene, leading to constant stream of win() calls and constant stream of transitions to the same scene "MSCREEN.mscreen" (this can't be good). OTOH if you set storyboard.purgeOnSceneChange = true then the previous scene, here the one with enterFrame that calls win(), is purged so win() will only get called once.
In conclusion, setting storyboard.purgeOnSceneChange = true may work but I think there is a problem with the logic you have there: a scene transition should not be called at every frame! If you are monitoring for some condition to declare a win, you should either remove the enterFrame callback in win() or ensure the condition is false after win() called once:
function scene:enterFrame(inEvent)
if (ball.x > display.contentWidth and failFlag == false) then
win();
Runtime:removeEventListener("enterFrame", scene);
end
end
With the guard variable it looks like this:
local winCalled = false
function win()
winCalled = true
...
end
function scene:enterFrame(inEvent)
if (ball.x > display.contentWidth and failFlag == false) then
win();
end
end
I'm working on a simple breakout game and I've problem with ball:addEventListener( "collision", removeBricks ), it works fine until the ball hits two bricks at same time, than the up/down direction (vy) switch twice, making the ball continue moving up or down.
How can do one by one addEventListener collision and disable multiple collides at once?
function removeBricks(event)
if event.other.isBrick == 1 then
vy = vy * (-1)
...
end
end
Instead of changing ball's velocity in the removeBricks function, you can just flip a flag that means "a ball has hit some bricks and should change it's direction", and then in your enterFrame handler just change the ball's speed:
local ballHasCollided = false
local function removeBricks(event)
if event.other.isBrick == 1 then
ballHasCollided = true
end
end
local function updateBallVelocity(event)
if ballHasCollided then
ballHasCollided = false
ball.vy = -ball.vy
-- ...
end
-- your game set up code somewhere
Runtime:addEventListener('enterFrame', updateBallVelocity)
I'm working on a simple "breakout" game and I have problem reloading a map.
for example: if I start with level1, break some bricks and lose, than I'm loading the same map again. next time that the ball collides with the same brick I "touched" before, will give me an error Attempt to remove an object that has already been removed
local map = lime.loadMap("maps/" .. currentLevel .. ".tmx")
local layer = map:getTileLayer("bricks_1")
local visual = lime.createVisual(map)
local physical = lime.buildPhysical(map)
function removeBricks(event)
if event.other.isBrick then
local brick = event.other
transition.to(brick, {time = 20, alpha = 0})
score = score + brick.scoreValue
ScoreNum.text = score
-- remove brick
brick:removeSelf()
brick = nil
...
i think the second time you go to your game the event.other is not created are you using storyboard if so you can try to remove the scene after the game is over so when you go to your game again it will recreate all the object
Have you try this?
transition.to(brick, {time = 20, alpha = 0, onComplete = function()
if brick then
brick:removeSelf()
brick = nil
end
end})
If you are using physics you also have to do a physics.removeBody(brick) before you remove the object itself so that it detaches from the physics engine. If not physics thinks it's still there.