9
\$\begingroup\$

I am having trouble wrapping my head around game design. On the android platform, I have an activity and set its content view with a custom surface view. The custom surface view acts as my panel and I create instances of all classes and do all the drawing and calculation in there.

Question: Should I instead create the instances of other classes in my activity?

Now I create a custom thread class that handles the game loop.

Question: How do I use this one class in all my activities? Or do I have to create a separate instance of the extended thread class each time?

In my previous game, I had multiple levels that had to create an instance of the thread class and in the thread class I had to set constructor methods for each separate level and in the loop use a switch statement to check which level it needs to render and update. Sorry if that sounds confusing.

I just want to know if the method I am using is inefficient (which it probably is) and how to go about designing it the correct way. I have read many tutorials out there and I am still having lots of trouble with this particular topic. Maybe a link to a some tutorials that explain this? Thanks.

\$\endgroup\$
0

3 Answers 3

13
\$\begingroup\$

I highly recommend that you have a render thread (using Canvas/OpenGL ES, Canvas is probably a little bit easier to setup) and a game thread where you put your game logic.

To actually "load" the game you can create a GameEngine class and make that the central point of your application. When your renderer is ready to go you can create a callback to the GameEngine instance which will create and start two threads using a Runnable for the rendering and another Runnable for the game logic.

Sample code:

Application start

private GameEngine engine;
private CanvasRenderer renderer;

@Override
protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   // Create instances of your two Runnable classes and pass that into
   // the GameEngine constructor.
   // Create an instance of the game engine.
   engine = new GameEngine(canvasRunnable, gamelogicRunnable);
   renderer = new CanvasRenderer(this, engine); 
   setContentView(renderer); 
}

CanvasRenderer

private GameEngine engine;    

// Save your instance from the GameEngine reference in your constrcutor and make
// a global initializion for your GameEngine instance.  

@Override
public void surfaceCreated(SurfaceHolder holder) {  
   // One time setup here.
   // When your view is ready, make this callback to the 
   // GameEngine.
   engine.surfaceIsReady();
}

GameEngine

private Thread canvasThread;
private CanvasRunnable canvasRunnable;
// You should be able to figure out how to create a second thread
// where you should put your game logic. :)

// Constructor stuff like creating instances of your threads
// and passing references as you wish to those.
// Don't start the threads here.
// Remember to set references from your Runnable's into your Thread's 
// instances here!

/**
 * Callback. Now your renderer is ready and you
 * can start your threads.
 */
public void surfaceIsReady() {
   thread.setName("Canvas");
   thread.start();
   // Same for game logic.
}
\$\endgroup\$
5
  • \$\begingroup\$ Wow, thank you. I liked how you explained it. That one explanation enlightens the whole concept to me. \$\endgroup\$
    – semajhan
    Commented Jan 14, 2011 at 23:17
  • \$\begingroup\$ @semajhan: Just ask if you have more problems. :) \$\endgroup\$
    – Viktor Lannér
    Commented Jan 14, 2011 at 23:18
  • \$\begingroup\$ This is what I have in my head: GameEngine class that acts as a "link" or "reference" to all other classes with the panel. Activity > Panel > GameEngine > all other classes. \$\endgroup\$
    – semajhan
    Commented Jan 14, 2011 at 23:27
  • \$\begingroup\$ @semajhan: Exactly. For your knowledge only: if you decide to go with OpenGL ES you should know that the renderer in OpenGL ES already have its own thread and in that case you don't need to manually create and start a new Thread and Runnable for that system. \$\endgroup\$
    – Viktor Lannér
    Commented Jan 14, 2011 at 23:30
  • \$\begingroup\$ Ignore this comment. \$\endgroup\$
    – semajhan
    Commented Jan 14, 2011 at 23:50
3
\$\begingroup\$

Typically, your game-loop is self-contained inside a single Activity.

when you switch Activity, you pause / kill your game-loop. Separate activities should correspond to pausing the game anyway (e.g. because you've switched to a "send email to friends" or "main menu" activity)

For extra levels, you shouldn't be creating or destorying any new threads ... unless you switched to a "level-complete, loading next level, please wait" Activity, and you're going to have to restart the "main game" Activity anyway. But even in that case, you're not really making "extra" threads, you're just making one thread in that one Activity, and sequentially killing / restarting / killing / restarting ... etc that Activity. each time a level is completed.

\$\endgroup\$
3
\$\begingroup\$

If you understand german, this tutorial is very nice.

For english language I can recommend this tutorial

Concerning the thread class: I don't know if it is really necessary that you can reference from all the classes in your application. In my game, I solved it that way:

The class that is responsible to draw the main GUI has an overriden render method. In this method a thread class is called which updates all the GUI elements and processes user inputs.

The thread is also responsible to maintain a constant framerate. Depending on the game you are developing this could be important.

\$\endgroup\$
1
  • \$\begingroup\$ That german tutorial is nice but it was roughly translated vai google so it's kind of hard to understand. \$\endgroup\$
    – semajhan
    Commented Jan 14, 2011 at 23:28

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .