4
\$\begingroup\$

Overview

My game is currently based on a single activity (rather than multiple activities) and I would like to keep it that way.

At the moment, it goes straight into the game at level 1. I will shortly be adding an options menu and another 20 or so levels. (As well as a high-score screen, help screen etc).

The thing I'm not sure about is, how do I tell the app/renderer what screen/part of the game to render?

It's an openGL ES 2.0 app so at the moment, the method I have in my mind is something like this:

Code Snippets

int level = 0;  //0 means menu, 1 means level 1 etc

in onDrawFrame(); have something like this:

@Override
public void onDrawFrame(GL10 gl) {

switch (level){

case 0:renderMenu();break;
case 1:renderLevel1();break
case 2............

And so on.

I would also do the same with the logic updating.

Is this the way to go? I'm just not sure it's very efficient but I can't really see what the alternatives are - another way I was looking into was having a separate GLRenderer for each 'screen / level' but this seems much more over-kill.

Would appreciate some guidance as to how to display the correct screen / level at the right time.

Edit This is the current structure of my code:

Activity class

public class MainActivity extends Activity {

//Various pieces of code here

    class MyGLSurfaceView extends GLSurfaceView {

    //Various pieces of code here

    @Override
    public boolean onTouchEvent(MotionEvent event) {

    //Touch events handles here

}

GL Renderer class

onDrawFrame(){

    render();
    update();
}
\$\endgroup\$
5
  • 1
    \$\begingroup\$ Can you explain your reasoning for keeping everything in one activity? It's good to know why you're placing these restrictions on yourself when people are answering. \$\endgroup\$
    – House
    Jun 20, 2013 at 15:40
  • \$\begingroup\$ Hey @Byte56, sure, if was just a decision I made and was advised of at the very beginning, I decided with the help of various texts and people that it was the way to go. I don't like the idea of have 35+ activities (ie, one for each level etc). Woudn't that mean 35+ GL renderers? It just seems unworkable and clumsy. \$\endgroup\$ Jun 20, 2013 at 16:27
  • 1
    \$\begingroup\$ Have you considered using some game engine like libgdx or andengine, so you can focus on the game classes? \$\endgroup\$
    – petervaz
    Jun 20, 2013 at 18:04
  • \$\begingroup\$ @petervaz, thanks for the comment, this is both writing an app and learning more about the Android API's so using an engine isn't really what I'm after. I looked at both AE and LGDX but decided to write my own library. There are people who say use multiple activities and those who say use just one. I just chose the latter. Any solution you could give would be much appreciated. :-) \$\endgroup\$ Jun 21, 2013 at 1:43
  • \$\begingroup\$ You can also combine the two approaches. Put splash screen, menu, credits and settings into one activity and game, level selection to another. It's completely upto you. Both has pros and cons. \$\endgroup\$ Jun 23, 2013 at 3:22

1 Answer 1

5
\$\begingroup\$

You are asking for a concept of scenes inside one activity. This is as easy as creating an abstract scene or an interface that will have methods like renderMe() and onUpdate(long timeElapsed). Then in your engine or game-loop you simply render the current scene. How do you switch between scenes is upto you. You can have a governing class SceneManager. So how is this gonna work?

Scene concept:

interface Scene {
  void renderMe(); // do the graphics rendering
  onUpdate(long timeElapsed); // update positions etc
  onTouch(MotionEvent e); // handle user input
}

class MyScene implements Scene {
  // implement rendering and update methods, you can pass in the activity and GLSurfaceView (in constructor or some injection)
}

Your game loop should look like this:

void loop() {
  while(running) {
    long timeStampBegin = getCurrentTime();
    SceneManager.getInstance().getCurrentScene().renderMe();
    SceneManager.getInstance().getCurrentScene().onUpdate(getCurrentTime() - timeStampBegin);
  }
}

And then when you switch your scenes by calling SceneManager.setCurrentScene(), your loop will just start rendering something else. SceneManager can be a singleton class or simply a class with static reference to the scene.

SceneManager concept (singleton):

class SceneManager {

  private static SceneManager INSTANCE = new SceneManager();

  private Scene currentScene;

  public static SceneManager getInstance() {
    return INSTANCE;
  }

  public Scene getCurrentScene() {
    return currentScene;
  }

  public void setCurrentScene(Scene scene) {
    currentScene = scene;
  }
}

You also have to implement the onTouchEvent in GLSurfaceView and pass the event to your scene to be able to handle touch events. This happens in separate thread, so it is not part of your loop.

This should be enough to create skeleton one-activity-multiple-scene model.

\$\endgroup\$
6
  • \$\begingroup\$ Hey @sm4, thanks where are SceneManager and getCurrentScene defined? I can't see them - thanks! \$\endgroup\$ Jun 21, 2013 at 23:43
  • \$\begingroup\$ @user22241 I did not define them. I will add it to the answer, but it is really simple :) \$\endgroup\$ Jun 22, 2013 at 3:07
  • \$\begingroup\$ Hey @sm4, this is great! Thanks, I've implemented and it seems to be working. I've also gone over it and understand how it works too :-) Just one last thing if you wouldn't mind and I will mark the answer. You mentioned making SceneManager a Singleton. How would that work? And lastly (:-)) the only line I don't really understand is private SceneManager INSTANCE = new SceneManager(); when exactly does this get called? Does it create a new instance every time I make a call to the SceneManager class? Guess not, that wouldn't make sense. Just like to understand how it works - thank you @sm4!! \$\endgroup\$ Jun 23, 2013 at 2:04
  • \$\begingroup\$ @user22241 Singleton is a pattern, in Java it is implemented similar to my SceneManager example. Optionally you want to implement a private constructor, so nobody else can call it, and override clone() method, so nobody can copy it. The new SceneManager() is called when the class is loaded by Java before your program is executed. Note that I was missing the static keyword there, fixed. \$\endgroup\$ Jun 23, 2013 at 2:52
  • 1
    \$\begingroup\$ @user22241 Judging from your comments, you should spend some time to understand more about Java. If you want to continue developing under Android, it can't hurt. \$\endgroup\$ Jun 23, 2013 at 3:23

You must log in to answer this question.

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