IwGame UI Progress Update

Got a quick update showing how the IwGame engines UI system is shaping up. Note that the UI system is “bitmap” based and IwGame does not draw things like buttons, grids etc.. manually. Here’s a quick screen shot at iPad resolution showing some basic UI:

Basic IwGame Engine UI Screenshot
Basic IwGame Engine UI Screenshot

This is just a static image however, so you cannot really see the animation that’s built into the UI, for that you need to take a look at a quick video I stuck together showing the UI in action at http://www.youtube.com/watch?v=oV3kYLbzcKo

 

The UI itself consists of the following elements:

  •  StackPanels – The top left hand control is a vertical stack panel containing 3 horizontal stack panels. Each horizontal stack panel contains multiple basic UI components including buttons, labels and text input boxes. The check boxes and the long named button are toggle buttons. The top stack panel and the components within the panel have been draggable so they can be dragged away from the stack panel and moved around. Tapping the Expert check box will spin the control 360 degrees using an animation time line. One of the buttons and two of the check boxes also have animation time lines applied to them.
  • Grid – The control to the bottom left is a 3×4 grid that contains 12 items. These items are simple label buttons that when tapped will animate. A XOML array variable is bound to the grid and data from the array is moved into the grid. Updating the XOML array will automatically update the grid elements. The types of elements within the grid are defined using an item template. You can create a grid manually by adding components directly to the grid in XOML or in code bypassing the binding system. This allows you to create more complex controls within each grid cell. Tapping an item in the grid will set it animating
  • List box – The list box to the top right work on the same principles as the grid where data is bound to the list box and a template can be specified that defnies the type of items. This list box is a multi-select list box which allows you to select multiple  items
  • List Box 2 – The list box to the bottom right is more complex list box that shows list items using a more complex control. The list box items in this instance are created using a horizontal stack panel, which contains a label and a button. The list box is a single item selection list box

The UI controls themselves can be moved around and placed anywhere in the scene. the whole scene can also be moved around.

To give you an idea as to how the XOML looks, here’s a short code clip showing the XOL that creates the list box to the upper right of the screen:

    <!-- Create a listbox --> 
    <!-- ListBoxItems - Defines a list of items that will be bound to the list box -->
    <Variable Name="ListBoxItems" Type="arraystring" Size="4" Value="Item 1, Item 2, Item 3, Item 4" />
    <!-- Create a template that will be used to generate the list box actors -->
    <Template Name="ListBoxItemTemp">
        <Label Name="ListItem$index$" Background="ListBoxItemBrush" BackgroundColour="200, 200, 200, 255" SelectedColour="80, 80, 255, 255" Font="trebuchet_12" TextColour="255, 255, 255, 255" SelectedTextColour="255, 255, 255, 255" Margin="0, 0, 20, 0" SelectType="toggle" Selected="false" />
    </Template>
    <ListBox Name="ListBox" Position="351, -190" Background="ListBoxBrush" MultiSelect="true" ItemsData="ListBoxItems" ItemsTargetType="text" ItemsTemplate="ListBoxItemTemp" HitTest="true" Draggable="true" />

 

As you can see its pretty straight forward:

  • We create an array string variable and assign it the data that will be bound to the list box
  • We create a template that represents our items
  • We create a list box that uses the template and data and make it draggable

Well that’s it for now. We will be adding more and more features to the UI over the coming weeks and will keep you updated.

 

IwGame Engine Update – XML Schema for XOML Now Available

Ok, so we’ve heard back from a few of you and its apparent that XOML can be a little difficult to work with especially as it had no intellisense to help create well formed XOML. In the interests of making XOML much easier to write we have created an XML Schema that you can use to validate your XOML and provide intellisense support. Please note that the schema has only been tested in Visual Studio 2010. If you have problems with it in any other IDE then please let us know.

The XML Schema for XOML can be downloaded from http://www.drmop.com/XOML.xsd

Updated versions of the Schema will also be included with the IwGame Engine from v0.35 onwards

To use the Schema in Visual Studio 2010, open your XOML file, right click somewhere on the page and select properties then go to the properties windows. Click in the Schemas box then click the small file selector to the right (this will open up all of the available XML schemas). If XOML.xsd is not already in the list then click the Add button which pops up the file select dialog. Select XOML.xsd and open it, this will place it in the XML schemas list. Now click in the Use column next to XOML.xsd and select “Use this schema” then click OK. Your document should now be validated against the XOML schema and you should have intellisense / auto-complete etc..

Note that there are a few restrictions, for example, the schema does not include support for custom actor / scene names or support for FromTemplate parameters. if you are XSD savvy enough to figure out how to add that support then please let us know (I personally have only spent one day working with XSD which was today so I’m still a little wet behind the ears). For the meantime, you may want to edit the XOML.xsd schema file and add them yourself. A quick and easy way to get the schema to recognise your custom named scenes is to edit XOML.xsd, go to the bottom of the file and you will see a group called TopLevel. Copy and paste the line that defines Scene and change the word Scene to the name of your own scene class, e.g:

<xs:element name=”Scene” type=”SceneType” />

<xs:element name=”MenuScene” type=”SceneType” />

To add a custom actor create a copy the ActorImage tag and rename the copy to your custom class name, e.g.:

<xs:element name=”ActorImage” type=”ActorImageType” />

<xs:element name=”FrogActor” type=”ActorImageType” />

For actors, you will also need to copy the same line to the ActorGroup (situated just below the TopLevel group)

Please note that this will not take into account your own custom parameters, for that you will need to add your own complex types and attributes to handle it.

Lastly, to add custom actions, go to the top of XOML.xsd to the ActionsEnum type and copy one of the existing actions, paste and replace your own action name, e.g:

<xs:enumeration value=”CustomAction1″ />

Well that’s it, hope the schema helps to make XOML more usable. Please let us know if you have any problems (don’t send me complex schema questions because I don’t have a clue :))

 

 

 

 

IwGame Engine v0.34 Released – Modifiers, Box2D Joints and Marmalade 6.0 fix

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.

Well this release is a little earlier I’m afraid, we wanted to get UI functionality into 0.34, but 0.33 had a compile issue with the recent Marmalade 6.0 release so we decided to do a release now.

Below is the list of changes for IwGame 0.34:

  • Fixed Marmalade 6.0 compile error
  • JPEG loading support has been removed as this is now supported by Marmalade image classes
  • New extensions system added (pass true for enable_extensions in IwGame::Init() to enable, enabled by default) – Extensions are none standard IwGame code that will be added over the coming months to support game specific features
  • Actions now have a 4th parameter
  • New modifier system added that allows you to add functionality units to actors and scene. This enables a build from blocks style development
  • New AddModifier action that can be used to add a modifier to an actor or scene and modifier its behaviour in real-time
  • New ChangeModifier action that can be used to change the active state or remove a modifier from an actor or scene
  • Actors can now be marked as draggable. A draggable actor can be moved aruond by the user using their finger
  • New SetProperty action added for actors. You can now directly change the properties of an actor using actions. Can also be used to add torque and force onto actors under control of the physics system
  • New AddProperty action added for actors. This action can be used to add a value onto the peoperties of an actor
  • IwGame now supports brushes in code and in XOML. Brushes can be created and attached to actors saving you from having to specify image and SrcRect for each actor. This enables actor styling across any actors
  • CIwGameActorImage can now be instantiated from XOML using the ActorImage tag
  • New XOML atlas inner tag added to animations to allow auto generation of sprite atlas frames
  • Support has been added for joints (distance, revolute, prismatic, pulley and wheel joints are supported in code and in XOML)
  • A scenes physics update can now be changed between constant time step and variable
  • Box2D materials now support bullet, fixed rotation and gravity scaling parameters
  • Checks for duplicates added to resources, variables, actions, modifiers, class creators
  • New CIwGameActorConnector extension actor added – This actor will size and orientate itself so that it connects two static / dynamic points in space (can target moving actors)
  • New CIwGameModFollowHeading modifier extension added – When added to an existing actor the actor can be controlled using headnig and speed instead of velocity
  • CIwGameImage::CreatePNG() now supports RGBA_8888
  • Two basic Hello World examples added, one that displays text in code and another that uses XOML
  • BUG FIX: IwGameBox2d now coompiles on Mac without error
  • BUG FIX: CIwGameBox2dBody::setFixture() now behaves as expected
  • BUG FIX: Collision flags are now restored when turning an object from none collidable to collidable
  • BUG FIX: Memory leak in CIwGameActorImage::SetSrcDest(), SetSrcRect() and SetDestSize()
  • BUG FIX: Fixed problem with html parsing in CIwGameAds::ExtractLinkAndImageFromtHTML()
  • BUG FIX: CIwGameImage::CreatePNG() crash bug fixed

Lots of changes and a few bug fixes for good measure. The most interesting changes include Box2D physics joints (been playing with them all week and they are awesome), the new modifiers system, draggable actors and the ability to set actor properties directly using actions. Lets look at some of these new changes in more detail:

Box2D Joints Support

Physics joints enable you to connect physical bodies together in a variety of ways. The following types of physical joints are currently supported:

  • Distance – A distance joint limits the distance of two bodies and attempts to keep them the same distance apart, damping can also be applied
  • Revolute – A revolute joint forces two bodies to share a common anchor point. It has a single degree of freedom and the angle between the two bodies can be limited. In addition a motor can also be applied to the joint
  • Prismatic – A prismatic joint limits movement between the two bodies by translation (rotation is prevented). The translational distance between the two joints can be limited. In addition a motor can also be applied to the joint
  • Pulley Joint – A pulley joint can be used to create a pulley system between two bodies so that when one body rises the other will fall.
  • Wheel Joint – A wheel joint restricts one body to the line on another body and can be used to create suspension springs. A motor can also be applied to the joint

All joints share the same base class IIwGameBox2dJoint

Joints can be created in code and attached to a body using CiwGameBox2dBody::addJoint(). Joints can later be removed using removeJoint(). You can also search for existing joints using getJoint() and findJoint()

        <ActorImage Name="Crate1" ...... />
        <ActorImage Name="Crate2" ...... >
            <Joints>
                <Joint type="distance" ActorB="Crate1" OffsetA="0, 50" OffsetB="0, -50" Frequency="10" Damping="0" SelfCollide="true" />
            </Joints>
        </ActorImage>

The easiest way to create and attach joints is using XOML. Below is an example showing how to create and attach a distance joint between two crates:

Actor and Scene Modifiers

IwGame supports modifiers using the IwGameModfier system. Modifiers can be thought of as small functional building blocks that can be stacked in an actor or scene to extend the functionality of that actor or scene. For example, a typical modifier for a scene could be one that tracks the players scores / hi-scores, change day / night settings or detects special gestures. An actor modifier example could be a modifier that allows the actor move around using heading and speed or even a modifier with functionality specific to your game such as make a baddy that walks left and right on a platform. The idea is to allow developers to build games and apps up from smaller re-usable building blocks and be able to add them using code or XOML. Below is a quick example showing how to attach a modifiers list to an actor in XOML:

     <ActorImage Name="Baddy1" ....... >
          <Modifiers>
              <Modifier Name="AddThrustMod" Active="true" Param1="1" />
              <Modifier Name="ShootPlayerWhenClose" Active="true" Param1="1" />
          </Modifiers>
     </ActorImage>

Here we have added two modifiers to the Baddy1 actor which modify its behaviour. Note that up to 4 parameters can be passed to the modifier

Modifiers can also be attached in code like this:

    // Find the modifiers creator
    IIwGameModifierCreator* creator = IW_GAME_MODS->findCreator("addthrustmod");
    if (creator != NULL)
    {
        // Create an instance of the modifier
        IIwGameModifier* mod = creator->CreateInstance();
        if (mod != NULL)
        {
            // Set up the instance
            mod->setName("addthrustmod");
            mod->setActive(true);
            mod->setParameter(0, "1");

            // Add the modifier to the actor
            actor->getModifiers()->addModifier(mod);
        }
    }

Draggable Actors

Any actor can now be set as draggable, allowing the user to tap it and drag it around the world. You can make any actor draggble in XOML by adding Draggable=”true” to its definition.

Setting / Updating Actor Properties from XOML

Its now possible to set or update actor properties directly from an action in XOML. Using the new SetProperty / AddProperty actions

Extensions System

From v0.34 of IwGame a new optional extensions system has been added. The extensions system is basically a collection of actors, scenes, actions, modifiers and other elements that are not part of the base IwGame engine. The extensions system provides support for game specific objects and other functionality that can be used to make creating specific types of games much easier. There’s not many extensions available yet but many more will be added in the future

IwGame Usage Changes

Please note the recent changes that have been applied to IwGame Usage. The new usage terms are shown below:

You are free to use IwGame in your projects in part or in whole as long as the header comments remain in-tact. Whilst you are not obliged to mention your usage of IwGame in your products it would be great and beneficial to let us know as we can publicise your product on our blog and other web sites / services (Our blog receives over 200,000 hits per month) However, if you use any part of the IwGame extensions system, which includes extension actors, extension scenes or extension modifiers then you are required to mention usage of the IwGame Engine in your product.

You may not claim the IwGame engine or its documentation as your own work or package it up and include it in any kind of middleware product without express prior written notice from an executive of Pocketeers Limited with the correct authority to grant authorisation. You may not publicly host any source code that is part of the IwGame Engine, the source will be hosted at http://www.drmop.com/index.php/iwgame-engine/

These changes apply to all versions of the IwGame Engine.

Well that’s it for this update

 

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 – The Game

CIwGame Object – The Eye in the Sky

Introduction

CIwGame is basically the kind of eye-in-the-sky controller of the game engine and can be thought of as the main loop of the game engine. CIwGame takes care of many things including:

  • Initialisation, processing and clean-up of many systems including graphics, input, resource manager and audio etc..
  • Managing and updating scenes
  • Sorting scenes by layer order
  • Notifying the user of scene change events
  • Rendering scenes
  • Tracking frame speed
  • Processing events such as tapped, touch begin / end

You never actually create an instance of CIwGame, instead you derive you own version of the class from CIwGame like this:

#define	GAME	Game::getInstance()

class Game : public CIwGame
{
	CDEFINE_SINGLETON(Game)
public:
protected:
	//// Properties
public:
	//// Properties end
protected:
public:
	void			Init(bool enable_http);
	void			Release();
	bool			Update();
	void			Draw();
	void			PostDraw();
	void			Save();
	void			Load();
};

You then implement Init(), Release(), Update() and Draw() methods to provide your own initialisation, clean-up, per frame update and per frame rendering code. You can also override PostDraw() to apply post rendering.

Note that the games Init() method takes a parameter called enable_http. If you plan on using anything relating to the HTTP manager, such as ads, web file / image access then you will need to pass true to the game object during initialisation.

Implementing our own CIwGame

Lets now take a quick look at a bare bones implementation of the above methods:

CDECLARE_SINGLETON(Game)

void Game::Init(bool enable_http)
{
	CIwGame::Init(enable_http);

	// TODO: Insert your own initialisation here
}

void Game::Release()
{
	// TODO: Insert your own cleanup here

	CIwGame::Release();
}

bool Game::Update()
{
	if (!CIwGame::Update())
		return false;

	// TODO: Insert your own custom game update functionality here

	return true;
}

void Game::Draw()
{
	CIwGame::Draw();

	// TODO: Insert your own custom game rendering functionality here
}

void Game::Save()
{
	// TODO: Insert your own game save functionality
}

void Game::Load()
{
	// TODO: Insert your own game load functionality
}

Note that if you utilise IwGames systems then it is very unlikely that you will need to add additional rendering code to Game::Draw().

At its heart, CIwGame contains a collection of game scenes (CIwGameScene’s) that in turn drive actors and cameras to provide your games functionality (more on these classes later).

CIwGame enables you to add, remove and search for scenes within the game as well as set the currently active scene using the following methods:

void		addScene(CIwGameScene *scene, bool bring_to_front = true);
void		removeScene(CIwGameScene* scene);
void		removeScene(unsigned int name_hash);
CIwGameScene*	findScene(unsigned int name_hash);
CIwGameScene*	findScene(const char* name);
CIwGameScene*	findScene(int type);
CIwGameScene*	getScene(int index);
void		clearScenes();
void		changeScene(CIwGameScene *new_scene);
bool		changeScene(unsigned int name_hash);
CIwGameScene*	getCurrentScene();
void		BringSceneToFront(CIwGameScene* scene);

Note that all visible scenes will be rendered every game frame and usually only the current scene will be updated.

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.

Merry Christmas!

Merry Christmas everyone, I hope all you nice, well behaved developers were left something nice from Santa!? Santa left me an HTML 5 game development book, so who knows, you may see some HTML 5 related tutorials appearing on drmop.com soon. Who knows, an HTML 5 version of IwGame may appear one day.

2011 has been a busy year, we’ve (Pocketeers Limited) released BattleBallz Chaos paid and free versions on iPhone, iPad, Android, Samsung Bada and Blackberry Playbook. We’ve also released Funky Cam 3D paid and free versions on iPhone, iPad, Android and Samdung Bada. In addition, we developed Murder Detective, Hampton Bridge Murder for Tournay Software on iPhone, iPad, Blackberry Playbook and Android as well as helped Honey Badger Studios port their Zixxby game over from Android to iPhone, iPad and Blackberry Playbook using the Marmalade SDK.

Now for a quck appraisal of the apps we developed this year:

Funky Cam 3D FREE has shipped over 500k units on Android, around 100k units on iOS and about the same number on Samsung Bada. Revenue income from Funky Cam 3D FREE is around $10-$20 per day (15k-20k impressions per day) across all platforms. Income from paid versions of Funky Cam 3D is very poor across all platforms. Funky Cam 3D FREE is currently the No 1 downloaded app for Samsung Bada on Samsung Apps. Reviews have  been a mixed back, some love it whilst some hate it

BattleBallz Chaos got a fair bit of publicity in association with the Marmalade SDK, being featured on stage at the Blackberry Dev Con 2011 as well as in an official Blackberry Playbook gaming advert, Pocketeers also received a fair bit of attention from the Blackberry press because of the speed at which we converted the game over Playbook and had it live on the store (less than 24 hours). BattleBallz Chaos paid sales have been better than Funky Cam 3D by around 200%, but ad revenue has been incredibly bad (less than $1 per day). Reviews have been pretty positive across all platforms, although we have had some Android compatibility issues which has skewed our Android ratings somewhat.

This year was our entry into the mobile market, we came in from console development, so we have had a lot to learn. In summary:

  • Know your audience – We expected mobile gamers to play similar games to console (not so). We have been watching the top 100 apps and games over this year and discovered that mobile gamers do not want console style games. Instead they want low intensity, easy learning curve gaming, less competitive game play with highly colourful quality graphics and animations. Mobile gamers also  expect a walk through or some kind of game introduction as opposed to a help screen that’s hidden away in the menu system.
  • Marketing is the key – App stores are filled with hundreds of thousands of apps so getting noticed is incredibly difficult. Genuine free apps for obvious reasons require less marketing as users are much more likely to download them because they don’t have to pay anything.  Most app stores base their rankings on number of downloads in the last X hours / days, because of this Marketing is best done in bursts to increase the chances that users will discover and and install your app in a short period of time. To rise up the charts quickly requires a lot of marketing in a short period of time.
  • Ad Mobs v Facebook advertising – Both are quite useless unless you have a LOT of money to spend on a campaign, although we did find that Facebook ads did work better than AdMobs
  • Freemium – Although we have not tested the great freemium theory, a majority of app revenue is coming from the sale of additional levels perks , items and other in-game consumables (much like the Zygna facebook model), so this is something we are going to test out in 2012.
  • Android platform – Whilst the Android platform is cool and all, it just isn’t much use for making money. In fact, if the Marmalade SDK did not support the Android platform ten we would most likely drop it altogether. Its ok, if you want to make a few bucks from ads, but not worth investing a significant amount of money into. That said, we are yet to try out a freemium based model of monetisation, so we will give it another chance this year.
  • Price playing – We discovered that we can  increase the visibility of an app or game by regularly dropping the price to very low or even free. Users notice the price drop and download discounted products in droves (everyone likes a bargain!). This can push your apps position up in the charts temporarily. We have  found that dropping our price to free for 2 days can give you a sales boost for 7-14 days.
  • Lite versions – We found that releasing a limited lite version of BattleBallz Chaos didn’t affect sales much, we had very few converts to the paid version. That said, BattleBallz Chaos is the completely wrong type of game for the mass mobile market
  • Cross promotion – We found that cross promoting apps and games worked quite well. We placed a large full sized ad into each of our apps, effectively advertising each others availability. We may try a system such as OpenFeint’s in 2012 to increase exposure
  • Don’t expect to get rich quick and don’t expect anything to be easy – We’ve spoken to many mobile developers this year and the general consensus is that mobile development is easy, but marketing is incredibly difficult. Very few developers actually make it into the top 50/100 which is where the money is at. The journey to the top is long and difficult so be prepared for the long haul and wave good bye to a lot of time and  money. if you are not prepared to gamble then walk away from mobile development altogether.
  • Cross platform is a MUST – If we had simply developed our products on either Android or iOS we would probably have packed up mobile development this year and moved onto something else.  If it wasn’t for the Marmalade SDK’s cool cross platform technology we would probably not have stuck with it. Going cross platform will increase the chances of a hit as you are catering for many platforms with very little extra effort or costs. Going cross platform also generally increases your return on investment (ROI).
  • Don’t believe app the hype – App publishers, app  stores and ad networks will say anything to hook you into using their services. Just be sure to research them before putting in the effort. Their advertised figures will usually be massively out of date. Insist on current figures and see what other developers are saying about them around the web.

We also began the development of IwGame this year, an open source  cross platform game engine for the Marmalade SDK community. We began development of IwGame for a number of reasons:

  • Lessen the learning curve for Marmalade developers and provide a solid game engine on top of the Marmalade SDK
  • To help promote the Marmalade SDK to mobile developers
  • To help promote Pocketeers Limited’s development services and apps

So far we are very pleased with IwGame and plan on continuing its development all the way through 2012. We also plan on putting our own internal engine on hold for a while to focus on creating games and apps with IwGame to show developers live apps and games created using the IwGame engine. Also, depending upon the success of IwGame this year, we may port the engine to Windows Phone 7 and HTML5.

IwGame Engine v0.26 Released – Supports 12 Ad Providers, Accelerometer and Compass

Well me, Santa and the elves have been very busy bees this week and between us we managed to hammer out another update to the IwGame Engine before Christmas (Thanks Santa, couldn’t have done it without those delicious mince pies!)

Here are the latest changeds for IwGame v0.26:

  • Bug fix – Actor crash bug when no camera assigned to the scene
  • Bug fix – Fixed CIwGameHttp crash bug
  • Bug fix – Fixed ad rendering crash bug
  • Bug fix – Deleted scenes are now removed at the end of a frame and not immediately
  • Bug fix – Scenes with no attached camera didnt set transform correctly
  • Bug fix – Sprite hit test could be called before transform was set up
  • Accelerometer support added to CIwGameInput
  • Compass support added to CIwGameInput
  • CIwGameAdsMediator added to mediate ad requests between multiple ad providers to improve fill rate
  • Support for VServ, Mojiva, Millenial Media and AdModa ad providers added
  • ExtraInfo added to ad requests to allow custom information to be passed to ad providers
  • Added URLDecode method to CIwGameString

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.

I want to include a big thank you to all those that have reported bugs and documentation errors, especially Phillip who saved me many hours of proof reading.

As you can see from te list of changes there are a fair few bug fixes (sorry about that), but more importantly some new stuff:

New Ad Networks Added

Yes, we now support six ad providers (twelve ad providers indirectly), a couple which also deliver ads from other networks providing you with access to 12 ad networks in total. Here’s the complete list:

  • 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
  • AdModa

Many thanks to those ad providers that bent over backwards to support our integration efforts.

New Ad Mediation Support

Now we have so many ad providers we need some way of mediating ad requests between them all. Ad Mediation is the process of going through a list of prioritised ad providers requesting an ad, if the ad provider does not provide an ad then request an ad from the next provider. Keep on doing this until you get an ad that you can use. This should hlpe you attaina near 100% fill rate and maximise your apsp potential ad revenues.

IwGame provides automated ad mediation using the CIwGameAdsMediator. To use the mediator you create a CIwGameAdsMediator, populate it with ad party’s then attach it to the CIwGameAds object as shown below:

// Create ad mediator and attach it to the main ad object CIwGameAdsMediator* ad_mediator = new CIwGameAdsMediator(); IW_GAME_ADS->setMediator(ad_mediator); // Create Inner-active ad party and add to the mediator CIwGameAdsParty* party = new CIwGameAdsParty(); party->ApplicationID = "Your inner-active App ID"; party->Provider = CIwGameAds::InnerActive; ad_mediator->addAdParty(party); // Create AdModa ad party and add to the mediator party = new CIwGameAdsParty(); party->ApplicationID = "You AdModa App ID"; party->Provider = CIwGameAds::AdModa; ad_mediator->addAdParty(party); // Create AdFonic ad party and add to the mediator party = new CIwGameAdsParty(); party->ApplicationID = "Your AdFonic App ID"; party->Provider = CIwGameAds::AdFonic; ad_mediator->addAdParty(party);

As you can see, incredibly simple. The process of attaching the ad mediator will ensure that the ad object will attempt to collect ads from all ad parties should previous parties fail to collect an ad. You do not need to make any changes to the ad view, the system is completely automated.

Support for Accelerometer and Compass added to CIwGameInput

CIwGameInput now has support for reading the devices accelerometer and compass devices allowing you to integrate these alternative input methods into your games.

Well that’s it for this update. More features coming soon (probably in the new year).

Happy holidays everyone!

IwGame Engine Update – v0.230

Well its been an interesting day to say that its a Sunday, some good news and some bad new . The good news is that I managed to sneak some time in today to add a few updates to IwGame. The bad news is that some robbing (insert lots of non-religious type words here) has skimmed my card and robbed my bank account! (Can’t these people just get jobs like the rest of us!). Anyways, anger vented, now to get back on topic. We have just updated the IwGame game engine to v0.230. If you don’t know what IwGame is then in short it is a cross platform game engine for smart phones and tablets based upon the awesome Marmalade SDK. Here are the new features:

  • Added CIwGameImage::CreatePNG(int& size) to CIwGameImage to allow the creation of memory based PNG files
  • Added pngilb and zlib dependents
  • Added helper support to CIwGameInput for detecting touched, tapped events, delta change and back / menu buttons
  • Added CIwGameSprite::HitTest(int x, int y) which basically tests to see if a screen point is inside a sprite (takes into account scaling and rotation)
  • Added CIwGameAudio, CIwGameSound and CIwGameSoundCollection classed to support playback of sound effects and music
  • Added visual layers to sprites and actor system allowing sprites / actors to be depth layered
  • Added support for clipping in CIwGameScene. The scene can now be clipped to a rectangular area of virtual canvas

And here are the general changes / bug fixes:

  • Changed CIwGameFile::Open(const char* path, const char* mode, bool blocking), we now use mode instead of read / write flag
  • Added new CIwGameFile::Seek(int offset, s3eFileSeekOrigin origin) method
  • Replaced CIwGameHttpPostData::AddHeader() with CIwGameHttpPostData::SetHeader() to allow replacement of http headers
  • Added ClearRequests() and CancelRequests() to CIwGameHttpManager() allowing us to clear the request queue and cancel any in progress http requests
  • Removed two bugs from CIwGameInput, one that was stopping button / key presses and another that was preventing keyboard update if touch screen wasn’t present (doh!)
  • Added helper support to CIwGameInput for detecting touched, tapped events, delta change and back / menu buttons
  • Fixed CIwGameScene::removeActor(CIwGameActor* actor) bug (could not remove unnamed actors)
  • Fixed CwGameScene::removeActor(unsigned int name_hash) (would not deallocate pooled actors for re-use)
  • Fixed sprites initial state as invisible bug in CiwGameSprite
  • Moved Width and Height from CIwGameBitmapSprite to CIwGameprite, makes sense that all sprites would need to have a size
  • IwGame has been made into its own standalone project
  • The IwGame Testbed has now been moved to the TestBed folder

Important note, IwGame now exists as a separate project from the test bed. You now have to add IwGame to your project by adding IwGame to the subprojects section of your MKB file. The test bed is also a separate project and is located in the IwGame sub folder named TestBed. Lets take a quick look at some of the changes

Sprite Depth Layers

Its now possible to layer sprites in a sprite manager. The feature is automatic, all you have to do is set the layer of the sprite using setLayer(int layer_number). To set the number of depth layers available to the sprite manager you pass the layer count into the sprite managers Init() method. The default is set to 10 layers. As a scene contains a sprite manager to handle its contained visuals, you can also specify the number of depth layers when you initialise a scene: int Init(int max_collidables = 128, int max_layers = 10); Again, the default is 10 layers. Note that sprites on higher layers will be drawn on top of sprites on lower layers.

Creating PNG’s

You can now create an in-memory PNG file from a  CIwGameImage using CIwGameImage::CreatePNG(): uint8* png_data = image->CreatePNG(png_size); The method currently only supports images in RGB_565 and RGB_888 format. more formats will be added when I implement a new pixel conversion helper class.

CIwGameInput Expansion

I decided to pan CIwGameInput out a little adding new methods to do common tasks such as:

  • bool hasTapped() – Returns true if user tapped the screen
  • bool isTouching() – Returns true if user is currently touching the screen
  • CIwVec2 getTouchedPos() – Returns the position at which the user is touching the screen
  • CIwVec2 getDragDelta() – Returns the number of pixels the user has moved their finger / stylus since the last frame
  • bool isBackPressed() – Returns true if the back button was pressed (nice for Android)
  • bool isMenuPressed() – Returns true if the menu button was pressed (nice for Android)

These should help if you want to get up and running quickly with input.

CIwGameSprite hit testing

CIwGameSprite got a new method called hitTest() that lets you check to see if a point is inside a transformed sprite:

// Generate transformed vertices bool CIwGameSprite::HitTest(int x, int y) { // Generate transformed vertices int w = Width / 2; int h = Height / 2; TransformedV[0].x = -w; TransformedV[1].x = w; TransformedV[2].x = w; TransformedV[3].x = -w; TransformedV[0].y = -h; TransformedV[1].y = -h; TransformedV[2].y = h; TransformedV[3].y = h; for (int t = 0; t < 4; t++) TransformedV[t] = Transform.TransformVec(TransformedV[t]); int i1 = 0; int i2 = 3; for (int t = 0; t < 4; t++) { int x0 = TransformedV[i1].x - TransformedV[i2].x; int y0 = TransformedV[i1].y - TransformedV[i2].y; int x1 = x - TransformedV[i2].x; int y1 = y - TransformedV[i2].y; if ((x1 * y0 - x0 * y1) >= 0) return false; i2 = i1; i1++; } return true; }

This basically transforms the sprite by the sprites current transform and checks to see if a point falls inside the sprite (takes into account rotation and scaling). If you are curious about the method it uses dot products . If the points liles on the outside of any of the lines that make up the sprite then it cannot possibly be inside the polygon.

CIwGameAudio – Let there be Sound

Yes, that’s right IwGame just got audio. I basically built a wrapper on top of IwSound that lets you easily play sound effects located in a resource file as well as music. New classes include:

  • CIwGameAudio – This is the singleton that is responsible for creating, destroying and updating the audio system
  • CIwGameSound – This class represents an instantiates sound effect
  • CIwGameSoundCollection – This class represents a collection of sound effects

if you are using IwGame then you do not need to do anything except load a resource file that contains your sound effects and set the CIwGameAudio’s group like this:

CIwResGroup* AudioGroup = IwGetResManager()->LoadGroup("Audio.group"); IW_GAME_AUDIO->setGroup(AudioGroup);

You then play sound effects like this: IW_GAME_AUDIO->PlaySound(“explosion”); And music like this: IW_GAME_AUDIO->PlayMusic(“music.mp3”); Couldn’t get much simpler really However, if you want to set up and update the audio system yourself you will need to:

// Initialise audio system CIwGameAudio::Create(); IW_GAME_AUDIO->Init();

Then in your main loop, every frame call:

// Update audio IW_GAME_AUDIO->Update();

And finally on clean up call:

// Shut down audio IW_GAME_AUDIO->Release(); CIwGameAudio::Destroy();

CIwGameScene Scene Clipping

You can now set a rectangular area on a  per scene basis that all actors / sprites within that scene will be clipped to. Parts of sprites that fall outside the clipping region will not be drawn. To set up clipping simply call CIwGameScene::setClippingArea(int x, int y, int w, int h) where x and y are the top / left hand corner of the clipping area whilst w and h are the width and height. Note that clipping coordinates are not specified in pixels but in virtual canvas coordinates. The origin (0,0) is the centre of the screen. So if you virtual canvas is set to 480 x 320 pixels then use x = -240, y = -160, w = 480, h = 320 to clip to the full canvas, although you can just set w to 0 to disable clipping (that’s the default).

Well that’s it for this week, unfortunately I didn’t get the time to do a new Marmalade SDK tutorial but I will try and get that done mid next week. I have some free time coming up soon so I can knock lots of tutorials out. Also have some interesting news coming up soon about an SDK we just finished that pulls ads from inner-active and displays them all fancy 🙂 Compatible with all Marmalade deployment platforms.

Marmalade SDK Tutorial – Downloading and Using an Image from a Web Based Image File

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

Unfortunately my brother rang me last night and asked me to have a few quick battles with him on World of Warcraft (I just can’t resist PvP) so as it happens, I forgot all about the time and missed publishing my next blog. In case you plaw Wow and you’re wondering I have Level 85 Mage, Warlock, Paladin and Druid!

In our previous tutorial we added the ability to send and receive data to and from a web server. We also created a new file class that deals with local and remote file access, allowing us to download files from the web and use them in our game. We also briefly mentioned that we had updated the CIwGameImage class to support JPEG’s and creation of images from memory based files. In this tutorial we are going to go into that a little more as well as show you how to use CIwGameFile and CIwGameImage to download and display images from the web inside your games and apps. If you just want the code to this tutorial then download it from here.

Imagine a situation whereby you can distribute your basic game without having to carry around any of its content, so no graphics, no audio, no level files etc. Whilst that may not be completely practical for some types of games it is for many others. Imagine your game running completely on dynamic content that lives on a server and you can modify it at any time, Your players will benefit greatly from new fresh content regularly. Well, this is all possible using the Marmalade SDK and IwGame (wow that sounded a bill salesy!)

IwGameImage Changes

Ok the first change we made was to add the ability to create a CIwGameImage image from a JPEG. This feature is unfortunately not supported by Marmalades image classes and missing out on JPEG compression for larger images is a bit of a pain. That said, Marmalade does provide access to LibJPG, allowing you to implement your own JPEG loader. However, seeing as we have already done the work for it, you may as well just rip the code straight out of IwGameImage.cpp.

The main method that takes care of JPEG decompression is CIwGameImage::DecompressJPEG(). Note that this method will create a RGB888 image from the JPEG file, I will add support for conversion to different image pixel formats in a future release.

The next change to CIwGameImage is the ability to create an image from a file that has already been loaded into memory. This is very useful if you want to cache the compressed versions of images in memory:

bool CIwGameImage::Init(const char* name, void* memory_file, int memory_file_size, bool is_jpeg)

name – The name you would like to assign to the file
memory_file – A pointer to the memory based file
memory_file_size – The size of the memory based file
is_jpeg – Determines if the memory based image file is a jpeg

Note that future versions will not rely on is_jpeg and instead, the header data will be checked to determine file type.

How to Create a CIwImage or CIw2DImage from a Memory Based File

Ok, lets take a look how we create an image from a memory based file in the CIwGameImage::Init() method:

bool CIwGameImage::Init(const char* name, void* memory_file, int memory_file_size, bool is_jpeg) { CIwGameFile file; if (file.Open(memory_file, memory_file_size)) { if (is_jpeg) { if (!DecompressJPEG((char*)memory_file, memory_file_size)) return false; } else { CIwImage image; image.ReadFile(file.getFileHandle()); Image2D = Iw2DCreateImage(image); Width = Image2D->GetWidth(); Height = Image2D->GetHeight(); } } State = CIwGameImage_State_Loaded; return true; }

As you can see we create a CIwImage by calling CIwImage::ReadFile() passing in the file handle of the memory based file (to find out how to create a file from a memory buffer take a look at CIwGameFile::Open(void* memory_buffer, int memory_buffer_len)).
To turn the CIwImage to a CIw2DImage we call Iw2DCreateImage() passing in the CIwImage.

How to Create a CIwImage or CIw2DImage from a Pixel Data

In our CIwGameImage::Init() method you will notice that if the image file is a jpeg then we call DecompressJPEG(). If you look towards the end of our DecompressJPEG() method you will notice that we create our CIwImage / CIw2DImage a slightly different way.

Because we are manually loading and decompressing the pixel data within the JPEG image we are left with a memory buffer containing our raw uncompressed images pixels. Marmalade’s usual create from file style image creation methods do not cover this, so instead we create the image ourselves from the pixel data like so:

CIwImage image; image.SetFormat(CIwImage::RGB_888); image.SetWidth(Width); image.SetHeight(Height); image.SetOwnedBuffers((uint8*)data, 0); Image2D = Iw2DCreateImage(image);

Basically we create a CIwImage, set its format and dimensions then tell it where our pixel data is using SetOwnedBuffers(). Like we did in the previous example, to turn the CIwImage into a CIw2DImage we call Iw2DCreateImage() passing in the CIwImage.

Creating an Image from a Web Based Image File

The new demo shows how to download an image file from the web and create an image from it then display that image as a sprite. Lets firstly take a look at how we download and create the image:

// Download an image file from the web CIwGameFile* image_file = new CIwGameFile(); image_file->Open("http://www.battleballz.com/bb_icon.gif", false, true); image_file->Close(); // Create an image from the downloaded gif file CIwGameImage* image = new CIwGameImage(); if (image_file->isFileAvailable() && image_file->getError() == CIwGameFile::ErrorNone) image->Init("", image_file->getContent(), image_file->getContentLength(), false); delete image_file; // We are done with the image file so we can delete it

Now we will create a sprite to display our downloaded web image::

// Create a test sprite to display our downloaded gif CIwGameBitmapSprite* test_sprite = new CIwGameBitmapSprite(); test_sprite->setImage(image); test_sprite->setDestSize(image->getWidth(), image->getHeight()); test_sprite->setSrcRect(0, 0, image->getWidth(), image->getHeight()); test_sprite->setPosition(image->getWidth() / 2, image->getHeight() / 2);

And that’s about all there is to it.

Some of you probably already have ideas buzzing around your heads on how to use this cool new system. I’m going to put some more time into the image class this week because I’m not happy about the way loading a jpeg and a web based image is different to the way we load images from a resource collection. I want to change the CIwGameImage class to basically allow you to specify not just a resource name, but also local file names and remote file names.

Well that’s it for this blog, as usual you can download the latest code from here

Happy coding and don’t eat too much tuna!