Iteration 2 – Production Diary

Monday, 25th

At the end of Iteration 1, I encountered an issue where the game would crash if an enemy was killed by two monsters at the same time, due to it being removed from the enemy array. In an attempt to fix this, James and I looked into using groups instead, and extending the Phaser sprite class. However, the game was producing increasingly complex errors, mainly due to how I was having to handle collisions. Therefore, I decided to give the game a clean slate, and switch physics systems to Arcade.

I created a new repository on Github so that I wouldn’t lose my Iteration 1 code. However, looking back on this decision I could have created a separate branch in the same repository instead as this would have allowed me to gain proficiency in maintaining separate branches of code.

In Iteration 1, I gave my altar, tentacles, pause button and enemies sprite properties. To update my code, I changed how their classes worked to extend the sprite class instead. This enabled me to cut some useless code out that created animations for changing the altar’s current frame – now I use the setTexture method instead.

Tuesday, 26th

Today I worked on the tentacle physics group. When I initially created the group, I attempted to make it so that the group’s class was the TentacleClass. However, this didn’t work, as Phaser 3 was looking for properties that it couldn’t find. The fix for this was very simple, if I didn’t define the class or set any properties of the group then I could just add tentacles to the group whenever I need to.

One of my main goals for Iteration 2 is to update the UI for the game. The first way that I am doing this is by changing how the player summons tentacles. Instead of opening a menu that clutters up the screen, the player presses a button that creates a sprite that they can drag and drop wherever they want. Next, the player must press the button again to confirm their decision. To implement this, I created a SpriteButton class that will change the sprite’s frame when the button is pressed so that the player will be prompted to press the button again.

A small issue from Iteration 1 that I fixed was that some of the spritesheets looked slightly off. Turns out that I had set the margin on each of the spritesheets to 1px, when I needed to set the spacing that way. Since none of the spritesheets were more than two columns wide, I hadn’t seen any major visual problems so it took me adding a new spritesheet to notice.

Currently, the amount of health and blood the player has is displayed next to text explaining what each number represents. To make the UI more compact, I sourced a heart icon for health and created a blood droplet for blood. I then moved where the blood and health was displayed from the top left of the screen to the bottom right. I want to keep as much of the game UI in a bar at the base of the screen to keep the game clean.

I re-implemented the tentacle summoning mechanic but updated it to put the tentacles into a group and snap their positions to a grid made from 32 x 32 squares. To do this I created a new function that takes in a value x and rounds it to the nearest multiple of 32.

function snap_to_grid(x) {
     if (x % 32 >= 16) {
         x = (Math.ceil(x / 32)) * 32;
     } else if (x % 32 > 0) {
         x = Math.floor(x / 32) * 32;
     }
     return x;
 }

Wednesday, 27th

Today I went into university for several hours as I had my tutorial with Aaron and I wanted to get some additional help from James. During my tutorial, we discussed the improvements to the UI and how now that I have the core mechanics in place I need to focus on making the game more complete, such as adding Game Over screens, options and ways for the player to be more active in the game during attack waves. Furthermore, we briefly spoke about the essay at the end of the year. On Aaron’s advice, I made it so that as the player drags the tentacle around the screen to choose where to place it, the tentacle will snap to the grid.

A key feature that I added today was the enemy base class, as well as a simple art asset to represent the enemies. Whenever an enemy dies, regardless of if a tentacle killed it or it reached the altar, the player gains a small amount of blood. This is so that the player doesn’t get stuck if they can’t kill any enemies because they need more damage.

To give the tentacles an area in which they can attack, I created a hit radius group that has an overlap with the enemies. When the overlap occurs, the tentacle that is associated with the hit circle attacks the enemy.

My tentacles were instantly killing the enemies when they entered their area, even though they were supposed to have a 3 second cooldown on their attack. I resolved this issue by changing the value I passed to the tentacle class, as I had been stating the attack cooldown to be 3 milliseconds, rather than 3000 ms.

The last feature that I added today was a wave of attack system. To do this, I created a WaveProperties class that takes in all the modifiers that I want for a wave so that the level can use this information.

class WaveProperties {
    constructor(spawn_speed, total_enemies, health_modifier, damage_modifier) {
        this.spawn_speed = spawn_speed;
        this.total_enemies = total_enemies;
        this.health_modifier = health_modifier;
        this.damage_modifier = damage_modifier;
    }
}

I then created an instance of this class for each wave that I wanted and stored it in a wave_properties array that could be accessed from the base class whenever there was a new wave. These properties were then added throughout the code where needed, such as where the timer for spawning enemies is created, or where the game stores the amount of health an enemy starts with.

        this.wave_properties = [
            new WaveProperties(2500, 2, 1, 1),
            new WaveProperties(2000, 5, 1, 1.2),
            new WaveProperties(1500, 25, 1.1, 1.3)];

Sunday, 31st

Today I worked on making sure my production diary was up to date.

Monday 1st

My main focus for today was to work on the UI and to implement the pause/play mechanic. Also, I wanted to add in the tentacles attacking sound effect so that whenever they attack the player gets an audio cue.

To begin improving the UI I created a circle asset to show the attack radius of the tentacles. This was so that I could turn off debug draw which would clean up the appearance of the rest of the game, especially since I had to leave it on for testing during Iteration 1.

I updated the summoning button by changing it from being a blank blue square to having a symbol of a pentagram as this associated with the summoning of demons. When the player has tapped the summoning button it lights up red to show that there’s a monster ready to be placed and to indicate to the player that they need to tap it again to complete the summon.

I also started on an upgrade button sprite to use when I add in that feature. Plus, I created a blank red and green button that could be used for general purposes in case I needed them.

One of the key features that I added today was the pause play button. I did this by creating a new class called Pause that extends Phaser.Scene. When the player taps the pause button and the wave is attacking the game will load up the pause scene. When the player taps anywhere on the screen the game will resume. I found this simpler to implement than having a new pause play buttons spawn in for the pause scene. I added in a default case for the pause buttons frame so that it would show is playing in most cases this is because it would end up getting stuck on pause when the scene switched from pause to play.

A bug that I’d been having was that the game wouldn’t end when the last wave was reached. I found that this was due to the wave number was not reaching the total number of waves in the level when it was supposed to be. I fix this by changing how I checked for if the level was complete.

if (this.wave_no === this.no_of_waves - 1)

Wednesday 3rd

Today I started work on the upgrade button for the tentacles. I created a new upgrade button class that extends Phaser.Sprite. I spent quite a bit of time planning out how I wanted the tentacles to be improved when the player picks to upgrade them, and less time than I would have liked actually coding the upgrades. However, this does mean that when I finish working on the upgrade mechanic, I know exactly how I want to proceed.

class UpgradeButton extends Phaser.Physics.Arcade.Sprite {
    constructor(x, y, sprite_path, scene) {
        super(scene, x, y, sprite_path, 0);
        this.sprite_path = sprite_path;
        this.setInteractive();
        this.on("pointerdown", this.upgrade, this.scene);
    }
    upgrade() {
        //what improves when the tentacles are upgraded?
    }
    update() {
        //this.scene.upgrade_text.
    }
}

Firstly, I decided that when the player upgrades it will upgrade all of the tentacles rather than just a specific one. That way I can loop through the tentacle group and update each tentacle’s properties.

I initially came up with a list of ideas of how the tentacles could be upgraded to make them stronger. One of the ways that I could have chosen to upgrade them would be to increase attack radius however, this is me in that I’d need a new sprite and I’d need to create a new object for each tentacles attack area. I decided that this was a bit too complicated to implement at this stage.

A simple way to upgrade the tentacles and make them more powerful would be to decrease their attack cooldown. This would also give the player instant feedback that something has changed in exchange for them spending blood to upgrade.

Monday 22nd

The main feature that I worked on today was the upgrade button that allows the player to spend blood to make their tentacles stronger. The first thing that I did was change the upgrade button class to extend Phaser.Physics.Arcade.Image rather than Phaser.Physics.Arcade.Sprite which fixed an issue I was having where the upgrade button was not visible despite being interactive. When the player clicks the upgrade button it first checks if they have enough blood to afford the upgrade. Then it deducts the cost of the upgrade from the players total blood and it increases the tentacle level.

To upgrade all of the tentacles that the player has already summoned I iterate through them and increase their attack damage or decreasing their cooldown. Each time the player upgrades their tentacles the cooldown length decreases by 100ms; this allows me to scale the upgrade easily as I can multiply the current tentacle level by 100 and subtract that from the base cooldown of 3000ms.

To make sure that any new tentacles that are summoned were also upgraded I had to edit the way that values are passed to the tentacle class when a new tentacle is created. I also changed the way that attack power was passed from TentacleClass to MonsterBaseClass to ensure that it was accurate regardless of any upgrades.

Wednesday 24th

When I spoke to Aaron at the end of Iteration 1 he mentioned that the game was currently deterministic and suffered with a lack of interactivity during enemy waves. The first way that I dealt with this was by adding the wave system and upgrade functionalities. Today, I created an enemy modifier. Based on the current wave number there is a fixed chance of an enemy having different properties. The properties that I changed were: speed, health, damage and value when killed. This means that within each wave there is some variation and how the enemies behave causing the player to need to plan for a greater range of scenarios.

It was very simple to upgrade the health, damage or value of an enemy. On the other hand, it was more complicated to upgrade the speed due to the way I had the enemies follow the path. To get this to work I created a fast property that would either be true or false. Then, when the game moves the enemy along the path I have it check if the enemy is fast. If they are, then the game increments the pi value twice rather than once causing the enemy to move twice as fast.

The last feature that I added today was the ability of the game to move on to the next level if there was one. I did this by checking the config object to see if the next scene was a new level or the pause scene. This also allows me to add new levels to the game whenever I like without having to edit individual levels code.

  if (game.config.sceneConfig[level_num + 1].name === "Pause") {
      this.wave_text.setText("You Win!")
  } else {
      this.scene.Launch("Level_" + (level_num + 1));
  }

Saturday 27th

My goal for today was to tidy up the game and make sure that it was fully compatible with my target phone: the Google Pixel. The first thing I did was to create a Game Over scene that would allow the player to restart the game. However, upon looking into how to do this in Phaser, it’s quite complicated to completely reset a scene to its initial state. Consequently, I just gave the player written instructions to refresh the page to start again, as this would take less time, especially as I had already sunk a chunk of time into attempting to solve the problem.

A Google Pixel phone has a screen resolution of 960 x 544 pixels and I wanted to use a 32 x 32 tile size. Unfortunately, this isn’t a perfect fit, so my game’s default size was 960 x 540. Therefore, I decided to use scale manager to add a full-screen mode and make the game compatible with more devices. To allow the player to toggle this mode I added a small, white icon that enables and disables full-screen based on the current state of the game.

My final feature for the game was to add a tutorial to the start menu. First, I created a tutorial button in the same font as the start button. Then, I took an in-game screenshot where an enemy was visible and the player had summoned a tentacle. I put this into paint to add in text descriptions of what each button did, as well as an explanation of how to exit the tutorial.

Instead of using an image object for the tutorial, I used my existing button base class, since I wanted it to close when clicked. When the tutorial is clicked, its setActive and setVisible properties are made false so that it disappears from the screen and the player can’t accidentally interact with it. Due to object layering, I can simply overlay the tutorial over the start menu’s buttons as it makes them unclickable until it is no longer active. This prevents the player from being able to accidentally start the game or open the tutorial twice while attempting to close it.

Iteration 2 Planning

From Iteration 1, there were a few features that I had planned that I didn’t get to implement. These included some asset creation, a system for waves of attack, the ability to upgrade your monsters that you summon and a way to pause the game. The main tasks I’d like to carry over to Iteration 2 are the attack wave system, the pause button and allowing the player to upgrade their monsters. If I have time, I will add in the missing assets, but this is of low priority to me as the game functions without them.

At the end of Iteration 1, there were still some major bugs in the code that need to be fixed moving forward into Iteration 2. The most important fix to make is to stop the game from randomly crashing when multiple objects collide and the object is removed before the collisions can resolve for both objects. I want to make this my first priority during Iteration 2 as it renders the game unplayable without refreshing the tab.

Some smaller problems that I would like to fix are the attack radius for the tentacles being off-centre as well as the tentacles only attacking when an enemy enters or exits their attack area. This is a problem as it means that even if an enemy is moving slowly enough that it can be hit more than twice by the same tentacle, it will only be hit at most twice. Finally, where my menu overlaps with the game screen enemies passing through the area appear on top of the menu so I need to adjust how far forward they are.

Based on my feedback from the testing phaser of Iteration 1, I have a few features that are in my nice to have category. Personally, I want to add a second monster type, as this would add further decision making to the game as the player would need to chose which type of monster to summon to optimise their strategy. During feedback, it was suggested that I should add some way for players to be able to generate blood faster through some form of shrine or building. The last feature is grid snapping so that players cannot summon monsters super close together and they are encouraged to spread out their monsters further.

During Iteration 1, I followed a very strict planning schedule. However, due to events outside of my control such as falling ill, I couldn’t stick to it effectively. In fact, it caused more stress as I felt as though I was constantly behind on work despite making good progress. For Iteration 2, I want to use a more goal based style of development, where I have greater flexibility in the order in which I approach the tasks. This will also better allow for any bugs that pop up that slow down the rest of the development.

My main goals for Iteration 2 are:

  • Fix the random collision crash bug
  • Update/Streamline the UI. During one of our meetings, Aaron suggested moving the summoning of monsters out of a menu and simplifying it to a button press.
  • Implement a pause/play button to make the game more user friendly.
  • Add in grid snapping as troop placement can currently be unwieldy.
  • Upgradable monsters to give the player more to think about during attack waves.
  • Creating better icons that communicate what a button does more effectively to the player.

Overall, I’m pleased with the ideas and themes that came out of Iteration 1 and I want to carry that forward into Iteration 2. The main structure of the game is going to remain the same, just be improved upon. My summarising statement for the game is as follows: Blood Magic is a tower defense game where you use blood to summon and upgrade monsters to protect your altar from waves of oncoming enemies.

Iteration 1 – Production Diary

Monday 4th:

I had planned to set up the GitHub repo, start on the UI elements, and create a basic start screen.

To start creating the UI elements, I made a button class that I can use anytime I need to generate a button. I did this because the game will have a pause/play button, and a menu that the player will use for summoning towers. By have a pre-made button class, I can simplify how much code I need to do in the future. I had hoped to have a few more UI assets completed today, but I didn’t get round to it. I plan to catch up on the asset creation later in the week.

For the start screen, I placed a button in the centre (missing its asset) that the player can touch and it will load up the first level. I would like to possibly add an options menu in the future, but I’m unsure at the moment.

I started on a basic tower selection menu, that will pop-up over the game screen to allow the player to select and upgrade their towers. The menu currently doesn’t do anything, but it’s there.

Tuesday 5th:

Today in the morning I had planned to work on the monster base class, the altar that the player will protect and start on an example level. In the afternoon I wanted to make the unit summoning menu functional, and start on my collision detection system.

Instead, I spent the day in bed, feeling sorry for myself with a nasty cold and headache 🙁

Wednesday 6th:

Originally, I wanted to work on the path following system today, and create the maths functions for upgrading and purchasing towers. However, the majority of today was a repeat of yesterday, spent in bed, trying to recover.

In the evening, I had started to feel better, so I decided to attempt to catch up on some of the work that I had been unable to complete.

The main task that I got done today was creating a class for creating an Altar object. The main goal of the game is to protect your Altar, so it was important to get this object into the game in way that will allow me to summon a new one each scene without having to duplicate code.

When the player’s remaining health goes below a set threshold, I want the altar’s frame to change. I didn’t realise that I could use the simple setTexture method to change the frame of the sprite until after I had created single frame animations for the Altar’s different frames. In the future I would know to use setTexture instead, but as I had already written code to use animations, I left it as it was.

I also created the lose state for the game, by creating the take_damage function for the altar. To stop the game when the player’s health goes negative, I disable input and pause the scene’s physics. I started on the tower’s (monster’s) base class, creating a few properties that I feel may come in useful later such as health, attack_speed and level.

For the cost functions, I referred to my old maths notes from A level to find a suitable curve that would be fairly simple to graph. I used Desmos a graphing web app the adjust the curves until they were just right. On paper I rearranged the equations so that they had y on one side and could be used to return a value when needed.

My upgrade function is: 

Even though the graph has an asymtope at x = 10, it is still fit for purpose as I don’t want the player to be able to upgrade past level 10.

My cost function is: 

By using this function, I can continue to increase the cost of purchasing a troop without imposing a limit on the number of a particular type the player can have.

Thursday 7th:

My plan for today had been to create win/game over states, and start on an enemy attack system. Due to the fact that I was behind on other tasks, I was unable to begin work on these particular problems.

I glued together the images for the tentacle’s spritesheet using a tool by Leshy Labs that allows you to create a spritesheet just by uploading the individual frame images.

To create a path for the enemies follow, I looked at a Phaser tutorial that allows you to use interpolation to create smooth paths for your sprites to follow. It uses two arrays of values – one for x, one for y – that I want to read in from a Tiled tile map in the future. Currently, I am using placeholder arrays for testing, as I pass these arrays to the level base class from the instance of a level.

I also started work on the enemy base class, putting in a basic attack function, and attempting to create the update function to allow the enemy to move. I couldn’t test this yet as the game didn’t have a start button, but it wasn’t throwing any errors due to improper syntax, so I left it as it was and moved on to a different code task.

In the past, I had created a cooldown function for enemy attacks where the game would compare the current time to the time of last attack. I looked over my previous code to help in creating a cooldown function for the towers, so that they couldn’t spam attacks. I wanted to do this so that the enemies could pass through a few towers attack areas, forcing the player to spread their towers out across the path to the altar.

Monday 11th:

During the Game Design Document planning phase, I only created planning for the first week of development time. This was to allow me flexibility going into the second week in case of tasks that were incomplete, or bugs that may have popped up during the first week.

The key tasks that I had left to do at the beginning of this week were:

  • Complete a start screen
  • Spawn in enemies when the player hits start at set intervals or in waves
  • Work on unit placement mechanics
  • Put individual sprite frames into spritesheets
  • Add in a start/pause/play button
  • Collision filtering/detection
  • Add in currency the player can spend

I spent a good section of today planning out in what order tasks would need to be completed, to make sure that I could properly test each new section of code for bugs without having to rely on something else being completed first.

Wednesday 13th:

Today I focused my time on working on the start/pause/play button, as well as the tower summoning mechanic. I briefly started working on the base class for the first type of monster I wanted to implement – a tentacle that has a slam attack.

I started on the summoning system by looking at some of my past work to see how I had implemented touch controls in the past. I started out using the method from the Matter Game, however I found that it wasn’t working quite as I needed. It was suitable for swipe input, but I wanted a drag system instead. I decided to fix this another day, to allow myself to continue to work on other components.

To implement my pause/play button, I created a new PausePlayButton class. I couldn’t extend my previous button class as I used a sprite sheet for my new class, whereas the other class uses an image instead. I decided to use a state constant to check whether the game was paused, playing, or stopped. This was so that on my update loop, I could ensure that the correct frame of the sprite sheet was displaying based on what state the game was in. This will also help in the future once I make the button interactive.

Thursday 14th:

Today was a check-in day at uni, so I wanted to use that opportunity to get some help with a couple of errors that had been troubling me over the past week.

I fixed a simple problem where my tentacle class was unable to inherit from my monster base class by simply changing the order in which they were loaded in the index file.

I created a SpawnerButton class that inherits from the Button class to use for confirming if the player is happy with where they have placed their unit.

Since I want to read in my enemy paths from a tilemap, I created two functions to read in the tilemap data, and convert the information from the objects layer into the arrays needed for the path creation functions.

During the university session today, I spoke to James about a way in which I could prevent specific objects from colliding with one another. For example, I wanted to be able to display a monster over the top of the summoning menu background, whereas they were colliding with each other and the monster was being pushed off of the menu area. He explained that I could set the background to static to prevent it from moving and set it to a sensor to prevent it from colliding with other objects.

The next task that I moved onto was changing the controls over. Built into Phaser was a drag input function, that allowed me to update the position of the sprite as the player moves it. Furthermore, there was a dragend function so I could have the confirm button pop-up whenever the player stopped dragging the sprite around.

                    this.input.on("dragstart", function (pointer) {
                        this.menu_background.setActive(false);        
                        this.menu_background.setVisible(false);
                    }, this);
                    this.input.on("drag", function (pointer, object, drag_x, drag_y) {
                        object.x = drag_x;
                        object.y = drag_y;
                    });

Saturday 16th:

For today, I updated my pause/play spritesheet, as there were white corners on all of the images. I also created a basic, plain, place holder tilesheet as well as a level that I could use for testing and debugging. I also changed the dimensions of the game canvas by 4 pixels. Originally, I had matched it to the Google Pixel’s dimensions however, I needed the screen dimensions to be a multiple of 32. Unfortunately, I wasted a lot of time over a mistake that I made importing the tileset into Tiled. Instead of setting the spacing of the tileset to 1px, I set the margin to 1px. Since I didn’t notice this problem immediately, I spent a while trying to diagnose the issue in another way, hence I didn’t get much more done today.

Sunday 17th:

As today was my last day of development time, I focussed on making sure that the game was playable all the way through to ensure that my testing tomorrow will go as smoothly as possible. A small change that I made was to move where I loaded in the animations from the altar class into the level loader, since I had more than one sprite with animations to load now. I also moved the spawner timer for the enemies from the Level_1 class into the level base class so that it can be access from new levels in the future. I fleshed out the game over state, properly pausing the scene. Before, I wasn’t pausing the physics correctly, as I hadn’t used the Matter specific way of freezing it.

Another problem I fixed was the enemies weren’t quite following their path correctly, this was due to the fact that when loading in the path, I was incrementing up to the number of items in the passed arrays, rather than iterating for each pixel in the width of the screen. Next, I implemented the enemies attacking the altar and being removed from the enemy array. I needed to add a new level property that tracked how many enemies had been spawned in. This was so that I could remove enemies from the array without infinitely spawning enemies in.

My main time sink today was creating a collision detection system. In Matter physics, you cannot determine which objects have collided with one another using functions built into Phaser, you can only detect that two objects have collided with one another. Initially, before I noticed that I couldn’t tell what was colliding, I looped through every enemy setting up collisions with all the tentacles. However, after realising that this wouldn’t work, I changed my approach. To figure out how I could tell what was colliding, I put in console logs for information on the two bodies that were colliding. I quickly realised that the only information that the event tracked was about the bodies themselves, not the objects that they belonged to.

In order to determine what was colliding, I created two for loops – one for all the monsters and one for all the enemies. Initially, I loop through the monsters and check if one of the bodies matches the body of a monster’s attack radius. If more than one tentacle is detected, then the event is exited. If no tentacles were detected, then the event also exits. I repeat this process but with the enemies. If there is a tentacle and an enemy colliding, then the tentacle attacks, else the event is exited. I found the keyword “instanceof” very helpful, as it allowed me to determine if my variables for storing the tentacle and the enemy had already been filled, enabling me to exit the event earlier if two tentacles or two enemies were colliding.

        this.matter.world.on("collisionstart", function (event, bodyA, bodyB) {
            var tentacle = {};
            var enemy = {};
            for (var i = 0; i < this.tentacles.length; i++) {
                if (bodyA.id === this.tentacles[i].hit_box.id) {
                    if (tentacle instanceof TentacleClass) {
                        break;
                    } else {
                        tentacle = this.tentacles[i];
                        break;
                    }
                } else if (bodyB.id === this.tentacles[i].hit_box.id) {
                    if (tentacle instanceof TentacleClass) {
                        break;
                    } else {
                        tentacle = this.tentacles[i];
                        break;
                    }
                }
            };

When this system was complete, I was very pleased with the outcome. However, it does occassionally freeze up the game when a new object is spawned and a collision event trigger within the same frame. This is something I will need to aim to fix in iteration 2.

Monday 18th:

Today I fixed a few last minute issues from the night before just to tidy up my code and make the game better for testing. The main task I completed was showing the cost of summoning a monster to the player so that they were better aware of if they were currently able to summon an extra monster or not.

Tank Game – Production Process

You can find my version of the game here

To add a twist to the tank base game we were given, I decided to add in a super bullet attack for the player and land mines. The super attack was available on the Q key, and it was an instant kill if it hit an enemy; however, the player could only use this attack up to 3 times before they ran out of super bullets. The land mines would deal 1 point of damage to an enemy and were randomly placed through the level.

To create the super bullet, I needed to make a new physics group, with a maxSize of 3, to prevent the player from using it an unlimited amount of times. I adapted the existing try_shoot function to create a try_shoot_special function. My reason for creating a separate function rather than extending the existing one was that I needed to get a bullet object from a different group, it needed to handle damage differently and there needed to be a counter for each super bullet fired.

function fire_special(bullet, rotation, target) {
    bullet.setDepth(3);
    bullet.body.collideWorldBounds = true;
    bullet.body.onWorldBounds = true;
    bullet.enableBody(false);
    bullet.setActive(true);
    bullet.setVisible(true);
    bullet.rotation = rotation;
    this.physics.velocityFromRotation(bullet.rotation, 500, bullet.body.velocity);
    var destruct_layer = this.map.getLayer("destructibles").tilemapLayer;
    this.physics.add.collider(bullet, destruct_layer, damage_wall, null, this);
    for (var i = 0; i < enemy_tanks.length; i++) {
        this.physics.add.overlap(enemy_tanks[i].hull, bullet, special_hit, null, this);
    }  
}

As the special bullet was incapable of hitting the player (as only the player could fire them) I didn’t need to detect who was firing the bullet, I only needed to cycle through all the enemy tanks. Furthermore, when a tank was hit by the bullet, I didn’t need to call damage tank, instead I skipped that step and moved straight to destroying the tank.

function special_hit(hull, bullet) {
    ...
    enemy.damage_count = enemy.damage_max;
    enemy.damage();
    kill_bullet(bullet);
    var explosion = explosions.get(hull.x, hull.y);
    if (explosion) {
        activate_explosion(explosion);
        explosion.on("animationcomplete", anim_complete, this);
        explosion.play("explode");
    }
    if (enemy.is_destroyed()) {
        enemy_tanks.splice(index, 1);
    }
}

I still called the is_destroyed() method of the enemy, to act as a safety buffer in-case an error had occurred elsewhere in the code that caused the tank to still be alive.

While implementing the land mines, I had to shrink the image size, as despite being pixel art, it was massive and filled the screen. I used some trial and error to calculate how much I had to reduce the landmine’s size by, but in the end I was happy with the result. I wanted the landmines to be randomly placed around the screen, so I used the Phaser.Math.RND function to scatter them as best as possible.

for (var i = 0; i < land_mines.maxSize; i++) {
        var land_mine = land_mines.get(Phaser.Math.RND.integerInRange(game.config.width * 0.01, game.config.width), Phaser.Math.RND.integerInRange(game.config.height * 0.01, game.config.height));
        land_mine.setScale(0.035);
    }

My main criticism with the landmines now is that they can spawn on top of walls. If I had created a collision between the landmines and the destructible walls, this would have resolved the problem, and created a unique feel to each play of the game by changing the landscape slightly every time. Another spawn problem I had was that enemy tanks all spawn in the initial game area, making the rest of the level map feel empty and boring, I could resolve this using objects in tiled, and spawning tanks at those locations, but this would mean the tanks positions were fixed, and would remove an element of randomness from the game.

If I was to continue to work on this game slice, I would add in the ability for the landmines to blow up walls to prevent the overlapped spawning. Also, I have the issue of tanks still being able to shoot even after they are damaged to the point that their turrets were blown off. I feel it would add more realism to the game if the enemies were incapable of shooting at this point. Finally, I would make it easier for the player to tell how many super bullets they have left, as they currently just have to remember.

Prototyping Project – Production Diary

My prototype is for a 2D platformer game where you play as a robot (Tyler) and its’ inventor (Mike). Tyler has the ability to take on properties of objects which allows him to remove obstacles from Mike’s path to the end of the level.

30/10/18

Today I worked on the character sprites, the initial level design, and the movement/switch functions. I got some basic boxes in to represent the characters, and on paper I created a sketch of how I want the level to look, and what obstacles the player may encounter. Tomorrow I will continue on the switch function.
Currently, it changes the value in the switch function, and where it is called from, but not globally, which is a major issue. The movement left and right for Tyler is effective, but I’ve been unable to test it for Mike so far.

31/10/18

Despite being ill today, I completed the implementation of the character switch function, allowing me to test the movement for Mike. The reason why it wasn’t working yesterday was that I had used a single equals sign in an if statement, where instead I needed to use 2.

01/11/18

Today I found a tile sheet map to use for my platforms that was freely available online at:
https://www.gameart2d.com/free-platformer-game-tileset.html
I also began work on the jump function for Tyler. I have got him moving up and back down again when you press the jump key, but it happens so quickly that you can’t see it, however, I still have tomorrow before his movement needs to be complete.

02/11/18

Using a branch on Github, I restarted work on the jump function for the robot today. I mostly scrapped what I did in terms of physics yesterday, and started over through implementing gravity to ensure the player would fall to a platform. This meant I also had to edit the second character’s movement, but it was quick and easy to update.

04/11/18

Today I implemented my level design I had done on paper earlier in the week and I worked on collision detection for the platforms throughout the level. It’s not quite working yet, but I have planned for it to be completed it for tomorrow.

05/11/18

I got lots done today in the computer lab before my afternoon session and during it. I implemented the lava, well and exit objects. I also made it so that the lava can be turned to stone when Tyler is carrying water. I started working on the bush game bonus, but I didn’t quite get to finish it. Finally, I created a game over state for if Mike fell into lava and a game won state for if Mike reached the exit.

06/11/18

I have completed a reflective journal entry on the first week of this project, which can be found here.

I also completed the bush bonus object, so that you can water it to make it grow or burn it down using lava. Once I completed that, I created a level reader that took in an array of numbers from a file and stored them in the map and collision_map arrays to allow new levels to be loaded and played.

07/11/18

On paper I started designing a second level for the game, then I transferred it into two txt files to be read from by the game. Finally, I tweaked a few functions so that they were compatible with different level layouts, such as filling out the collision function. This needed to be done as I had only set up specific cases for the function, rather than fleshing it out completely to work for all cases.

08/11/18

In our session today we tested out each other’s prototypes, and I gained valuable feedback on my game which I will use in my write-up.