Marmalade SDK Tutorial – Actors, Scenes and Cameras Make the World Go Round

This tutorial is part of the Marmalade SDK tutorials collection. To see the tutorials index click here

In our previous tutorial we created an extensible animation system that allowed us to create discrete frame based image animation as well as other types of animations. This week we will continue on our quest to create an easy to use, extensible cross platform 2D game engine. In order to do this effectively we need to get organised and organised we will be. If you just want the code to this tutorial then download it from here.

Ok, so how do we organise things in a 2D engine? What sort of things do we want our 2D engine to do? Here’s a brief list:

  • We want sprites and animations obviously, these we already covered in previous tutorials
  • We want sprite creation / handling to be automated so that we do not have to worry about creating, updating and destroying sprites
  • We want to define specific types of game objects (players, bombs, aliens, pickups etc..) modelled on a single game object type
  • We want scenes that contain our game objects, managing their life times and updates
  • We want cameras that we can move around in our scene to view different parts of the scene.
  • We want our game objects to recognise when they collide with each other and react to each other

To manage all of the above we are going to create a Camera, Actor, Scene (CAS) system.

Cameras, Actors and Scenes

The camera, actor and scene system (CAS) constitutes the logical implementation of our game engine. The scene represents our finite gaming world, whilst actors represent our individual game objects that live within our gaming world. The scene manages all of our actors for us, taking care of updating them and deleting them when they are no longer needed. The camera represents a view into the gaming world that can be moved around, rotated and scaled to view different parts of the world.

CIwGameActor – Our game objects are really just actors on a stage

Ok, we will begin by taking a look at the CIwGameActor class:

class CIwGameActor { protected: // Properties CIwGameScene* Scene; // Scene that actor lives in bool Used; // Used is used when actors pooled to reduce memory fragmentation bool Managed; // Marks this actor as being managed by another object so we do not delete it unsigned int NameHash; // Name of Actor (stored as an hash for speed) int Type; // Type of Actor (use to distinguish beteeen different actor types) CIwFVec2 OriginalPosition; // Original position of actor in the scene (when actor was first spawned) CIwFVec2 Position; // Current position of actor in the scene CIwFVec2 Velocity; // Current velocity of actor CIwFVec2 VelocityDamping; // Dampens the velocity float OriginalAngle; // Original angle in scene (when first spawned) float Angle; // Orientation in scene (degrees) float AngularVelocity; // Angular velocity float AngularVelocityDamping; // Angular velocity damping float Scale; // Scale CIwColour Colour; // Colour bool IsActive; // Active state of actor bool IsVisible; // Visible state of actor bool IsCollidable; // Collidable state of actor CIwGameSprite* Visual; // Visual element that represents the actor CIwGameAnimManager* VisualAnimManager; // Visuals animation manager, used to control the actors visual componen animations int CollisionSize; // Size of collision area CIwRect CollisionRect; // Spherical collision size float PreviousAngle; // Previous updates angle CIwFVec2 PreviousPosition; // Previous updates position public: void setUsed(bool in_use) { Used = in_use; } bool isUsed() const { return Used; } void setManaged(bool managed) { Managed = managed; } bool isManaged() const { return Managed; } void setScene(CIwGameScene* scene) { Scene = scene; } CIwGameScene* getScene() { return Scene; } void setName(const char* name) { NameHash = IwHashString(name); } unsigned int getNameHash() { return NameHash; } void setType(int type) { Type = type; } int getType() const { return Type; } void setOriginalPosition(float x, float y) { OriginalPosition.x = x; OriginalPosition.y = y; } CIwFVec2 getOriginalPosition() { return OriginalPosition; } void setPosition(float x, float y) { Position.x = x; Position.y = y; } CIwFVec2 getPosition() { return Position; } void setOriginalAngle(float angle) { OriginalAngle = angle; } float getOriginalAngle() { return OriginalAngle; } void setAngle(float angle) { Angle = angle; } float getAngle() { return Angle; } void setVelocity(float x, float y) { Velocity.x = x; Velocity.y = y; } CIwFVec2 getVelocity() { return Velocity; } void setVelocityDamping(float x, float y) { VelocityDamping.x = x; VelocityDamping.y = y; } void setAngularVelocity(float velocity) { AngularVelocity = velocity; } float getAngularVelocity() const { return AngularVelocity; } void setAngularVelocityDamping(float damping) { AngularVelocityDamping = damping; } void setScale(float scale) { Scale = scale; } float getScale() const { return Scale; } void setColour(CIwColour& colour) { Colour = colour; } CIwColour getColour() const { return Colour; } void setActive(bool active) { IsActive = active; } bool isActive() const { return IsActive; } void setVisible(bool visible) { IsVisible = visible; } bool isVisible() const { return IsVisible; } void setCollidable(bool collidable) { IsCollidable = collidable; } bool isCollidable() const { return IsCollidable; } void getVisual(CIwGameSprite* visual) { Visual = visual; } CIwGameSprite* getVisual() { return Visual; } void setVisualAnimManager(CIwGameAnimManager* anim_manager) { VisualAnimManager = anim_manager; } CIwGameAnimManager* getVisualAnimManager() { return VisualAnimManager; } void setCollisionRect(CIwRect& rect); CIwRect getCollisionRect() const { return CollisionRect; } int getCollisionSize() const { return CollisionSize; } void setPreviousPosition(float x, float y) { PreviousPosition.x = x; PreviousPosition.y = y; } CIwFVec2 getPreviousPosition() const { return PreviousPosition; } void setPreviousAngle(float angle) { PreviousAngle = angle; } float getPreviousAngle() const { return PreviousAngle; } // Properties end CIwGameActor() : Used(false), Managed(false), Scene(NULL) { Reset(); } virtual ~CIwGameActor(); // Reset the actor (used by memory pooling systems to save actor re-allocation, usually called after re-allocation to reset the object to a default state) virtual void Reset(); // Update the actor (called by the scene every frame) virtual bool Update(float dt); // Update the visual that represents this actor on screen virtual bool UpdateVisual(); // Actors are responsible for carrying out there own collision checks. Called after all actor updates to check and resolve any collisions virtual void ResolveCollisions() = 0; // NotifyCollision is called by another actor when it collides with this actor virtual void NotifyCollision(CIwGameActor* other) = 0; // Call to see if this actor was tapped by the user virtual bool CheckIfTapped(); // Checks to see if another actor is colliding with this actor bool CheckCollision(CIwGameActor* other); };

Hmm, I agree, its a bit on the BIG side, but if you look carefully our CIwGameActor class provides a lot of functionality built in, which in the long run will save us lots of coding time. Again, you never create a direct instance of this class as it is abstract, you dervice your own different actor types from CIwGameActor.

We handle a lot of functionality with this base class including:

  • Position, orientation, scale, angular velocity, velocity damping and angular velocity damping – Physical attributes of our actor
  • Visibility state, active state, collide-able state – Used to hide, disable and mark as collide-able objects
  • Object type identifier, object name (used to search for specific types of objects or named objects). These are very useful as they allow you to create actors and forget about them, no need to store a pointer to them to reference them later, you simply ask the scene to find the object by name or type to access it again.
  • Visual, colour and animation manager – We will use these variables to give our object a visual representation in our world
  • Collision size and collision rectangle are used for collision detection

Note that eventually we will be replacing the physical components in this class with the Box2D physics engine.

I would like to point out a few important methods in this class:

  • Update() – When you implement your own actor types you override this method to provide the implementation of your game object specific behaviour. For example, if you create a player actor then you may check and move the player, maybe fire of different animations / sound effects. The default implementation of Update() will update the basic physics for the actor, any attached playing animations as well as add the actor to the collision check list if it is collision enabled. You should call CIwGameActor::Update() in your own Update() implementation, if you want to keep this functionality.
  • UpdateVisual() – You do not generally need to override and provide your own implementation of this method as this method will automatically update the actors associated visual for you.
  • ResolveCollisions() – When the scene has finished calling all of its actor updates it will then call ResolveCollisions() on each of the actors. You provide the implementation of this method to check for collisions with other actors. We implement collision checking this way as it allows us to optimise which collision checks to make. For example, lets say we are creating the old game Asteroids. The scene consists of 10 asteroids, 10 bullets and our ship. Our ship actor only needs to check for collisions with the asteroids and not the bullets or the ship.
  • NotifyCollision() – When an actor collides with another actor we need some mechanism for letting the other actor know that we have collided with them. When an actor collides with this actor it will call its NotifyCollision() method to let it know, this gives the actor a chance to respond to the collision event
  • CheckIfTapped() – Whilst this method is not currently implemented it will eventually allow us to check and see if the actor was tapped by the user. This is good for allowing the user to interact with our actors
  • CheckCollision() – Helper method for checking if two actors bounding circles overlap

One important note about Actors is there coordinate system. As far as our scene is concerned, the worlds centre is the the middle of the scene (0, 0), which corresponds to the centre of the screen for a scene that has not been moved.

CIwGameActorImage – An image based actor helper class

I suspect that many of you will want to simply get up and running quickly with your game and not have to worry about deriving your own actor class. With that in mind I created an image based actor that allows you to quickly set up a basic image based actor, complete with a sprite atlas, a base animation and a size. Lets take a quick look at the code in that class as I thin it will prove helpful when it comes to you designing your own actors:

bool CIwGameActorImage::Init(CIwGameScene* scene, CIw2DImage* image, CIwGameAnimImage* anim, int width, int height) { // Reset the actor CIwGameActor::Reset(); // Set the scene Scene = scene; // Create sprite if (image != NULL) { CIwGameBitmapSprite* sprite = new CIwGameBitmapSprite(); if (sprite == NULL) return false; // Set sprite image sprite->setImage(image); sprite->setDestSize(width, height); // Set sprite as visual Visual = sprite; // Add sprite to the sprite manager so it can be managed and drawn Scene->getSpriteManager()->addSprite(sprite); } // Create an animation manager and add the animation to it if (anim != NULL) { VisualAnimManager = new CIwGameAnimManager(); VisualAnimManager->setUpdateAll(false); if (VisualAnimManager == NULL) return false; VisualAnimManager->addAnimation(anim); // Set the first animation in the animation manager as the current animation VisualAnimManager->setCurrentAnimation(0); } return true; }

Our Init() method is pretty simple, it resets the actors internal data to default, creates a bitmapped sprite visual from the image and actor size then creates an animation manager and adds our default animation to it.

bool CIwGameActorImage::UpdateVisual() { if (CIwGameActor::UpdateVisual()) { // Update the sprite if (VisualAnimManager != NULL) { // Get the animations current image frame data and copy it to the bitmapped sprite CIwGameAnimImage* anim = (CIwGameAnimImage*)VisualAnimManager->getAnimation(0); if (Visual != NULL) ((CIwGameBitmapSprite*)Visual)->setSrcRect(anim->getCurrentFrameData()); } return true; } return false; }

Our UpdateVisual() method simply moves the image animation frame data to our sprite to update its image.

Unfortunately you will still need to derive your own actor from CIwGameActorImage() in order to create an actor object

CIwGameScene – A place for actors to play

The scene is the place where we put actors. When you add an actor to a scene the scene will take care of calling game logic update and visual update methods and building a list of potential colliding actors, as well as cleaning up the actors when the game is finished.
The scene also takes care of updating the camera and fitting our game across different sized screens with different aspect ratios. Look as the scene as the driving force that manages much of our game processes for us, so we can get on with coding up cool actors and other game logic.Lets take a quick look at the CIwGameScene class:

class CIwGameScene { public: // Public access to actor iteration typedef CIwList::iterator _Iterator; _Iterator begin() { return Actors.begin(); } _Iterator end() { return Actors.end(); } // Properties protected: CIwGameSpriteManager* SpriteManager; // Manages sprites for the whole scene CIwGameAnimFrameManager* AnimFrameManager; // Manages the allocation and clean up of animation frames unsigned int NameHash; // Hashed name of this scene CIwVec2 ScreenSize; // Native screen size CIwVec2 VirtualSize; // The virtual size is not the actual size of the scene. but a static pretend size that we can use to render to without having to cater for different sized displays CIwMat2D VirtualTransform; // Virtual transform is used to scale, translate and rotate scene to fit different display sizes and orientations CIwMat2D Transform; // Scene transform CIwList Actors; // Collection of scene actors CIwRect Extents; // Extents of scenes world CIwGameCamera* Camera; // Current camera CIwGameActor** Collidables; // List of collidable objects built this frame int MaxCollidables; // Maximum allowed collidables int NextFreeCollidable; // Points to next free slot in sollidables list pool public: CIwGameSpriteManager* getSpriteManager() { return SpriteManager; } // Manages sprites for the whole scene CIwGameAnimFrameManager* getAnimFrameManager() { return AnimFrameManager; } // Manages the creation and clean up of animation frames void setName(const char* name) { NameHash = IwHashString(name); } unsigned int getNameHash() { return NameHash; } CIwVec2 getScreenSize() const { return ScreenSize; } CIwVec2 getVirtualSize() const { return VirtualSize; } void setVirtualTransform(int required_width, int required_height, float angle, bool fix_aspect = false, bool lock_width = false); CIwMat2D& getVirtualTransform() { return VirtualTransform; } CIwMat2D& getTransform() { return Transform; } void addActor(CIwGameActor *actor); void removeActor(CIwGameActor* actor); void removeActor(unsigned int name_hash); CIwGameActor* findActor(unsigned int name_hash); CIwGameActor* findActor(int type); void clearActors(); void setExtents(int x, int y, int w, int h) { Extents.x = x; Extents.y = y; Extents.w = w; Extents.h = h; } CIwRect getExtents() const { return Extents; } void setCamera(CIwGameCamera* camera) { Camera = camera; } CIwGameCamera* getCamera() { return Camera; } bool addCollideable(CIwGameActor* actor); CIwGameActor** getCollidables() { return Collidables; } int getTotalCollidables() const { return NextFreeCollidable; } // Properties end private: public: CIwGameScene() : Collidables(NULL), SpriteManager(NULL), AnimFrameManager(NULL), NextFreeCollidable(0), Camera(NULL), MaxCollidables(0) {} virtual ~CIwGameScene(); // After creating the scene, call Init() to initialise it, passing the maximum number of actors that you expect can collide virtual int Init(int max_collidables = 128); // Update() will update the scene and all of its contained actors virtual void Update(float dt); // Draw() will draw all of the scenes actors virtual void Draw(); // Event handlers };

Yep, I know, its another biggy, but again it supports lots of cool functionality such as:

  • Handles all of our actors
  • Handles our camera
  • Fits our game to any sized screen / any aspect ratio using a virtual size display
  • Tracks potential colliders
  • Manages sprites and animation frames

You will be happy to know that you do not need to derive you own scene from CIwGameScene() and you will generally instantiate and work with a version of this class directly. Our scene class does not however need a little setting up initially. Heres asome basic code on how to set up a scene:

CIwGameScene* game_scene = new CIwGameScene(); game_scene->Init(); game_scene->setVirtualTransform(VIRTUAL_SCREEN_WIDTH, VIRTUAL_SCREEN_HEIGHT, 0, true, false);

I think at this point I need to explain something about the virtual screen system that I use to ease the pain of cross platform development

Using a Virtual Screen Size to Target Any Sized Screen

There are quite a few different solutions knocking around that solve the problem of targeting our game at a variety of different screen resolutions, including:

  • Scale to fit – This is a very simple scaling of the scene to match the display resolution. This is quick and simple but your game can appear stretched or squashed on displays that have a different aspect ratio to your game aspect ratio
  • Bordered – Another simple system that displays your game at its native resolution but with a border around it to fill the space that your game doesn’t cover. I don’t like this method as you are giving up too much screen real-estate
  • Unlimited screen size – This method is quite complex and involves rendering enough stuff on screen at a 1:1 pixel resolution to cover the entire screen. This disadvantage (and advantage, depends how much time you have on your hands) of using this method is that you would need to display a much larger area of the gaming world on a higher resolution display than on a lower resolution display.
  • Virtual screen – This method uses a pretend screen size that best fits many resolutions (800 x 512 / 512 x 800 is a good choice). Your game renders everything as though it is rendering to the virtual size and not the actual phones / tablets native screen size. You later scale and translate the virtual canvas to fit onto the native phones screen resolution.

We could use any of these methods in our game, but I am going to use a virtual canvas because it is the most convenient. Our CIwGameScene class has a method called setVirtualTransform() which will set this up for us, so that all of our actors will render to the virtual screen size. Heres how to use the method:

void CIwGameScene::setVirtualTransform(int required_width, int required_height, float angle, bool fix_aspect, bool lock_width)

  • required_width, required_height – This is the width and height we would like to use for our virtual screen
  • fix_aspect – Tells the scene to fix the aspect ratio of the scene to match the native screen aspect ratio
  • lock_width – Tells the scene to fix eth aspect ratio based on the width of the display instead of the height

CIwGameCamera – Our View Into the Gaming World

Many games can get away with simply one visible screen of information (such as Asteroids, Space Invaders, Pac-man etc..), but other types of games such as platformers, sports games, strategy games etc.. require the ability to move around the gaming world in some fashion. This is usually accomplished by using a camera that can move our point of view within the world. CIwGameScene supports the attachment of a camera to allow us to move our view around a larger virtual world. Lets take a quick look at the CIwGameCamera class:

class CIwGameCamera { public: // Properties protected: unsigned int NameHash; // Hashed name of this camera CIwMat2D Transform; // The combined camera transform CIwFVec2 Position; // Position of view within scene float Scale; // Cameras scale float Angle; // Cameras angle bool TransformDirty; // Marks camera transform needs rebuilding public: void setName(const char* name) { NameHash = IwHashString(name); } unsigned int getNameHash() { return NameHash; } CIwMat2D& getTransform() { return Transform; } void setPosition(float x, float y) { Position.x = x; Position.y = y; TransformDirty = true; } CIwFVec2 getPosition() const { return Position; } void setScale(float scale) { Scale = scale; TransformDirty = true; } float getScale() const { return Scale; } void setAngle(float angle) { Angle = angle; TransformDirty = true; } float getAngle() const { return Angle; } void forceTransformDirty() { TransformDirty = true; } bool isTransformDirty() const { return TransformDirty; } // Properties end private: public: CIwGameCamera() : Position(0, 0), Scale(1.0f), Angle(0), TransformDirty(true) {} virtual ~CIwGameCamera() {} // Updates the camera virtual void Update(); // Event handlers };

Ah much better, nice and short. As you can see the camera class is quite simple, supporting position, rotation and scaling of the view. To use a camera we simply create one and attach it to the Scene, the scene will then follow the camera around. To see different areas of the game world we simply move the camera around and all of our actors will move along with it.

Cool, I’m now done with explaining the new classes. I’ve been battling with trying to keep this article short and to the point, but alas I don’t think its quite happening for me.

What’s changed in IwGame Code

Marmalade SDK - Actor, Scene Camera Example
Marmalade SDK - Actor, Scene Camera Example


I will be honest, A LOT has changed since the previous article and I will try my best to walk through most of it; this is the main problem with an engine that’s  in-development.

Firstly I have had to make quite a few changes to our previous classes including:

  • CIwGameAnim – CIwGameAnimFrameManager now handles the life time of animation frames and not the separate animation classes themselves
  • CIwGameAnimFrameManager – Added the ability to retrieve allocated animation frames
  • CIwGameAnimManager – setCurrentAnimation() never actually set the current animation (oops, fixed)
  • CIwGameBitmapSprite – Source rectangle can now be set from a CIwGameAnimImageFrame (helper method just saves some typing)
  • CInput – This class has been renamed to CIwGameInput to fit in with the frameworks naming conventions. CIwGameInput is now a singleton and not declared as a global variable (I’m not generally a fan of global variables and prefer to use singletons for systems that there will only ever be one instance of). If you do not know what a singleton is then think of it as a global instance of a class.

Now onto the changes to Main.cpp. Note that I won’t be going into minor details such as “Oh I included these header files”.

We now accesss input using a singleton, here we have to create the IwGameInput singleton and then initialise it:

// Initialise the input system CIwGameInput::Create(); IW_GAME_INPUT->Init();

Note that IW_GAME_INPUT is just a macro that calls CIwGameInput::getInstance() (I find it more readable to use the macro)

Next, we create and initialise a scene then create a camera and attach that to the scene

// Create a scene CIwGameScene* game_scene = new CIwGameScene(); game_scene->Init(); game_scene->setVirtualTransform(VIRTUAL_SCREEN_WIDTH, VIRTUAL_SCREEN_HEIGHT, 0, true, false); // Create a camera and attach it to the scene CIwGameCamera* game_camera = new CIwGameCamera(); game_scene->setCamera(game_camera);

Next, we allocate a bunch of image animation frames for our manic face animation. Take note that we now allocate them through the game scenes animation manager. This ensures that the game scene later cleans them up for us.

// Allocate animation frames for our player CIwGameAnimImageFrame* anim_frames = game_scene->getAnimFrameManager()->allocImageFrames(8, 36, 40, 0, 0, 512, 40, 512);

Within our main loop we check for the player tapping the screen and if they do we explode 10 sprites into the scene at the tapped position:

if (IW_GAME_INPUT->getTouchCount() > 0) { if (!PrevTouched) { // Get tapped position in our virtual screen space CIwFVec2 pos = game_scene->ScreenToVirtual(IW_GAME_INPUT->getTouch(0)->x, IW_GAME_INPUT->getTouch(0)->y); // Create 10 player actors for (int t = 0; t < 10; t++) { // Create and set up our face animation CIwGameAnimImage* face_anim = new CIwGameAnimImage(); face_anim->setFrameData(anim_frames, 8); face_anim->setLooped(-1); face_anim->setPlaybackSpeed(0.2f); face_anim->Start(); // Create player actor ActorPlayer* player = new ActorPlayer(); player->Init(game_scene, sprites_image, face_anim, 36, 40); player->setName("Player"); player->setPosition(pos.x, pos.y); // Add player actor to the scene game_scene->addActor(player); } } PrevTouched = true; } else PrevTouched = false;

Note that because we are now dealing with a virtual screen resolution and not the actual native screen resolution, our tap coordinates need converting to virtual screen coordinates. We achieve that using the ScreenToVirtual() method of the CIwGameScene class.

Also note that we still have to create our face_anim animation, but this time we pass it to the ActorPlayer Init() method, so that the actor / scene can take of its management.

Next we update and draw the scene:

// Update the scene game_scene->Update(1.0f); // Draw the scene game_scene->Draw();

Lastly we clean-up the camera, scene and input system:

// Safely clean up the camera if (game_camera != NULL) delete game_camera; // Safely cleanup game scene if (game_scene != NULL) delete game_scene; // Shut down the input system IW_GAME_INPUT->Release(); CIwGameInput::Destroy();

ActorPlayer our First Derived Actor

ActorPlayer is our very first user defined CIwGameActor based actor and because we derived it from CIwGameActorImage (and in turn CIwGameActor) we get all of the useful functionality defined in those classes.

The only parts of our ActorPlayer that’s worth drawing out are the Init() and Update() methods:

bool ActorPlayer::Init(CIwGameScene* scene, CIw2DImage* image, CIwGameAnimImage* anim, int width, int height) { CIwGameActorImage::Init(scene, image, anim, width, height); FadeTimer.setDuration(1000); Velocity.x = IwRandMinMax(-100, 100) / 20.0f; Velocity.y = IwRandMinMax(-100, 100) / 20.0f; AngularVelocity = IwRandMinMax(-100, 100) / 20.0f; return true; }

Our Init() method calls the base CIwGameActorImage::Init() method to initialise the base CIwGameActorImage part of the actor. We then set up a fade timer and random velocities for position and spin.

bool ActorPlayer::Update(float dt) { // If fade timer has timed out then delete this actor if (FadeTimer.HasTimedOut()) { return false; // Returning false tells the scene that we need to be removed from the scene } // Calculate our opacity from time left on fade timer int opacity = FadeTimer.GetTimeLeft() / 2; if (opacity > 255) opacity = 255; Colour.a = opacity; return CIwGameActorImage::Update(dt); }

Our Update() method is called every game loop by the scene system, so keep in mind that this code will be called every single game frame. Firstly we check to see if the fade timer has timed out and if it has then we return false to the the scene system (this causes the actor to be removed from the scene / game) after the scene has finished updating all actors.

We then calculate the opacity of our actor from the time left on the fade timer which causes the actor to fade out of existence.

And that’s about it for this article, hope that most of your managed to stay awake, long drawn out technical stuff can send the best of us to sleep, especially if read on a few hours sleep, which is usually the case for us programmer types. The source code that accompanies this article can be downloaded from here

I’m quite happy with this blog as it marks the start of a real usable cross platform game engine that we can now build upon. In our next tutorial we are going to cover upgrading the engine to include some very basic collision detection and response whilst building a small game using the engine to show working collision. We will also cover handling frame rate variations and putting some audio in there. Hopefully I will get the time to do that this weekend.

That’s it for now and don’t forget HTML 5 is evil! (Just kidding, I got a book on it the other day and it looks quite good, think that I may use it to spruce up my blog)

Marmalade SDK News – Marmalade SDK 5.1.9 now available for download

A new minor update of the Marmalade SDK has been released. Here are the changes:

  • IwGx: Added [GX] DisableFBOSurface icf option to allow disabling this functionality on devices which do not or poorly support FBO surfaces.
  • Android: Fix s3eKeyboardSetInt(S3E_KEYBOARD_GET_CHAR) having incorrect behaviour after user closes soft-keyboard with back key.
  • Android: Fix for s3eWebView extension crashing in certain circumstances.

Jusr a few fixes really. The most exiting thing about this release is the version number 5.1.9, that’s the version prior to the big 5.2 update that many of us Marmaladians are eagerly awaiting 🙂

Beginning of the end for Nintendo?

Just read here that Nintendo are to reveal a pre-tax loss of ¥100 billion (£821 million), which is a lot of money even for Nintendo. With the recent flop of 3DS and developers turning away from Nintendo DS / Wii because of high production costs, bad sales and the terrible WiiWare and DSiWare platforms, is there much future left for Nintendo? Nintendo are also suffering at the hands of smart phones and tablets such the iPhone, iPad and Android, with the insanity driven sea of free and $0.99 games and apps (termed frapp-mentality) taking over, people do not want to pay $20-$40 for a hand held game these days,

How can Nintendo survive? Well they can go the way of console hardware manufacturers of the past such as Sega and sell / rework old intellectual properties / develop games across platforms. They could even embrace the Android platform and create their own handheld based / phone / tablet on the technology, offering their own premium Nintendo apps channel.

Who knows, is this the beginning of the end of the much loved Nintendo as a console developer / manufacturer or do Nintendo have something up their sleeves that will blow us away like the Nintendo Wii originally did? Maybe some crazy cool virtual reality console that you control with your mind!? I guess we will have to just wait and see.

Hats off to Nintendo and good luck to them.

Holographic Universe from a Computer Programmers Perspective

Picked up a book today that I started reading a while back but then forgot about called “The Holographic Universe” by Michael Talbot. The book so far is an interesting read on the theory of the Universe being a projection of a 2D surface into 3D, so reality would basically be two dimensional. Personally,I don’t see why not when a 3D game is a projection of a one dimensional software program onto a virtual 3D world that we simple humans can do quite easily.

Anyway, I decided to a do a little digging into the holographic Universe theory and it looks very interesting and does put some very good arguments forward to explain various un-explainable physical and none physical phenomena.  You can read more about the theory here

What’s more interesting to me (with me being a programmer) is the talk that Philip Rosedale gave (the creator of second life). He compares quantum tunnelling to the information processing limits of the system and quantum entanglement to optimisations.

According to quantum physics, all particles exhibit both wave and particle properties. It goes further to say that the natural unobserved state of a particle is wave-like and not what you would class as a solid particle. Once observed by a consciousness the particles wave-like nature collapses and  we see a solid particle. This type of behaviour could represent an optimisation by the Universe, maybe wave like particles use less universal processing power? In game and software development in general you tend not to process everything all of the time as it is a waste of processing power and resources. Instead the programmer tends to reduce or stop processing objects that are not immediately visible or in some way interacting with the user (our conscious observer). For example, when you are playing Call of Duty Modern Warfare or some other shooter, the computer is only processing objects that are visible to / interacting with the player or about to be visible / interacting with the player. The rest lay either in a dormant state inside the computers memory (wave-form like when compared to particles), or have been completely removed from the game.

Also according to quantum physics, if you entangle two particles and move them apart vast distances (lets say the other side of the Universe) then change the state of the first particle, the state of the 2nd entangled particle will change to the opposite state.  How is that possible over such vast distances? Don’t forget nothing can travel faster than the speed of light according to Einstein, so how does the 1st particle send the signal to the 2nd particle to change state? It’s just not physically possible. In software development we use variables to represent the states of objects. We can entangle two objects by giving each object a pointer to the other, so Object 1 points to Object 2 and Object 2 points back at Object 1 (they essentially remember each other). We could create a game that simulates a world the size of the universe using super massive numbers, we could then place these objects at opposite ends of our super massive game universe. Now I  change the state of Object 1 and because I kept a pointer to Object 2 i can also tell it to change its state. No matter how far apart my two objects are, I can still change the state of either object just by having one of the objects at hand.

Yes, I know I’m no quantum physicist and this is all pure speculation, but nonetheless its very interesting speculation.

Are we all just living inside a vastly complex, almost infinite speed, super resolution 2D software program where our three dimensional reality is just a projection?

Bada App and Game Marketing – Playing the Samsung Apps Store for Bada to Boost Sales

Hello fellow Samsung Bada app developers! We know exactly what it’s like to drop a few products onto Samsung Apps store and see them teeter around 5-10 sales per day at $0.99.

We have two products up on the Samsung App Store:

BattleBallz Chaos (a game)
Funky Cam 3D (a camera app)

You may be asking questions such as, how can I breath life into my app / game sales? How do I get my apps and games into Samsung’s top 10? How do I get enough exposure to make my app or game stand out amongst the mass of products already on the Samsung App Store?

The simple answer is to be generous and give it away for free! You may be thinking that I have lost my mind at this point, but I will show you why I haven’t.

Think of giving your app away for free as a temporary promotion tool. You set your app free until users have downloaded the magical number of downloads then you cancel your promotion and put your price back to its original price. This is a guaranteed way of boosting your apps sales and increasing visibility temporarily, shooting your app or game up in the charts.

We have done a fair bit of “price playing” since we launched our products on the Samsung Apps store and it appears that we need to give away around 4000-5000 copies to get into the top 10 over a period of two days. This free promotion will give us a sales boost for around 7-10 days, where we will be selling 5-10x as many products at $1.99.

When to make your product free on Samsung Apps? We saw our greatest downloads on a Monday (triple the number of downloads on any other day). Just be hopeful that products such as Angry Birds or Cut the Rope aren’t on promotion at the same time 🙂

The great thing about a free promotion is that the Samsung Bada press will usually pick up on it and advertise your product as going free on their web sites, which is added exposure.

Marmalade SDK Tutorial – Creating an Extensible Animation System

This tutorial is part of the Marmalade SDK tutorials collection. To see the tutorials index click here

Had flu all week and now I’ve been afflicted with a chest infection so it’s been a pretty miserable week. At least the news of our game BattleBallz Chaos being shown at the Blackberry Devcon 2011 lifted the old spirits.

In the last tutorial we covered basic sprites and more to the point bitmapped sprites. We began to create a basic API called IwGame which will eventually serve as our game engine framework that we can all hopefully build cool games around (that is once we have weeded all of my bugs out 🙂 ). The idea this week is to get those sprites animating (aside from rotating, scaling and moving), we want the image of our sprite to change. My plan for this week was to build a very basic animation class that we could use to animate our bitmap frames. Well my intentions were good and I started out creating a basic image frame animation class but decided to scrap it and create a more extensive animation system that we can use for more than just image animations. If you just need the code then you can grab it from here, otherwise please feel free to read on.

What is an Animation System?

In the context of this article, an animation system is a bunch of classes that deal with animating specific components. These components could be anything from a simple one dimensional variable that represents speed or a two dimensional variable such as a vector that represents the players position to something a little more complex such as a rectangular area of space that represents a frame in an image animation

How could an animation system be useful to us? Well we could use it to animate the texture that appears on a sprite giving it personality (a face that smiles, cries or laughs for example), or we could animate an objects position and rotation to follow a specific path around the game world. We could even animation a list of instructions or game object states using a discrete animation to give the impression that the object is intelligent.

Here are a few terms that I use during this article:

  • Animation – Refers to the complete animation including all its frames, its playback rate, callbacks etc..
  • Frame – Refers to a single discrete component of the animation, this could be a particular image, position or velocity etc..
  • Frame Index – Refers to the position of a particular animation frame in an array of animation frames

An Extensible Animation System – IwGameAnim

Our new animation system IwGameAnim is built around the CIwGameAnim class. This class serves as a general purpose abstract class that we can derive custom animation types from. In this weeks code we have created 3 animation classes from CIwGameAnim:

  • CIwGameAnimImage – A rectangular bases image animation
  • CIWGameAnimFloat – A single floating point variable animation (useful for animating one dimensional components such as angle, speed and distance)
  • CIwGameAnimFVec2 – A 2D floating point vector variable animation (useful for animating two dimensional components such as velocity and position)

Its important to note at this point that I have not fully tested this code yet. I only spent a few hours writing it and testing it (time constraints), but be certain that as we use more of the animation system in our tutorials it will get fully tested eventually.

We are not going to carry out a lot of in-depth analysis of the code this seek as i want to move the Marmalade SDK tutorials series tutorials along faster, believe it or not creating these tutorials takes up a fair amount of time (although I do thoroughly enjoy writing them). That said lets take a quick look at the CIwGameAnim class:

class CIwGameAnim { // Properties protected: bool Playing; // Current playing state float CurrentFrame; // Current animation frame float PlaybackSpeed; // Rate at which to playback animation int FrameCount; // Total number of animation frames in the animation bool FrameHasChanged; // Set to true when a frame has changed bool Looping; // True if the animation loops int NumLoops; // Total number of loops played back so far int MaxLoops; // Maximum number of loops before animation stops (-1 to play forever) int PlayDelayMs; // Amount of time to wait before starting animation CIwGameCallback StartedCallback; // Callback which is called when the animation starts playing CIwGameCallback StoppedCallback; // Callback which is called when the animation stops playing CIwGameCallback LoopedCallback; // Callback which is called when the animation loops public: void setPlaybackSpeed(float speed) { PlaybackSpeed = speed; } bool hasFrameChanged() const { return FrameHasChanged; } void setPlayDelay(int delay_ms) { PlayDelayMs = delay_ms; } void setStartedCallback(CIwGameCallback callback) { StartedCallback = callback; } void setStoppedCallback(CIwGameCallback callback) { StoppedCallback = callback; } void setLoopedCallback(CIwGameCallback callback) { LoopedCallback = callback; } void setLooped(int num_loops); void setCurrentFrame(float frame); float getCurrentFrame() const { return CurrentFrame; } void Start() { Playing = true; if (PlayDelayMs != 0) PlayDelay.setDuration(PlayDelayMs); } void Stop() { Playing = false; } bool isPlaying() const { return Playing; } void Restart(); // Properties End protected: CIwGameTimer PlayDelay; // Timer used to time start of animation public: CIwGameAnim() : Playing(false), CurrentFrame(0), PlaybackSpeed(0), FrameHasChanged(true), Looping(false), NumLoops(0), MaxLoops(0), PlayDelayMs(0), StartedCallback(NULL), StoppedCallback(NULL), LoopedCallback(NULL) {} virtual ~CIwGameAnim() {} virtual void Release() = 0; virtual bool Update(float dt); };

Below is a brief description of the classes properties:

  • Playing – Marks the animation as playing or stopped
  • CurrentFrame – The current animation frame index (think of the integer part of this variable as the frame number of the animation frame we are currently seeing)
  • PlaybackSpeed – The rate at which to play back the animation, a value of  1.0f / davice_frame_rate would play the animation back at one animation frame per second (quite slowly in other words)
  • FrameCount – Total number of frames in this animation
  • FrameHasChanged – Marked true when the animation switches from one animation frame to the next
  • Looping – True if this animation loops when it reaches the end
  • NumLoops – The total number of times the animation has looped around
  • MaxLoops – The maximum number of times the animation is allowed to loop before stopping (a value of -1 means loop forever)
  • PlayDelayMs – This can be used to delay the animation playing at the start. This can be useful if you want to fire off a group of animations at the same time, but have them start at different times
  • StartedCallback – This callback (that you supply) will be called when the animation starts to play
  • StoppedCallback – This callback (that you supply) will be called when the animation stops playing naturally (not when Stop() is called)
  • LoopedCallback – This callback (that you supply) is called each time the animation reaches its end and loops to the start again

You never directly create an animation from this class, instead you can derive your own animation type from this class or use one of those already provided.

Bitmap Image Animation – IwGameAnimImage

Image animation in our game engine involves displaying different image frames one after the other to give the impression of giving personality to our sprite based objects. We store all of our animations on a sprite atlas (also known as a sprite sheet), which looks something like this:

Example sprite atlas / sheet
Example sprite atlas / sheet

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

A sprite atlas is basically a large image that contains a group of other images. To create an image animation we simply display different portions of the sprite atlas.

Bitmap animations are handled by the CIwGameAnimImage class. The CIwGameAnimImage class looks like this:

class CIwGameAnimImage : public CIwGameAnim { protected: CIwGameAnimImageFrame* Frames; // This class takes over management of Frames memory public: CIwGameAnimImage() : CIwGameAnim(), Frames(NULL) {} virtual ~CIwGameAnimImage() { Release(); } void Release(); CIwGameAnimImageFrame* getCurrentImageFrame() const { if (CurrentFrame >= 0) return Frames + (int)CurrentFrame; return NULL; } void setFrameData(CIwGameAnimImageFrame* frames, int count) { Frames = frames; FrameCount = count; } };

The class itself is very basic, it allows you to set the frame data and number of frames using setFrameData() and get the current frame using getCurrentImageFrame(). We will take a look how to use this class a little later on.

CIWGameAnimFloat and CIwGameAnimFVec2 will be discussed in more depth in a separate article that deals with animating in-game objects.

Managing Animation Frames – CIwGameAnimFrameManager

Once we begin building our game we are going to end up with many animations of a variety of types, animating images, paths for objects, spinning slick user interfaces and so on. It’s usually a good idea to have some class that can oversee the creation and tracking of this kind of information. In this case we use the CIwGameAnimFrameManager to help us create blocks of animation frames

This class provides us with the following functions for allocating blocks of frames:

float* allocFloatFrames(int count);
CIwFVec2* allocFVec2Frames(int count);
CIwGameAnimImageFrame* allocImageFrames(int count);
CIwGameAnimImageFrame* allocImageFrames(int count, int frame_w, int frame_h, int start_x, int start_y, int pitch_x, int pitch_y, int image_width);

The second version of allocImageFrames() is a helper method that will auto-generate a group of image animation frames for a sprite atlas. The parameters are:

  • count – Number of frames to generate
  • frame_w, frame_h – Width and height of each animation frame
  • start_x, start_y – Upper left hand corner of first animation frame
  • pitch_x, pitch)y – The horizontal and vertical spacing between frames
  • image_width – Width of the sprite atlas

Managing Animations – CIwGameAnimManager

It would be great to be able to just create a bunch of animations and have something to automatically update them all for us without having to track each one individually, this is where CIwGameAnimManager comes in. CIwGameAnimManager allows us to add a bunch of animations to it and the manager will manage the updating and cleaning up of the animations and all of their frames for us.

It would also be cool if we had an object that had a collection of different animations that it could play to depict it doing different actions, such as running, walking, sleeping, falling etc.. CIwGameAnimManager allows us to add all of these animations and then select which animation is the currently active animation. Switching animations will stop the current animation and set the next one off playing.

The default behaviour of a freshly created CIwGameAnimManager object is to update all animations within the manager and not just the currently playing animation. To switch the manager into tracking and playing only the current animation call setUpdateAll(false).

What’s changed in the example code

Note that our project is now called IwGame and future game engine examples will retain this name.

If you build and run the IwGame project you will see 100 sprites spinning around on the screen, but the difference will be that the sprite is of a face animating manically,.

IwGame Marmalade SDK Tutorial Example
IwGame Marmalade SDK Tutorial Example

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

In terms of assets, we now have a single sprite atlas containing all of our sprites called sprites.png located in the data folder. We have also updated our Leve1l.group group file to include just the sprites.png file into our deployment archive.

We have added four new files to our MKB file:

  • IwGameAnim.cpp
  • IwGameAnim.h
  • IwGameUtil.cpp
  • IwGameUtil.h

IwGameAnim contains our new animation classes, whilst IwGameUtil contains a collection of utility classes, types and constants. The only class we really use from IwGameUtil is the CIwGameTimer, which is a software based polled timer that allows us to time events. We use this to delay the start of animations in the animation system. We also use the CIwGameCallback to define a callback function, although we are not using callbacks in this example, we will use them in the future to activate events such as sound playback

And without further ado, lets take a quick look at Main.cpp to see whats changed:

The first thing is the inclusion of the IwGameAnim.h header file

The next thing is the removal of loading test1 and test2 resources and the addition of loading our sprite atlas sprites.png instead:

CIw2DImage* sprites_image = Iw2DCreateImageResource("sprites");

The next change is the creation of our animation frames and the animation itself:

// Create an image frame manager (manages allocation of our animation frames) CIwGameAnimFrameManager* anim_frame_manager = new CIwGameAnimFrameManager(); // Auto create a 8 frames of animation 36x40 pixels in size CIwGameAnimImageFrame* anim_frames = anim_frame_manager->allocImageFrames(8, 36, 40, 0, 0, 512, 40, 512); // Create and set up our face animation CIwGameAnimImage* face_anim = new CIwGameAnimImage(); face_anim->setFrameData(anim_frames, 8); face_anim->setLooped(-1); face_anim->setPlaybackSpeed(-0.1f); face_anim->Start();

Its not a complex piece of code, just a bit wordy. Firstly we create an animation frame manager which in turn lets us create actual animation frames. In this case we use the helper method allocImageFrames() to generate the 8 frames manic head animation from our sprite atlas.

Next we create the actual image animation, set its animation frames, tell it to loop forever and then finally set it off playing.

The next change is a bit sneaky, I had to make a few upgrades to the IwGameSprite class to allow it to render portions of a larger image, more on that in a sec. In our loop where we create 100 sprites we now set the destination size (on screen size with no scaling) explicitly:

sprite->setImage(sprites_image); sprite->setDestSize(36, 40);

We also only have to assign one texture to every sprite (this will speed up rendering as texture swapping no longer occurs when drawing two sprites with different textures)

If we now move to the main loop and take a look at our sprite update code:

for (CIwGameSpriteManager::Iterator it = sprite_manager->begin(); it != sprite_manager->end(); ++it, speed++) { // Set sprites rotation (*it)->setAngle((*it)->getAngle() + speed); // Set sprites source rectangle from its current animation frame CIwGameBitmapSprite* sprite = (CIwGameBitmapSprite*)*it; sprite->setSrcRect(anim_frame->x, anim_frame->y, anim_frame->w, anim_frame->h); }

You will notice that we now set the sprites image source rectangle (this is the rectangular area of the source image that will be displayed on the sprite), this data is pulled directly from the animation system for the animations current frame.

We then update our animation:

// Update animation face_anim->Update(1.0f);

Note that we didn’t actually place our animation inside a CIwGameAnimManager, so we call the animations Update() method manually.

And finally outside our main loop we clean up our animation data using:

// Cleanup animations if (face_anim != NULL) delete face_anim; if (anim_frame_manager != NULL) delete anim_frame_manager;

The animation system is a chunky bit of code that may take a while to absorb for some of you at the moment, but it will become apparent over the coming weeks just how to utilise it as we plan on using it quite a lot.

Changes to IwGameSprite

I found whilst adding the animation system into the latest example code that our robust sprite class needed to be a little more robust. CIwGameBitmapSprite needed support for drawing areas of of images rather than the whole image. We replaced the previous rendering code with:

int x = -(Width / 2); int y = -(Height / 2); Iw2DDrawImageRegion(Image, CIwSVec2(x, y), CIwSVec2(Width, Height), CIwSVec2(SrcX, SrcY), CIwSVec2(SrcWidth, SrcHeight));

This code calls the Marmalade SDK Iw2D function Iw2DDrawImageRegion() which allows us to draw a rectangular portion of a source image instead of the whole thing.

Note that we use absolutely no object pooling in any of these classes, but we will be adding it in the near future. I left it for now because the code is already quite complex in its current state.

Well that’s it for this tutorial. Our next tutorial will introduce Scenes and Actors where we get to tie our animation and sprites systems together into a core game engine that we can make some cool games with.

You can download the code that accompanies this article from here.

Hope you all find this blog useful and until next time, don’t forget that…., hmmm I forgot!

Marmalade SDK News – Tim Closs on why the Marmalade SDK is so good

Interview with Tim Closs the CTO of the cross platform smart phone and tablet SDK, Marmalade SDK at Blackberry Devcon 2011 conference. Tim mentions how the Marmalade SDK is a good choice for bringing premium content to a variety of platforms (iOS, Android, Bada, Playbook, Symbian, LG TV and more) using the same code base and programming language. Many well known developers are already on board including big game publishers such as Electronic Arts, Popcap, Konami, Activision as well as many indie developers such as ourselves.

Tim then goes on to explain how cross platform development is possible using the Marmalade SDK as well as how super easy it is to re-target a full range of different mobile and emerging technology platforms with very few changes (This we have proved from our own experience with the Marmalade SDK). He also explains how code compiled for the Marmalade SDK is “native”, which means full throttle gaming with no VM’s getting in the way.

Tim then mentions how we took our game BattleBallz Chaos from our existing platforms (iPhone, iPad, Android, Bada) straight to Blackberry Playbook within 24 hours of getting our hands on a Blackberry Playbook. (4 hours tweaking and signing, the rest of the time was spent waiting for approval from RIM).

Tim finally gives some brief information on how Marmalade SDK licensing works.

Nice work Tim and thank you for the mention!

BattleBallz Chaos by Pocketeers Limited Shown on Blackberry Playbook Gaming Ad

One of our games “BattleBallz Chaos” for Blackberry Playbook has been shown on Blackberry’s Playbook gaming ad!

Well, not bad to say it only took us four hours (yes, you did read that right), 4 hours to convert the game using the amazing Marmalade SDK. We we’re also the first native Marmalade SDK app to hit the Blackberry Playbook platform, getting approval within 24 hours.

BattleBallz Chaos can be downloaded for Blackberry Playbook at Blackberry App World

Pocketeers Limited’s BattleBallz Chaos featured on stage at Blackberry Devcon 2011

Well, I’m pleased as punch today, our game and in association with the Marmalade SDK, BattleBallz Chaos got featured on stage (on the big screen – man I seriously want one of those big babies!) by the posh smart men in suits 🙂 Here’s the proof:

Pocketeers Limited's BattleBallz Chaos featured on stage at Blackberry Devcon 2011

Oh yeah that’s right, come on, give me an “Oh yeah baby!”. BattleBallz Chaos for is available for Blackberry Playbook from Blackberry App World

Big thanks to Alex Caccia and the rest of the Marmalade team and Blackberry

Marmalade SDK Bitesize Tutorial – How to force a CIw2DImage texture to upload

Welcome to another bite size Marmalade SDK tutorial. I’ve seen this question pop up a few times in the Marmalade SDk forums so I thought that I would cover it here as a bite size tutorial.

You are using the Iw2D module to render handle 2D images, but you need to force the images to be uploaded to texture RAM before the game begins. You took a quick look at CIw2DImage to discover that it is in fact an abstract class with not a lot of info in there, except a few pure virtual methods  for retrieving width, height and the material associated with the CIw2DImage.

You can call GetMaterial() to return the material that makes up your CIw2DImage() and then in turn, call GetTexture() on the returned material to locate its texture. Finally you can call Upload() on the texture to tell Marmalade to upload it. Here’s a quick example code to show what I mean:

CIwMaterial* mat = your_iw2d_image->GetMaterial();
CIwTexture* texture = mat->GetTexture();
texture->Upload();

Don’t forget that unless you mark the texture as modifiable using texture->SetModifiable(true), the system will delete your pixel / palette data to free up memory.