Phaser Runtimes
Friday, September 29, 2017 9:10 PMOverview
This document describes how to use the Phaser runtimes. The language of the runtimes is in JavaScript. We will go through an example of how to load an exported JSON file and play it back in the scene. Please note this runtime requires a WebGL enabled backend.
Grabbing the runtimes
You can either download the runtimes directly from the Creature Game Runtimes window or grab them from the repository here.
Picking a File Format and Runtime type
There are 2 types of runtimes you can choose: JSON/Creature FlatData or CreaturePack Web Format.
-
JSON/Creature FlatData : Gives you the full bone structure, is more feature complete but larger in size and more expensive to evaluate if you are not using point caching.
-
CreaturePack Web Format. : Only gives you the deformed points, uvs and colours. You do not get the skeletal structure of the character. However, it can be a lot smaller and is very cheap to evaluate, making playback very fast.
JSON/Creature FlatData
Included Scripts
Here are the scripts that need to be included:
<script src="phaser.js"></script>
<script src="https://raw.githubusercontent.com/toji/gl-matrix/master/dist/gl-matrix.js"></script>
<script src="CreatureMeshBone.js"></script>
<script src="CreaturePixiJSRenderer.js"></script>
<script src="CreaturePhaserRenderer.js"></script>
Loading and Initialization
Let us assume we have an exported dragon animation file called dragonTest.json. We also have its corresponding texture atlas called character-dragon.png. We start off by first loading the file assets:
function preload () {
game.load.text('dragonJSON', 'dragonTest.json');
// create a texture from an image path
texture = PIXI.Texture.fromImage("character-dragon.png");
}
...
The above will load the JSON data from disk and into memory. Next, let us create the actual objects that can make use of these loaded assets:
var actual_JSON = JSON.parse(game.cache.getText('dragonJSON'));
new_creature = new Creature(actual_JSON, false);
new_animation_1 = new CreatureAnimation(actual_JSON, "default", false);
new_animation_2 = new CreatureAnimation(actual_JSON, "pose2", false);
new_manager = new CreatureManager(new_creature);
new_manager.AddAnimation(new_animation_1);
new_manager.AddAnimation(new_animation_2);
In the example above, the JSON file has 2 animation clips: default and second. Hence, we will need to create 2 animations from the creature_manager object to make them available for playback.
Now that we are done loading, we can set the active animation to default for playback, as well as some playback properties:
new_manager.SetActiveAnimationName("pose2", false);
new_manager.SetShouldLoop(true);
new_manager.SetIsPlaying(true);
new_manager.RunAtTime(0);
We will now go ahead and create the object(s) required to render the character animation:
creaturePhaserObject = new Phaser.CreatureDraw(game.world,
game.world.centerX,
game.world.centerY,
new_manager,
texture);
creaturePhaserObject.scale.set(35.0);
game.world.add(creaturePhaserObject);
Character Animation Playback speed
Changing the playback speed is easy. It just involves setting a new value for the timeDelta attribute on your Phaser Creature Object:
creaturePhaserObject.timeDelta = 0.01; // or some other value
Complete Code Sample
Here is the complete code layout. Most the the code is generated from the default Phaser project starter template:
<!doctype html>
<html>
<head>
<meta charset="UTF-8" />
<title>hello phaser!</title>
<script src="phaser.js"></script>
<script src="https://raw.githubusercontent.com/toji/gl-matrix/master/dist/gl-matrix.js"></script>
<script src="CreatureMeshBone.js"></script>
<script src="CreaturePixiJSRenderer.js"></script>
<script src="CreaturePhasePhaserrRenderer.js"></script>
</head>
<body>
<script type="text/javascript">
window.onload = function() {
var game = new Phaser.Game(800, 600, Phaser.WEBGL, '', { preload: preload, create: create });
var texture = null;
var new_creature = null;
var new_animation_1 = null;
var new_animation_2 = null;
var new_manager = null;
var creaturePhaserObject = null;
function preload () {
game.load.text('dragonJSON', 'dragonTest.json');
// create a texture from an image path
texture = PIXI.Texture.fromImage("character-dragon.png");
}
function create () {
// Core Creature Objects
var actual_JSON = JSON.parse(game.cache.getText('dragonJSON'));
new_creature = new Creature(actual_JSON, false);
new_animation_1 = new CreatureAnimation(actual_JSON, "default", false);
new_animation_2 = new CreatureAnimation(actual_JSON, "pose2", false);
new_manager = new CreatureManager(new_creature);
new_manager.AddAnimation(new_animation_1);
new_manager.AddAnimation(new_animation_2);
new_manager.SetActiveAnimationName("pose2", false);
new_manager.SetShouldLoop(true);
new_manager.SetIsPlaying(true);
new_manager.RunAtTime(0);
console.log('Loaded and created Core Creature Objects.');
// Phaser Creature Object
creaturePhaserObject = new Phaser.CreatureDraw(game.world,
game.world.centerX,
game.world.centerY,
new_manager,
texture);
creaturePhaserObject.scale.set(35.0);
game.world.add(creaturePhaserObject);
}
};
</script>
</body>
</html>
Custom Time/Frame Range
You can set custom time/frame ranges for the currently active animation. Say you wanted to limit the playback to the frame range of 10 to 20, you would do the following:
new_creature_manager.SetUseCustomTimeRane(true);
new_creature_manager.SetCustomTimeRange(10, 20);
Animation Blending
You can blend between 2 animation clips by doing the following:
curManager.SetBlending(true);
curManager.SetBlendingAnimations("default", "pose2");
curManager.SetBlendingFactor(0.5); // 0 to 1 blends between the 2 clips
You can also perform Auto Blending, that is allow smooth transitions to happen automatically between animation clips. To do this:
// First enable auto blending, call this once
new_manager.SetAutoBlending(true);
// Now transition to a new animation clip.
// In this case we are transitioning to a clip called "back" smoothly with a delta of 0.1.
// The delta is a value > 0 and < 1.
new_manager.AutoBlendTo("back", 0.1);
Skin Swap
You can swap in/out items/clothing/weapons etc. if you setup Skin Swap groups in the Creature Editor. The Skin Swap information is exported out as a MetaData JSON in the export folder ( it has the .mdata extension ).
First, make sure you load the MetaData JSON into a JSON object in Javascript. Then, you should proceed to create the CreatureMetaData object:
// Create Meta Data object
var meta_data = CreatureModuleUtils.BuildCreatureMetaData(meta_json);
// Assign Meta Data object to your Creature object
new_creature.SetMetaData(meta_data);
To enabled Skin Swapping, call EnableSkinSwap on the CreatureRenderer object:
// This swaps to the new Skin. In this case, we swap into "cape" and enable it to true
new_creature_renderer.EnableSkinSwap("cape", true);
Similarly, to disable skin swap call:
new_creature_renderer.DisableSkinSwap();
Speeding up Load Times + Reducing Memory Usage with Creature Flat Binary Data
You can speed up load times + reduce memory usage of large character assets by converting your Creature JSON files over into the Creature Flat Binary Data format. If you are running out of heap memory on your device, we recommend using the Flat Binary Data format for loading of Creature character assets.
In the your exported Creature assets folder, there will be a file with the .bytes extension. That is your binary flat data file.
Using the Creature Flat Binary
First, retrieve the binary file as you would in your current framework. If you are unfamiliar with retrieving binary files on the web, you need to make sure the data is converted into a JS Uint8Array. Here is an example:
game.load.binary('dataBin', 'char_data.bytes', binaryLoadCallback, this);
where binaryLoadCallback is a function you write which does the following:
function binaryLoadCallback(key, data) {
// Convert our binary file into a Uint8Array
// We must return the data value or nothing will be added to the cache, even if you don't modify it.
return new Uint8Array(data);
}
After that, do the following:
var actual_data = CreatureModuleUtils.LoadCreatureFlatData(game.cache.getBinary('myFlatDataBinary.bin'));
new_creature = new Creature(actual_data, true);
new_animation_1 = new CreatureAnimation(actual_data, "idle", true);
As you can see, all you are doing is to grab a reference to the flat data object. Then set the last parameter in the Creature and CreatureAnimation creation to true. This triggers a binary flat data load.
CreaturePack Web Format
Tuning the CreaturePack Web Format
In the Game Engine Export Window of Creature, you have the following options:
-
Gap Step : This decides how much approximation is done on export. The higher the number, the smaller the file size but lower the quality. A value of 1 means no approximation. Try anything from 1 to 6.
-
UV Swaps : Check this on or off to decide whether to export UV swapping. If you are using image swaps, you should check this option to ON.
-
Color Changes :Check this on or off to decide whether to export any opacity changes. If you are fading regions, check this option to ON.
File sizes can be reduced quite a bit by increasing the Gap Step at the expense of some quality loss.
Included Scripts
You will need the following:
<script src="msgpack.js"></script>
<script src="CreaturePackModule.js"></script>
<script src="CreaturePixiPackJSRenderer.js"></script>
<script src="CreaturePhaserPackRenderer.js"></script>
Loading and Initialization
Grab the binary buffer of your file and pass it into the CreaturePackLoader:
creature_pack = new CreaturePackLoader(game.cache.getBinary('raptorPack').buffer);
Rendering
Create the CreaturePackDraw object and add it onto the scene:
creature_pack = new CreaturePackLoader(game.cache.getBinary('raptorPack').buffer);
console.log('Loaded and created Core Creature Objects.');
var creature_renderer = new Phaser.CreaturePackDraw(game.world,
game.world.centerX,
game.world.centerY,
creature_pack,
texture);
creature_renderer.pack_renderer.setActiveAnimation("default");
creature_renderer.scale.set(15.0);
creature_renderer.timeDelta = 1;
game.world.add(creature_renderer);