About Monkey 2 › Forums › Monkey 2 Programming Help › Monkey 2 App Template
Tagged: App Template, OnActivate, OnDeactivate
This topic contains 13 replies, has 3 voices, and was last updated by
codifies
2 years, 3 months ago.
-
AuthorPosts
-
January 13, 2017 at 12:54 pm #6487
Hello Monkey Team,
I put together a Monkey 2 App template for GUI that includes the OnRender, OnUpdate and the OnActivate and OnDeactivated ( same as MX1 OnSuspend and OnResume), I am assuming that OnLoad happens in the App initialization Method (New). On the second code I implemented the “isSuspended” to minimized the app activity in the background, so I save the App.FPS in this mode and display it when the Window app is Maximized. I need your input to finalize this template and share it with you.
Monkey1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556#Import "<std>"#Import "<mojo>"#Import "<mojox>"Using std..Using mojo..Using mojox..Global virtualResolution:=New Vec2i( 640,480 )Class MyApp Extends WindowField isSuspended:Bool=FalseMethod New( title:String,width:Int,height:Int,flags:WindowFlags=WindowFlags.Resizable )Super.New( title,width,height,flags )' Assign a Method to the App.Activated.App.Activated+=OnActivated ' Resume the App when Window maximizes or gets focus' Assign a Method to the App.Deactivated.App.Deactivated+=OnDeactivated ' Suspend the App When Window minimazes or loose focus.' Hide the mouse pointer.'Mouse.PointerVisible = FalseEndMethod OnRender( canvas:Canvas ) Override'Print "OnRender"OnUpdate()EndMethod OnUpdate()' Print "OnUpDate"If isSuspendedsavedFPS=App.FPS'Print "App is in runing the Background"EndifEndMethod OnActivated()Print "OnActivated"isSuspended=FalseEndMethod OnDeactivated()isSuspended=TruePrint "OnDeactivated"EndMethod OnMeasure:Vec2i() OverrideReturn virtualResolutionEndEndFunction Main()New AppInstanceNew MyApp( "MX2 Template",640,480 )App.Run()EndNow for Mobile Devices we need to reduce app activity on the background to save battery power, so a added the following to the code and I want to know if what I did reduces power consumption. Minimize the App window on PC or press the Home button to put it in the background. In MX1 I setup the update rate to 5 (SetUpdateRate(5)) in suspended and back to 60 (SetUpdateRate(60)) on resume, I don’t know if this is the case with MX2.
Monkey12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879#Import "<std>"#Import "<mojo>"#Import "<mojox>"Using std..Using mojo..Using mojox..Global virtualResolution:=New Vec2i( 640,480 )Class MyApp Extends WindowField isSuspended:Bool=FalseField savedFPS:Int=0' Screen TitleField titlemsg:StringField title_y:IntField title_x:FloatMethod New( title:String,width:Int,height:Int,flags:WindowFlags=WindowFlags.Resizable )Super.New( title,width,height,flags )' Assign a Method to the App.Activated.App.Activated+=OnActivated ' Resume the App when Window maximizes or gets focus' Assign a Method to the App.Deactivated.App.Deactivated+=OnDeactivated ' Suspend the App When Window minimazes or loose focus.' Hide the mouse pointer.'Mouse.PointerVisible = Falsetitlemsg="Monkey 2 Window Template - Click Minimize/Maximize Window "EndMethod OnRender( canvas:Canvas ) Overridetitle_x=canvas.Font.TextWidth(titlemsg) 'get the titlemsg text lengthtitle_x=virtualResolution.X *.5-title_x *.5 'center it on the screenIf Not isSuspendedApp.RequestRender()' canvas.DrawText(App.FPS,virtualResolution.X*.5,virtualResolution.Y*.5)canvas.DrawText("FPS:"+App.FPS,0,16)canvas.DrawText("FPS - On App Suspended:"+savedFPS,0,32)canvas.Color=Color.Greencanvas.DrawText(titlemsg,title_x,0)ElsesavedFPS=App.FPSEndifOnUpdate()EndMethod OnUpdate()' Print "OnUpDate"If isSuspendedsavedFPS=App.FPS'Print "App is in runing the Background"EndifEndMethod OnActivated()isSuspended=FalsePrint "FPS - App Suspended:"+savedFPSEndMethod OnDeactivated()isSuspended=TruePrint "OnDeactivated"EndMethod OnMeasure:Vec2i() OverrideReturn virtualResolutionEndEndFunction Main()New AppInstanceNew MyApp( "MX2 Template",640,480 )App.Run()EndJanuary 13, 2017 at 2:18 pm #6488check with a cpu load meter both on all platforms you can, but you might need to yield to the OS (sleep) after onDeactivated.
I’d do some canvas.scale first thing onRender, so you can preserve either a fixed resolution (that gets scaled) or ideally a fixed resolution scalled to a fixed aspect ratio…
also in keywords – can you mix up the case a bit like UsInG just for pedants… >:)
January 13, 2017 at 5:53 pm #6489I tested on iOS 10.2 on iPhone 6 and when it goes to OnDeactivate the app sleeps, the behavior is different on PC running Windows 10 and the same on my MacBook Pro running OSX Sierra, they run on the back ground. I will run on my Android device.
January 14, 2017 at 2:48 am #6494You could try something like this:?
[/crayon]Monkey12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758[crayon-5cba89eae76c1880267107 inline="true" ]#Import "<std>"#Import "<mojo>"#Import "<mojox>"Using std..Using mojo..Using mojox..Class MyApp Extends WindowField UpdateTimer:TimerField ticker:ULong = 0Method New( title:String,width:Int,height:Int,flags:WindowFlags=WindowFlags.Resizable )Super.New( title,width,height,flags)App.Activated += OnActivatedApp.Deactivated += OnDeactivatedUpdateTimer = New Timer(60, OnUpdate)SwapInterval = 0EndMethod OnUpdate()ticker += 1EndMethod OnRender( canvas:Canvas ) OverrideIf Not App.Active Then ReturnApp.RequestRender()canvas.DrawText("Click Minimize/Maximize Window", 10, 10)canvas.DrawText("FPS: " + App.FPS, 10, 50)canvas.DrawText("Ticker: " + ticker, 10, 90)canvas.Flush()EndMethod OnActivated:Void()UpdateTimer.Suspended = FalseEndMethod OnDeactivated:Void()UpdateTimer.Suspended = TrueEndEndFunction Main()New AppInstanceNew MyApp( "MX2 Template", 640, 480 )App.Run()EndJanuary 14, 2017 at 1:27 pm #6498impixi,
Thank you this looks much cleaner, one interesting thing is the FPS in my Original template runs at 60 frames per second , on yours the frame rate is much higher, on Windows and OSX.
This works great with mobile, I tested on iOS so far .
January 14, 2017 at 8:41 pm #6505Here is the updated Monkey 2 App Template.
Monkey123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475#Import "<std>"#Import "<mojo>"#Import "<mojox>"Using std..Using mojo..Using mojox..Global virtualResolution:=New Vec2i( 640,480 )Class MyApp Extends WindowField UpdateTimer:TimerField ticker:ULong = 0' Screen TitleField titlemsg:StringField title_y:IntField title_x:FloatMethod New( title:String,width:Int,height:Int,flags:WindowFlags=WindowFlags.Resizable )Super.New( title,width,height,flags)' Set OnActivated and OnDeactivated methods for when App loses or gain focus.App.Activated += OnActivatedApp.Deactivated += OnDeactivated' Load images, sounds and game data hereOnLoad()' Trigger OnUpdateUpdateTimer = New Timer(60, OnUpdate) ' start game timer at 60 HertzSwapInterval = 0EndMethod OnLoad()titlemsg="Click Minimize/Maximize Window "EndMethod OnUpdate()ticker += 1EndMethod OnRender( canvas:Canvas ) OverrideIf Not App.Active Then Returntitle_x=canvas.Font.TextWidth(titlemsg) 'get the titlemsg text lengthtitle_y=canvas.Font.Height*.5title_x=virtualResolution.X *.5-title_x *.5 'center it on the screenApp.RequestRender()canvas.DrawText(titlemsg, title_x, title_y)canvas.DrawText("FPS: " + App.FPS+" Ticker: " + ticker,10,64 )canvas.Flush()EndMethod OnActivated:Void()UpdateTimer.Suspended = FalseEndMethod OnDeactivated:Void()UpdateTimer.Suspended = TrueEndMethod OnMeasure:Vec2i() OverrideReturn virtualResolutionEndEndFunction Main()New AppInstanceNew MyApp( "MX2 Template",640,480 )App.Run()EndJanuary 15, 2017 at 12:36 am #6513one interesting thing is the FPS in my Original template runs at 60 frames per second , on yours the frame rate is much higher, on Windows and OSX.
SwapInterval = 0 disables vsync, I believe, so that’s the frame rate difference.
January 15, 2017 at 10:55 am #6528bare in mind vsync can be overriden by user settings on Linux, ~/.drirc on Intel GPU and on Nvidia there is a GUI that allows you to override frame sync.
Looking at the way most games work, including unity seem to just ignore user settings and assume frame sync is enabled meaning they run at silly speed! There are some games that seem to work correctly however regardless of user sync setting.
can I suggest that you make some of the methods abstract and those that do need code like OnRender make them call another method that is abstract. My idea is here that the end user would have one object to create and just simply override methods in the framework rather than hacking on the framework itself…
January 15, 2017 at 4:22 pm #6532codifies, it is a good suggestion. Can you send me a sample code of what you proposed?
January 15, 2017 at 5:12 pm #6535you’d like me to write it for you?
if you’re unsure about abstract have a look at the language reference.
I suggested abstract over virtual as people might not know you need to call super (even if you write it in the frameworks readme!)
January 15, 2017 at 8:45 pm #6538here is an example of keeping your drawing to 16:9
[/crayon]Monkey1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677[crayon-5cba89eb0bba7424259254 inline="true" ]#Import "<std>"#import "<libc>"#Import "<mojo>"#Import "assets/"using std..using mojo..using libc..global image:Imageclass MyWindow extends WindowField NewWidth:floatField NewHeight:floatmethod new()' new window deliberatly not 16:9super.new("hello",1024,768,WindowFlags.Resizable)ClearColor=new Color( 0,.25,0 )' image is same size as our virtual resolution (960x540)image = Image.Load( "asset::testcard.png" )endmethod OnRender( canvas:Canvas ) overrideApp.RequestRender()canvas.Clear(ClearColor)NewWidth = WidthNewHeight = Height' the smallest dimention is used to scale to largest 16:9 that fitsIf ((Width/16.0)<=(Height/9.0)) ThenNewHeight = (Float(Width) / 16.0) * 9.0ElseNewWidth = (Float(Height) / 9.0) * 16.0EndifLocal scaleX:float = NewWidth/960.0Local scaleY:float = NewHeight/540.0Local Xoffset:int = -((NewWidth-Width) / 2.0) / scaleXLocal Yoffset:int = -((NewHeight-Height) / 2.0) / scaleYcanvas.Scale( scaleX, scaleY )canvas.Translate(Xoffset, Yoffset)' from here on all drawing is at 16:9 and centred' NB may need to gl scissor the letter boxcanvas.DrawImage(image, 0,0)endendfunction Main()' boiler plate just to ensure random is different each runlocal tv:timevalgettimeofday( varptr(tv) )local t:long = tv.tv_sec * 1000 + tv.tv_usecSeedRnd(t)' more boiler plate just to kick the app off...new AppInstancenew MyWindowApp.Run()endJanuary 15, 2017 at 9:00 pm #6539codifies,
I know how to write abstract methods, I would like you to expand on your idea.
January 15, 2017 at 9:55 pm #6540I’m sure you can work it out for yourself…
January 16, 2017 at 1:22 am #6543canvas.Scissor=New Recti( Xoffset*scaleX,Yoffset*scaleY, (960+Xoffset)*scaleX, (540+Yoffset)*scaleY )
-
AuthorPosts
You must be logged in to reply to this topic.