Retry Button

Hello,

I was thinking about creating a restart button which returns the objects moved by the player to their initial positions and their initial rotation. So lets say the player moves an object to a certain location and rotates it  then clicks on the start button which applies physics on the objects and since the object is dynamic it will move to a new position, then the player clicks on the retry button and i want to create a function which returns the objects moved to the initial location set by the player.

I tried something out which didn’t work that well. I basically tried to save the location of the objects in the ended phase of the touch function and then try to set the x and y of the objects to their previous coordinates by using the retry button. 

Here is the initial code:

-- Here is the code i used for rotating the objects: local function rotatePlatform(event) local t = event.target local phase = event.phase if (phase == "began") then display.getCurrentStage():setFocus( t ) platformTouched.isFocus = true -- Store initial position of finger platformTouched.x1 = event.x platformTouched.y1 = event.y elseif platformTouched.isFocus then if (phase == "moved") then platformTouched.x2 = event.x platformTouched.y2 = event.y angle1 = 180/math.pi \* math.atan2(platformTouched.y1 - platformTouched.y , platformTouched.x1 - platformTouched.x) angle2 = 180/math.pi \* math.atan2(platformTouched.y2 - platformTouched.y , platformTouched.x2 - platformTouched.x) print("angle1 = "..angle1) rotationAmt = angle1 - angle2 --rotate it platformTouched.rotation = platformTouched.rotation - rotationAmt print ("platformTouched.rotation = "..platformTouched.rotation) platformTouched.x1 = platformTouched.x2 platformTouched.y1 = platformTouched.y2 elseif (phase == "ended") or (phase == "cancelled") then display.getCurrentStage():setFocus( nil ) platformTouched.isFocus = false display.remove( rotationalert ) rotationalert = nil end end return true end -- Here is the code i used to move the objects: local function movePlatform( event ) platformTouched = event.target transition.to(platformTouched, {onComplete = inventory}) if event.phase == "began" then display.getCurrentStage():setFocus( platformTouched ) platformTouched.isFocus = true audio.play ( selectionSound ) display.remove( rotationalert ) rotationalert = nil platformTouched.startMoveX = platformTouched.x platformTouched.startMoveY = platformTouched.y elseif platformTouched.isFocus then if event.phase == "moved" then -- The line below is the 392th line, where the error arises: platformTouched.x = ( event.x - event.xStart ) + platformTouched.startMoveX platformTouched.y = ( event.y - event.yStart ) + platformTouched.startMoveY elseif event.phase == "ended" or event.phase == "cancelled" then display.getCurrentStage():setFocus( nil ) platformTouched.isFocus = false end end return true end

Here is the move function with the extra code that i added to the ended phase. The code didnt work because it only saved the location of the last object moved using the function ( Im assuming that this was because platformtouched (event.target) could only have one set of coordinates?)

I’m hoping someone would be able to help me create this retry button. 

platformTouched = event.target transition.to(platformTouched, {onComplete = inventory}) if event.phase == "began" then display.getCurrentStage():setFocus( platformTouched ) platformTouched.isFocus = true audio.play ( selectionSound ) display.remove( rotationalert ) rotationalert = nil platformTouched.startMoveX = platformTouched.x platformTouched.startMoveY = platformTouched.y elseif platformTouched.isFocus then if event.phase == "moved" then -- The line below is the 392th line, where the error arises: platformTouched.x = ( event.x - event.xStart ) + platformTouched.startMoveX platformTouched.y = ( event.y - event.yStart ) + platformTouched.startMoveY elseif event.phase == "ended" or event.phase == "cancelled" then display.getCurrentStage():setFocus( nil ) platformTouched.isFocus = false if platformTouched.name == "box" then platformTouched.endMoveX = platformTouched.x platformTouched.endMoveY = platformTouched.y elseif platformTouched.name == "woodenPlank1" then platformTouched.woodendMoveX = platformTouched.x platformTouched.woodendMoveY = platformTouched.y end end end return true end

This problem isn’t really about the button.

It is about understanding how to restore the state of your game to a prior known state.

Except in the basic case (complete restart) this is a pretty advanced topic.

I suggest you do this:

  1. Write your game content as a module, not in a scene file.

  2. Write your game module like this:

    – save this as game.lua local m = {} local content local last function m.create( group ) group = group or last or display.currentStage last = group – m.destroy() – content = display.newGroup() group:insert(content) – DO NOT modify the above. – -- PUT YOUR GAME BUILDING CODE HERE – Add all groups and objects you create into the group ‘content’ end function m.destroy() display.remove( content ) content = nil end return m

  3. Without using composer.* at all, just require your game module in main and call it like this:

    local game = require “game” – Creates game first time game.create() – re-creates game 5 more times once every second. timer.performWithDelay( 1000, function() game.create() end, 5 )

Once you have that working without crashing, you can then use the module in  a composer.* scene to create your game like this:

function scene:create( event ) local sceneGroup = self.view game.create( sceneGroup ) end

You can then add a button to your scene and have the button listener call ‘game.create()’ to 'restart the game.

Sorry I’m kinda new to corona so i didn’t completely understand all this. Rn I’m using storyboard instead of composer and i know that storyboard is no longer supported by corona but i kept getting an error when using the composer. Anyways, would using game.create() restart the entire scene? as i don’t want to restart the scene and only want the objects to return to the locations set by the player.

Getting an error using Composer isn’t a reason to use Storyboard. There is nothing wrong with Composer so it would be an error in your code. It would be a much better learning experience to work out what you’re doing wrong, than just run away from the problem and create a whole load of new ones by using a deprecated library…

If you didn’t understand RG’s very simple code, you need to go back to basics and re-read the API docs and basic tutorials.

@mparvareshnia80 If I were you I would go completely with the beautiful code that @roaminggamer has given you. Thanks @roaminggamer, I know it’s not my topic, but I found very interesting information in it.

Maybe you are not familiar with the concept of modules, i.e classes. 

I suggest this to familiarize yourself with them:

http://lua-users.org/wiki/ModulesTutorial

Also, please switch off of Storyboard, Composer is easier and is supported.

This guide will tell you to set up Composer, transition between scenes, how to set up your code around the composer template, etc. 

What I suggest doing is create a new file or project, read the docs, and re-add your code based on what you learned from the documentation.

https://docs.coronalabs.com/guide/system/composer/index.html

Game.create would create a scene, game.destroy would destroy that scene. Therefore, you use game.destroy as a cleanup tool.

Btw, if you are familiar with the concept of classes, say from Java, or C++, this is not at all hard to grasp, just takes practice. (the documentation helps too)

This problem isn’t really about the button.

It is about understanding how to restore the state of your game to a prior known state.

Except in the basic case (complete restart) this is a pretty advanced topic.

I suggest you do this:

  1. Write your game content as a module, not in a scene file.

  2. Write your game module like this:

    – save this as game.lua local m = {} local content local last function m.create( group ) group = group or last or display.currentStage last = group – m.destroy() – content = display.newGroup() group:insert(content) – DO NOT modify the above. – -- PUT YOUR GAME BUILDING CODE HERE – Add all groups and objects you create into the group ‘content’ end function m.destroy() display.remove( content ) content = nil end return m

  3. Without using composer.* at all, just require your game module in main and call it like this:

    local game = require “game” – Creates game first time game.create() – re-creates game 5 more times once every second. timer.performWithDelay( 1000, function() game.create() end, 5 )

Once you have that working without crashing, you can then use the module in  a composer.* scene to create your game like this:

function scene:create( event ) local sceneGroup = self.view game.create( sceneGroup ) end

You can then add a button to your scene and have the button listener call ‘game.create()’ to 'restart the game.

Sorry I’m kinda new to corona so i didn’t completely understand all this. Rn I’m using storyboard instead of composer and i know that storyboard is no longer supported by corona but i kept getting an error when using the composer. Anyways, would using game.create() restart the entire scene? as i don’t want to restart the scene and only want the objects to return to the locations set by the player.

Getting an error using Composer isn’t a reason to use Storyboard. There is nothing wrong with Composer so it would be an error in your code. It would be a much better learning experience to work out what you’re doing wrong, than just run away from the problem and create a whole load of new ones by using a deprecated library…

If you didn’t understand RG’s very simple code, you need to go back to basics and re-read the API docs and basic tutorials.

@mparvareshnia80 If I were you I would go completely with the beautiful code that @roaminggamer has given you. Thanks @roaminggamer, I know it’s not my topic, but I found very interesting information in it.

Maybe you are not familiar with the concept of modules, i.e classes. 

I suggest this to familiarize yourself with them:

http://lua-users.org/wiki/ModulesTutorial

Also, please switch off of Storyboard, Composer is easier and is supported.

This guide will tell you to set up Composer, transition between scenes, how to set up your code around the composer template, etc. 

What I suggest doing is create a new file or project, read the docs, and re-add your code based on what you learned from the documentation.

https://docs.coronalabs.com/guide/system/composer/index.html

Game.create would create a scene, game.destroy would destroy that scene. Therefore, you use game.destroy as a cleanup tool.

Btw, if you are familiar with the concept of classes, say from Java, or C++, this is not at all hard to grasp, just takes practice. (the documentation helps too)