In this post I am writing about the onKilled event that is fired when a sprite is killed with the sprite.killed method in phaser ce. There is also the onDestroy event that is fired when a sprite is completely removed from the game world, and cache completely. In most projects I like to have a pool of sprite objects that I reuse, rather than the alternative which would be a mechanic where there is no set maximum of enemies that can be in the world. In any case it is good to be ware of both of these events, as well as the many other events that are fired by game objects in phaser ce.
For this posts full working example I made a simple little project that involves a pool of sprites that spawn from the upper left corner of the screen, and then move across the screen, wrapping around within the screen when going out of bounds. When a sprite is clicked it looses hp, and will be killed when hp reaches zero. At which point the sprite.events.onKilled event will fire, in this example I have some logic that determines how many points the player should get when killing the enemy.
For this module I went with just the Object literal module pattern, which works fine for this example as it is okay that everything is public. I then start off with a setup method that I will call in a boot state when making the phaser game instance later.
When I do call the setup method it will create an append a data object to the game instance when I call it with Function.call. Just appending a data object to the Phaser.Game instance is a common way to set some game wide variables.
Here is the handler that I will use with the sprite.events.onKill method.
So in this example each time an enemy is killed a points value will be figured out, and appended to the score property of my game.data object.
So another useful event is the sprite.events.onInputDown event. I this example I will want one of these attached for each sprite as well, so that when one is clicked by the player something happens in this case it looses a single hp point.
So this method will create a new data object for a sprite. The sprite.data object is an official phaser ce way of setting some values and methods for a sprite that are specific to the nature of the game itself that I am making. The sprite.data object is not used my phaser itself internally, so it is safe to do whatever seems right with it.
In this example I will just be setting some delta values, and a hit point value.
So this is just a simple demo rather than a real serious game that consists of many lines of code. Never the less I am using sprites, and I will want a way to skin these sprites, even if they are just solid colored boxes. So for many of my examples for these posts I like to use a canvas solution for making a sprite sheet.
So because this is an example of sprite.events.onKilled, I will be working with a pool of sprites. This is because of the differences between the sprite.kill, and the sprite.destroy methods. The sprite.kill method will set a bunch of properties of a sprite to a status that is that considered dead. The sprite can then later be reused by using a method like group.getFirstDead, or sprite.revive. This is very different from the sprite.destroy method that will completely remove the sprite from phaser all together.
So I am calling sprite.kill right after making the sprite to start it off in a dead state. I then have another method Enemy.spawn that will revive these at a set rate.
So here is my spawn method that will be called every second or so in the main state that will run this example.
Here I am using the group.getFirstDead method to get and revive the first dead sprite in the pool or group of sprites. In the event that they are all alive this method will return null, so i test if it is not before setting a new sprite.data object to it with the genSpriteData helper I made earlier.
So when I make a module like this I often have an update method as well that will be called each time there is a frame tick in the main game state when making my state objects of the instance of Phaser.Game
For this method I am using group.forEach to loop over all sprites an stepping there position with the current deltas in the sprite.data object.
So now to tie everything to together with a Phaser.Game instance an a few state objects. For this example I just have a boot state, and a demo state, I guess I could just have everything in a single state, but I like to start off with this even for simple examples like this one. In a real game there will end up being a lot of state objects, this helps to break things down, making them more fine grain. Fine grain code is often easier to read, and debug.
So like always I create a new instance of Phaser.game, setting a mobile friendly resolution of 32- by 240. I just about always set the renderer to Phaser.AUTO, and often have a div in my html with an id attribute of ‘gamearea’.
In my boot state I set up the game.data object with the Enemy.setup method, create the sprite sheet with Enemy.mkSheet, and set up the sprite pool with Enemy.createEnemyPool. Once way or another I need to share the instance of Phaser.Game with these methods, by passing them as an argument, or using Function.call to set the value of the this keyword.
I start the game by starting the boot state, that will set some things up, and then start the actual demo state. In the demo state I start a loop that will call Enemy.spawn every second to spawn a new enemy, and create a text display object to display the current player score.
In the update method of the demo state I call my Enemy.update method, and update the score to the latest value in the game.data object created with Enemy.setup
All of this results in an example where sprites in a pool a revived at a rate of one per second, the player can then click on one to damage it, and again to kill it. Once the sprite is killed the onKilled event that I attached to it fires, and in the body of this method I update the players score.