AlessandroSilva.com

41 6c 65 73 73 61 6e 64 72 6f 53 69 6c 76 61 2e 63 6f 6d

Crazy Twirl Game (iOS) - Mechanics/C++/Architecture

User Rating: / 6
PoorBest 

Crazy Twirl - Mechanics/C++/Architecture

Recently the game I've working on for the last months was approved in App Store. Its name is Crazy Twirl Game.

Crazy Twirl Game is a game base on the device acceleration orientation to guide a projectile to gather yellow forms (in the first episode they are asterisks).

History and Context

I was developing some ideias to put in my C++ library (here) when I reach the accelerometer input processor component design.

When I've seen the data for the first time an image of the game mechanics come to my mind :) .

I though: "Why anybody uses the accelerometer to change the orientation of the virtual world?" .

Looking around I discovered that there are a lot of games that uses the accelerometer to control and rotate the player, to apply physics and do some view adjustments to keep the angle oriented up.

This is how I come up with the main ideia the game has: You control the scene orientation, but the player direction is fixed and it moves forward with a speed.

The development started last year, and it have taken almost a year to be done. I worked in weekends and pair time to make it.

Prototyping and Evolution

The first version of the prototype had the player move implemented and the basic collision.

The version was not very funny, but sufficient to test the player control that was in my mind.

After some mechanics review made by me and Alysson (brother) I've added some features that allowed to create the goal of the game:

  • Added a screen border that indicates when the player gets an item
  • Added customized behavior items
    • With them it is possible to create any kind of interaction.
    • When you get all yellow items then you complete the stage.
  • Creation of the "happy" game state that causes the world to turn into psychedelic
    • The music, colors, behaviors, and some scene objects behaviors changes.

Development

The code is written in C++, the sound uses OpenAL and the renderer uses OpenGL (Desktop and ES 1.1).

The earlier stage of the development was based on SFML library with my library to implement the vertex and matrix structures. As the SFML and my library are based on CMake, it allowed the code to be built on Windows, Linux and MacOS with a click :).

After get some code to work I applied for the apple iOS development program and started to port the desktop implementation to the mobile.

The Game Mechanics

You control the game with the device orientation, to get a better control, you can hold it like a steering wheel.

If you pay attention on the game, you may notice that the player is "always trying" to reach the device button and it is true even when you change the device orientation.

The player always starts from the origin (0,0,0) in the virtual world and its goal is to get all the yellow items that are in the virtual world.

There is some screen helpers (in Yellow) that indicates the items direction related to the current player position.

game screen

The first episode has the following Items:

  • Arrow Down: descreases the player speed to the initial speed
  • Arrow Up: increases the player speed
  • Asterisk: You need to get it to complete the stage
  • Bloquer Ball:
    • In normal mode: Kills the player
    • In happy mode: reppels the player as a pinball pin
  • Moving Blocker Ball:
    • Same as the blocker ball, but it moves in circle.
  • Triangle: Item that causes the gameplay to change to the Happy mode.

Defining the Game Architecture

As it is the first game I've done to mobile, I've tested a lot of architectures during the development.

The current version is a "best of the best" class and components organization I reached so far.

game class diagram

As well as any graphical application, the game has a window controller that receives the general input and is responsible to manage the resources related to it.

The OpenglESApp holds the Game instance too.

From that point the code must have the controller for the resources. The first version of the prototype had a lot of singletons, but I really don't like the way it was coded.

In this last version I tried something different: I put all the resources managers/controllers as dynamic classes (so you can release them - wich releases the resources too). And all this classes are members of the Game.

Each game component (state, item, behavior, etc...) has a reference to the Game, so they can access any resource manager or controller through the Game instance.

Following the same fashion, I organized the game global states (menu, in-game, etc...) in two controllers: The StateManager: holds the current active state; and The StateHolder: holds a reference to all available game states. During the execution, any state can operate over the StateManager to change the root state, push new states or pop them.

The in-game controller (StateStage) is a bit confusing looking to the diagram, but the implementation is simple. It uses a global game controller, a collision helper and it has the item group controller (a list of them). All the game Logic is computed in the GlobalGameController using callbacks.

The basis of Game configuration are a XML set. There are some Xml that describes the scene, the items, the player, the sounds, the GUI, etc...

And the main structure is the CrazyScene: the game stage container (holds information about the items and lines that is positioned in the scene).

I spent some time implementing this structure (insane programming hours in weekends). After the first release, I noticed that it became easy to change or update.

Rendering

The rendering was not so problematic, as well as I didn't have a lot of graphical items. Below is a list with the efforts I've done to render and optimize things:

  • Porting OpenGL Desktop to ES
    • ES has less primitive types than Desktop. So I converted all QUADS references to TRIANGLES.
    • ES must have buffers for anything. So I throw away all direct drawing code I had.
    • I couldn't do alpha to coverage to work. So the transparent things are all rendered with the default transparent blend state.
    • Pure AA lines in mobiles doesn't seems cool as the Desktop does. The first tests I've made, I was using the pure line drawing from the rendering API, when I ported to the device, the lines becomes ugly. To make them more pleasant, I've implemented a smooth line rendering based on a circle texture and a set of 6 triangles per line.

Today the code can render the same thing in either: Desktop platform and iOS platform.

I used Blender to model the entities, scenes and GUI. The first problem I've was to get the Line information from the blender scene.

First I tried to get the Assimp library to read a exported COLLADA. But the file the blender exports didn't have the information I need (points and lines).

Curiously the last Blender build can export the information I need.

To get it to work, I've written an importer based on Assimp project, and the geometry I export is a set of degenerated triangles. Inside the model processor there is a structure that is generated with a line reference based on this.

Complementary Stuff

The Delegation - C++ Method Pointers

Recently I have contact with the Gwen project and I've seen a way to implement an elegant method pointer with c++ templates.

The struct they used was not very easy to implement in another source, but after some changes I've come up with a way to declare and use a structure like the C# Delegation.

Example of use in the code:

// Definition of a Callback in the GlobalGameController class
class GlobalGameController{
public:
    // Declaration of the delegate type DelegateVoid that doesn't has any parameter
    BEGIN_DECLARE_DELEGATE(DelegateVoid ) () END_DECLARE_DELEGATE;

    // Defining the DelegateVoid variable
    DelegateVoid OnStarsGotten; // win -- end game

    // Call the methods registered in the OnStarsGotten with a Callback fashion
    void getStar(){
        if (mStarCount >= mStarCountMax)
            return;
        mStarCount++;
        if (mStarCount >= mStarCountMax)
            OnStarsGotten.call(); // The callback
	}
}

To use the "events" from the GlobalGameController definition, it is possible to assign any method pointer to the delegate as follow:

class StageState : public Object {
    
    GlobalGameController *mGlobalGameController;
    
    void callbackWhenTheStartAreGotten(){
    	// Here treat the event that comes from the GlobalGameController
    }
    
    // Callbacks setup: registering the class callback methods
    void registerCallbacks(){
        mGlobalGameController->OnStarsGotten.add(this,&GlobalGameController::callbackWhenTheStartAreGotten);
    }

    // Callbacks setup: unregistering the class callback methods
    void unregisterCallbacks(){
        mGlobalGameController->OnStarsGotten.remove(this,&GlobalGameController::callbackWhenTheStartAreGotten);
    }
}

This structure allows the implementation of plugable objects in c++ -- The game controler has the input methods and it calls the callbacks through the method pointer implementation.

I've used it extensively in the game to implement the common use components.

Music

I hope people notice that all music inside the game are original.

I spent a lot of time playing, recording and mixing the loops the game has.

Below are some screen shots of the Garage Band projects during the recordings.

game screen

game screen

game screen

I really enjoy when I was coming up with the musics. I recorded a lot of other loops I'll publish with the game next releases.

Development Roadmap - What we can expect from next release?

I hope everybody like the game. As well as I didn't get any support to build the game, I've published it with a symbolic price tier at App Store. For the next release we can expect the following upgrading in the game:

  • more stages
  • more items behaviors
  • more items shapes
  • more music loops
  • gameplay balancing
  • tutorials

Final

If any good soul would like to support a developer today, just tell your friends and colleagues about the game.

Game Link: Crazy Twirl Game

Probably my next blog's post will be related to the accelerometer data. Explaining how I implemented the signal filtering and rotation in the game.

Thanks.

Last Updated on Thursday, 21 June 2012 17:10