Creating Plasma battle animation - jjppof/goldensun_html5 GitHub Wiki

This tutorial will show how to build in GSHTML5 engine the Plasma psynergy battle animation without programming skills. For a complete reference of all battle animation resources, check Battle animations page.

Creating the spritesheet

You first need to create your spritesheet for plasma lighting images. You can use Texture Packer for this:

Image:

JSON:

You can set whatever the names of the frames you want. But frames index should always have zero pad 3.

{"frames": {

"lighting/000":
{
	"frame": {"x":1,"y":1,"w":48,"h":112},
	"rotated": false,
	"trimmed": false,
	"spriteSourceSize": {"x":0,"y":0,"w":48,"h":112},
	"sourceSize": {"w":48,"h":112}
},
"lighting/001":
{
	"frame": {"x":1,"y":115,"w":48,"h":112},
	"rotated": false,
	"trimmed": false,
	"spriteSourceSize": {"x":0,"y":0,"w":48,"h":112},
	"sourceSize": {"w":48,"h":112}
}}
}

Save both under the below path.

  • assets\images\abilities_animations\plasma.json
  • assets\images\abilities_animations\plasma.png

The name of the files must be the ability key name plus the extension.
If you have multiple animations, you need to pack all of them in a single spritesheet.

Initializing the animation recipe and starting in battle animation tester mode

The animation recipe is a JSON file that should follow this name pattern: <ability key name>_db.json. Then, you need to save it in the below area:

  • assets\dbs\abilities_animations\plasma_db.json

We can initialize this recipe like this:

{
  "key_name": "plasma",
  "cast_type": "psynergy_cast",
  "wait_for_cast_animation": false
}

We need to specify the animation key name by setting it at key_name property.
When warriors are casting abilities, they generally play specific types of casting animation before it. You define it at cast_type. For psynergy ability types, we want to set "psynergy_cast". For this recipe animation, you can check it here. The property wait_for_cast_animation will tell if we want to wait for this cast animation to finish before starting Plasma. In our case, we don't want it.

This is enough to start the engine in the battle animation tester mode. In order to do this, set start_battle_tester_on_init to true in init.json and then start the engine.
The engine will start in battle mode with an editor on the right side. Paste the plasma_db.json recipe there, we'll modify this JSON on the fly and test while we add features in the recipe. In order to fire the animation to aim at one target, press O; multiple targets, press P.
Please notice that changes in this editor won't reflect in plasma_db.json, you need to copy the content and paste in the original file to save it.

Lighting configuration and animation

In order to use the lighting sprite, we need to config it in the recipe like the following:

"sprites": [{
  "key_name": "cast",
  "per_target": false,
  "position": "between",
  "initial_config": {
    "x": "targets",
    "y": "targets",
    "blend_mode": "screen",
    "alpha": 0,
    "scale": {
      "x": 1.75
    },
    "anchor": {
      "x": 0.5,
      "y": 1.0
    }
  }
}]

Just append the above to the main object of the recipe.

The sprites key will hold all the sprites configuration you may use in the recipe you're mounting. It expects a list of objects, each object a sprite configuration. Later, we want to reference these sprites by their index inside this list. In this example, the index for the plasma lighting is 0.

key_name is the name of the set of frames (animation) you want to use, in our case, we are calling it "lighting" as we set in plasma.json. per_target is whether we want one sprite for each target, this is not the case here, independently of the number of targets, we always want only one sprite. position is whether we want to place this sprite below all battle sprites (allies and enemies), between them (which is this case), or above all of them.

We can also set some initialization properties for the sprite using initial_config. As you can notice in x and y properties, it's possible to set the values relative to targets' position, so we don't need to pass a raw number.

Now, we'll make it appear in the canvas by setting its alpha and playing the animation. For this, we have sequence battle animation properties, where we can control many aspects of the battle stage over time.

"play_sequence": [{
  "animation_key": "lighting",
  "start_delay": 1500,
  "sprite_index": 0,
  "frame_rate": 12,
  "repeat": false,
  "wait": true,
  "hide_on_complete": true
}],
"alpha_sequence": [{
  "to": 0.95,
  "is_absolute": true,
  "start_delay": 1500,
  "duration": 0,
  "sprite_index": 0
}]

With the above piece of configuration, we are saying to the engine that the lighting sprite animation should start playing (play_sequence) after 1500ms passed since the beginning of the animation, and also set its alpha channel to 0.95 (alpha_sequence) at the same time. Please notice that we are referring to the lighting sprite by setting sprite_index to 0, since it's the first element of the sprites property list.

This is the result we get:

plasma_1

Enemies animation and effects

Now we'll add some animations and effects to the enemies since they're getting electrocuted.

Damage animation

First we add the damage animation like below:

"play_sequence": [
  {...},
  {
    "animation_key": "damage",
    "start_delay": 1500,
    "sprite_index": "targets",
    "wait": false
  }
]

Damage animation is already built-in, you just need to pass it as the animation_key. Also, "targets" can be used here as the sprite_index, which is also built-in.

White blink sequence

The targets blink white a few times when they get hit. For this effect, we want to use the blink_sequence.

"blink_sequence": [{
  "sprite_index": "targets",
  "start_delay": 1500,
  "count": 1,
  "interval": 150
},{
  "sprite_index": "targets",
  "start_delay": 1800,
  "count": 2,
  "interval": 30
}]

As you can see, there are two moments the targets blink, one at 1500ms with a longer interval of 150ms. Another one at 1800ms with a smaller interval of 30ms, but it blinks twice.

Small jump after hit

The targets also do a small jump outwards from the stage center when they get hit. In order to reproduce this, we do the following:

"y_sequence": [{
  "start_delay": 1500,
  "to": -20,
  "is_absolute": false,
  "tween": "Linear.None",
  "sprite_index": "targets",
  "duration": 150,
  "yoyo": true
}],
"center_shift_sequence": [{
  "start_delay": 1500,
  "to": 15,
  "is_absolute": false,
  "tween": "Quadratic.Out",
  "sprite_index": "targets",
  "duration": 250
}]

y_sequence will do the movement in the y-axis, notice that yoyo is set to true, hence the targets will go up, then down. center_shift_sequence translates the targets outward from the center of the stage, this setting is special because it doesn't need the yoyo property. Every time a battle animation finishes, the battle system resets for all players the center shift value.

Final result

This is what we get when we implement everything above:

plasma_2

Background effects

The background also gets some effects in this animation, like darkening, colorization to a purple palette, and also a small shake due to lighting hit.

Darkening

This is a simple alpha manipulation by reducing it to 75%, then returning it back to 1.0:

"alpha_sequence": [
  {...},
  {
    "start_delay": 900,
    "to": 0.75,
    "is_absolute": true,
    "tween": "Linear.None",
    "sprite_index": "background",
    "duration": 400
  },{
    "start_delay": 1500,
    "to": 1.0,
    "is_absolute": true,
    "tween": "Linear.None",
    "sprite_index": "background",
    "duration": 200
  }
]

Please notice that now sprite_index is now set to the built-in "background".

Colorization

We can use the colorize filter to change the background to something closer to purple and create that plasma atmosphere.

"colorize_sequence": [{
  "sprite_index": "background",
  "start_delay": 1470,
  "color": 0.1,
  "intensity": 0.3
},{
  "sprite_index": "background",
  "start_delay": 1650,
  "remove": true
}]

Please notice that we need to add it at 1470ms, then remove it at 1650ms. You can check Battle animations wiki page for more info about this sequence. But color will vary according to below image:

Shaking

We can use the below to do a little shake in the background when targets get hit:

"shake_sequence": [{
  "sprite_index": "background",
  "start_delay": 1500,
  "interval": 50,
  "shake_count": 2,
  "intensity": 1,
  "direction": "y"
}]

Final result

This is what we get when we implement everything above:

plasma_3

Particles

To finish, the hardest part, the particles emission when targets get hit. Full particles reference at Particles engine.

Let's start with this basic setup:

"particles_sequence": [{
  "data": {
    "explosion": {
      "red": 152,
      "green": 48,
      "blue": 240,
      "lifespan": 1000,
      "velocity": {
        "initial": {"min": 0.7, "max": 6.0},
        "radial": {"arcStart": -90, "arcEnd": 90}
      }
    }
  },
  "zones": {},
  "emitters": [{
    "x": "targets",
    "y": "targets",
    "position": "between",
    "render_type": "pixel",
    "emitter_data_key": "explosion"
  }],
  "emission_delay": 1500,
  "emission_finish": 1800
}]

In order to setup particles, we need to config the emitter and the particles themselves.

If you check the emitter section, you'll see that it has source point location set in x and y. The particles are of "pixel" type, they'll be placed between enemies and allies, and the emitter will emit 250 particles.

The particles data is labeled as "explosion". And it has a purple color set by the "red", "green", "blue" properties. It has a lifespan of 1000ms. They will be emitted radially on the given arc range.

This is the preliminary result:

plasma_4

The particles are going up forever, but they fall a bit. For this, we add a bit of acceleration down and, for fine grain control, we also control how the velocity will behave over time with control property (check more details here).

"particles_sequence": [{
  "data": {
    "explosion": {
      "red": 152,
      "green": 48,
      "blue": 240,
      "lifespan": 1000,
      "ay": 0.04,
      "velocity": {
        "initial": {"min": 0.7, "max": 6.0},
        "radial": {"arcStart": -90, "arcEnd": 90},
        "control": [{ "x": 0, "y": 1 }, { "x": 0.5, "y": 0.75 }, { "x": 1, "y": 0.25 }]
      }
    }
  },
  "zones": {},
  "emitters": [{
    "x": "targets",
    "y": "targets",
    "position": "between",
    "render_type": "pixel",
    "total": 250,
    "emitter_data_key": "explosion"
  }],
  "emission_delay": 1500,
  "emission_finish": 1800
}]

Then:

plasma_5

Now, we finally add some trails and white core to the particles, which is very characteristic of the Golden Sun games:

"particles_sequence": [{
  "data": {
    "explosion" : {
      "red": 152,
      "green": 48,
      "blue": 240,
      "lifespan": 1000,
      "ay": 0.04,
      "velocity": {
        "initial": {"min": 0.7, "max": 6.0},
        "radial": { "arcStart": -90, "arcEnd": 90 },
        "control": [ { "x": 0, "y": 1 }, { "x": 0.5, "y": 0.75 }, { "x": 1, "y": 0.25 } ]
      }
    }
  },
  "zones": {},
  "emitters": [{
    "x": "targets",
    "y": "targets",
    "position": "between",
    "render_type": "pixel",
    "show_trails": true,
    "trails_clear_factor": 0.3,
    "pixel_size": 8,
    "pixel_reducing_factor": 0.027,
    "pixel_is_rect": false,
    "particles_display_blend_mode": "screen",
    "render_white_core": true,
    "core_custom_color": "rgba(255,255,255,0.85)",
    "total": 250,
    "emitter_data_key": "explosion"
  }],
  "emission_delay": 1500,
  "emission_finish": 1800
}]

We also changed the pixel size for the particle and its format to circle.

Final result

Final recipe

{
  "key_name": "plasma",
  "cast_type": "psynergy_cast",
  "wait_for_cast_animation": false,
  "sprites": [{
    "key_name": "lighting",
    "per_target": false,
    "position": "between",
    "initial_config": {
      "x": "targets",
      "y": "targets",
      "blend_mode": "screen",
      "alpha": 0,
      "scale": {
        "x": 1.75
      },
      "anchor": {
        "x": 0.5,
        "y": 1.0
      }
    }
  }],
  "play_sequence": [{
    "animation_key": "lighting",
    "start_delay": 1500,
    "sprite_index": 0,
    "frame_rate": 12,
    "repeat": false,
    "wait": true,
    "hide_on_complete": true
  },{
    "animation_key": "damage",
    "start_delay": 1500,
    "sprite_index": "targets",
    "wait": false
  }],
  "alpha_sequence": [{
    "to": 0.95,
    "is_absolute": true,
    "start_delay": 1500,
    "duration": 0,
    "sprite_index": 0
  },{
    "start_delay": 900,
    "to": 0.75,
    "is_absolute": true,
    "tween": "Linear.None",
    "sprite_index": "background",
    "duration": 400
  },{
    "start_delay": 1500,
    "to": 1.0,
    "is_absolute": true,
    "tween": "Linear.None",
    "sprite_index": "background",
    "duration": 200
  }],
  "blink_sequence": [{
    "sprite_index": "targets",
    "start_delay": 1500,
    "count": 1,
    "interval": 150
  },{
    "sprite_index": "targets",
    "start_delay": 1800,
    "count": 2,
    "interval": 30
  }],
  "y_sequence": [{
    "start_delay": 1500,
    "to": -20,
    "is_absolute": false,
    "tween": "Linear.None",
    "sprite_index": "targets",
    "duration": 150,
    "yoyo": true
  }],
  "center_shift_sequence": [{
    "start_delay": 1500,
    "to": 15,
    "is_absolute": false,
    "tween": "Quadratic.Out",
    "sprite_index": "targets",
    "duration": 250
  }],
  "colorize_sequence": [{
    "sprite_index": "background",
    "start_delay": 1470,
    "color": 0.1,
    "intensity": 0.3
  },{
    "sprite_index": "background",
    "start_delay": 1650,
    "remove": true
  }],
  "shake_sequence": [{
    "sprite_index": "background",
    "start_delay": 1500,
    "interval": 50,
    "shake_count": 2,
    "intensity": 1,
    "direction": "y"
  }],
  "particles_sequence": [{
    "data": {
      "explosion" : {
        "red": 152,
        "green": 48,
        "blue": 240,
        "lifespan": 1000,
        "ay": 0.04,
        "velocity": {
          "initial": {"min": 0.7, "max": 6.0},
          "radial": { "arcStart": -90, "arcEnd": 90 },
          "control": [ { "x": 0, "y": 1 }, { "x": 0.5, "y": 0.75 }, { "x": 1, "y": 0.25 } ]
        }
      }
    },
    "zones": {},
    "emitters": [{
      "x": "targets",
      "y": "targets",
      "position": "between",
      "render_type": "pixel",
      "show_trails": true,
      "trails_clear_factor": 0.3,
      "pixel_size": 8,
      "pixel_reducing_factor": 0.027,
      "pixel_is_rect": false,
      "particles_display_blend_mode": "screen",
      "render_white_core": true,
      "core_custom_color": "rgba(255,255,255,0.85)",
      "total": 250,
      "emitter_data_key": "explosion"
    }],
    "emission_delay": 1500,
    "emission_finish": 1800
  }]
}

Final animation

plasma_6