Time to leave enemies for the time being and move on to weaponry – really the last missing piece of the puzzle. If I’m going to make any new enemies they need to be tougher and it’s impossible to gameplay test them effectively with the underpowered pistol which is all I had implemented up to this point.
The first weapon I wanted to build was a shotgun, but before I got into designing the weapon itself I needed to think a little harder about how weapon swapping and ammo supply works in the game.
Up to this point if you run out of ammo you basically have no useable weapon available. This makes logical sense but seems kind of harsh. It becomes impossible to defend oneself so, unless there is an obvious ammo cache onscreen, death is pretty much inevitable. I needed to find a balance between keeping the necessity to drop down and pick up ammo caches (I like this part of the gameplay), not leaving the player totally ‘high and dry’ and not leaving them overpowered either.
My current solution to this is to use the pistol as a default weapon. If your current weapon runs out of ammo you will switch to the pistol automatically – if your pistol runs out of ammo then an ammo cache will automatically drop onscreen making it easy to reload but still, hopefully, enough of a pain to make the player try and avoid this situation if possible. Your ‘old’ weapon is placed in a weapon crate somewhere in the world meaning it can be retrieved and is not lost for good. These aspects of the game design may well need tweaking but at the moment this seems to provide a decent balance between the various parameters.
So, once the above was implemented, shotgun time! I thought the shotgun would be a pretty easy weapon to create but as it turned out I was wrong, no surprise there then.
First thing I did was work on the visuals. I ended up adding three different particle effects – one to represent the ‘pellets’, one for smoke from the barrel, and one as a kind of abstract explosion effect to give some idea of the effective range of the blast. I also added a very short sprite-based ‘muzzle flash’ animation. My weapon superclass already handles barrel recoil and recoil for the player so I put a nice bit of knockback in there to make the blast seem pretty weighty.
Lastly – collision detection. This is the part that I thought would be easy (as the shotgun blast is a one frame ‘hit check’) but turned out to be more complicated. You can’t get away with simple rectangle-based collisions (as I use in the rest of the game) as the blast range is really an arc, like a slice of pie. Fortunately some time ago I spent a while implementing some SAT-based collision detection routines in my game libraries so I could call on them now – luckily they worked (which is a good job as I remember SAT-based collision checking was pretty complex and I had no desire to go back rooting around that code)! What I do is approximate the blast ‘arc’ with a simple polygon and check whether that intersects the enemy’s collision rectangle. This seems to work fine (though I ended up widening the ‘hit range’ around the muzzle of the shotgun more than you see in the GIFs). I calculate the damage done to each enemy based on the distance from the muzzle both horizontally and vertically – a maximum 50% reduction in damage each way.
The next issue to raise it’s head was that I had to stop the shotgun blast being effective through buildings. This seemed like it was going to be complicated, I’d have to trace a line between the blast and the point it hit the enemy and see if any buildings intersected it, but I managed to implement a much cheaper solution which seems to work fine. All I do is see if there’s a side of a building between the shotgun muzzle and the enemy. If there is and the muzzle is below the level of the top of the building I assume the blast is blocked (as it would be the vast majority of the time). If the muzzle is above the top of the building and the top of the enemy is below the top of the building I also assume the blast is blocked. These two simple checks seem to cover off most scenarios realistically enough.
Once the shotgun was working as a weapon for the player I then needed to try arming the enemies! Because of the way I have structured my classes this was pretty simple but unfortunately it uncovered limitations in the enemy AI.
Up to this point I had been assuming an ideal place to shoot at the player is with the barrel of the weapon level with the centre of the player. This is still true with the shotgun but it won’t be true for all weapons (for example a grenade launcher) and there also needs to be additional logic for when an enemy decides whether to fire or not which takes into account the blast range of the shotgun.
So what I’ve done is implement two different methods as part of my Weapon superclass. One returns the ideal height at which to fire at the player and the other returns ‘true’ if the weapon is likely to hit the player if fired. These can both be overridden in the subclass to provide more weapon-specific logic. This architecture works great – enemies with shotguns are pretty deadly now and I’ll easily be able to extend to different weapon types to make enemies automatically change their behaviour based on which weapon they are carrying.
Last touch was to design some audio for the shotgun blast. I was going to leave any additional audio and do it all in one batch but seeing that shotgun fired and not make a sound was disturbing me!
Dev Time: 2.5 days
Total Dev Time: approx 62 days