Tuesday, 8 January 2013

The anatomy of Tank Rampage


Game Tasks

The general game consists a few fixed parts. These parts are necessary to read input, process data, show graphics, play sounds etcetera. In order to develop a game in an efficient & organized fashion and to determine what these parts are, it’s important to look at what a game has to do.

A game has to:


·      Register user input;       -The player touches the screen at (253,142)

·      Process input;       -The aim of the tank is changed to -3°

·      Update game logic;        -A missile is fired
         
·      Update the screen;        -The barrel of the tank is rotated to -3°, the missile is created
     
·      Play sounds;                  -The sound “BarrelRotation.caf” is played

                  



Figure 1-1. Game tasks

‘Task Handlers’ (or Frameworks)

On the iPhone, the base layer of all apps is the Foundation Framework. The Foundation framework contains several primitive object classes and paradigms that help extend the functionality of Objective-C. For example, it contains the NSObject class (the root object class) and the NSString class.

The User Interface framework (UI Framework) handles, amongst many other things, touch events. That is, it gives us an easy way to register and retrieve information from the touches a user makes. Touches are represented by the UITouch class, which inherits from NSObject.

The framework we’ve been working with most of the time is called Cocos2d for iPhone. Cocos2d for iPhone is an Objective-C version of the Cocos2d framework, and supports iOS and OS X devices. It’s a framework for building 2-dimensional games, based on the OpenGL graphics platform. It uses an easy-to-use API. It functions as our graphics and sound engine, meaning it also handles the drawing of objects on the screen (rendering) and the playing of sounds. Finally, cocos2d has integrated physics support. For the physics engine, you can choose between the Chipmunk engine and Box2d. Tank Rampage uses the C++ written- physics engine Box2d. More on Cocos2d and Box2d in their respective chapters.

The processing of the user input and is where the magic happens: here the game logic comes in to play. The game logic is the code that defines a game. It tells the graphics engine to place the tank on a certain spot on the screen, and how much the player has to wait before the tank can shoot again. It responds to the input of the player and plays a sound when necessary; to put it short: it updates the gameworld.
The game logic uses a lot of classes from Cocos2d’s and Box2d’s API. Since writing the game logic is the most major part of developing a game, most of the code in this paper will be using Cocos2d.
Tank Rampage is designed with the help of the level-editor program Levelhelper. Levelhelper comes with its own API that acts as a wrapper of Cocos2d and Box2d, meaning that, for instance, an instance LHSprite contains both a CCSprite (a Cocos2d class) and a b2Body (a Box2d class). However, in practice, the code is very similar to a vanilla Cocos2d project. More on Levelhelper in a later chapter.


Figure 1-2. Code hierarchy

It is possible to write all the code needed to handle these tasks yourself. This gives a few advantages and possibilities; after all, you’re not limited by the capabilities of someone else’s engine. Cocos2d does not always support the latest features of a new OpenGL release, and a self-written engine can be more suitable for the project you’re working on, and may therefore have a better performance. Writing your own engine requires, however, extended knowledge of OpenGL and even more time. Since we had neither, nor did we need any features not offered by Cocos2d, we decided not to do this.

Game Loop

         In order for a game (or video) to run smoothly, the screen has to be updated about 30 times per second or more. If the framerate (FPS) drops any lower, motion will be perceived as jerky, and the game will be less responsive. Every update of the screen, not only the visual output has to be updated; the game logic has to be updated too, and any user input has to be processed.
         This means that every frame, the game has a similar work process. This is called the main loop. The main loop consists of three primary elements: checking for and handling incoming events (in other words: user input; e.g. a touch or input from the accelerometer), updating the game logic (processing the input, simulating the game worlds next frame), and rendering the screen.


Figure 1-3. Main loop sequence

         The main loop is a standard feature of an interactive program. The way these loops are implemented depends on the system used. A simple game loop might look as follows:

while( !finished ) { 
handle_events();
update();
render(); 
sleep(20);
}



The sleep function makes sure the loop doesn’t form a solid loop that constantly sucks up all of the CPU’s time.
         However, some systems (including the iPhone) don’t allow for users to make such loops; a callback system is used instead. The functions are called periodically each loop. Such a loop would look something like this:

void main(void) {
OS_register_event_handler( myEventHandler );         
OS_register_update_function( myUpdate ); 
OS_register_render_function( myRender );
}


      

In practice, we will mostly be focused on the update function, as rendering and event handling is done by Cocos2d and Foundation respectively.




For this chapter, one of the sources used was: 
Paul Zirkle & Joe Hogue Iphone Game Development, O’Reilly (2009) ISBN 978-0-596-15985-6

No comments:

Post a Comment