Resources – The Stuff that Games are Made of

Introduction

One of the central features of Booty5 is the management of resources. Resources are assets that the game needs to help it function such as bitmaps and sound effects. Booty5 supports a number of different types of resources including:

Resources can be stored and managed locally by scenes or globally by the main App object. Local resources are loaded with the scene and destroyed when the scene is destroyed, whilst global resources are loaded and managed by the global App object and will remain in memory for the duration of the application or until removed manually. This type of resource management system is useful when dealing with games that run on resource constrained devices such as mobile phones.

Each resource has its own name which should be unique to its category of resource that can be used to find the resource at a later date. For example, you should not have two images called “player”, although you can have an image called player and a shape called “player”.

You can add a resource to a scene or the main App by calling addResource(), e.g.:

1

2

3

4

5

// Create a bitmap resource

varbitmap=newb5.Bitmap("background","images/background.jpg",true);

// Add to a scene to be managed

scene.addResource(bitmap,"bitmap");

Resources can be manually removed from a scene or the main App by calling removeResource(), e.g.:

1

scene.removeResource(bitmap,"bitmap");

You can also call destroy() on the resource to remove and destroy it, e.g.:

1

bitmap.destroy();

Once a resource has been added to a resource manager it can later be searched for using findResource(), e.g.:

1

varbitmap=scene.findResource("background","bitmap");

Note that if you call the scene version of findResource() and the resource is not found in the scene then it will automatically check the global App’s resource list.

Resource Paths

All resources in Booty5 can be located using their child hierarchy path. A child hierarchy path is a string that consists of the names of the parents separated by dots. For example, if you want to locate a physics material called “material1” that is located in a scene named “scene1” then the path to that resources would be “scene1.material1”. If the material was located in the Apps global resource space then the path would simply be “material1”. To find the instance of the resource from the path you can call b5.Utils.findResourceFromPath(path, type), e.g.:

This method of locating a resource is so convenient that many parts of the Booty5 engine utilise it. For example, all resources that are passed to actions accept either an instance of a resource or a path to the resource. Many object properties also accept paths, such as b5.Actor._clip_shape and b5.Actor.bitmap etc…

Scenes, actors, timelines and actions lists can also be searched for using paths using the b5.Utils.findObjectFromPath(path, type), where type can be timeline, actions or null for scene / actor.

Bitmap Resources

Bitmap resources are resources that hold image data that is loaded from a file. Bitmaps are commonly used as the visual representation for sprites (Actors). To create a bitmap you create an instance of a b5.Bitmap class, for which the prototype is:

1

b5.Bitmap(name,location,preload,onload)

Where name is the name of the Bitmap object, location is the location of the bitmap, preload is a flag that tells Booty5 to load the image immediately and onload is an optional callback function which will be called when the bitmap has finished loading.

Lets take a quick look at an example:

1

varbitmap=newb5.Bitmap("player","images/player_anims.png",true);

Lets take a quick look at an example of how to create a Bitmap that notifies us when it has finished loading:

1

2

3

varbitmap=newb5.Bitmap("player","Textures.png",true,function(b){

console.log("bitmap loaded "+b.name);

});

You can check to see if a Bitmap has finished loading by checking its loaded property.

You can tell a Bitmap to load itself by calling b5.Bitmap.load().

Bitmaps are usually assigned to an Actor via its bitmap property or _bitmap property setter. Remember that a property setter can take an instance of a resource or a path to a resource.

If you intend to manage the Bitmap yourself then you do not need to add the Bitmap to a scene or the main App objects resource managers.

Bitmaps can also be assigned to an ImageAtlas brush if the bitmap contains multiple sub-images. More on this later.

Sound Resources

Sound resources are resources that hold audio data that is loaded from a file. Sounds are commonly used to play back music and sound effects. To create a sound you create an instance of a b5.Sound class, for which the prototype is:

1

b5.Sound(name,location,reuse)

Where name is the name of the Sound object, location is the location of the sound file, reuse is a flag that tells Booty5 that it should be created only once and re-used.

Lets take a quick look at an example:

1

varsound=newb5.Sound("explosion","sounds/explosion.mp3",true);

Sounds are usually added to a scene or the main App object for management

Because not all sound file types are supported across all platforms, Booty5 supports a fallback option when loading sound effects by assigning a second sound effect to the Sound object, if the first sound fails to load then Booty5 will attempt to load the second,e.g.:

1

2

varsound=newb5.Sound("explosion","sounds/explosion.ogg",true);

sound.location2="sounds/explosion.mp3";

In the above example, if the ogg sound file fails to load then Booty5 will attempt to load the mp3 instead.

A sound can be made to automatically play once loaded by setting its auto_play property to true.

You can tell a Sound to load itself by calling b5.Sound.load()

You can play, stop and pause a playing sound by calling b5.Sound.play(), b5.Sound.stop() and b5.Sound.pause(). When you call play() an instance of the created HTML5 Audio object (or equivalent) will be returned. You can also get access to this instance via b5.Sound.snd property. Note that in the case of playing multiple copies of the same sound, a different instance of Audio will be returned for each one if the sound is not set as reuse.

Note that if using the Web Audio API then an object consisting of {source, gain} is returned from play(), where source represents the AudioBufferSourceNode and gain the GainNode. You can use the GainNode to modify the volume of the sound, e.g.:

1

2

varsound=music.play();

sound.gain.gain.value=0.5;

In addition, sound.snd will contain this object if the sounds auto_play property is set to true.

The sound can be told to loop by setting b5.Sound.loop to true.

One important note, when testing locally Web Audio sounds will not be played as they cannot be loaded locally, so disable web audio usage when testing locally.

Shape Resources

Shape resources are resources that hold information about a geometric shape or path. Unlike bitmaps and sounds, shapes are not stored in separate files. Shapes are commonly used as the geometric visual representation for sprites, as fixtures for physics bodies, as clipping regions for actors and scenes or as paths for objects to follow. To create a Shape you create an instance of a b5.Shape class, for which the prototype is:

1

b5.Shape(name)

Where name is the name of the Shape object. However, this only creates an instance of a Shape object, we still need to fill in the rest of the information.

Shapes can be of 3 different kinds:

b5.Shape.TypeBox – A rectangular box with width and height

b5.Shape.TypeCircle – A circular shape with a radius

b5.Shape.TypePolygon – A polygonal shape made from vertices

All 3 types can be used for rendering, physics fixtures and as clippers. However, only polygon shapes can be used as paths.

Lets take a quick look at an example that shows how to create a shape of each type:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

// Create a box shape

varbox=newb5.Shape();

box.type=b5.Shape.TypeBox;

box.width=100;

box.height=50;

// Create a circle shape

varcircle=newb5.Shape();

circle.type=b5.Shape.TypeCircle;

circle.width=100;

// Create a polygon shape

varpolygon=newb5.Shape();

polygon.type=b5.Shape.TypePolygon;

polygon.vertices=[0,-100,100,100,-100,100];

Material Resources

Material resources are resources that hold information about physical properties of an object. Like Shapes, Materials are not stored in separate files. To create a Material you create an instance of a b5.Material class, for which the prototype is:

1

b5.Material(name)

Where name is the name of the Material object. However, this only creates an instance of a Material object, we still need to fill in the rest of the information.

fixed_rotation – Set to true to prevent objects from rotating, default is false

You can use material properties when you add physics fixtures to an Actor, e.g.:

1

2

// Add a physics fixture from a shape and material

actor.addFixture({shape:circle_shape1,material:material1});

Brush Resources

Brush resources are resources that are used to fill shapes and create bitmap animations. Booty5 currently supports two kinds of brushes:

Gradient – A gradient brush is used to create fill styles that draw gradients on shape and text based actors (ArcActor, RectActor, PolygonActor and LabelActor)
ImageAtlas – An ImageAtlas brush is used to draw different bitmap animations frames on an Actor

Note that all brush types use the resource type “brush”, so when searching for a Gradient or ImageAtlas resource ensure that you search for the “brush” type.

Gradient

The Gradient is a an object that stores gradient information. A gradient is made up of a number of colour stops which define a colour and distance along the gradient at which the colour should appear. For example, if I specify a colour at distance 0 then this colour will appear at the start of the gradient. If I specify a distance of 1 then the colour will appear at the end of the gradient. All colour in between will be smoothly interpolated to create the gradient. Lets take a quick look at an example that shows how to create a gradient:

1

2

3

4

vargradient=newb5.Gradient();

gradient.addColourStop("#ff0000",0);

gradient.addColourStop("#00ff00",0.5);

gradient.addColourStop("#0000ff",1);

In the above example, we create a gradient with 3 colour stops:

A gradient stop with colour red at distance 0 (start of gradient)
A gradient stop with colour green at distance 0.5 (half way through the gradient)
A gradient stop with colour blue at distance 1 (end of gradient)

Once a Gradient has been created you should add it to a Scene or App resource manager so that it can be managed.

Once we have a gradient brush we can create a fill style from it and assign that to an Actor to be rendered, e.g.:

In the above example we call the b5.Gradient.createStyle() method to generate a fill style. createStyle takes 4 parameters:

w – Width of the gradient area (usually width of fill area)

h – Height of the gradient area (usually height of fill area)

start – Start point of gradient {x, y}

end – End point of gradient {x, y}

To see the gradient we set it to either the fill_style or stoke_style of the actor.

1

2

3

4

5

6

7

8

// Create an actor and assign the gradient fill style

varactor=newb5.ArcActor();

actor.x=-100;

actor.w=100;

actor.radius=100;

actor.filled=true;

actor.fill_style=fill_style;

scene.addActor(actor);

ImageAtlas

Booty5 creates bitmap animations by displaying one image after another, or more accurately one area of an image after another. The ImageAtlas brush is used to store bitmap frame information as rectangular areas as well as a sprite sheet based bitmap image. Each frame of animation has an x,y location in the bitmap and a frame width and height. Animation is achieved by displaying those different areas over time.

Lets take a quick look at how to create an ImageAtlas:

1

2

3

varatlas=newb5.ImageAtlas("sheep",sheep_bitmap);

atlas.addFrame(0,0,86,89);// Add frame 1 to the atlas

atlas.addFrame(86,0,86,89);// Add frame 2 to the atlas

In the above example we create an ImageAtlas object called sheep using the bitmap sheep_bitmap. We then add two frames, the first is located at x=0,y=0 in the bitmap and the second is located at x=86, y=0, both frames are the same size 86×89 pixels.

Once an ImageAtlas has been created you should add it to Scene or App resource manager so that it can be managed.

We can now assign this atlas brush to an actor to make it animate. Lets take a quick look at an example:

1

2

3

4

5

6

7

varactor=newb5.Actor();

actor.w=86;

actor.h=89;

scene.addActor(actor);

actor.atlas=atlas;

actor.current_frame=0;// Set initial animation frame

actor.frame_speed=1;// Set animation playback speed

In the above example we assign the atlas to the atlas property then set the frame_speed to begin the playback of the bitmap animation.

The b5.ImageAtlas.generate() method has been added to ImageAtlas to enable easy automatic generation of frames. Lets take a quick look at an example of how to use it:

1

2

varatlas=newb5.ImageAtlas("car_anim",car_bitmap);

atlas.generate(0,0,64,32,10,20);

The above example will generate 20 animation frames each 64×32 pixels in size, starting at x=0,y=0 on the bitmap, picking 10 frames across the bitmap then moving down 32 pixels then picking another 10 frames.