IwGame Engine – Using Templates Tutorial

New here? What’s IwGame? IwGame is an open source free to use cross platform game engine for iPhone, iPad, Android, Bada, Playbook, Symbian, Windows Mobile, LG-TV, Windows and Mac, built on top of the Marmalade SDK.

A forum poster asked a question recently that made me realise that XOML Templates can quite easily be overlooked as a means for creating re-usable actors and such, so I thought to help make Templates more visible that I would create a very quick tutorial showing how to use them.

To begin with, lets take a look at what a template actually is and does. A template is a XOML tag that allows you to define generic XOML that is not instantiated immediately, yuo can think of a Template as a blue print for something that you will later instantiate into your game or app world. A template also takes any number of parameters that can be passed when you instantiate the template.

When creating items inside a Template, template parameters are defined using a template parameter name that is enclosed inside double dollar signs ($$), for example $position$. When you later instantiate the items within the template the parameters within the template will be replaced by values that are passed to the template.

Lets take a quick look at creating an actor / child actor with a template

[sourcecode language=”xml”]
<Template Name="TankTemp">
<TankActor Name="$name$" Style="TankActorStyle" Position="$pos$″ >
<TankActor Name="$name$_sel" Style="TankActorSelectedStyle" Position="0, 0″ />
</TankActor>
</Template>
[/sourcecode]

Here we create a template called TankTemp that defined an actor with a name of $name$ and a position of $pos$. Note that because these two parameters are enclosed in $$ they are classed as template parameters.

Now to instantiate this elements within this template in XOML we use the following:

[sourcecode language=”xml”]
<FromTemplate Template="TankTemp" name="Tank" pos="310, -120" />
[/sourcecode]

The above code will instantiate the following code:

[sourcecode language=”xml”]
<TankActor Name="Tank" Style="TankActorStyle" Position="310, -120″ >
<TankActor Name="Tank_sel" Style="TankActorSelectedStyle" Position="0, 0″ />
</TankActor>
[/sourcecode]

To instantiate a template from C++, we firstly need to find the template, build the parameters then instantiate the template passing in the parameters:

[sourcecode language=”cpp”]
// Find the tank template
CIwGameTemplate* temp = (CIwGameTemplate*)scene->getResourceManager()->findResource("TankTemp", "template");
if (temp != NULL)
{
// Create a set of XML attributes that will replace the template parameters
CIwGameXmlNode* replacements = new CIwGameXmlNode();
replacements->Managed = false;
CIwGameXmlAttribute* attrib;

// Set name template parameter
attrib = new CIwGameXmlAttribute();
attrib->Managed = false;
attrib->setName("name");
attrib->setValue("Tank");
replacements->AddAttribute(attrib);

// Set position template parameter
attrib = new CIwGameXmlAttribute();
attrib->Managed = false;
attrib->setName("pos");
attrib->setValue("310, -120");
replacements->AddAttribute(attrib);

// Instantiate the Tank template
temp->Instantiate(scene, replacements);

// Clean up replacement attributes
delete replacements;
}
[/sourcecode]

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 Tutorial – Loading bitmaps and rendering sprites with Iw2D

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

Carrying on from my previous Marmalade SDK tutorial that covered creating a basic game loop, I promised that I would move onto something a little more interesting. Well I was going to write this some other day, but I wanted to get it out of the way. As usual if your here just for the code then you can download it from here

Ok, in this tutorial we are going to cover drawing a sprite using Marmalade’s Iw2D module. if you do not know what Iw2D is then its Marmalade’s simple 2D drawing API that you can use for drawing a whole host of simple 2D objects, including:

  • Lines
  • Arcs
  • Rectangles
  • Polygons
  • Images
  • Text

Primitives can be rotated, translated, scaled and flipped. You can also set the colour and opacity.

Its worth noting at this point that Iw2D is context (or state) based (like Open GL). which means that if you modify a parameter within the context, such as a transform or a colour then it will be applied to all rendered primitives until you change the parameter again. So for example, if you set the current colour to red using Iw2DSetColour(0xff0000ff) then all primitives will have a red tint until you change the colour.

Ok, so lets get to some code. I put together some quick sprite rendering code that renders two sprites using rotation, scaling and translation:

// Marmalade headers #include "s3e.h" #include "Iw2D.h" #include "IwGx.h" void DrawSprite(CIw2DImage* image, int at_pos_x, int at_pos_y, iwangle angle = 0, iwfixed scale = IW_GEOM_ONE) { // Set the rotation transform CIwMat2D m; m.SetRot(angle); // Scale the transform m.ScaleRot(scale); // Translate the transform m.SetTrans(CIwSVec2(at_pos_x, at_pos_y)); // Set this transform as the active transform for Iw2D Iw2DSetTransformMatrix(m); // Render the sprite int x = -(image->GetWidth() / 2); int y = -(image->GetHeight() / 2); Iw2DDrawImage(image, CIwSVec2(x, y)); } int main() { // Initialise Marmalade graphics system and Iw2D module IwGxInit(); Iw2DInit(); // Set the default background clear colour IwGxSetColClear(0x40, 0x40, 0x40, 0); // Create two images from PNG files CIw2DImage* image1 = Iw2DCreateImage("test1.png"); CIw2DImage* image2 = Iw2DCreateImage("test2.png"); // Get the display surface width and height int surface_width = Iw2DGetSurfaceWidth(); int surface_height = Iw2DGetSurfaceHeight(); // Dynamic variables iwangle angle = 0; // Main Game Loop while (!s3eDeviceCheckQuitRequest()) { // Update keyboard system s3eKeyboardUpdate(); if (s3eKeyboardGetState(s3eKeyAbsBSK) & S3E_KEY_STATE_DOWN) // Back key is used to exit on some platforms break; // Update pointer system s3ePointerUpdate(); // Clear the screen IwGxClear(IW_GX_COLOUR_BUFFER_F | IW_GX_DEPTH_BUFFER_F); // Draw two sprites DrawSprite(image1, surface_width / 2, surface_height / 2, -angle, (iwfixed)(IW_GEOM_ONE * 2)); DrawSprite(image2, surface_width / 2, surface_height / 2, angle, IW_GEOM_ONE); // Spin our awesome sprite angle += IW_ANGLE_2PI / 60; // Show the surface Iw2DSurfaceShow(); // Yield to the opearting system s3eDeviceYield(0); } // Safely cleanup images if (image2 != NULL) delete image2; if (image1 != NULL) delete image1; // Shut down Marmalade graphics system and the Iw2D module Iw2DTerminate(); IwGxTerminate(); return 0; }

The main() function code looks pretty much the same as in our BasicMKB example except for a few additions (marked in bold). The additions are:

// Create two images from PNG files CIw2DImage* image1 = Iw2DCreateImage("test1.png"); CIw2DImage* image2 = Iw2DCreateImage("test2.png");

These two lines basically create two images from PNG files that I have added to our projects MKB file. if you open up the DrawSprite_Iw2D.mkb file and take a look, you will notice that the following two lines have appeared in the assets section:

test1.png
test2.png

This instructs Marmalade to include these files when we deploy our app or game to a phone, tablet or TV

Its worth noting at this point that if I had forgotten to add these two lines then my awesome sprites would not have been included in the build when I go to deploy it to an actual device, but it would still work on the emulator no problem (I’ve fallen for this many times)

We also added new code to get the width and height of the drawing surface that we are going to draw our sprites to using:

// Get the display surface width and height int surface_width = Iw2DGetSurfaceWidth(); int surface_height = Iw2DGetSurfaceHeight();

We will later use these values to centre our sprite on the display because it looks much nicer than being stuck in the top left hand corner.

Because we want our sprites to do something a little more interesting than just sitting there in the middle of the screen, we are going to spin them (spinning stuff usually impresses people). In order to do that we need track an angle and change it every game frame.

// Dynamic variables iwangle angle = 0;

We create our angle variable of type iwangle. You could just use int if you like but, then the variable would lose some of its meaning. Angles in Marmalade are integer and the range of 360 degrees is defined by the constant IW_ANGLE_2PI

In the main loop we use the following two lines of code to render our sprites:

// Draw two sprites DrawSprite(image1, surface_width / 2, surface_height / 2, -angle, (iwfixed)(IW_GEOM_ONE * 2)); DrawSprite(image2, surface_width / 2, surface_height / 2, angle, IW_GEOM_ONE);

I decided to stick all of the sprite rendering code into a nice easy to use re-usable function so that you just whip off with it and use it. It also keeps my code nice and readable.

Lastly, we update the angle of the sprites using:

// Spin our awesome sprite angle += IW_ANGLE_2PI / 60;

This spins our sprites 6 degrees every game frame (pretty fast in other words)

Ok, now those bits are out of the way, we will move onto the DrawSprite() function. Unfortunately, you do bump into matrices at this point, if you do not know what they are then do not worry as long as you know how to use them. In a nutshell, A matrix is a mathematical object that allows you to transform a set of coordinates. In our case we are using it to rotate, scale and then translate (move) the coordinates of our sprite. The important parts of code in DrawSprite() that I want to point out are:

// Set this transform as the active transform for Iw2D Iw2DSetTransformMatrix(m);

Here we tell Iw2D to set the “current” transform to use when drawing “anything”. Remember that Iw2D is context based and this transform will be remembered, so if you attempt to draw something else without again changing the transform then it will be drawn in the same position, at the same angle and at the same scale. Note that you can reset the current transform back to normal using Iw2DSetTransformMatrix(CIwMat2D::g_Identity). The identity matrix is the default transformation matrix that has no rotation, no translation and no scaling.

// Render the sprite int x = -(image->GetWidth() / 2); int y = -(image->GetHeight() / 2); Iw2DDrawImage(image, CIwSVec2(x, y));

This section of code draws our sprite on screen. Note that we offset the sprite up and to the left by half its height and width so that it is positioned using its centre point rather than its top-left hand corner. This allows out sprite to be rotated and scaled around its centre.

The final result should look something l like this:

DrawSprite example shot
DrawSprite screenshot for Marmalade SDK Iw2D Tutorial

Like anything to do with game development you will eventually come to the point where you need to squeeze every last drop of power out of your rendering engine. Each time you render a different image a new state change is sent to the underlying hardware (this is not efficient by any stretch of the imagination). To help you, Marmalade built an automated batching system into Iw2D so that multiple draw calls using the same image are collected together and batched. Batched is a term used to describe sticking lots of data together and sending it to the hardware in one go. This process is not totally automated however, you will need to draw images by group. For example, lets say you have 10 trees and 5 balls in your scene. The most optimal way would be to draw all of the trees then all of the balls, not 2 trees, 1 ball, 2 trees, 2 balls etc..The astute among you will have noticed a simple problem with batching and that is the problem of draw order. Sometimes it is not practical to draw all trees then all balls because sometimes a ball may appear behind a particular tree.

So how do we solve this problem other than using a z-buffer, which I believe is not supported by Iw2D? The solution is to arrange the ball and tree image on a single bitmap (usually called a sprite atlas or sprite sheet). When you want to draw the tree, you simply render the portion of the image that represents the tree and when you want to draw a ball, you simply render the portion of the image that represents the ball. This way, you are always rendering the same image (albeit different potions of the image) and never have to worry about batching optimisations.

As usual you can download the source code for this tutorial from here

Happy coding and until next time, be careful crossing roads!

Marmalade SDK Tutorial – Up and Running in a Jiffy – The Main Game Loop

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

Ok, so you downloaded and installed the Marmalade SDK, took a quick scan over the help files and thought “Hmm, this is a biggy, where do I start?” When we start something new we all feel like complete and utter noobs. Al you want to do is get a “hello world” application up and running so you can have some kind of sense of achievement and feel comfortable with the process of updating code, compiling it and seeing it actually working. With this in mind, this tutorial will help you accomplish just that. On the other hand, if you just want the source code to the tutorial then you can download it here.

By the way, if you haven’t already done so then http://www.madewithmarmalade.com/download and grab a copy of the free trial version of the Marmalade SDK and install it.

We will begin with a few Marmalade basics so you don’t get lost during the tutorial.

Project files (MKB’s)

To begin with, Marmalade uses the concept of project files to organise your source files, data files and deployment settings. The MKB file is basically a text file that when opened up will generate a Visual Studio or XCode project containing your source files etc.

The MKB file is split into a number of sections, each with a heading name followed by curly braces containing the sections data. Here’s an example of a section:

subprojects { iw2d }

For now you only need to be concerned with the following basic sections of the MKB:

  • options – Options to pass to the build system
  • includepath – Tells marmalade where to look for your header files
  • subprojects – This section tells Marmalade which parts of the SDK you would like to use. Here you put the names of the SDK parts you would like to access from your code, for example, the 2D API is called Iw2D
  • files – This section tells Marmalade which editable files you would like including in your generated project, such as source files, XML files, configuration files etc..
  • assets – This section tells Marmalade which assets you would like to include when deploying your app or game, assets include files such as bitmaps, audio files, meshes, fonts, data files etc.. You can define assets in groups if you need a particular set of assets specific platforms
  • deployments – This section allows you to define certain parameters on a per target platform basis. We won’t be covering this section in this tutorial but its worth mentioning.

Ok, now we have explained a few things about MKB files, here is a very basic one to get you started:

#!/usr/bin/env mkb options { } subprojects { iw2d } includepath { ./source } files { [Source] (source) Main.cpp } assets { }

To generate a project from this file you need to:

  • Create a folder on your hard drive, lets call it BasicMKB
  • Create a text file called BasicMKB.mkb and add the above lines to it
  • Create a sub folders called source
  • Add a Main.cpp file to the source folder
  • Double click the BasicMKB.mkb file to have the Marmalade SDK generate your Visual Studio or XCode project

Notes:

  • Marmalade will generate a data folder containing two .icf files and a build folder, you do not need to be concerned with these for the time being.
  • You should not add additional source files via XCode or Visual Studio. instead, edit the MKB file, add your source files then re-launch the MKB file regenerate the project.

Now we are finally have the basics of creating a Marmalade SDK project out of the way, we now need something to compile and run.

A very basic game loop

In this section we will cover creating a very basic game loop that checks for the user quitting and clears the screen.

Ok, re-using the previous example, you need to edit the Main.cpp file that you created and add the following code:

// Marmalade headers #include "s3e.h" #include "Iw2D.h" #include "IwGx.h" int main() { // Initialise Marmalade graphics system and Iw2D module IwGxInit(); Iw2DInit(); // Set the default background clear colour IwGxSetColClear(0x40, 0x40, 0x40, 0); // Main Game Loop while (!s3eDeviceCheckQuitRequest()) { // Update keyboard system s3eKeyboardUpdate(); if (s3eKeyboardGetState(s3eKeyAbsBSK) & S3E_KEY_STATE_DOWN) // Back key is used to exit on some platforms break; // Update pointer system s3ePointerUpdate(); // Clear the screen IwGxClear(IW_GX_COLOUR_BUFFER_F | IW_GX_DEPTH_BUFFER_F); // Update the game // Render the games view // Show the surface Iw2DSurfaceShow(); // Yield to the operating system s3eDeviceYield(0); } // Shut down Marmalade graphics system and the Iw2D module Iw2DTerminate(); IwGxTerminate(); return 0; }

You can download a zip archive containing the project MKB and source code from here

If you build and run this example you will be presented with a grey screen. yes I know its a bit boring, but we will cover drawing sprites and other interesting topics very soon.