2
\$\begingroup\$

When using a gameloop like (much simplified)............

updateLogic();
render();

How does one perform 'single' operations? I mean, things like triggering sounds (which will only be played once), displaying a 'Get ready' graphic at the start of the game etc...

Currently I'm simply using 'flags' so maybe something like: (Pseudo code)

if(gameNotStarted==true)
display getReady;

This does work, but I end of up with a ton of condition checks in my game Loop.

Being that I can't just stop the game loop (I can't right?) every time I want to perform a single operation, is what I'm doing the correct way or is there something that I'm missing?

Another example might be when a player completes a level. I want to stay within my class/activity (I.E., the game as a whole is contained within one activity), then I move onto a small 'cut scene' which simply displays 'Well done' and plays a little piece of music, before returning to the next level of the game.

How would one handle that situation, again remembering that I'm not starting a new activity for each level (if I did, I could see that being a nightmare to manage).

\$\endgroup\$
7
  • 2
    \$\begingroup\$ Google "state machines" and consider how you might implement one using activities in Android. \$\endgroup\$
    – House
    May 6, 2013 at 13:28
  • \$\begingroup\$ If you downvote it would be helpful to leave a comment, as I see nothing wrong with this question - SO has tags for 'architecture' i.e., 'Engine design related questions. How code is structured' which is precisely what this question relates to. I've been clear and have only posted this after extensive research, so I see absolutely nothing wrong with it. Would be interested to know why you've downvoted....... \$\endgroup\$ May 6, 2013 at 17:02
  • \$\begingroup\$ Sorry, I didn't down vote, just commented. \$\endgroup\$
    – House
    May 6, 2013 at 17:21
  • \$\begingroup\$ No, that comment wasn't directed at you @Byte56 don't worry mate! It was directed at whoever did the downvote. I know it wasn't you. It's just helpful to know when one gets down-voted so they know how to structure my questions better in the future!! Cheers for the comment by the way. \$\endgroup\$ May 6, 2013 at 17:29
  • \$\begingroup\$ I agree, down voting without commenting is useless. I'm betting the down vote was because it's a simple question, that's also somewhat broad. There are lots of ways to approach this problem, and hard to give a definitive answer. \$\endgroup\$
    – House
    May 6, 2013 at 17:54

2 Answers 2

2
\$\begingroup\$

One option is messaging and event handling. This basically works by setting up objects that "listen" for when the appropriate message is sent out and do something (like playing a noise or even handling game logic) when they receive it.

So essentially you would have a sound listener object that would be in charge of playing sounds. When the action happens you send out a message saying which sound you want to be played along with any other data relevant to that. Then the listener would find the appropriate sound and play it. The message would then be destroyed and you would move on to the next frame.

\$\endgroup\$
2
  • \$\begingroup\$ Hi @LucasC this is a very interesting idea, I'd be interested in learning more, could you please provide a practical example (code or pseudo code) as I'm not quite sure how I would implement something line this......thanks! \$\endgroup\$ May 6, 2013 at 16:59
  • \$\begingroup\$ There's an existing thread on the topic, as an explanation would be a little long for the comments section here is the link gamedev.stackexchange.com/questions/38746/… \$\endgroup\$
    – Lucas C.
    May 9, 2013 at 20:04
0
\$\begingroup\$

I have only done minor experiments with Android so this answer will be platform agnostic. Ignore it if you want an Android specific solution.

For specific case of the "Get ready" screen my laziest and favorite way is to load an image into the game window and outside the game main loop. Enter the resources loading code, the image will remain visible as nothing is refreshing the graphics. When resource loading finished and entering the main loop, the typical renderGraphics() call, or whatever you named it, at the end of the loop will get rid of the "Get ready" image during its first execution, as you probably are clearing all pixels to black before draw anything each frame.

For sounds, the audio api calls probably do not block while playing. OpenSL? Your game only needs to be fast enough when queuing buffers to avoid artifacts. Then you only need a class with a play method that let you specify the sound to play by resource name or file name. Something like:

SoundService.play(string name, bool loop, bool stream)

When stream is true, the file should be big and you want it to be read in chunks and not all at once, or another option is to let the method decide it by examining the file size, and not having a stream parameter at all.

Number of buffers are probably limited like in OpenAL, when streaming the code that checks if new buffers can be queued and read, and probably decodes to PCM, a new chunk of the file to a buffer, can be part of the main loop, something like SoundService.update() at the end of the main loop, or it can reside in a separate thread. Having a thread per audio resource playing is chaotic, better to have a single thread for all audio streaming.

For example, during collision detection and response you will do something like this:

If (player.health == 0) SoundService.play("boom", false, false)

You can have play calls everywhere but probably you will only need them during collision response, or, in some cases, during input handling.

For other things not audio related. The idea of messaging and event handling was already proposed by another answer. To give an alternative, you can translate the concept of the play method to code that should run like tasks, for example:

TaskQueue.add(Task task);

Task is a class, that have a run virtual method. Then during main loop you iterate through the task list and call it run method. You enqueue tasks following the same logic that sounds, I mean that you can do it everywhere in you code. Something like this:

If (victory condition reached) taskQueue.add(new ScenarioLoaderTask("level2"))

ScenarioLoaderTask is a class derived from Task that implements run.

Despite its name, tasks are not mean to spawn threads (while the AudioService may). Also they not must contains loops, because that may block the game for a long time. If you need a task to run in more than one game frame, then implement a way of tell the code calling the run method that you don't want it to be removed yet from the queue. Something like the run method returning a bool.

I called it tasks, but don't get confused to that another pattern that exists, that is not what I proposing here.

The disadvantage of this recommendation again a message system is that with messages, when you post a message you don't know how the game will react to it, you are only informing the game that something happened but how the game will react will depend of what objects are alive at that time listening to that particular message. So messages may be more versatile.

\$\endgroup\$

You must log in to answer this question.

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