Code with several draw loops - structure?

Monkey Forums/Monkey Programming/Code with several draw loops - structure?

GfK(Posted 2011) [#1]
I have a bunch of classes, for example; frontend, intro, game, etc. Each of these classes has its own loop for drawing, updating and timing (its Blitzmax code). Here's a little example (that obviously doesn't work) to explain what I mean. How do I restructure this code for Monkey?:
Import mojo

Function Main()
	New myApp
End Function

Class myApp extends App
	Field frontEnd:cFrontEnd
        Field game:cGame
	Method OnCreate()
		Self.frontEnd = New cFrontEnd
		Self.frontEnd.Play()
	End Method
End Class

Class cFrontEnd
	Method Play()
		Repeat
			Self.UpdateLogic()
			Self.DrawScreen()
		Forever
	End Method
	
	Method UpdateLogic()
	End Method

	Method DrawScreen()
		Cls
		DrawText "Front End",50,50
	End Method

Class cGame
	Method Play()
		Repeat
			Self.UpdateLogic()
			Self.DrawScreen()
		Forever
	End Method
	
	Method UpdateLogic()
	End Method

	Method DrawScreen()
		Cls
		DrawText "Game",50,50
	End Method
End Class



wiebow(Posted 2011) [#2]
I would put the frontend, intro etc into the game class.

Then in your myApp, add the OnUpdate() and OnRender() methods.
From there, call cGame.Update() and cGame.Render(), which in turn call your cFrontEnd (and intro, etc) update and render methods. Delete the Play() method.


Volker(Posted 2011) [#3]
Screens? Take a look at diddy.


wiebow(Posted 2011) [#4]
Diddy? what's that?


GfK(Posted 2011) [#5]
Well, I don't think Diddy will help in this case.

The core of my game is an infinite loop. Pseudocode:
Repeat
  FrontEnd = new tFrontEnd
  result = FrontEnd.Play() 'has its own update/drawscreen functions
  If result = 0 'quit game
    End
  Else
    Game = new tGame
    result = Game.Play() 'has its own update/drawscreen functions
    If result = level_won
      winScreen = new tWinScreen
      winScreen.Play() 'has its own update/drawscreen functions
    EndIf
  EndIf
Forever


As you can see, this loop first calls the frontend, and the result from that determines whether we quit, or play a game. If the player wins, we show the winScreen. After that we go back to the frontend.

This does not seem possible in Monkey. With a loop like this, OnRender will never ever be called since I can find no manual way of rendering the screen other than OnRender(). And it seems I can only have one of those anywhere in my program.

Its a puzzler.


Warpy(Posted 2011) [#6]
what's to stop tFrontEnd, tGame and tWinScreen extending a base type called something like tScreen, and then the app has a pointer to the current screen object?

Then OnUpdate would call currentScreen.Play, and OnRender would call currentScreen.Draw.

That's probably what diddy does, though I haven't looked.


GfK(Posted 2011) [#7]
Sounds crazy enough to work... think I might take a break cos my head hurts.


Tibit(Posted 2011) [#8]
I use a statemachine, I think that is how diddy does it too. You add a state per "loop" and then you switch beteen them, since each state has an ENTER method, you simply put you logic there instead of your Play() methods.

That how I would do it anyway, good luck! :)


dawlane(Posted 2011) [#9]
I concur with Tibit. Using a statemachine is a lot simpler and easier. It's best to think of

Class myApp extends App

Method OnCreate()
End Method

Method OnUpdate()
End Method

Method OnRender()
End Method

End Class

As a ready made game loop and use the Select/Case structure.

If you dig around therevills did an Asteroids game and kindly made the source public. It should give you some ideas.

http://www.monkeycoder.co.nz/Community/posts.php?topic=373&app_id=45


GfK(Posted 2011) [#10]
Not sure what a statemachine even is (I'm really crap with techie jargon).

I have a global var which is set to SEGMENT_FRONTEND, SEGMENT_INTRO or whatever, depending on where the player is - I did that right from the start, for some reason. I'm using this in my OnUpdate loop to call the updateLogic function for whichever bit of the game the player is in. Progress is a little slow because all of this is new to me but I can write my next game with this in mind.

Not even sure if I got it right but I'm hopeful - it makes sense in my head! It'll be quite a while before my game is runnable on mobile devices. My plan is to get it running (however badly), then go through and fix everything up.


therevills(Posted 2011) [#11]
It all depends on how you want to design your game, IMHO I think state based are pretty annoying as you always have to keep adding to your main loop if you add more states, with lots of IF statements (or CASE). The screen based approach that is in Diddy is so much more easier, the main loop with repeat the current screen until you tell it to move to another screen:

Global titleScreen:GameScreen
Global gameScreen:GameScreen
Global levelScreen:LevelScreen

Class GameScreen Extends Screen
  Method Update:Void()
  Method Render:Void()
End

Blah Blah Blah ;)