IwGame – We Need Your Feedback

Hi Everyone,

The IwGame Engine has been in development for around 6 months now and although we’ve received lots of feedback regarding bug reports and feature requests we would like to know your opinions on the current state of the engine. Here are a few questions to consider:

  • Is IwGame difficult to use, if so can you suggest any improvements that we could make to make it easier to use?
  • How are you finding the current feature set? Is anything particularly buggy, hard to use or simply missing something?
  • What’s the next BIG feature for you, what would you really like to see come next?
  • How are you finding using XOML? Do you prefer the declarative approach or do you prefer to code things up in C++ instead. Can you suggest any improvements you would like to see?
  • If you have recently stopped using IwGame, what made you leave? Was there a better option and if so, what was the deal making features?

This is the opportunity to have your say, any feedback that you can provide is greatly appreciated and will help steer the direction of the IwGame engine.

Mat

IwGame Engine Tutorial – Actors

CIwGameActor Object – Sprites With Brains

Introduction

Whilst our title comparison suggests that actors are simply sprites with brains they have the potential to be much more.

Going back to comparison in the scene introduction section, actors play a pivotal role in our scenes, each actor having its own unique role and visual appearance. Actors are the building block of the game, they provide the actual unique functionality and visuals that make up the game as a whole. They can provide any type of functionality from a simple bullet fleeting across the screen to something as complex as a dynamic machine that modifies its behaviour and appearance based upon data streamed from a web server.

A CIwGameActor is a very generic object that provides quite a lot of functionality out of the box. The idea is for developers to create their own actor types from the base CIwGameActor class then implement their own custom functionality within its Update() method. The basic functionality provided by CIwGameActor includes:

  • Support for actor pooling to help reduce memory fragmentation
  • Unique names so they can be searched
  • Actor types
  • Position, Depth, Origin, velocity and velocity damping
  • Angle, angular velocity and angular velocity damping
  • Scale and Colour
  • Layers
  • Active and visible states
  • A visual that represents it on screen
  • Animation timeline that can be attached to the visual
  • Collision size / rectangle
  • Wrapping at scenes extents
  • Instantiation itself from XOML
  • Animation timline update
  • Other actor linkage (used to connect actors in a child / parent style system)
  • A Box2D physical body consisting of a material and shape
  • Box2D collision category, mask and group

Note that any changes made to the actor will automatically be applied to the actors visual.

As IwGame progresses more actor types with additional functionality will be created to create more out of the box style game objects (plug-in actors if you will). For the moment the following actors have been created for you:

CIwGameActorImage – This object represents a basic image based actor which has an associated image and animation.
CIwGameActorText – This object represents a basic text based actor which has an associated font and animation.
CIwGameActorParticles – This object represents a complex particle based actor system consists of manypatricles that move independently and have varying life spans.

A word of warning, do not forget to call the based classes Init(), Reset(), Update(), UpdateVisual() methods from your own derived classes or the underlying functionality will not be provided.

Creating Actors

Creating an actor is very simple as the following code shows:

	// Create player actor
	MyActor* actor = new MyActor();
	if (actor == NULL)
		return NULL;

	actor->Init();
	actor->setName("Player1");
	actor->setPosition(x, y);

	// Add player actor to the scene
	scene->addActor(actor);

In the above code we create a a basic MyActor object, which is a class that I created derived from CIwGameActor giving us the base CIwGameActor functionality. However, adding this code into a game wouldn’t actually see anything as we have not assigned a visual element to the actor. CIwGameActor does not handle the creation of a visual for you, instead it handles the rendering and update of a visual and its animations.

To get developers started with actors we included the CIwGameActorImage that will create a basic image based actor that supports animation.

If you require your actor to support Box2D physics then you should either define the Box2DMaterial and Shape in XOML or if creating manually then call:

	InitBody(Scene, shape, material, &Position, Angle, com.x, com.y);

This can be called before or after CIwGameActor::Init()

Creating a CIwGameActorImage

Creating an image based actor is a little more complicated, lets take a look at some example code:

	// Create a new instance
	ActorPlayer* actor = new ActorPlayer();
	if (actor == NULL)
		return NULL;

	// Create player actor
	actor->setScene(scene);
	actor->Init(image, 36, 40);
	actor->setPosition(x, y);

	// Add player actor to the scene
	scene->addActor(actor);

Creation is very similar to creating a basic CIwGameActor with the additional complication of having to pass an image to the actors Init() method.

Looking at the above code we create an ActorPlayer, which is a class that I created derived from CIwGameActorImage as we want some basic image functionality.

We then call the actors its Init() method to set up actor internals. We give the actor a name so that we can find it later then set its world position to the centre of the scene. Finally we add the actor to the scene.

You will notice that ActorPlayer’s Init() method has quite a a few parameters. When we call Init(….) we are actually calling CIwGameActorImage::Init(….) and passing along all the details shown in the code above which includes an image that will represent our actor (or more usually an image atlas), and the width and height of the visual on screen (in virtual canvas coordinates). Internally CIwGameActorImage will create a sprite to display our actor.

The end product of the above code is an actor that can be seen, moved around, scaled, rotated etc..

Now lets take a look at a slightly more complicated ezmple that creates an image based actor that uses an animation time line (more details on time line’s later):

	// Create a new instance
	ActorPlayer* actor = new ActorPlayer();
	if (actor == NULL)
		return NULL;

	// Create an animation timeline to hold our image animation
	CIwGameAnimTimeline* timeline = new CIwGameAnimTimeline();

	// Create and set up our face animation
	CIwGameAnimInstance* face_anim = new CIwGameAnimInstance();
	face_anim->setAnimation(anim);
	face_anim->setTarget(actor, "SrcRect");
	timeline->addAnimation(face_anim);
	timeline->play();

	// Create player actor
	actor->setScene(scene);
	actor->Init(image, 36, 40);
	actor->setTimeline(timeline);
	actor->setPosition(x, y);

	// Add player actor to the scene
	scene->addActor(actor);

I have marked the changes from the previous example.

The first set of changes deals with creating a time line object then creating the instance of an animation and adding that to the time line. This process allows the actor to track and update its own animations

In the last change we simply assign the time line to the actor, the actor will now take care of playing the animation and updating the actors visual with animation changes.

Text Based Actors

Text based actors enable you to instantiate text into the scene with very little effort from code or more easily from XOML. Thse text objects can be use very much in the same way as image based actors in that they can be moved around, scaled, rotated, hit tested or even have physics and collision applied to them.

Lets firstly take a look at creating a text based actor in code:

	// Find our preloaded font
	CIwGameFont* font = (CIwGameFont*)IW_GAME_GLOBAL_RESOURCES->getResourceManager()->findResource("font1", CIwGameXomlNames::Font_Hash);

	// Create a text actor
	CIwGameActorText* text_actor = new CIwGameActorText();
	text_actor->Init(font);
	text_actor->setText("Hello World!");
	text_actor->setRect(CIwRect(-100, -100, 200, 200));
	text_actor->setColour(0, 0, 0, 255);
	text_actor->setPosition(0, 0);
	text_actor->setAngle(45);

	// Add to the scene
	CIwGameScene* scene = findScene("Scene1");
	scene->addActor(text_actor);

In the above code we firstly locate our font (which we have already preloaded into the resource system) then we create a text based actor from CIwGameActorText initialising it with the font. We then set the text, rect and some other parameters.

We now search for the scene we want to place the actor in and it to the scene.

Now lets take a look at how to instantiate a text based actor in XOML:

<ActorText Position=”0, 0″ Rect=”-100, -100, 200, 200″ Angle=”45″ Font=”font1″ Text=”Hello World!” Colour=”0, 0, 0, 255″ />

As you can see the XOML definition is much more compact and readable.

Particle System Actors

From v.030 of IwGame the new particle system based actor is available. This actor is special in that it is optimised for creating, displaying and updating a complete system of sprites (kind of like its own sprite manager). The advantage of this actor is that it does not have to deal with each particle as a separate actor object. The CIwGameActorParticles actor supports both manual and auto generation of particles. Auto generation can be controlled using a number of a control parameters.

Particles have a number of properties that can be adjusted:

  • Visual
  • Position
  • Velocity
  • Velocity Damping
  • Gravity
  • Scale
  • Scale Velocity
  • Scale Velocity Damping
  • Angle
  • Angle Velocity
  • Angle Velocity Damping
  • Colour
  • Colour Velocity
  • Colour Velocity Damping
  • Depth
  • Depth Velocity
  • Depth Velocity Damping
  • Active state
  • Visible state
  • Lifespan – Duration of particle in seconds
  • SpawnDelay – The amount of time to wait before spawning for the first time
  • Lives – Number of times the particle will re-spawn (-1 for infinite)

The CIwGameActorParticles class contains two methods for generating random particles:

void GenerateRandomParticles(int count, CIwRect& src_rect, CIwFVec4& colour, CIwFVec4& colour_velocity, float duration, int repeat_count, float spawn_delay_change, float gravity)
void GenerateRandomParticles(int count, CIwGameActorParticle* particle, CIwRect& src_rect, float duration, int repeat_count, float spawn_delay_change)

Both of these methods will generate a number of particles based on a set of limits.

To determine which particle parameters are generated randomly the CIwGameActorParticles class supports the following methods:

void	setPositionMode(eParticleMode mode)
void	setAngleMode(eParticleMode mode)
void	setScaleMode(eParticleMode mode)
void	setVelocityMode(eParticleMode mode)
void	setAngVelocityMode(eParticleMode mode)
void	setScaleVelocityMode(eParticleMode mode)
void	setDepthMode(eParticleMode mode)
void	setDepthVelocityMode(eParticleMode mode)

By setting the mode to PAM_Random the specified parameters will be generated randomly.

When parameters are generated the following methods specify limits to the random formulas used to generate the parameters:

void	setPositionRange(CIwFVec2& range)
void	setAngleRange(CIwFVec2& range)
void	setScaleRange(CIwFVec2& range)
void	setDepthRange(CIwFVec2& range)
void	setVelocityRange(CIwFVec4& range)
void	setAngVelocityRange(CIwFVec2& range)
void	setScaleVelocityRange(CIwFVec2& range)
void	setDepthVelocityRange(CIwFVec2& range)

Lets take a look at some code that generates an explosion type particle system:

CIwGameActorParticles* GameScene::AddExplosion(int num_particles, float x, float y, float scale, float depth, int layer, float gravity)
{
	// Create explosion particle actor
	CIwGameActorParticles* actor = new CIwGameActorParticles();
	addActor(actor);
	actor->Init(num_particles);
	actor->setImage((CIwGameImage*)ResourceManager->findResource("sprites1", CIwGameXomlNames::Image_Hash));
	actor->setPosition(x, y);

	// Set random parameters
	actor->setScaleMode(CIwGameActorParticles::PAM_Random);
	actor->setAngVelocityMode(CIwGameActorParticles::PAM_Random);
	actor->setVelocityMode(CIwGameActorParticles::PAM_Random);

	// Set paramater limits
	CIwFVec2 scale_range(scale, scale + scale / 2);
	actor->setScaleRange(scale_range);
	CIwFVec2 angle_range(-5, 5);
	actor->setAngleRange(angle_range);
	CIwFVec4 vel_range(-5, 5, -5, 5);
	actor->setVelocityRange(vel_range);
	CIwRect src_rect(908, 440, 100, 100);
	CIwFVec4 colour(255, 255, 255, 255);
	CIwFVec4 colour_vel(0, 0, 0, -5);

	// Generate the particles
	actor->GenerateRandomParticles(num_particles, src_rect, colour, colour_vel, 2, 1, 0, gravity);

	return actor;
}

Here we create a particle actor, set up the which parameters should be randomised then set the random limits. Finally we tell the actor to generate random particles

Now lets take a quick look at generating particles manually in code:

CIwGameActorParticles* GameScene::AddStream(int num_particles, float x, float y, float scale, float depth, int layer, float gravity)
{
	// Create stream particle actor
	CIwGameActorParticles* actor = new CIwGameActorParticles();
	addActor(actor);
	actor->Init(num_particles);
	actor->setImage((CIwGameImage*)ResourceManager->findResource("sprites1", CIwGameXomlNames::Image_Hash));
	actor->setPosition(x, y);
	CIwRect src_rect(800, 291, 68, 65);
	CIwFVec4 colour(255, 255, 255, 128);
	CIwFVec4 colour_vel(0, 0, 0, -3);

	// Create and add particles
	float spawn_delay = 0;
	for (int t = 0; t < num_particles; t++)
	{
		CIwGameActorParticle* p = new CIwGameActorParticle();
		p->LifeSpan = 1;
		p->Lives = -1;
		p->SpawnDelay = spawn_delay;
		p->Gravity = gravity;
		p->Colour = colour;
		p->ColourVelocity = colour_vel;
		p->DepthVelocity = -0.01f;

		actor->addParticle(p, src_rect);
		spawn_delay += (float)1.0f / num_particles;
	}

	return actor;
}

This method creates a particle actor then manually creates a stream of particles that spawn at slightly different times to create a stream type particle system.

Particle actors can also be created in XOML. Lets take a quick look at an example:

    <ActorParticles Name="StreamParticles" Image="sprites1" Position="0, 0" Scale="1.0" Depth="1.0" Layer="1" VelAngMode="random" VelMode="random" AngMode="random" ScaleMode="random" PositionRange="100, 100" AngleRange="0, 360" AngVelRange="-5, 5" ScaleRange="0.25, 0.5" DepthRange="0.5, 1.0" VelRange="-2, 2, -2, 2" ScaleVelRange="0, -0.1" DepthVelRange="0, 0">
        <Particle Count="10" Position="0, 0" VelocityDamping="0.95, 0.95"
		SrcRect="908, 440, 100, 100" ColourVelocity="0, 0, 0, -4" Duration="2"
		Repeat="-1" SpawnDelay="0" />
        <Particle Position="0, 0" VelocityDamping="0.95, 0.95" SrcRect="908, 440, 100, 100"
		ColourVelocity="0, 0, 0, -4" Duration="2" Repeat="-1" SpawnDelay="0" />
        <Particle Position="0, 0" VelocityDamping="0.95, 0.95" SrcRect="908, 440, 100, 100"
		ColourVelocity="0, 0, 0, -4" Duration="2" Repeat="-1" SpawnDelay="0.4" />
        <Particle Position="0, 0" VelocityDamping="0.95, 0.95" SrcRect="908, 440, 100, 100"
		ColourVelocity="0, 0, 0, -4" Duration="2" Repeat="-1" SpawnDelay="0.8" />
        <Particle Position="0, 0" VelocityDamping="0.95, 0.95" SrcRect="908, 440, 100, 100"
		ColourVelocity="0, 0, 0, -4" Duration="2" Repeat="-1" SpawnDelay="1.2" />
        <Particle Position="0, 0" VelocityDamping="0.95, 0.95" SrcRect="908, 440, 100, 100"
		ColourVelocity="0, 0, 0, -4" Duration="2" Repeat="-1" SpawnDelay="1.6" />
    </ActorParticles>

The above XOML firstly generates 10 random particles at time 0, followed by 4 additional particles at times 0.4, 0.8, 1.2 and 1.6 seconds.

If you would like finer grained control over particle actors then you can simply derive your own version from CIwGameActorParticles

Actor Lifetimes

Actors will persist within the scene until a) the scene is deleted b) you explicitly remove them or the recommended method c) they remove themselves. An actor can easily remove and delete itself from the scene by returning false from its Update() method. Here’s an example:

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 no need to be removed
	}

	// 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);
}

Actor Naming and Finding Actors

As mention previously for scenes, actors also named objects, each instance of an object that you wish to query should have its own unique name (per scene) so that it can be located and modified at a later date.

You can find an actor in a particular scene using:

	CIwGameActor* actor = scene->findActor(“Player1”);
	if (actor != NULL)
	{
		// Do somethinig with the actor
	}

There are three ways to locate actors within a scene:

	CIwGameActor*		findActor(const char* name);
	CIwGameActor*		findActor(unsigned int name_hash);
	CIwGameActor*		findActor(int type);

These allow you to search for actor by string, hash or type. Note that searching by type will return the first and only the first instance of that particular actor type. This is very useful if you want to find a unique actor type, for example the player.

Actor Types

When developing games I find it incredibly useful to assign different types of actors different type ID’s, this allows me to optimise many area of my code such as collision checks. Carrying a type ID for each actor also comes in handy when you want to know the types of actor that you are interacting with.

You can set and get the actors type ID using:

	void		setType(int type)
	int		getType() const

Moving, Rotating and Spinning Actors

Actors come with a very basic physics system that allows movement via velocity and angular velocity, actors can also be scaled. CIwGameActor provides the following basic functionality to handle these features:

	void				setPosition(float x, float y)
	CIwFVec2			getPosition()
	void				setAngle(float angle)
	float				getAngle()
	void				setVelocity(float x, float y)
	CIwFVec2			getVelocity()
 	void				setVelocityDamping(float x, float y)
	void				setAngularVelocity(float velocity)
	float				getAngularVelocity() const
	void				setAngularVelocityDamping(float damping)
	void				setScale(float scale)
	float				getScale() const

Note that velocity and angular velocity damping is a reduction factor that is applied each game frame to slow down objects linear and angular velocities. Their default values are 1.0f which provides no damping, setting this value to less than 1.0f will dampen velocity whilst setting it to a value greater than 1.0f will enhance velocity.

Also note that changing position or angle will not effect velocity.

If the actor was created with Box2D physics enabled then you can also use the supplied force application methods.

Attaching a Visual and an Animation Timeline

For our actor to become visible on screen we need to assign it a visual component. If you are rolling your own actor and don’t go the CIwGameActorImage route then you will need to create and assign your own visual component to the actor.

To assign a visual to an actor you would call:

	void		setVisual(CIwGameSprite* visual)

Now when the scene renders the actor it will attenot to render the visual. I want to mention at this pont that as far as IwGame is concerned a visual is an object type that derived from a CIwGameSprite (we will cover this later), but for now we will just say that a sprite as far as IwGame is concerned is anything that can be displayed, be it a simple image or a complex piece of SVG.

And where you find visuals you will usually find some kind of animation. The actor class supports attachment of CIwGameAnimTimeline which is basically a collection of animations (we will cover this in more depth later). To assign a time line we call:

	void		setTimeline(CIwGameAnimTimeline* timeline) { Timeline = timeline; }

Changing an Actors Colour

Each actor has its own independent colour (including opacity). All actors are set to a default colour of white and full opacity. To change the colour of an actor you can call:

	void		setColour(CIwColour& colour)

Note that an actors colour will be combined with its parents base colour.

Obeying Scene Extents

By default an actor would merrily travel across the game scene and beyond its extents into oblivion and out of range coordinates, this can cause a bit of a mess for the underlying math and rendering routines. To prevent actors from going off into oblivion we can tell them to wrap around to the other side of the scene if they hit its extents boundary. To force actors to wrap around at the boundaries of the scene we call setWrapPosition(true):

	void		setWrapPosition(bool enable)
	bool		getWrapPosition() const					{

Actor Layering

We touched on layering earlier when we talking about layering in scenes. All actors within a scene exist (visually) on a layer. The layer determines the order in which the actors are rendered with lower layers appearing below higher layers. The maximum layer that an actor can exist on is determined by the scene that it lives in. To change the layer that an actor appears on and to retrieve its current layer we use:

	void		setLayer(int layer)
	int		getLayer() const

Scene Visibility and Active State

You can query an actors visibility state and set its visibility state using:

	void		setVisible(bool visible)
	bool		isVisible() const

You can query an actors active state and set its active state using:

	void		setActive(bool active)
	bool		isActive() const

Note that when an actor is made inactive it will also become invisible. However making an actor invisible will not make it inactive.

Resetting Actors

Because actors can be part of an object pooling system and may not get re-initialised when re-used, we provide the functionality to reset them to a default state. This allows developers to re-use objects and not worry about the previous state of the object. Just remember to call the underlying CIwGameActor::Reset() method from your own Reset() method to ensure that the actor is completely reset.

Collision Checking

Right now IwGame does not carry out collision checks for you, instead it calls back each actor in the scene after the scene has been updated to give each possible colliding object a chance to check and respond to collisions. To take advantage of this functionality you need to implement the following handler in your derived actor class:

	virtual void	ResolveCollisions() = 0;

A basic actor to actor collision method is included in CIwGameActor to allow actors to test for overlap based on the size set by setCollisionRect();

When a collision does take place, actors can notify each other by calling:

	virtual void	NotifyCollision(CIwGameActor* other) = 0;

Here’s a quick example showing how to use the system:

void ActorPlayer::ResolveCollisions()
{
	// Walk the scenes actors
	for (CIwGameScene::_Iterator it = Scene->begin(); it != Scene->end(); ++it)
	{
		// Only test collision against ball type actors
		if ((*it)->getType() == ActorType_Ball)
		{
			// Check for physical collision
			if (CheckCollision(*it))
			{
				// Notify ourselves that we collided with ball actor
				NotifyCollision(*it);
				// Notify ball actor that we collided with it
				(*it)->NotifyCollision(this);
			}
		}
	}
}
Note that if you are using integrated Box2D then you safely bypass this collision check system.

Creating an Actor from XOML

Actors can be created declaratively using XOML mark-up, making actor creation much easier and more intuitive. Below shows an example of an actor declared using XOML:

        <MyActor Name="Player1" Position="0, 0" Size="100, 100" Angle="45" SrcRect="0, 0, 36, 40" Image="Sprites" Timeline="Player1Intro2" />

The basic actor tag supports many different attributes that determine how an actor is created and how it behaves. A description of these tags are listed below:

  • Name – Name of the scene (string)
  • Style – Style that should be applied to this actor. If a properties that exists in the style is added to the definition then it replaces the property found in the style
  • Type – A numerical type that can be used to identify the type of this actor (integer)
  • Position– Position in the scene (x, y 2d vector)
  • Origin– Origin in the scene, moves the point around which the actor will rotate and scale (x, y 2d vector)
  • Depth – Depth of the actor in 3D (float – larger values move the sprite further away)
  • Velocity – Initial velocity of the actor (x, y 2d vector)
  • VelocityDamping – The amount to dampen velocity each frame (x, y 2d vector)
  • Angle – The orientation of the actor (float)
  • AngularVelocity – The rate at which the orientation of the actor changes (float)
  • AngularVelocityDamping – The amount of rotational velocity damping to apply each frame (float)
  • Scale, ScaleX, ScaleY – The scale of the actor (float)
  • Colour – The initial colour of the actor (r, g, b, a colour)
  • Layer – The scenes visible layer that the actor should appear on (integer)
  • Active – Initial actor active state (boolean)
  • Visible – Initial actor visible state (boolean)
  • HitTest – If true then this actor will receive touch events
  • Collidable – Collidable state of actor (boolean)
  • CollisionSize – The circular size of the actor (float)
  • CollisionRect – The rectangular collision area that the actor covers (x, y, w, h rect)
  • WrapPosition – If true then the actor will wrap at the edges of the canvas (boolean)
  • Timeline – The time line that should be used to animate the actor
  • Box2dMaterial – Sets the physical material type used by the Box2D actor
  • Shape – Box2D fixture shape for the Box2D actor
  • COM – Centre of mass of Box2D body (x, y 2d vector)
  • Sensor – Can be used to set the Box2D actor as a sensor (boolean)
  • CollisionFlags – The Box2D body collision flags (category, mask and group)
  • OnTapped – Tapped event handler
  • OnBeginTouch – Event handler that specifies an actions list to call when the user begins to touch the actor
  • OnEndTouch – Event handler that specifies an actions list to call when the user stops to touching the actor
  • OnTapped – Event handler that specifies an actions list to call when the user taps the actor
  • OnCreate – Event handler that specifies an actions list to call when this actor is created
  • OnDestroy – Event handler that specifies an actions list to call when this actor is destroyed
  • LinkedTo – Name of actor that this actor links to (string)

For actors that are derived from CIwGameActorImage we have the following additional properties:

  • Image – The image that is to be used as the actors visual (string)
  • Size – The on screen visible size of the actor (x, y 2d vector)
  • SrcRect – The position and source of the source rectangle in the image atlas (x, y, w, h rect). Used for panning the portion of a sprite atlas shown allowing frame based animation.
  • FlipX – Horizontal flipped state (boolean)
  • FlipY – Vertical flipped state (boolean)

For actors that are derived from CIwGameActorText we have the following additional properties:

  • Font – Name of font to use to draw the text (string)
  • Rect – The area thuat the text should be drawn inside of (x, y, w, h rect)
  • Text – String to display (string)
  • AlignH – Horizontal alignment (centre, left and right)
  • AlignV – Verticalalignment (middle, top and bottom)
  • Wrap – If true then text is wrapped onto next line if to long (boolean)

Note that unlike scenes you cannot create an Actor or ActorImage directly as their corresponding CIwGameActor and CIwGameActorImage classes are abstract, so you must derive your own actor class. More on this later.

In addition, actors must be declared inside a scene tag element as they must have a parent scene and cannot be declared as resources.

Animating Actor Components

Actors allow an animation time line to be attached to them that animates various properties of the actor. The following properties are currently supported:

  • Position – Actors current position
  • Depth – Actors 3D depth
  • Origin – Actors transform origin
  • Velocity – Actors current velocity
  • Angle – Actors current angle
  • AngularVelocity – Actors current angular velocity
  • Scale, ScaleX, ScaleY – Actors current scale
  • Colour / Color – Scenes current colour
  • Layer – Actors current visible layer
  • Visible – Actors current visible state
  • HitTest – Determines if the actor can be tapped
  • Timeline – The currently playing timeline

For actors that are derived from CIwGameActorImage we have the following additional properties:

  • SrcRect – Actors currebt bitmapped visual source rectangle
  • Size – Actors visible size on screen

Any of these properties can be set as an animation target

Creating a Custom Actor

Whilst CIwGameScene can be instantiated and used as-is, CIwGameActor and CIwGameActorImage are abstract and cannot. The actor system is designed this way as the developer is meant to create their own custom actor types that provide bespoke functionality that is specific to their game.

You begin the creation of a custom actor by deriving your own actor class from either CIwGameActor or CIwGameActorImage then overloading the following methods to provide implementation:

	virtual void		Init();
	virtual bool		Update(float dt);
	virtual bool		UpdateVisual();
	virtual void		ResolveCollisions() = 0;
	virtual void		NotifyCollision(CIwGameActor* other) = 0;

Here’s a quick example:

class MyActor : public CIwGameActor
{
public:
	MyActor() : CIwGameActor() {}
	~MyActor() {}

	void		Init()
	{
		CIwGameActor::Init();
	}

	bool		Update(float dt)
	{
		if (!CIwGameActor::Update(dt))
			return false;

		// Here we put our actor specific implementation

		return true;
	}

	bool		UpdateVisual()
	{
		if (!CIwGameActor::UpdateVisual())
			return false;

		// Here we put our actor specific rendering code (if any is needed)

		return true;
	}

	void		ResolveCollisions() {}
	void		NotifyCollision(CIwGameActor* other) {}
};

We have provided a very basic implementation of Init(), Update() and UpdateVisual() which call the base CIwGameActor class methods so we keep its functionality in-tact.

We also provide a none functional implementation of ResolveCollisions() and NotifyCollision() as these are required methods

You can take the implementation one step further by implementing both the IIwGameXomlResource and IIwGameAnimTarget interfaces to allow instantiation of your custom actor class from XOML and to allow your class to be a target for animation time lines.

Firstly lets take a look at XOML enabling your custom actor class. To get IwGame to recognise your class whilst parsing XOML files you need to do a few things:

  • Derive your class from IIwGameXomlResource and implement the LoadFromXoml method
  • Create a class creator that creates an instance of your class then add this to the XOML engine

Lets start by taking a look at step 1.

Because we have derived our class from CIwGameActor we already have the support for step 1. However we would like to insert our own custom attribute tags so we need to make a few changes.

Lets take a look at our new class with thiose changes:

class MyActor : public CIwGameActor
{
public:
	// Properties
protected:
	int		NumberOfEyes;
public:
	void		setNumberOfEyes(int num_eyes)	{ NumberOfEyes = num_eyes; }
	float		getNumberOfEyes() const		{ return NumberOfEyes; }
	// Properties End
public:
	MyActor() : CIwGameActor() {}
	~MyActor() {}

	void		Init()
	{
		CIwGameActor::Init();
	}

	bool		Update(float dt)
	{
		if (!CIwGameActor::Update(dt))
			return false;

		// Here we put our actor specific implementation

		return true;
	}

	bool		UpdateVisual()
	{
		if (!CIwGameActor::UpdateVisual())
			return false;

		// Here we put our actor specific rendering code (if any is needed)

		return true;
	}

	void		ResolveCollisions() {}
	void		NotifyCollision(CIwGameActor* other) {}

	// Implementation of IIwGameXomlResource interface
	bool		LoadFromXoml(IIwGameXomlResource* parent, bool load_children, CIwGameXmlNode* node)
	{
		if (!CIwGameActor::LoadFromXoml(parent, load_children, node))
			return false;

		// Add our own custom attribute parsing
		for (CIwGameXmlNode::_AttribIterator it = node->attribs_begin(); it != node->attribs_end(); it++)
		{
			unsigned int name_hash = (*it)->getName().getHash();

			if (name_hash == CIwGameString::CalculateHash("NumberOfEyes"))
			{
				setNumberOfEyes((*it)->GetValueAsInt());
			}
		}

		return true;
	}
};

Our new class now basically supports a new NumberOfEyes attribute that we will eventually be able to set in XOML using something like:

    <MyActor Name="AlienCritter" Position="100, 100" Size="100, 100" NumberOfYes="3" />

However, before we can do that we need to let the XOML system know about our new type of class (MyActor), so it can be instantiated when the XOML parser comes across it. To do this we need to create a XOML class creator:

class MyActorCreator : public IIwGameXomlClassCreator
{
public:
	MyActorCreator()
	{
		setClassName("MyActor");
	}
	IIwGameXomlResource* CreateInstance(IIwGameXomlResource* parent) { return new MyActor();	}
};

The creator basically defines the tag name “MyActor” and returns an instance of the MyActor class when CreateInstance() is called.

To get the XOML system to recognise our new creator we need to add it to the XOML parsing system using:

	// Add custom MyActor to XOML system
	IW_GAME_XOML->addClass(new MyActorCreator());

Now XOML integration is out of the way, lets take a quick look at enabling our class as an animation target.

To enable a class as an animation target we derive it from IIwGameAnimTarget and implement the UpdateFromAnimation() method. Luckily we derived our MyActor class from the CIwGameActor class which already provides this functionality.

Lets take a quick look at how we extend the animation update method to account for animating our NumberOfEyes variable.

	bool	UpdateFromAnimation(CIwGameAnimInstance *animation)
	{
		if (CIwGameActor::UpdateFromAnimation(animation))
			return true;

		// Add our own custom animating property
		unsigned int element_name = animation->getTargetPropertyHash();

		if (element_name == CIwGameString::CalculateHash("NumberOfEyes"))
		{
			CIwGameAnimFrameFloat* frame = (CIwGameAnimFrameFloat*)animation->getCurrentData();
			setNumberOfEyes((int)frame->data);
			return true;
		}

		return false;
	}

We added the above code to our MyActor class definition. We begin by calling the base UpdateFromAnimation() method so we can keep the existing animation properties of the actor. We then add our own custom check for the NumberOfEyes variable. If the animation property matches NumberOfEyes then we set the number of eyes to the provided interpolated value.

 

 

IwGame Engine Tutorial – Scenes

CIwGameScene Object – A Place for Actors to Play

Introduction

Its easier to think about game development if we think in terms of the movie business, we all watch movies and programmes on the TV which makes it easy to relate to.

A movie usually consists of a number of scenes that contains the environment, actors and cameras. At the moment, IwGame only supports actors and cameras (environments may be added at a later date).

A CIwGameScene is responsible for the following functionality:

  • Setup and handling of the virtual canvas
  • Managing, updating and cleaning up actors
  • Managing, updating, rendering and cleaning up sprites
  • Managing and clean up of animation data
  • Managing and clean up of animation timelines
  • Managing and clean up of Marmalade resource groups
  • Managing and clean up of images
  • Managing and clean up of physics materials and shapes
  • Clipping sprites against the scenes visible extents
  • Updating the camera
  • Tracking actors that can potentially collide
  • Transitions between scenes
  • Updating the scenes animation timeline
  • Instantiating itself from XOML
  • Managing and clean up of XOML variables
  • Updating physics

Its also worth a major note at this point that any actors that live inside a scene will be transformed by the same transform as the scene, so if you move, scale or spin the scene then the contained actors will also move, scale and spin with it. The same can also be said about the base colour of the scene

Creating a Scene

Creating a scene is very simple, as the following code shows:

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

In the above code snippet we allocate a new CIwGameScene object and called its Init() method to set up scene internals. We give the scene a name so we can find it later then set the virtual transform (see next section for explanation of the virtual canvas). Finally we ask the game to change the current scene to our newly created scene (CIwGame::ChangeScene())

You can create as many scenes as you like and add them to the game, just remember only one can be the active scene, but all visible scenes will be rendered.

I would like to add some additional information regarding CIwGameScene::Init(), its prototype looks like this:

int	Init(int max_collidables = 128, int max_layers = 10);

As you can see, the method actually takes two parameters (defaults are applied so you can go with the defaults if you like). The two additional parameters are defined as:

  • max_collidables – This the maximum size of the collidable objects list and should be as large as the maximum number of objects that can possibly collide in your scene. For example, if you have 100 objects that are marked as collidable then you can set this value to 100
  • max_layers – Scenes support object layering, the default number of layers is set to 10, but you can change this value here

If you would like to prevent the internal Box2D physics engine update then set the scenes WorldScale to 0:

	game_scene->getBox2dWorld()->setWorldScale(0, 0);

This stops the internal Box2D physics update. It can be re-enabled by changing WorldScale to a valid value.

Virtual Canvas

Targeting a large selection of different phones, tablets and other devices with a variety of screen sizes and aspect ratios is a bit of a nightmare when it comes to game development. Luckily the CIwGameScene class takes care of this for us. A scene is quite a clever object in that it can render itself to any sized / configuration display using the virtual canvas concept. A virtual canvas is basically our own ideal screen size that we want to render to. The scene will scale and translate int visuals to fit our canvas onto the devices display allowing us to get on with developing our game using a static resolution. Lets take a look at the prototype for setting a scenes virtual canvas:

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

And an explanation of its parameters:

  • required_width – The width of the virtual canvas
  • required_height – The height of the virtual canvas
  • angle – Angle of the virtual canvas
  • fix_aspect – Forces the rendered canvas to lock to the devices aspect ratio (you may see letter boxing or clipping)
  • lock_width –Calculates scale based on screen_width / required_width if set true, otherwise scale based on screen_height / required_height.
  • 3.4 Scene Object Management
  • When it comes to coding I am quite bone idle and hate having to track things such as allocating actors, images / memory for animations etc,. I want something that will let me allocate these types of objects, assign them then forget about them. CIwGameScene contains a SpriteManager, and a ResourceManager (will cover these in detail later) that takes care of the things that I don’t want bothering with during development. In addition, if I remove a scene from the game CIwGameScene will clean the lot up for me when it gets destroyed.

This automated clean-up does come at a very small price however, if you want to add a resource group to the scene then you will need to do that through the scene itself. Here’s an example:

	// Create and load a resource group
	CIwGameResourceGroup* level1_group = new CIwGameResourceGroup();
	level1_group->setGroupName("Level1");
	level1_group->setGroupFilename("Level1.group");
	level1_group->Load();
	// Add the resource group to the scenes resource manager
	game_scene->getResourceManager()->addResource(level1_group);

As you can see we need a reference to the scene so that we can get to the resource manager. Not too painful, but thought it best to make you aware of this small caveat.

Scene Extents and Clipping

Scenes have an extents area that can be defined which defines the area in which actors can be, actors that are outside of the scenes extents are wrapped around to the other side of the scene. This behaviour can be enabled / disabled on a per actor basis. You can set the scenes extents by calling:

	void CIwGameScene::setExtents(int x, int y, int w, int h);

Scenes also allow you to define a visible clipping area, pixels from the scene that fall outside that area will not be drawn. You can set the clipping area of a scene by calling:

	void CIwGameScene::setClippingArea(int x, int y, int w, int h);

The default behaviour is for the clipping area to move with the scenes camera, but this can be disabled by enabling the scenes ClipStatic state. When ClipStatic is true, the scenes clipping rectangle will remain static on screen, whilst the contents move around inside the clipping area.

Scene Camera

A scene has a camera associated with it that allows the user to pan around the scene as well as rotate and scale the view. All actors within the scene will move / rotate and scale in relation to the camera. It is possible to switch cameras within a scene, although you will need to manage the lifetime of these cameras, the scene will only manage the currently attached camera (so do not delete it a camera if it is assigned to the scene. You can assign a camera to the scene using:

	void CIwGameScene::setCamera(CIwGameCamera* camera);

Potential Colliders and Collision Handling

As a scene processes actors it will build a list of references to all actors that are marked as possibly colliders, once all actors have been processed the scene will walk the list of potential colliders and call their ResolveCollisions() method to give each actor a chance to handle its own collisions. Note that the scene does NOT handle collision detection and response, actors themselves should take care of that.

Note that actors that have a physics material attached are under the control of the Box2D physics engine and collision is handled separately (more on this in the actors section)

 

Current Scene Concept

Because the game consists of multiple scenes and only one scene can have the focus at any one time we use the concept of the current scene. Whilst all scenes are visible (unless made hidden) and rendered they are not all processed. By default the only scene that is processed is the current scene. It is however possible to force a scene to be processed even when it does not have the focus by calling CIwGameScene::setAllowSuspend(false). This will prevent the scene from being suspended when another scene is made the current scene.

Scenes can exist in two states, suspended or operational (resumed). Suspending scenes are not processed but are still rendered. When a new scene is switched to using CIwGame::changeScene(CIwGameScene* new_scene) the old scene will be put into a suspended state and the new scene will be resumed. IwGame will notify you when either of these events occur via the following methods:

virtual void	NotifySuspending(CIwGameScene* new_scene)    // This event is called when this scene is being suspended
virtual void	NotifyResuming(CIwGameScene* old_scene)      // This event is called when this scene is being resumed
virtual void	NotifyLostFocus(CIwGameScene* new_scene)     // This event is called when this scene has just lost focus
virtual void	NotifyGainedFocus(CIwGameScene* old_scene)   // This event is called when this scene has just gained focus

In order to receive these events you should implement them in your derived scene class, e.g.:

void	MyGameScene::NotifySuspending(CIwGameScene* new_scene)
{
	// Add code to handle the scene being suspended
}

Note that you do not need to derive your own scene class from CIwGameScene as long as you are happy with the generic functionality that it ptovides, however you will not have access to the suspend / resume functionality as C style callbacks are not used in this instance.

You can tie into these events in XOML by implementing the OnSuspend /OnResume events, e.g.:

    <Scene Name="GameScene3" OnSuspend="SuspendActions">
        <Actions Name="SuspendActions">
            <Action Method="ChangeScene" Param1="GameScene2" />
            <Action Method="PlayTimeline" Param1="GameScene3Anim" />
            <Action Method="PlaySound" Param1="Explosion" />
        </Actions>
    </Scene>

When the scene is suspended, the actions set SuspendedActions will be executed.

Actor Management

The main reason that scenes exist is to facilitate actors. Once an actor is created and added to a scene the scene handles their update, rendering and clean up. CIwGameScene contains the following methods for adding, removing and searching for actors within a scene:

void				addActor(CIwGameActor *actor);
void				removeActor(CIwGameActor* actor);
void				removeActor(unsigned int name_hash);
CIwGameActor*			findActor(const char* name);
CIwGameActor*			findActor(unsigned int name_hash);
CIwGameActor*			findActor(int type);
void				clearActors();

 

Scene Naming and Finding Scenes

IwGame is designed to prevent what I like to call “unreliable references”. To me an unreliable reference is a reference to an another object that can disappear at any moment without the object that references it knowing about it, this can lead to some pretty nasty bugs that are incredibly difficult to track down. So instead of simply keeping a reference to an object we keep a name.

IwGame uses object naming quite extensively for major system such as actors and scenes. The idea is that if we want to speak to a scene from somewhere outside that scenes instance we simply find it by name using CIwGame::findScene(). Once found we can grab a pointer to it and access it. The wonderful thing about this system is that if the scene has disappeared when we call findScene() a NULL pointer will be returned signifying that it no longer exists, allowing our calling code to determine what to do about it (as opposed to simply crashing or doing something even worse such as writing all over memory that its not supposed to).

The naming system does add a little overhead to our game but not a great deal as searches are done using string hashes instead of string comparisons. The tiny overhead is definitely worth the buckets of tears that you can potentially save from days of tracking down hard to find bugs.

 

Scene Layers

Actors within a scene can be depth sorted using layers. Each actor has its own layer number which decides where it will appear within the scenes depth tree. Actors on higher layers will appear over actors on lower layers. Actors on the same layer will be drawn in the order in which they were added to the layer, so later actors will be drawn on top of earlier added actors.

Note that the layering system is not strictly part of the scene engine, instead it is handled by the sprite manager contained within a scene, but for the purpose of easy access is accessible through the scene.

 

Scene Origin

A scenes origin is set at 0, 0, which is the centre of the virtual canvas (usually centre of screen) for the default transform.

 

Scene Visibility and Active State

Scenes can be made visible or invisible by calling CIwGameScene::setVisible(). You can also query the visibility of a scene using CIwGameScene::isVisible(). When a scene is invisible it is not rendered.

Scenes can also be made active or inactive by calling CIwGameScene::setActive(). You can also query the active state of a scene by calling CIwGameScene::isActive(). When a scene is active it is processed.

Note that a scenes active and visibility states are independent, an inactive scene will still be rendered and an invisible scene that is active will still be processed.

 

Scene Transitions

Scene transitions are taken care of by the timeline system. A quick scroll scene transition is shown below:

    <Animation Name="SceneTransition1" Type="vec2" Duration="2" >
        <Frame Value="0, 0"    Time="0.0" />
        <Frame Value="480, 0"  Time="2.0" />
    </Animation>

    <Scene Name="GameScene" …..... OnSuspend="SuspendActions">
        <Actions Name="SuspendActions">
            <Action Method="SetTimeline" Param1="SceneTransition1" />
        </Actions>
        <Timeline Name="SceneTransition1" AutoPlay="true">
            <Animation Anim="SceneTransition1" Target="Position" Repeat="1" StartAtTime="0"/>
        </Timeline>
    </Scene>

In the above XOML we create a scene and attach the SuspendActions collection to the OnSuspend scene event. Note that the timeline was defined inside the scene because it is not requested until some actor actually suspends the scene. Here’s an example showing an actor that raises the scene suspended event when it is tapped:

    <TestActor Name="Player4" ...... OnTapped="SuspendScene3">
        <Actions Name="SuspendScene3">
           <Action Method="SuspendScene" Param1="GameScene3" />
        </Actions>
    </TestActor>

 

Creating a Scene from XOML

Scenes can be created declaratively using XOML mark-up, making scene creation much easier and more readable. Below shows an example of a scene declared using XOML:

    <Scene Name="GameScene" CanvasSize="320, 480" FixAspect="true" LockWidth="false" Colour="0, 0, 255, 255" AllowSuspend="false">
    </Scene>

The scene tag supports many different attributes that determine how a scene is created and how it behaves. A description of these tags are listed below:

  • Name – Name of the scene (string)
  • Type – Type of scene (integer)
  • CanvasSize – The virtual canvas size of the screen (x, y 2d vector)
  • FixAspect – Forces virtual canvas aspect ratio to be fixed (boolean)
  • LockWidth – Forces virtual canvas to lock to with if true, height if false (boolean)
  • Extents – A rectangular area that describes the extents of the scenes world (x, y, w, h rect)
  • AllowSuspend – Determines if the scene can be suspended when other scenes are activated (boolean)
  • Clipping – A rectangular area that represents the visible area of the scene (x, y, w, h rect)
  • Active – Initial scene active state (boolean)
  • Visible – Initial scene visible state (boolean)
  • Layers – The number of visible layers that the scene should use (integer)
  • Layer – The visual layer that this scene should be rendered on (integer)
  • Colliders – The maximum number of colliders that the scene should support (integer)
  • Current – If true then the scene is made the current scene (boolean)
  • Colour / Color – The initial colour of the scene (r, g, b, a colour)
  • Timeline – The time line that should be used to animate the scene
  • Camera – Current camera
  • OnSuspend – Provides an actions group that is called when the scene is suspended
  • OnResume – Provides an actions group that is called when the scene is resumed
  • OnCreate – Provides an actions group that is called when the scene is created
  • OnDestroy – Provides an actions group that is called when the scene is destroyed
  • OnKeyBack – Provides an actions group that is called when the user presses the back key
  • OnKeyMenu – Provides an actions group that is called when the user presses the menu key
  • Gravity – Box2D directional world gravity (x, y 2d vector)
  • WorldScale – Box2D world scale (x, y 2d vector)
  • Batch – Tells the system to batch sprites for optimised rendering (boolean)
  • AllowFocus – If set to true then this scene will receive input focus events that the current scene would usually receive exclusively. This is useful if you have a HUD overlay that has functionality but it cannot be the current scene as the game scene is currently the current scene1Anim
  • DoSleep – If set to true then actors that utilise physics will eb allowed to sleep when they are not moving / interacting

 

Animating Scene Components

Scenes allow an animation time line to be attached to them that animates various properties of the scene. The following properties are currently supported:

  • Camera Position – Cameras current position
  • Camera Angle– Cameras current angle
  • Camera Scale– Cameras current scale
  • Colour – Scenes current colour
  • Clipping – Scenes current clipping extents
  • Visible – Scenes current visible state
  • Timeline – The currently playing timeline
  • Camera – change current camera

Any of these properties can be set as an animation target

 

Creating a Custom Scene

Whilst CIwGameScene can suffice for most tasks, you may find that you need to create your own type of scene that has functionality specific to your game or app. You begin the creation of a custom scene by deriving your own scene class from CIwGameScene then overloading the following methods to provide implementation:

	virtual int	Init(int max_collidables = 128, int max_layers = 10);
	virtual void	Update(float dt);
	virtual void	Draw();

Here’s a quick example:

class MyGameScene : public CIwGameScene
{
public:
	MyGameScene() : CIwGameScene() {}
	virtual ~MyGameScene();

	virtual int		Init(int max_collidables = 128, int max_layers = 10)
	{
		CIwGameScene::Init(max_collidables, max_layers);
	}
	virtual void	Update(float dt)
	{
		CIwGameScene::Update(dt);
	}
	virtual void	Draw()
	{
		CIwGameScene::Draw();
	}
};

We have provided a very basic implementation of Init(), Update() and Draw() which call the base CIwGameScene class methods so we keep its functionality in-tact.

You can take the implementation one step further (or maybe two) by implementing both the IIwGameXomlResource and IIwGameAnimTarget interfaces to allow instantiation of your custom class from XOML and to allow your class to be a target for animation time lines.

Firstly lets take a look at XOML enabling your custom scene class. To get IwGame to recognise your class whilst parsing XOML files you need to do a few things:

Derive your class from IiwGameXomlResource and implement the LoadFromXoml method
Create a class creator that creates an instance of your class then add this to the XOML engine

Lets start by taking a look at step 1.

Because we have derived our class from CIwGameScene we already have the support for step 1. However we would like to insert our own custom attribute tags so we need to make a few changes.

Lets take a look at our new class with those changes:

class MyGameScene : public CIwGameScene
{
public:
	// Properties
protected:
	float		Gravity;
public:
	void		setGravity(float gravity)	{ Gravity = gravity; }
	float		getGravity() const		{ return Gravity; }
	// Properties End
public:
	MyGameScene() : CIwGameScene(), Gravity(10.0f) {}
	virtual ~MyGameScene();

	virtual int		Init(int max_collidables = 128, int max_layers = 10)
	{
		CIwGameScene::Init(max_collidables, max_layers);
	}
	virtual void	Update(float dt)
	{
		CIwGameScene::Update(dt);
	}
	virtual void	Draw()
	{
		CIwGameScene::Draw();
	}

	// Implementation of IIwGameXomlResource interface
	bool	LoadFromXoml(IIwGameXomlResource* parent, bool load_children, CIwGameXmlNode* node)
	{
		if (!CIwGameScene::LoadFromXoml(parent, load_children, node))
			return false;

		// Add our own custom attribute parsing
		for (CIwGameXmlNode::_AttribIterator it = node->attribs_begin(); it != node->attribs_end(); it++)
		{
			unsigned int name_hash = (*it)->getName().getHash();

			if (name_hash == CIwGameString::CalculateHash("Gravity"))
			{
				setGravity((*it)->GetValueAsFloat());
			}
		}

		return true;
	}
};

Our new class now basically supports a Gravity attribute that we will eventually be able to set in XOML using something like:

    <MyGameScene Name="GameScene" Gravity="9.8">
    </MyGameScene>

However, before we can do that we need to let the XOML system know about our new type of class (MyGameScene), so it can be instantiated when the XOM parser comes across it. To do this we need to create a creator:

class MyGameSceneCreator : public IIwGameXomlClassCreator
{
public:
	MyGameSceneCreator()
	{
		setClassName("MyGameScene");
	}
	IIwGameXomlResource* CreateInstance(IIwGameXomlResource* parent) { return new MyGameScene(); }
};

The creator basically defines the tag name “MyGameScene” and returns an instance of the MyGameScene class when CreateInstance() is called.

To get the XOML system to recognise our creator we need to add it to the XOML parsing system using:

	// Add custom MyGameScene to XOML system
	IW_GAME_XOML->addClass(new MyGameSceneCreator());

Now XOML integration is out of the way, lets take a quick look at enabling our class as an animation target.

To enable a class as an animation target we derive it from IIwGameAnimTarget and implement the UpdateFromAnimation() method. Luckily we derived our MyGameScene class from the CIwGameScene class which already provides this functionality. Lets take a quick look at how we extend the animation update method to account for animating our gravity variable.

	bool	UpdateFromAnimation(CIwGameAnimInstance *animation)
	{
		if (CIwGameScene::UpdateFromAnimation(animation))
			return true;

		// Add our own custom animating property
		unsigned int element_name = animation->getTargetPropertyHash();

		if (element_name == CIwGameString::CalculateHash("Gravity"))
		{
			CIwGameAnimFrameFloat* frame = (CIwGameAnimFrameFloat*)animation->getCurrentData();
			setGravity(frame->data);
			return true;
		}

		return false;
	}

We added the above code to our MyGameScene class definition. We begin by calling the base UpdateFromAnimation() method so we can keep the existing animation properties of the scene. We then add our own custom check for the Gravity variable. If the animation property matches Gravity then we set the gravity to the provided interpolated value.

 

Creating Custom Actions

XOML’s event / action system is very powerful, allowing you to tie certain events to collections of actions without writing any code. Lets take a quick look at an example:

        <!-- Create back button -->
        <InertActor Name="Back" Position="-120, 10" Size="200, 90" SrcRect="600, 333, 200, 90" Image="sprites2" OnTapped="BackAction" OnBeginTouch="BackBeginTouch" OnEndTouch="BackEndTouch">
            <Actions Name="BackAction">
                <Action Method="SetTimeline" Param1="fly_out_back" Param2="PauseMenu" />
            </Actions>
            <Actions Name="BackBeginTouch">
                <Action Method="SetTimeline" Param1="buttonin_anim1" />
                <Action Method="PlaySound" Param1="ui_tap" />
            </Actions>
            <Actions Name="BackEndTouch">
                <Action Method="SetTimeline" Param1="buttonout_anim1" />
            </Actions>
        </InertActor>

In the above XOML our actor handles the events OnEndTouch, OnTapped and OnBeginTouch. Each of these events calls an actions list when the event occurs on that object. Below the actor definition we have three action lists defined that correspond to the actions that are specified in our events:

            <Actions Name="BackAction">
                <Action Method="SetTimeline" Param1="fly_out_back" Param2="PauseMenu" />
            </Actions>

            <Actions Name="BackBeginTouch">
                <Action Method="SetTimeline" Param1="buttonin_anim1" />
                <Action Method="PlaySound" Param1="ui_tap" />
            </Actions>

            <Actions Name="BackEndTouch">
                <Action Method="SetTimeline" Param1="buttonout_anim1" />
            </Actions>

The first action collection “BackAction” is called when a user performs a tap action on “Back” actor. This collection contains a single action which contains a method called “SetTimeline” and two parameters “fly_out_back” and “PauseMenu”.

This action actually changes the time line of the PauseMenu object to the fly_out_back animation time line (defined elsewhere in XOML). However, how does the system know how to do this and more importantly how do we define our own actions that we can call from XOML events?

Well firstly it depends on where the action is being called as certain object types have their own list of actions. In addition, there is also a global list of actions carried by the global resource manager.

Here we will take a look at adding our own custom action to the global resource manager.

The first thing we need to do is derive a class from IIwGameXomlAction and implement the Execute() method like this:

class CustomXomlAction_Global : public IIwGameXomlAction
{
public:
	CustomXomlAction_Global() {}
	{
		// Set out action name
		setActionName("customaction1");
	}
	void Execute(IIwGameXomlResource* source, CIwGameAction* action)
	{
		CIwGame* game = NULL;
		CIwGameScene* scene = NULL;
		CIwGameActor* actor = NULL;

		// Determine the scene, game and possibly actor that called the action
		if (source->getClassTypeHash() == CIwGameXomlNames::Scene_Hash)
		{
			scene = (CIwGameScene*)source;
			game = scene->getParent();
		}
		else
		if (source->getClassTypeHash() == CIwGameXomlNames::Actor_Hash)
		{
			actor = (CIwGameActor*)source;
			scene = actor->getScene();
			game = scene->getParent();
		}

		// TODO: Do something with the action here (Param1 and Param2 contain parameters

	}
};

Now that we have an action object we need to tell the XOML system that its available using:

IW_GAME_XOML->addAction(new CustomXomlAction_Global());

We would place this call somewhere in our main boot up so it gets called before any XOML parsing that contains this action begins.

Now lets take a look at a bit of XOML that shows the use of our new action:

    <Actions Name="BackAction">
        <Action Method="CustomeAction1" Param1="Hello World!" Param2="Im an action!" />
    </Actions>

 

Augmenting Scenes

A scene once declared in XOML can later be updated / augmented with additional XOML code elsewhere. For example, lets say that you declare some common scene that contai9ns a basic background and some other elements that are common across a number of screens. You can later load the scene and then augment it by declaring the scene again then supplying the additional elements inside the newly declared scene:

    <Scene Name="CommonScene" ............ >
        <Original_Element1 />
        <Original_Element2 />
        <Original_Element3 />
    </Scene>

Now declare a 2nd scene with the same name:

    <Scene Name="CommonScene">
        <Extra_Element1 />
        <Extra_Element2 />
        <Extra_Element3 />
    </Scene>

In memory the scene now looks like this:

    <Scene Name="CommonScene" ............ >
        <Original_Element1 />
        <Original_Element2 />
        <Original_Element3 />
        <Extra_Element1 />
        <Extra_Element2 />
        <Extra_Element3 />
    </Scene>

IwGame Engine Tutorial – Basic introduction

What is the IwGame Engine?

Welcome to the home of IwGame, the free open source cross platform mobile 2D game engine for smart phones, tablets and emerging technologies developed by Pocketeers Limited. IwGame is designed and written on top of the Marmalade SDK the ultimate  cross platform SDK for smart phones tablets and emerging technologies. In order to use the IwGame game engine you will need to download and install the Marmalade SDK.
IwGame supports the following platforms:

  • iPhone, iPod and iPad
  • Android phones and tablets (1.5+ including Ice Cream Sandwich)
  • Samsung Bada 1.0 / 2.0
  • Blackberry BBX (Playbook)
  • Symbian
  • WebOS
  • Windows Mobile
  • Mobile Linux
  • LG-TV
  • Windows Desktop
  • Mac OSX

IwGame is free to use at your own discretion and the code base is open source . You do not need to submit bug fixes or improvements, but we would be very happy if you did.

You can find out more and download the IwGame Engine from the IwGame Engine home

The IwGame engine has been in development since November 2011 and has had 14 releases to date

The original IwGame concept set out to achieve the following:

  • Create a game layer on top of the Marmalade SDK allowing developers to get game code up and running incredibly quickly without having to learn the ins and outs of the Marmalade SDK
  • Create a solid feature rich gaming SDK that does not rely on the underlying platform
  • Enable developers and designers to create content without writing any code

In around 6 months time we achieved all three of the above aims and more:

  • IwGame now supports a wealth of features that enable developers to create 2D games quickly and efficiently
  • IwGame boasts a vast array of features, including all the basic game development features such as scenes, sprites, actors, animation, audio, input, mark-up language. IwGame also supports advanced features such as HTTP communications, unified Ads API, Facebook API and unified in-app purchasing.
  • We wanted to put the IwGame engine into the hands of designers as well as programmers. We also wanted a way to separate game and UI layout design from code. We accomplished both of these aims by introducing the XOML mark-up language into the IwGame engine, allowing programmers and designers to not only design the layout and general interaction of games and apps but also define animations, resources, variables, conditions, events and actions. We also made the whole system extensible allowing developers to extend the language to fit whatever needs they may have.

Platform Independence

The IwGame engine strives to provide platform independence, so the developer has to deal less with the differences that separate platform from platform and spend more time dealing with creating a game. Because IwGame is built atop of the Marmalade SDK, this platform independence is mostly catered for, although there are a number of areas where the Marmalade SDK falls short:

  • Screen size independence – IwGame uses a virtual canvas system, allowing each scene to specify a working resolution that the developer can rely on not changing from device to device. The scene will scale all its content to fit the target display resolution with no extra effort on the developers part
  • Frame rate independence – Regardless of the target platform speed, all transient variables within a game are scaled by time to ensure that animations and movement etc do not suffere slow down or speed up on different platforms
  • In-app purchasing – IwGame allows the developer to set-up and utilise in-app purchasing in a platform independent manner
  • Unified Ads – IwGame provides a mediated unified Ad API that allows the developer to serve ads to their apps regardless of platform and from a number of different ad providers

Scene / Actor Concept

The most important concept behind the IwGame engine is the Scene / Actor system. IwGame uses scenes to hold collections of Actors. A game can be made up of a single scene or more usually a collection of scenes. For example, your main game can be built up of the following scenes:

  • Game world background scene
  • Game world foreground scene
  • In-game HUD scene
  • In-game menu scene
  • End of level dialog

Actors represent the game objects that live and work in your gaming world. An actor has logical, visual and physical components associated with them. The logical component is the game logic that gives the actor its purpose in the game world, the visual component is how the actor will appear on screen, usually some kind of sprite and finally the physical component tells the system how the actor will behave under physics (this component is optional). Actors can be defined hierarchically, allowing the developer to create complex objects that consist of multiple actors that are all connected with each actor having its own independent logic and visual but sharing the parents visual transform. Actors also support functionality components that can be stacked allowing the creation of vastly complex game objects from many smaller independent modules.

Scenes can be hidden, moved and animated, all actors contained within a scene will obey the scenes visibility, colour and transforms.

Creating a game is a case of creating scenes that represent the different components of a game then creating and adding actors that define the games behaviour.

Resource Management

IwGame supports resource management on a local per scene and a global basis. The resource management system will take care of cleaning up resources at the correct time. For example, all resources that are local to a scene will be destroyed when the scene has been destroyed. Global resources will remain present throughout the duration of the game, unless removed manually. The resource manager handles many different types of resources including images, animations, timelines, shapes, materials, fonts etc..

Animation

IwGame supports a very powerful key frame based animation system supports the following features:

  • Time based frame and interpolated named animations
  • Delayed and looped animations
  • Support for boolean, float, vectors (2d, 3d and 4d), rect (for image frames), string and custom frame data types
  • Resource manager that tracks and manages sets of animations (scene local and global)
  • Animation data re-use using animation instances
  • Animation time lines to support multiple simultaneous animations that can target object specific properties such as the colour of a scene or the position of an actor
  • Time line manager that tracks and manages sets of animation time lines
  • Callback notifications for animation instance started, stopped and looped events
  • Animations and animation time lines can be defined and attached to actors and scenes using XOML
  • Support for OnStart, OnEnd and OnRepeat events in code and in XOML
  • Linear, quadratic, quartic and cubic in and out easing

Scenes and actors can contain an animation timeline that will be applied to the scene or actors properties. For example, you may set up a timeline that contains animations that target position, scale, rotation and colour then attach that to a group of actors. The group of actors will all take on the animation properties of the timeline.

XOML Mark-up Language

By far the best feature of the IwGame engine is its built-in XML mark-up language (can be thought of as HTML for game development). XOML enables designers and developers to both create interactive content. XOML is a little more than a simple mark-up language as it allows the definition of variables, conditions, actions and events. Its entirely possible to create a complete interactive presentation, app or game using XOML. XOML also contains features to help create styled content using styles and templates.

Lets take a look at a typical piece of XOML:

<!-- Create a scene to contain our logo actors -->
<Scene Name="IntroScene" Style="GenericSceneStyle" Camera="IntroCam" Timeline="camera_zoom" Current="true" OnGainedFocus="GainedFocus" Batch="false">

    <Actions Name="GainedFocus">
        <Action Method="SetBGColour" Param1="64, 128, 200, 255" />
    </Actions>

    <!-- End of logo actions -->
    <Actions Name="NextScene">
        <Action Method="LoadXOML" Param1="Menu.xml" />
        <Action Method="KillScene" Param1="IntroScene" />
    </Actions>

    <!-- Create a camera-->
    <Camera Name="IntroCam" Position="0, 0" Angle="0" Scale="1.0" />

    <!-- Create delayed fade out animation -->
    <Animation Name="fade_out" Type="vec4" Duration="5" >
        <Frame Value="255, 255, 255, 255" Time="3" />
        <Frame Value="64, 128, 200, 0"  Time="5"/>
    </Animation>

    <!-- Create a zoom animation for the camera -->
    <Animation Name="camera_zoom" Type="float" Duration="5" >
        <Frame Value="2"  Time="0.0" Easing="quadout" />
        <Frame Value="0.75" Time="2.0" />
    </Animation>
    <Timeline Name="camera_zoom" AutoPlay="true">
        <Animation Anim="camera_zoom" Target="Scale" Repeat="1" StartAtTime="0" OnEnd="NextScene" />
        <Animation Anim="fade_out" Target="Colour" Repeat="1" StartAtTime="0" />
    </Timeline>

    <!-- Define logo image -->
    <Image Name="logo" Location="logo.png" Preload="true" />

    <!-- Create animations for the logo pieces -->
    <Animation Name="x_axis" Type="vec2" Duration="4" >
        <Frame Value="500, 0"  Time="0.0" Easing="quadout" />
        <Frame Value="0, 0" Time="2.0" />
    </Animation>
    <Animation Name="x_axis2" Type="vec2" Duration="4" >
        <Frame Value="600, 0"  Time="0.0" Easing="quadout" />
        <Frame Value="0, 0" Time="2.25" />
    </Animation>
    <Animation Name="scale_axis" Type="float" Duration="4" >
        <Frame Value="1"  Time="0.0" Easing="quadout" />
        <Frame Value="1.25" Time="2.0" />
    </Animation>
    <Animation Name="spin_axis" Type="float" Duration="4" >
        <Frame Value="180"  Time="0.0" Easing="quadin" />
        <Frame Value="90"  Time="1.0" Easing="quadout" />
        <Frame Value="0" Time="2.0" />
    </Animation>
    <Timeline Name="orbit1" AutoPlay="true">
        <Animation Anim="x_axis" Target="Position" Repeat="1" />
        <Animation Anim="scale_axis" Target="ScaleY" Repeat="1" />
    </Timeline>
    <Timeline Name="orbit2" AutoPlay="true">
        <Animation Anim="x_axis" Target="Position" Repeat="1" />
        <Animation Anim="scale_axis" Target="ScaleY" Repeat="1" />
        <Animation Anim="spin_axis" Target="Angle" Repeat="1" />
    </Timeline>
    <Timeline Name="orbit3" AutoPlay="true">
        <Animation Anim="x_axis2" Target="Position" Repeat="1" />
        <Animation Anim="scale_axis" Target="ScaleY" Repeat="1" />
    </Timeline>

    <!-- Define the logo actors -->
    <InertActor Name="logo" Position="0, 0" Size="1024, 300" Angle="0" SrcRect="0, 0, 1024, 300" Image="logo" Timeline="orbit1" />
    <InertActor Name="logo" Position="0, 0" Size="1024, 300" Angle="0" SrcRect="0, 0, 1024, 300" Image="logo" Timeline="orbit2" Colour="255, 255, 255, 128" />
    <InertActor Name="logo" Position="0, 0" Size="1024, 300" Angle="0" SrcRect="0, 0, 1024, 300" Image="logo" Timeline="orbit3" Colour="255, 255, 255, 64" />

    <ActorText Name="Text1" Position="0, -260" Rect="-400, -50, 800, 100" Angle="0" Font="trebuchet_12" AngularVelocity="0" Text="Developed By Pocketeers Limited" Colour="255, 255, 255, 255" Scale="1.5" />
    <ActorText Name="Text2" Position="0, 250" Rect="-200, -50, 400, 100" Angle="0" Font="trebuchet_12" AngularVelocity="0" Text="www.drmop.com" Colour="255, 255, 255, 255" Italic="true" Scale="1.5" />

</Scene>

This XOML defines the complete animation sequence that can be seen in the Puzzle Friends / cOnnecticOns game. Three logos spin onto the screen and 2 lines of text zoom into place.

XOML also now supports data binding, which allows developers to bind variables to properties of actors or scenes. Any changes to bound variables will be reflected in object that they are bound to.

Lastly, XOML is extensible allowing the developer to extend the language to support their own needs.

Input and Audio

IwGame provides access to the various input devices on the device including:

  • Single and multi-touch input
  • Button and key states (including support for Android back and menu)
  • On screen keyboard input
  • Accelerometer
  • Compass

Actors handle events that deal directly with touch events, including OnTapped, OnBeginTouch and EndTouch. These events can be handled directly in code or actions can be attached in XOML.

Scenes also handle menu and back button presses using the OnBackKey and OnMenuKey events

IwGame provides an API that provides access to the devices audio playback systems

  • Compressed WAV software sound effect playback
  • MP3 playback via the devices media engine
  • Support for multiple simultaneous sound effects
  • Control over volume and pitch

Music and sound effects can be played directly in XOML via actions, allowing the developer to tie music and sound effect playback to specific events declaratively.

Physics

The Box2D physics engine is integrated into the IwGame engine allowing physics to be attached to any actor. IwGame supports shapes, joints (distance, revolute, prismatic, pulley and wheel) and physics materials that can be defined and attached to actors, putting them under control of the Box2D physics system. Actors will also receive collision events from the Box2D collision system, allowing the actor to respond to collisions.

Gravity and world scale can be set on a per scene basis.

Facebook API

IwGame currently supports basic Facebook interaction providing log-in and allowing the developer to post information to the users wall stream.

Unified In-App Purchasing

IwGame provides unified in-app purchasing for both iOS and Android. A single easy to set-up API can be used to track products and purchase them regardless of platform.

Unified Ads API

IwGame provides a platform independent ad collection, display and processing system called IwGameAds. The whole system is automated and once set-up will collect ads from a variety of ad providers using ad mediation and display them using a slick animation system. The system also handles ad clicks directing the user to the target URL.

The following ad providers are currently supported:

  • Inner-active
  • AdFonic
  • Vserv – Also provides support for InMobi, BuzzCity, JumpTap, ZestAdz / Komli Mobile and Inner-active
  • Mojiva
  • Millennial Media – Also provides support for AdMob, Amobee, JumpTap and Mojiva

So why use IwGame Engine?

IwGame was designed by game developers for game developers. IwGame is built on many years of game development experience, using tried and tested game development techniques. IwGame provides a mass of out-of-the-box features that would take many months to develop and test from scratch. Above all else, using XOML enables the developer to create games insanely quickly (our recent game cOnnecticOns took just 3 days to create from scratch). Lastly, using separation of coding and game layout / design, XOML encourages easy and smart game development, where designers can take care of the design / layouts and programmers can take of the gaming logic.

IwGame Engine Tutorial – Installation

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.

Firstly, download the latest version of the IwGame SDK from http://www.drmop.com/index.php/iwgame-engine/

If you haven’t already installed the Marmalade SDK then grab a copy from http://www.madewithmarmalade.com

IwGame is currently provided as a Marmalade library project and test bed project giving examples of how it should be used.

The IwGame zip archive that you downloaded contains the following important folders:

IwGame
	Docs – Contains documentation
	h – Contains IwGame engine headers
	Libs – Contains IwGame dependencies such as zlib and libpng
	Source – The full source to IwGame
	Examples – Contains example apps
	TestBed – A test bed app that shows IwGame usage and integration

To open up the test bed app go to IwGame\TestBed and open the IwGame_TestBed.mkb Marmalade project file, this will open up the test bed project in Visual Studio / XCode.

If you take a look at the solution explorer you will see a IwGame filter / folder. If you drill down you will be able to see the source files and the Marmalade project file that make up the engine.

Now lets take a look at the IwGame_TestBed.mkb project file to find out how to integrate IwGame into your project.

From the MKB we can see that we only need to add two commands to integrate IwGame into our project:

options
{
	module_path="../IwGame"
}

subprojects
{
	IwGame
}

These commands will tell Marmalade where to locate the project.

Once you have updated your project MKB with the above changes, run your MKB file again to regenerate your project. You can of course place the IwGame engine anywhere you like, just remember to change the module path.

Note that if you already have something in module_path then you can quite easily tag IwGame into the path like this:

module_path=”module_path=”$MARMALADE_ROOT/modules/third_party;../IwGame”

IwGame Engine v0.32 Released – Data Bindings and Conditional Variables

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. You can find out more and download the SDK from our IwGame Engine page.

A lot of bugs (mostly minor) have been reported since the forum went live so we decided to release 0.32 now and push in-app purchasing to another future release (hopefully 0.33).

We finally got cOnnecticOns approved for BlackBerry PlayBook, its now on sale on BlackBerry App World. Version 2.0 also went live today for iOS on iTunes and for Android on the Android Market / Amazon. Not happy with Samsung however, the game has been knocked back on Bada 1 and 2 numerous times for minor issues that should be footnotes!

Ok, on with the changes, here is the list of changes for 0.32:

  • New XOML RemoveAllScenes action added – This will remove all scenes excluding the scene that is provided
  • Data bindings now added to XOML – You can now create a bindings list which pair properties up to variables. Changes made to those variables will bautomaticaly be applied to the object that they are bound to.
  • Actors and Scenes now support data bindings
  • Conditions variables now added to XOML – A condition variable allows you to string together some basic logic based on the value of other variables, these can then be attached to Actions to create conditional actions
  • Actions and Action groups now support conditional variables
  • IIwGameXomlResource now have parents
  • CIwGameString now supports encoding / decoding to / from hex
  • CIwGameSprite now has a RebuildTransformNow() method
  • CIwGameSprite now has an update method where the trabnsform will be rebuilt. This ensures that all transforms have been buuilt before rendering
  • CIwGameScene now has a PreDestroy() method which gets called when a request to destroy a scene is received
  • CIwGameActorImage now has a SetSrcRect() method
  • Added sound and music volume control to CIwGameAudio
  • CIwGameSound now accepts a paramater that allows you to specify volume, frequency and panning when playing a sound effect
  • BUG FIX: PNG lib fix for Visual Studio 2008
  • BUG FIX: Mac compile issues
  • BUG FIX: CIwGameSprite setScale() fixed
  • BUG FIX: Precision issues graphical glitches at lower resolutions
  • BUG FIX: Actor collilsion size now read corrctly from XOML
  • BUG FIX: CIwGameActorText text aligment now applie correctly
  • BUG FIX: When an actor or scene has a timeline attached, the first frame was not benig set before displaying the object
  • BUG FIX: CIwGameTextSprite hit test fixed
  • BUG FIX: CIwGameAds – VServ local now set correctly
  • BUG FIX: CIwGameScene – Initial camera transform is now built correctly
  • BUG FIX: CIwGameString::URLEncode now calculates correct buffer size
  • BUG FIX: CIwGameString::URLDecode now checks for the correct character
  • BUG FIX: Infinite loop removed from CIwGameXmlNode::GetAttribute()

The most exciting changes for us at least are the XOML data bindings and conditional variables / actions. They enable the creation of some very complex and ultra re-usable stuff. We are planning on starting a library of useful generic classes and XOML layout files that can be used as plug-ins to help create games and apps even quicker. Our first experiment with this is to create a set of XOML files and scene classes that handle ScoreLoop integration. If this is successful then we will release this as a plug-in library that you can simply drop into your own games and style with your own styles. Will blog about this in the near future.

XOML Data Binding

Data binding is the ability to map properties of objects to XOML variables. Changes to those variables will be immediately reflected in all properties of all objects that are bound. Lets take a look at a quick example:

We declare a global variable that holds a profile name:

    <Variable Name="ProfileName" Type="string" Value="None" />

Next we create a bindings set that contains a single property called “Text” that is bound to the “ProfileName” variable that we just defined:

    <Bindings Name="SC_ProfileBindings">
        <Binding Property="Text" Variable="ProfileName" />
    </Bindings>

We now attach our bindings list “SC_ProfileBindings” to a text actor:

    <ActorText Name="NameLabel" ......... Bindings="SC_ProfileBindings" />

Now if we change the ProfileName variable in XOML or in code, our NameLabel actor’s Text property will be automatically updated.

We opted to use independent binding lists (as opposed to in-line bindings as used in XAML / MXML) because they are re-usable, the same bindings list can be used across many objects. They are also much more readable as bindings are not intermingled with normal property values.

Note that if you also have a timeline animation that updates the same property then the timeline is given priority and the timeline will write over the binding value.

Binding lists can be attached to scenes and actors. The following properties can be bound:

CiwGameScene:

  • Position
  • Angle
  • Scale
  • Colour
  • Clipping
  • Timeline
  • Binding
  • Camera
  • Type
  • Active
  • Visible
  • AllowSuspend
  • AllowResume

CIwGameActor:

  • Position
  • Depth
  • Origin
  • Angle
  • Scale
  • Colour
  • Velocity
  • Angular Velocity
  • Timeline
  • Binding
  • Type
  • Active
  • Visible
  • Collidable
  • HitTest

CIwGameActorImage (in addition to those present in CIwGameActor):

  • Size
  • SrcRect
  • Image

CiwGameActorText (in addition to those present in CIwGameActor):

  • Text
  • Rect

Binding sets that are defined outside a scene will be assigned to the global resource manager, whilst bindings defined inside a scene will be assigned to the scenes resource manager.

Data bindings offer a way to create complex scenes and user interfaces without having to manually update the properties of the individual elements

Conditional Variables and Actions

XOML supports a new variable type called a condition variable. A condition variable is a variable that contains an expression that is defined by a list of variables, operators and values. Lets take a look at a quick example:

    <!--Create a bog standard int variable that contains the current level /-->
    <Variable Name="current_level" Type="int" Value="1" />

    <!--Create a condition variable that tests the current level is between 1 and 9 /-->
    <Variable Name="low_level_extras" Type="condition" Value="current_level GTE 1 AND current_level LT 10" />

We create an integer variable called current_level and assign it the value of 1. Next we create a new variable called “low_level_extras” that is of type “condition”. The most interesting part of our condition variables is the value, which is:

     current_level GTE 1 AND current_level LT 10

Unlike normal variables which contain constant values of some kind, condition variables contain dynamic expressions that are evaluated at run-time. The end result of a condition variable is always either true or false. The above expression in terms of C code would read like this:

     bool low_level_extras = (current_level >= 1 && current_level < 10);

Condition variables aren’t much use on their own and are usually used in conjunction with actions to provide conditional action functionality whereby an action or actions group will only be executed if a certain set of conditions are met. Lets take a look at a quick example:

    <Actions Name="NextScene">
       <Action Method="LoadXOML" Param1="MainScene.xml" />
       <Action Method="LoadXOML" Param1="LowLevelExtras.xml" Condition="low_level_extras" />
       <Action Method="KillScene" />
    </Actions>

The above actions group is called when we click a button to start a game. The actions group starts by loading the MainScene XOML file which creates the main game scene. Next the condition variable “low_level_extras” is checked to see if It is true, if current_level is between 1 and 9 then the variable will return true and the additional XOML file “LowLevelExtras” will be loaded. If however the current_level variable is less than 1 or greater than 9  then the additional XOML file will not be loaded.

This is just a very simple example showing how conditional actions can be used to re-use and extend XOML code.

And that’s it for this update. Thank you to all those who have downloaded cOnnecticOns on one platform or another and massive thanks to those who left us a review, you are awesome.

XOML Conditions – New IwGame Feature Coming Soon

Thought I would put a quick update outlining what’s happening with the IwGame Engine. In-app purchasing has been started, so hopefully that will make it into 0.32. We are looking at a way of combining iOS and Android in-app purchasing into the same system (CIwGameMarket). Will provide more details when the system is up and running.

One cool change that’s just been finished is XOML Conditions. XOML conditions are variables that evaluate to either true or false and their value is an expression of other variables. Lets take a quick look at an example:

<!--Create a bog standard int variable that contains the current level --/>
<Variable Name="current_level" Type="int" Value="1" />
<!--Create a condition variable that tests that the current level is between 1 and 9 --/>
<Variable Name="low_level_extras" Type="condition" Value="current_level GTE 1 AND current_level LT 10" />

The above condition variables value is basically an if statement which translates to:

if (current_level >= 1 && current_level < 10)

But what use is that to anyone you may ask?

Lets consider that we have an actions group such as that show below:

<!-- Next scene action -->
<Actions Name="NextScene">
    <Action Method="LoadXOML" Param1="MainScene.xml" />
    <Action Method="LoadXOML" Param1="LowLevelExtras.xml" Condition="low_level_extras" />
    <Action Method="KillScene" />
</Actions>

The above actions set would usually just load the MainScene scene and run it then load the LowLevelExtras scene and run that. However using the condition variable LowLevelScene will only be loaded and ran if the condition variable low_level_extras equates to true, allowing us to only load the extra stuff if the level is between 1  and 9. The condition variable is evaluated at run-time so you can change variables and affect the result, allowing a very dynamic system to be put together.

It may seem like a small change but it adds the ability to add mark-up side logic, which IMO is huge. My mind is whirring away with ideas for its use at the moment!

Conditions can be attached to individual actions as well as actions groups

XOML Bindings

XOML bindings are currently being implemented (nearly finished). This allows you to bind properties of objects such as actors and scenes to XOML variables using a bindings  list. When you change the value of the XOML variable it also changes the value of the property that it is bound to. This system will be particularly useful for hooking up UI’s and HUD’s to in-game data.

 

 

 

 

IwGame Engine v0.31 Released – Facebook and Full cOnnecticOns Source Available

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. You can find out more and download the SDK from our IwGame Engine page.

Its been a tough week, my Apple Mac blew a gasket and refused to boot. Didn’t know this until I had spent 4 hours trying to make the Mac boot from Snow Leopard, but you cannot boot a Mac Mini from any version of the OS other than the original version that came with the Mac! Arrrgggghhhhh, insanity! In the end I turned my office and house upside down to find the original Mac disk.

Finally got cOnnecticOns cleaned up and submitted to the app stores. I also added 10 more levels and a game editor that allows players to create up to 20 of their own levels on-device and play them. I plan to allow sharing of these custom levels in a future version. We also added Facebook posting to IwGame and therefore has now been added to cOnnecticOns. You can find our more info about the game at http://appliter.com/apps/connecticons/connecticons.aspx

Ok, onto the update. IwGame v0.31 is kind of a special release because it contains the FULL source and assets of the game that you will see on Android Market and very soon Blackberry App World, Apple iTunes and SamsungApps for Bada.

Here’s the full list of changes for 0.31:

IwGame 0.31 Changes:

  • cOnnecticOns full commercial game with source and assets provided as an example of engine usage
  • CIwGameFacebook added – Currently provides login and wall posting access
  • New AddVariable action added which allows you to add a positive or negative value to a XOML variable with limits
  • New EnterValue action added that brings up the devices keyboard allowing the user to enter a value into a XOML variable
  • New UpdateText action added will update a text actor with the value of a variable
  • New Exit action added that allows the user to exit the game
  • 3rd paramater added to XOML actions
  • DoSleep added to CIwGameBox2dWorld to enable / disable object sleeping, also added to scene XOM
  • IIwGameXomlResource now has an actual type, allowing type checking for exact object types
  • OnKeyBack and OnKeyMenu events added to scene and XOML. These fire when back and menu keys are pressed
  • BUG FIX: CIwGameSprite position and origin now 32 bit vectors, which helps prevent positions overflowing
  • BUG FIX: When a scene is destroyed and it has touch focus it was causing a crash
  • BUG FIX: If a scene becomes inactive or invisible it now loses touch focus
  • BUG FIX: Velocity / angular velocity now applied when actors have no physics attached
  • BUG FIX: JPEG image data is now correctly converted from BGR to RGB
  • BUG FIX: CIwGameString, find index now properly reset

As well as the release of the full source for cOnnecticOns, we also snook a few extra col bits and bobs in there.

New CIwGameFacebook Class

The main purpose of this class is to allow the user to log into facebook and interact with it. Right know, only logging in and wall posting functionality is provided using the following method:

bool PostWall(const char* message, const char* link_uri, const char* image_uri, const char* name, const char* description);
  • message – Message to display to the users wall visitors
  • link_uri – URL that the user will visit when clicking on the wall post link
  • image_uri – URL of an image that you would like to be displayed along with the post
  • name – The title of the post
  • description – Description of the post (displayed in weaker font beneath title)

A Facebook wall post will look something like this:

Post to Facebook example
POst to Facebook Example

New XOML Actions

It is now possible to add a value onto an existing XOML variable using the new AddVariable action. You can also update a text actor with the value of a variable in XOML. Here’s an example showing how the editor in cOnnecticOns uses both actions together to create an up / down UI element that the player can use to change the number of cOnnecticOns available in the level:

        <!-- Create change connecticons buttons -->
        <InertActor Name="ConnectButton2" Position="0, -200" Size="81, 84" SrcRect="555, 482, 81, 84" Image="sprites1">
            <ActorText Name="ConnectButton" Depth="0" Font="trebuchet_12" Rect="-100, -50, 200, 100" Colour="0, 0, 0, 255" Text="2" />
            <InertActor Name="DownButton" Position="-60, 0" Angle="-90" Size="48, 51" SrcRect="868, 299, 48, 51" Image="sprites1" Depth="0" OnBeginTouch="DownBeginTouch" OnEndTouch="DownEndTouch" OnTapped="DownTapped">
                <Actions Name="DownBeginTouch">
                    <Action Method="SetTimeline" Param1="buttonin4_anim" />
                    <Action Method="PlaySound" Param1="ui_tap" />
                </Actions>
                <Actions Name="DownEndTouch">
                    <Action Method="SetTimeline" Param1="buttonout4_anim" />
                </Actions>
                <Actions Name="DownTapped">
                    <Action Method="AddVar" Param1="EditorConnecticons" Param2="-1" Param3="0" />
                    <Action Method="UpdateText" Param1="ConnectButton" Param2="EditorConnecticons" />
                </Actions>
            </InertActor>
            <InertActor Name="UpButton" Position="60, 0" Angle="90" Size="48, 51" SrcRect="868, 299, 48, 51" Image="sprites1" Depth="0" OnBeginTouch="UpBeginTouch" OnEndTouch="UpEndTouch" OnTapped="UpTapped">
                <Actions Name="UpBeginTouch">
                    <Action Method="SetTimeline" Param1="buttonin5_anim" />
                    <Action Method="PlaySound" Param1="ui_tap" />
                </Actions>
                <Actions Name="UpEndTouch">
                    <Action Method="SetTimeline" Param1="buttonout5_anim" />
                </Actions>
                <Actions Name="UpTapped">
                    <Action Method="AddVar" Param1="EditorConnecticons" Param2="1" Param3="10" />
                    <Action Method="UpdateText" Param1="ConnectButton" Param2="EditorConnecticons" />
                </Actions>
            </InertActor>
        </InertActor>

The mark-up marked in red show the new AddVar and UpdateText XOML actions.

Basically when the user taps the DownButton actor the OnTapped event fires which calls the DownBeginTouch actions list. This actions list contains two actions:

AddVar – This adds -1 onto the EditorConnecticons variable and limits it to 0, so it does not go below 0.
UpdateText – The next action copies the value of the EditorConnecticons variable into the ConnectButton text actor, which updates the number of connecticons on screen.

Support for Android Back and Menu Buttons in XOML

It is now possible to attach actions in XOML to the menu and back button events in a scene by handling the OnKeyBack and OnKeyMenu events. Note that only the current scene will handle button events.

Text Input via XOML

Using the new EnterValue XOML tag you can bring up the device keyboard and allow the user to input some text into a XOML variable.

cOnnecticOns

As previously mentioned the full source to cOnnecticOns has been provided to enable developers to see a real working commercial game utilising IwGame. The first thing you will notice when looking at the code base is just how little code is actually there. This is because much of the mundane functionality such as creating layouts, handling events, creating animations, scenes etc.. are all handled by XOML. Please note that the supplied XOML is not optimised in way shape or form, in fact I have done many things long hand so as not to make the scripts convoluted and difficult to understand. When creating your own XOML you should probably focus more on re-use with templates, styles and global actions / animations etc..

Here is a brief overview of the provided XOML scripts:

  • Actors – This file contains physics materials, shapes and game object templates
  • Common – Contains common styles, animations and actions that are used across many scenes
  • ConfirmDialog – This is the dialog box scene for the rest scores action, it is displayed to the user when they attempt to reset their records
  • EditLevelSelect – Level selection screen that allows the user to select a custom level to edit
  • Editor – The level editor scenes
  • GameComplete – Shown to the player when they complete all zones and all rounds
  • Help – The basic help dialog that is accessible from the main menu
  • HUD – The in-game HUD that displays the scores and game buttons
  • Intro – The IwGame intro that is displayed at game boot
  • LevelCleared – The end of level score dialog that is displayed when the user completed or fails a round
  • LevelSelect – Level selection screen that allows the user to select a level to play
  • LevelSelect2 – Level selection screen that allows the user to play a custom level to play
  • Menu – The main front-end menu scenes
  • PauseMenu – The in-game pause men scene
  • ZoneLocked – Dialog scene that is displayed when the player finishes round 10 but has not unlocked all levels in the zone
  • ZoneSelect – Zone selection scene
  • Scenes 1 to 30 – Game level scenes
  • Scenes 101-120 – Custom blank level scenes

Note that some files contain more than one scene. For example, each game level file contains the pause menu, the main game level scene as well as the in-game HUD. The pause menu and HUD exist as separate XOML files so they can be re-used across all levels.

The code base contains implementations of the following custom scenes:

  • EditScene – Level editor scene, contains level editor logic
  • GameScene – A game level scene, contains game logic
  • LevelSelectScene – Custom scene for level select that handles updating of the scores in the level screen
  • ZoneSelectScene – Custom scene for zone select that handles updating of the lock / unlocked status of each zone

The following custom actors are also used:

  • ConnectActor – An actor that connect two bugs together with minimal logic
  • CounterActor – This is the main bug actor (originally called counters), handles all bug logic / collision etc
  • FloaterActor – Handles floating / fading text
  • GravityPlacerActor – Special actor that can be modified to change gravity within the editor
  • InertActor – Basically an actor that doesn’t much other than display itself
  • PlacerActor – A basic placeable object, used to position actors in the editor
  • SelectorActor – A basic selector actor used by the editor object selection screen to select which object to place

The rest of the code is pretty bog standard stuff. Game is the implementation of CIwGame and contains initialisation and shut down. Probably the most interesting part is where the custom XOML classes and events are added using the following code:

	// Add custom classes to XOML system
	IW_GAME_XOML->addClass(new InertActorCreator());
	IW_GAME_XOML->addClass(new GameSceneCreator());
	IW_GAME_XOML->addClass(new LevelSelectSceneCreator());
	IW_GAME_XOML->addClass(new ZoneSelectSceneCreator());
	IW_GAME_XOML->addClass(new CounterActorCreator());
	IW_GAME_XOML->addClass(new PlacerActorCreator());
	IW_GAME_XOML->addClass(new GravityPlacerActorCreator());
	IW_GAME_XOML->addClass(new SelectorActorCreator());
	IW_GAME_XOML->addClass(new EditSceneCreator());

	// Add custom game actions to XOML system
	for (int t = 0; t < CIwGameXomlAction_Global::Action_Max; t++)
 		IW_GAME_XOML->addAction(new GameXomlAction_Global((GameXomlAction_Global::ActionType)t));

These custom actions and events allow us to tie our game logic much closer to our XOML code.

Well that’s it for this update. We were aiming to get conditional XOML actions in for 0.31, but unfortunately it didn’t make it, but should do for 0.32.

cOnnecticOns is now available on the Android Market!

Hey everyone, some good news. We finally got the first version of the first IwGame Engine game  cOnnecticOns up on the Android Market at https://market.android.com/details?id=com.pocketeers.connecticons. Playbook, Bada and iOS builds will be available within the next few weeks.

And the even better news is that we are on schedule for releasing the full source this weekend! We’ve had a bit of a delay because we decided to upgrade the game a bit. We added an extra zone with 10 additional levels, as well as a game editor to allow players to create and play up to 20 of their own levels. Oh, and players can also post their scores to Facebook using the new CIwGameFacebook class (coming in the next IwGame engine update 0.31 this weekend)

cOnnecticOns for Android, iPhone, Bada and Blackberry
cOnnecticOns for Android, iPhone, Bada and Blackberry

The next update of the game will feature sharing levels between users using a web service, for which we will release the full source code, including the server side scripts.

The update after that will feature in-app purchase content using new classes that e are developing for the IwGame engine.

If you download the game then please consider leaving a nice review