App changes state while suspended in iOS

35 views
Skip to first unread message

RobB

unread,
Jun 6, 2013, 3:55:38 PM6/6/13
to fantom...@googlegroups.com
Hi, Michael,

Our app is nearing completion. It works very well on the iPad2 and Touch as long as it is running. However, we have one problem that we can't figure out. When we close the app without totally terminating it, and open it back up, our parallax background objects, which stay perfectly within boundaries when the app is operating, have somehow migrated out of the screen boundaries.  The  midground and background parallax images are slightly larger than the screen size. They are limited to a given difference from the center as they sort of ping pong off the four edges of the screen. The speed and direction are determined based on accelerometer readings. It all works fine while the app is running, and the parallax backgrounds stay where they should be. But when the app is paused, and then resumed, often the midground and foreground images will have traveled outside the prescribed boundaries and appear in mixed up positions. It seems that the images keep traveling at their set speed and direction after the app is paused, but the boundary conditions no longer keep them in the proper screen area. I tried setting update to 0 when the program is suspended, but that didn't work either. Other parts of the program seem to stay in place, but the fantomImages used for mid and foreground parallax background seem to keep moving at their set speed and direction even after suspension.

Can you tell me a way to freeze everything as is on suspension and resume exactly from that point on continuation of the program?

I notice that in 1.51 you added the ability to pause transitions. Is this what I need to halt the unexpected movement of the images when paused in iOS.

I may not have given you all the information you need to answer this, so let me know if I need to add more.

Thanks again.

Michael Hartlef

unread,
Jun 6, 2013, 5:23:57 PM6/6/13
to
Hi Rob,

besides using Get/SetPaused during OnSuspend/OnResume nothing comes to my mind.

'------------------------------------------

Method OnResume:Int()

' Set the pause flag of the engine to FALSE so objects, timers and transitions are updated again

fE.SetPaused(False)

Return 0

End

'------------------------------------------

Method OnSuspend:Int()

' Set the pause flag of the engine to TRUE so objects, timers and transitions are paused (not updated)

fE.SetPaused(True)

Return 0

End



Did you enable Suspending/Resuming in your app?

' Set the AutoSuspend functionality to TRUE so OnResume/OnSuspend are called

#MOJO_AUTO_SUSPEND_ENABLED=True


To my current knowledge, OnUpdate/OnRender is not called when the app is suspended.

When fE is paused, all timers, transitions, etc. should be paused too.


And you are not updating anything during OnRender, right?


Cheers
Michael

RobB

unread,
Jun 7, 2013, 3:32:47 PM6/7/13
to fantom...@googlegroups.com
Thank you, Michael! We're back on track to hopefully submit our app in a month or two. The three things you suggested were all needed. I had to use SetPause() instead of SetPaused(), but I had seen you discussing that with others (I haven't installed latest upgrade yet).  I didn't have Auto Suspend enabled and I didn't have the fE.SetPause (I used eng. instead of fE.) included in my OnResume() and OnSuspend (),  I had just worked off of one of your basic skeleton examples, and since it worked all along (until we tried pausing on the iPad), I never thought to look at it closely to notice the lack of the fE commands. I just had "isSuspended" and SetUpdateRate().  Everything seems to be working well now when we pause the app on the iPad.  I guess my only question now is what to use on SetUdateRate() when paused.  I now have 0 in it because I tried that to get things to pause before I asked for your help. But you originally had it set to something like 6.  Is that better than 0, and, if so, what is slower updating do during pause?

Below is the working code with your suggestions highlighted in yellow.

Method OnResume:Int()
          isSuspended = False
          ' Set the pause flag of the engine to FALSE so objects, timers and transitions are updated again
          eng.SetPause(False)

          SetUpdateRate(60)
          Return 0
        End Method 'OnResume       
   
        '------------------------------------------
        Method OnSuspend:Int()
          isSuspended = True
          ' Set the pause flag of the engine to TRUE so objects, timers and transitions are paused (not updated)
          eng.SetPause(True)

          SetUpdateRate(0)
          Return 0
        End Method 'OnSuspend

Michael Hartlef

unread,
Jun 8, 2013, 6:56:29 AM6/8/13
to
Yes I have "renamed" ins v1.51. Get/SetPause to Set/GetPaused as the naming it is more consistant with other methods.

When I started with monkey and wrote the book then, I was under the impression that OnUpdate/OnRender is still called when an app is suspended. So I thought it was a good idea to lower
the updaterate to save on the batteries. But it seems not to be the fact that OnUpdate and OnRender are called. So in the new versions of the basescript I don't lower the UpdateRate anymore.

And I have renamed the basic objects in the basescript in some common way. A class starts with a lower c, engine was renamed to fE (fantomEngine) and so on. Thsi si all cosmetic and you can
even name the fantomEngine instance "Hugo" if you want. Do what suits your style of coding the best.

I am sorry of these changes have caused any confusion.

Here is the current version of the basic script.


Strict


#rem

Script: BaseScript.monkey

Description: Basic fantomEngine script

Author: Michael Hartlef

Version: 1.11

#End


' Set the AutoSuspend functionality to TRUE so OnResume/OnSuspend are called

#MOJO_AUTO_SUSPEND_ENABLED=True


' Import the fantomEngine framework which imports mojo itself

Import fantomEngine


' The _g variable holds an instance to the cGame class

Global _g:cGame


'***************************************

' The cGame class controls the app

Class cGame Extends App

' Create a field to store the instance of the cEngine class, which is an instance

' of the ftEngine class itself

Field fE:cEngine

'------------------------------------------

Method OnCreate:Int()

' Set the update rate of Mojo's OnUpdate events to 60 FPS

SetUpdateRate(60)

' Create an instance of the fantomEngine, which was created via the cEngine class

fE = New cEngine


Return 0

End

'------------------------------------------

Method OnUpdate:Int()

' If the CLOSE key was hit, exit the app ... needed for GLFW and Android I think.

If KeyHit( KEY_CLOSE ) Then fE.ExitApp()

' Determine the delta time and the update factor for the engine

Local timeDelta:Float = Float(fE.CalcDeltaTime())/60.0


' Update all objects of the engine

If fE.GetPaused() = False Then

fE.Update(timeDelta)

Endif

Return 0

End

'------------------------------------------

Method OnRender:Int()

' Check if the engine is not paused

If fE.GetPaused() = False Then

' Clear the screen

Cls

' Render all visible objects of the engine

fE.Render()

Endif

Return 0

End

'------------------------------------------

Method OnResume:Int()

' Set the pause flag of the engine to FALSE so objects, timers and transitions are updated again

fE.SetPaused(False)

Return 0

End

'------------------------------------------

Method OnSuspend:Int()

' Set the pause flag of the engine to TRUE so objects, timers and transitions are paused (not updated)

fE.SetPaused(True)

Return 0

End

End


'***************************************

' The cEngine class extends the ftEngine class to override the On... methods

Class cEngine Extends ftEngine

'------------------------------------------

Method OnLayerTransition:Int(transId:Int, layer:ftLayer)

' This method is called when a layer finishes its transition

Return 0

End

'------------------------------------------

Method OnLayerUpdate:Int(layer:ftLayer)

' This method is called when a layer finishes its update

Return 0

End

'------------------------------------------

Method OnObjectCollision:Int(obj:ftObject, obj2:ftObject)

' This method is called when an object collided with another object

Return 0

End

'------------------------------------------

Method OnObjectDelete:Int(obj:ftObject)

' This method is called when an object is removed. You need to activate the event via ftObject.ActivateDeleteEvent.

Return 0

End

'------------------------------------------

Method OnObjectRender:Int(obj:ftObject)

' This method is called when an object was being rendered. You need to activate the event via ftObject.ActivateRenderEvent.

Return 0

End

'------------------------------------------

Method OnObjectSort:Int(obj1:ftObject, obj2:ftObject)

' This method is called when objects are compared during a sort of its layer list

Return 0

End

'------------------------------------------

Method OnObjectTimer:Int(timerId:Int, obj:ftObject)

' This method is called when an objects' timer was being fired.

Return 0

End

'------------------------------------------

Method OnObjectTouch:Int(obj:ftObject, touchId:Int)

' This method is called when an object was touched

Return 0

End

'------------------------------------------

Method OnObjectTransition:Int(transId:Int, obj:ftObject)

' This method is called when an object finishes its transition and the transition has an ID > 0.

Return 0

End

'------------------------------------------

Method OnObjectUpdate:Int(obj:ftObject)

' This method is called when an object finishes its update. You can deactivate the event via ftObject.ActivateUpdateEvent.

Return 0

End

'------------------------------------------

Method OnMarkerBounce:Int(marker:ftMarker, obj:ftObject)

' This method is called, when a path marker reaches the end of the path and is about to bounce backwards.

Return 0

End

'------------------------------------------

Method OnMarkerCircle:Int(marker:ftMarker, obj:ftObject)

' This method is called, when a path marker reaches the end of the path and is about to do another circle.

Return 0

End

'------------------------------------------

Method OnMarkerStop:Int(marker:ftMarker, obj:ftObject)

' This method is called, when a path marker reaches the end of the path and stops there.

Return 0

End

'------------------------------------------

Method OnMarkerWarp:Int(marker:ftMarker, obj:ftObject)

' This method is called, when a path marker reaches the end of the path and is about to warp to the start to go on.

Return 0

End

'------------------------------------------

Method OnMarkerWP:Int(marker:ftMarker, obj:ftObject)

' This method is called, when a path marker reaches a waypoint of its path.

Return 0

End

'------------------------------------------

Method OnSwipeDone:Int(touchIndex:Int, sAngle:Float, sDist:Float, sSpeed:Float)

' This method is called when a swipe gesture was detected

Return 0

End

'------------------------------------------

Method OnTimer:Int(timerId:Int)

' This method is called when an engine timer was being fired.

Return 0

End

End


'***************************************

Function Main:Int()

' Create an instance of the cGame class and store it inside the global var 'g'

_g = New cGame

Return 0

End




RobB

unread,
Jul 18, 2013, 2:39:20 PM7/18/13
to fantom...@googlegroups.com
Hello, Michael,

This is an elementary question, I'm sure, but I am confused with saving and reloading data to my .data folder. All I need to do is save (savestring?) and then be able to retrieve (loadstring?) an integer (or a character I could convert back to an integer) to and from my .data file for our iOS app.  I couldn't find any examples of how to do this. That's all I need is a single integer value saved to .data in the app and then able to be recalled. Can you give me a quick, simple example? Thanks.

Michael Hartlef

unread,
Jul 18, 2013, 4:48:22 PM7/18/13
to fantom...@googlegroups.com
SaveString only works with GLFW and StdCpp. You need to use brl.FileStream module.
Mark has created the filetest.monkey example. That shows you how to write and read into a file.
Reply all
Reply to author
Forward
0 new messages