When building my Win8 port of Super Rawr-Type, I ran into all sorts of performance issues, due to lack of optimization. This was to be expected, as I on gave myself 1 month to complete the base game, then I would take the second and final month to port it to different platforms and worry about optimization.
The design of my levels is where most of my issues came from. I explain it pretty well in this post here. The gist of it is this: When the map loads, it is filled with ~150 enemies, which are constantly being updated. Obviously this comes with quite a bit of overhead. The browser version played well, but on a dedicated OS it chugs.
Removing all enemies
I went back to the drawing board and redesigned the way I spawn enemies now. The first thing I did was remove all entities (enemies) from the level.
I looked at a number of different ways for spawning enemies for shmup and bullet hell. Matt and Jason Doucette at Xona games do it in an interesting way for their upcoming title Duality-ZF: They store all of the enemies in an excel spreadsheet, which is then parsed by their game engine and appropriately draws the entities on screen.
Then again, they are using C# and running on the Xbox, whereas I’m running JavaScript on a PC, so JSON may be a more appropriate format here, if I were to take this approach. I don’t even think the Xbox has a way of parsing JSON; I know that Visual Studio just adopted JSON.NET, so it’s doubtful that the 8 year old Xbox has the ability to do the same.
Creating the Random Enemy Spawner
I found that my best approach was to create an entity, Random Enemy Spawner which sits just off the right side of the screen, and is always aligned on the Y-axis with the player. For debug purposes, I threw in placeholder art which is a copy of the player’s ship, and had it sit on the edge of the screen so that I could see not only where my enemies spawn, but also how frequently.
As you can see here, the enemies and spawner are all aligned on the X-axis. This may appear as though the enemies come in flat waves, but to counter that I have them all spawning on a timer. Three timers, actually.
I broke the enemy ships into three groups, and one example is illustrated below:
/****************************************** * randomFromTo * Random number generator * Courtesy of Liza Shulyayeva's flea project ******************************************/ randomFromTo: function (from, to) { return Math.floor(Math.random() * (to - from + 1) + from); }, /****************************************** * spawnEnemyGrpA * Spawns 1 of 2 types of enemies at random intervals ******************************************/ spawnEnemyGrpA: function () { // Resets random number var rndNum = null; // Rolls a random number rndNum = this.randomFromTo(1, 10); // Spawns enemies within the Y bounds of the screen this.randomSpawnLocY = this.randomFromTo(ig.system.height - 20, ig.system.height / 20); // determines which enemy type will spawn if (rndNum > 5){ ig.game.spawnEntity(EntityEnemyShip01, this.pos.x, this.randomSpawnLocY); } if (rndNum < 5){ ig.game.spawnEntity(EntityEnemyOrb, this.pos.x, this.randomSpawnLocY); } // Resets timer this.spawnTimerGrpA.reset(); },
I use spawnEnemyGrpB and C to spawn different types of enemies. They are set on timers like this:
/****************************************** * init * Handles initialization ******************************************/ init: function (x, y, settings) { ... // Spawning timers for enemy ships this.spawnTimerGrpA = new ig.Timer(this.randomFromTo(3, 9)); this.spawnTimerGrpB = new ig.Timer(this.randomFromTo(3, 8)); this.spawnTimerGrpC = new ig.Timer(this.randomFromTo(4, 9)); }
These timers are responsible for triggering enemy spawns at random times, which is what allows for a staggered appearance on screen.
I’ve noticed an incredible performance improvement from this, although it has been tricky to balance the difficulty. What I really need to do is create a variable that affects how frequently enemies are spawned, and that variable will adjust based on the chosen difficulty level of the game. A higher difficulty will obviously spawn more enemies at once.
The EnemySpawner.js class can be found in its entirety on my GitHub.
-----------------------@DaveVoyles
Pingback: Tutorial Links – AIN Online Journal