Jetboard Joust Devlog #68 – Ray Of Hope!

I felt the latest weapon deserved a post to itself as it took a bit longer than the others and I’m particularly pleased with the result.

It’s called the ‘Gamma Ray’ and I was deliberately going for a kind of retro 50s sci-fi vibe with it. As with the bulk of the weapons (probably more so), there’s actually very little to coding the mechanics of it – probably around 90% of the development time here was spent on the visuals.

The ‘ray’ effect is all created with a custom shader. At its heart it’s an approximated sine wave (calculated using the smoothstep algorithm) – to get it looking more ‘electric’ I vary the amplitude of the wave at random each cycle.

I had a lot of issues finding a technique for generating random numbers in HLSL that I was happy with. I tried out a couple of algorithmic solutions but none of these seemed to look much good to me. In the end I used a second texture as a ‘noise’ lookup table, I created this texture myself by rendering to a RenderTarget2D in MonoGame so I could be sure the ‘noise’ was perfectly distributed. I’ll probably write a simple tutorial post on this subject and include some PNGs with different type of randomness.

I didn’t like using a consistent wavelength for the shader as it seemed to make things too uniform so I tried varying the wavelength per frame. This looked much better but I ran into an issue where the ‘end’ of the ray looked weird if it didn’t taper out to a point, which it wouldn’t do when there wasn’t an exact number of wave cycles across the length of ray.

I tried fading out the end to get around this – this worked OK but not great and looked weird when the ray ‘collided’ with enemies or buildings. In the end I settled on a solution whereby I taper out both the amplitude and ‘stroke width’ of the wave to zero, this seems to work fine and, even with a fractional amount of cycles, the ray now always tapers out to a nice point!

Lastly I applied a raster effect to the wave (again in HLSL) and overlaid two different rays with wavelengths cycling at different rates. The wavelength of both waves in tweened using a ‘Bounce’ tween algorithm so it seems to cycle regularly but in a fairly non-linear fashion.

The concentric circles at the muzzle of the gun and at the point the ray hits something are created using the geometric shaders I discuss here, though I’ve added a raster effect and a gradual fade out.

Dev Time: 2 days
Total Dev Time: approx 134.5 days

previous | next

mockup_3x
One Of The First Drafts Of The Raygun Shader

mockup_3x
The Finished Raygun Effect

mockup_3x
The Gamma Ray In Action

mockup_3x
Gamma Ray vs Particle Storm
Advertisements

Jetboard Joust Devlog #67 – Finger On The Pulse

Started on the more space-age weapons this week! Got three done which isn’t bad going I guess, I would have liked to get started on another but, as you’ll see below, I wasn’t happy with one of these and decided to start again from scratch.

I also made a couple of changes to my particle system, the main one was adding the ability to align particles left, right, up or down when they’re drawn. This has added a great deal of flexibility in designing the various particle fx which has been the bulk of the work here.

Plasma Rifle
I wanted the first weapon to be pretty close to the feel of the player’s weapon in Defender or Jet Pac (which was probably based on Defender anyway). The actual logic here is pretty simple, a beam is fired and the ‘back’ of the beam moves at a slower rate to the front. Tweaking the particle fx is what took the time and there are three different particle states here, one for the ‘head’ of the beam, one for the ‘tail’, and one for the rings that are formed around it.

I also went through several iterations of the explosion at the end of the beam, going through a bunch of ideas that looked decent but too ‘geometric’ before settling on the version you see here.

Originally I was just performing collision detection for the ‘head’ of the beam but I found this looked a bit weird when enemies moved into the tail and nothing happened to them. Now I also check to see if an enemy has moved into the tail of the beam and apply a smaller amount of damage if they have (based on the theoretical strength of the beam at that point).

Pulse Cannon
I have very fond memories of the two Turok shooters on N64 and my ‘Pulse Cannon’ is somewhat inspired by the ‘Pulse Rifle‘ in those games. It fires rapid bursts of energy with a short delay between each burst.

The mechanics of this weapon were very simple as it’s just basic projectiles moving in a straight line. Again, what took the time was getting the visuals right. here I have a sprite for the centre of the ‘pulse’ and three different particle generators, one for the ring around the pulse and two for its trail.

Spreader
The last of this batch of weapons was originally going to be based on the ‘triple blaster’ found in a bunch of ‘bullet hell’ style 2D SHMUPs. I spent almost a day going down this path and tweaking some ok looking ‘fireball’ style projectiles (well, the particles are OK, the sprites in front looking pretty lame) but, when the weapon was finally done, I was left feeling rather disappointed with the result. It just seemed rather bland and lacked anything to differentiate it from the other projectile-based weapons in the game (of which there are many).

So I went back to the drawing-board and instead engineered a weapon that creates an expanding field of energy. Even after about an hour of experimenting I could tell that this was going to be much more effective, and it was. Of course it took a long time tweaking the particles again but there’s only two different generators here so less than the previous two weapons.

I didn’t like the energy field just fading out at full ‘spread’ as I felt this looked a bit weird, so instead I made it contract back to a point which seemed to look pretty cool. The damage done by the field of energy is based on how much of the enemy overlaps the field and how concentrated the field is at that point, focussing the field at the end therefore also has implications in the use of the weapon as it means that damage done is super-concentrated at that point.

I’ll probably re-use the original ‘spreader’ bullets for a bespoke enemy weapon or something later in the game. I suspect I haven’t given up tweaking some of these effects either, particularly the plasma rifle – I like it but there’s still something that’s not quite sitting right with me. I think I may like my original version better in some respects.

Also, ‘spreader’ is a bit of a shite name for a weapon. Sound more like something you use to plaster walls or make a toasted sandwich. Must think of something better.

Dev Time: 4 days
Total Dev Time: approx 132.5 days

previous | next


The Original Plasma Rifle


The Current Plasma Rifle

mockup_3x
The Pulse Cannon

mockup_3x
The Original (Shit) Spreader

mockup_3x
The Reworked Spreader

mockup_3x
Some Gratuitous Action With The New Weapons

Jetboard Joust Devlog #66 – Out With A Bang!

Well, all the major coding on the conventional weapons is now done so there’s just a few bits and bobs before I move on to the more ‘futuristic’ weapon set.

Firstly, I had to design upgrade UI icons for the weapons I’ve added over the past few weeks. These are 32×32 icons so require more detail than the in-game sprites. I was pretty much a #pixelart noob before starting this game and don’t find this type of drawing easy, one of the reasons I went with a limited colour palette (other than liking the ‘gameboy meets spectrum’ aesthetic) was that it would considerably narrow down my options when it came to the art and thus make the drawing considerably less intimidating. I think that was a good move.

You can see the final icons here – I’m not sure, in retrospect, that a square format was the best format to choose for these as many weapons are much more ‘landscape’ in shape – particularly things like R.P.G.s, making them tough to fit in that space without them looking too spindly and weak.

The other major thing to do was add audio for the new weapons. As with the rest on the in-game FX, I designed all the sounds using the DSI Tempest. I stick mainly to the analog oscillators but also use the digital oscs for noise and (sometimes) a pure sine wave. I really love the Tempest for this type of sound design work, the eight-slot mod matrix makes it incredibly flexible, yet it’s really intuitive to use for a synth that’s so deep. Yeah, there’s a couple of things I really wish it had from a sound design perspective (individual level control over each analog osc and pre/post filter as a modulation target) but overall it’s a beast with just the right balance of flexibility and limitations.

I also used my cheapo Boss RV-100 ‘retro’ digital reverb unit and a couple of plug-ins for (sometimes fairly hardcore) compression and limiting.

Lastly, because I liked the chunky Gatling Gun bullets so much (see previous post) I’ve increased the size of the grenade and R.P.G. rocket. Also added a bit of spin to the grenade when it’s fired.

Getting the conventional weapon set done feels like a bit of a milestone so I’m pleased that’s done! next step – plasma rifle!!

Dev Time: 2 days
Total Dev Time: approx 128.5 days

previous | next

mockup_3x
Upgrade Icons For The Conventional Weapon Set

mockup_3x
Tweaking Sounds On The DSI Tempest

mockup_3x
Bigger Grenades With Added Spin!

Jetboard Joust Devlog #65 – Bullet Hell

For the last ‘conventional’ weapon in the set I’ve decided to create an old-fashioned Gatling gun.

‘What’s that?’ I hear you cry – ‘There’s already a Gatling gun in the alpha!’

You’d be right of course, but it’s bothered me for a while that the Gatling gun in the alpha doesn’t really react much like a ‘proper’ Gatling gun. It’s far too ‘polite’ and doesn’t have the all-important ‘wind up’ effect where the speed of fire starts slow but increases to ridiculously fast as you keep the trigger held. I remember particularly enjoying the Gatling gun in the underrated ‘Bulletstorm‘.

I’m still keeping the ‘old’ Gatling gun but this will be renamed ‘Uzi 9mm’ which seems more fitting for the way it operates.

Actually coding the ‘new’ Gatling gun was pretty straightforward. As usual I spent most of the time tweaking explosions and the particle effects for the muzzle flash and the bullet trail. For the muzzle flash I’m using a new geometric shader type called ‘burst’ based on offset circles. I was particularly pleased with the bullet explosions and will probably re-use this effect elsewhere in the game (maybe on a much larger scale for some real ‘oomph).

The gun gradually gets faster and more inaccurate as you hold down the trigger. It also recoils pretty badly. I’ve opted for super-big bullets which I think kind-of work (I think they’re funny anyway) even if they’re ridiculously big.

The bullets are the first time I’ve used sprite rotation in the game. I was a bit worried this would look out of keeping with the visual style (as the rotation is done at ‘full’ res rather than the game’s pixel resolution) but it seems to work fine.

So I’m pretty much done with the ‘conventional’ weapons now – just have to add sound FX for this one, the flamethrower, R.P.G. and grenade launcher.

Dev Time: 1.5 days
Total Dev Time: approx 126.5 days

previous | next

mockup_3x
The Original Gatling Gun – Now Re-christened Uzi 9mm

mockup_3x
New Geometric Shader – ‘Burst’
mockup_3x
Repeat Fire Takes A While To Get Going

mockup_3x
Does Jetboard Joust Now Qualify As A ‘Bullet Hell’ Game?

mockup_3x
Some Gratuitous Gatling Action

Jetboard Joust Devlog #64 – Rocket Science

Another day, another piece of overpowered weaponry. And on it goes…

This week’s project has been to add an R.P.G. And of course in this context that stands for ‘Rocket-Propelled Grenade’ rather than ‘Role Playing Game’.

In theory the R.P.G. is a very straightforward weapon to code. Shoot a projectile in a straight line that explodes when it hits something – job done. There’s nothing particularly complex about the mechanics of it at all.

What took the time in practice was tweaking the visuals. Because the R.P.G is a powerful weapon it needs to have a certain ‘wow’ factor attached, consequently I spent considerably more time animating the rocket’s travel and detonation than I have for any other projectile in the game.

When in flight the rocket has a spin animation and two particle generators, one that leaves a ‘thrust trail’ and one that generates a ‘flare’ at the rocket’s exhaust. For the explosions I made use of my new geometric shaders described in this post.

Another difference to other weapons is that the rocket is displayed ‘loaded’ into the launcher before it is fired. This means I have to cope with the scenario where the user is out of ammo (no rocket displayed) and also create an animation for when the next rocket loads. None of this was particularly complicated but it necessitated some changes in the way I deal with weapon attachments for the jetboard.

One area where the mechanics of the R.P.G. needed a bit of specialised treatment was in the distribution of damage when the rocket explodes. I had been working on a similar principle to the bombs and grenades in that damage would be applied equally around the rocket depending on how far away the enemy/player is. The problem with this was that, as the rocket detonates with a very powerful explosion, it was simply too easy to commit suicide by firing into a building or opponent at close range. To rectify this I created a kind of ‘safety zone’ behind the rocket. Characters positioned directly behind the rocket take significantly less damage, characters behind but above or below the rocket are still offered some protection but less so depending on how far away they are. You still have to be careful firing R.P.G.s when you’re low on health though!

Dev Time: 2 days
Total Dev Time: approx 125 days

previous

mockup_3x
Early Stages – Muzzle Flash And Recoil To Give The R.P.G. More ‘Heft’

mockup_3x
The R.P.G. Flight In Slow Motion

mockup_3x
Working On The Explosions

mockup_3x
Be Careful Using High Explosives When Your Health Is Low

Jetboard Joust Devlog #63 – Geometric Pixel Shader Tutorial

Been spending the last couple of days working on some geometric pixel shaders that I can use for various in game lighting effects to further juice up my explosions etc.

These may well be of use to others so I thought I’d get them into a serviceable state and do a mini-tutorial on their usage. OK, maybe ‘tutorial’ is too grand a word but I’ve commented the code thoroughly at least! Links to the HLSL source files for these shaders are included at the bottom of this article (scroll down).

I’m assuming the reader has a basic knowledge of HLSL – if not then there’s an excellent introductory tutorial here.

The shaders provided both draw a user-defined number of concentric shapes. The stroke width and spacing between the shapes can be set via user-defined parameters, as can the amount the spacing and stroke width increases at each iteration.

A parameter ‘multiply_increments’ allows the user to set whether the spacing/stroke width increment as applied linearly (by addition) or exponentially (by multiplication).

The supplied texture is used to draw the shapes (I often use a 2×2 white square), a user-defined tint can be applied to this.

All sizes, widths etc are calculated as a proportion of the texture size so usually between 0.0f and 1.0f though you can go larger than 1.0f if you wish some of your outer shape to be drawn outside of the texture (and therefore cropped).

Setting the shader parameters from your .net code would look something like the code below. Adjust these parameters over time to get the kind of trippy effects you see in some of the example GIFs. Maybe you could smooth these parameter changes using LERPing?

mockup_3x
Two Geometric Shaders Overlaid
Microsoft.Xna.Framework.Graphics.Effect shader = Game.Content.Load (“circles”);

// The tint that will be applied to the texture – set all values
// to 1.0 to leave the texture untouched
Microsoft.Xna.Framework.Vector4 tint;
tint.W = 1.0f; // alpha – 0.0f – 1.0f
tint.X = 1.0f; // red – 0.0f – 1.0f
tint.Y = 1.0f; // green – 0.0f – 1.0f
tint.Z = 1.0f; // blue – 0.0f – 1.0f
shader.Parameters [“tint”].SetValue(tint);

// The size of the first shape to be drawn
shader.Parameters [“size”].SetValue ( 1.0f );

// The stroke width of the first shape to be drawn
shader.Parameters [“strokewidth”].SetValue ( 0.1f );

// The initial spacing between shapes
shader.Parameters [“spacing”].SetValue ( 0.1f );

// The number of shapes
shader.Parameters [“repeats”].SetValue ( 3 );

// The amount by which spacing increases for each consecutive shape drawn
shader.Parameters [“spacing_increment”].SetValue ( 0.0f );

// The amount by which stroke width increases for each consecutive shape drawn
shader.Parameters [“strokewidth_increment”].SetValue ( 0.0f );

// Whether the spacing/stroke width increment as applied linearly (by addition)
// or exponentially (by multiplication).
shader.Parameters [“multiply_increments”].SetValue ( false );

// Adjust depending on how you’re doing your rendering
SpriteBatch.Begin (…);
shader.CurrentTechnique.Passes[0].Apply ();
SpriteBatch.End (…);

Probably also worth mentioning are the settings required to get the ‘endless loop’ effect you see in these GIFs. It’s pretty straightforward if the spacing and stroke width of shapes is consistent, but if not you need to tween the strokewidth and spacing so that they are the same for the second shape at the end of the loop as they were for the first shape at the start of the loop. It took me a while to get my head round this.

The code below shows some example values – don’t try and cut/paste this as it uses my own tweening classes and a wrapper class for the shader itself. It should be good enough to get an idea of how to set things up though…

// Initial stroke width relative to texture size
float width = 0.0025f;

// My wrapper class for the shader
shader = GeometryShader.CircleShader ();

// Used by my wrapper class – the size I’m drawing the texture on screen
shader.ScaleX = 506;
shader.ScaleY = 506;

// Set up initial spacing and stroke width for the shader
shader.Spacing = width;
shader.StrokeWidth = width;

// Spacing and stroke width will increase by 50% for each concentric shape drawn
shader.SpacingIncrement = 1.5f;
shader.StrokeWidthIncrement = 1.5f;
shader.MultiplyIncrements = true;

// Sets up the values to tween the size of the outer shape over a 30 frame seamless loop
// First two values are the start and end size
shader.TweenSize = new Tween (1.0f, 1.0f + shader.Spacing/shader.SpacingIncrement + shader.StrokeWidth/shader.StrokeWidthIncrement, 30, Tween.Linear);

// Sets up the values to tween the spacing over a 30 frame seamless loop
// First two values are the start and end spacing
shader.TweenSpacing = new Tween (width, width / shader.SpacingIncrement, 30, Tween.Linear);

// Sets up the values to tween the stroke width over a 30 frame seamless loop
// First two values are the start and end stroke width
shader.TweenStrokeWidth = new Tween (width, width / shader.StrokeWidthIncrement, 30, Tween.Linear);

And here are the actual HLSL source files. Note that I am pretty much a beginner at this stuff myself so I make no guarantees as to the suitability of this code for any purpose and I would welcome any contributions towards making it execute more efficiently.

I have plans to add more shape types at a later stage and combine these into one uber-shader that also also shapes to be combined in different ways. Watch this blog for updates…

circles.fx | squares.fx

If this is of use to you I’d welcome more followers on Twitter.

Dev Time: 2 days
Total Dev Time: approx 123 days

previous|next

mockup_3x
Two Circle Shaders Slightly Offset

mockup_3x
Square Shader With Additional Rotation Applied

Jetboard Joust DevLog #62 – Pulling The Pin

Been continuing with the ‘conventional’ weapons after finishing the dreaded flamethrower. Next one on the list – grenade launcher. Every self-respecting shooter should have one!

Thankfully this was a lot simpler than the flamethrower. A large chunk of the time was spent tweaking the grenade explosion – I wanted something that gave an ‘area of effect’ type flash and wasn’t able to do this without using a custom shader. Luckily I was able to re-use the ‘smoke’ shader I talked about here. I may tweak this some more but am pretty happy with it as is.

There were also a few issues with the movement of the grenade itself. I started with a simple ‘real world’ type physics model, the same I use for the falling pickups. This looked good but it was too hard to tweak the range for the different weapon levels and also hard to predict the range a grenade would travel for the enemy AI.

I ended up using LERPing for the horizontal movement. This meant I could predict and tweak the travel distance with 100% accuracy. When the grenade hits an obstruction LERPing is turned off and motion reverts to a ‘real world’ model.

Vertical motion remains a ‘real world’ model but I cheat a bit here as well, starting with a lighter ‘gravity’ applied to the grenade and increasing the gravity as the grenade reaches the end of its horizontal travel. This enables me to get a nice arc of travel for the grenade whilst keeping things playable and predictable for the enemy AI.

I’m still undecided as to whether I should allow grenade ‘suicide’ or only allow enemy grenades to damage the player…

Dev Time: 1.5 days
Total Dev Time: approx 121 days

previous|next

mockup_3x
Working On The Explosions

mockup_3x
Never Trust A Mutant With A Grenade Launcher!

mockup_3x
The Grenade Launcher Makes Earning Combos Easier!

mockup_3x
Remember The Martyrdom Perk In COD? Should I Allow This?

Jetboard Joust Devlog #61 – Flamethrower Blues pt. 2

Another huge lapse of time since the last update. Sorry! I’ve had my head down in contract work, been on holiday, had some private parking scammers issue court proceedings against me and had renovation work to do on a couple of rental properties. I can’t believe it’s been three months!

Contract’s over now though so back to it. I’m determined not to let ‘Jetboard Joust’ become vapourware. This post will be a bit sparse though as I can barely remember what I’ve been doing, it’s been spread over such a long period of time.

In the last post I spoke about getting the basics of the flamethrower action right. Now that was done I needed to make the flamethrower actually have an effect on enemies.

At a basic level this is very simple, I perform a straightforward ‘bounding box’ check on all the flamethrower particles and each enemy. Get the enemy to ‘burn’ in a visually convincing way wasn’t so simple though.

In my first approach I tried ‘sticking’ the flamethrower particles to the enemy once they came in contact. This just looked weird though as all the flames tended to appear in the same place rather than consuming the enemy as one would expect. It also threw up loads of other issues to do with the particles tracking the movement of the flamethrower (see previous post). After a while going down this route my code was starting to look so hacky, and the visuals were still so poor, that I decided to scrap it all and start again.

For my next approach I tried removing the flamethrower particles when they came into contact with an enemy and triggering a ‘burn’ animation instead. Even with a draft ‘burn’ animation this looked much better.

For the ‘burn’ animation itself I created a Flame class that utilised a similar particle effect to the flamethrower particles. After much tweaking I settled on the following ‘burn’ effect: whilst an enemy is burning flames appear at random locations over the enemy. Each flame has a sightly randomized lifespan. Flames may appear in front or behind the enemy, if they appear behind they are placed at the edges of the enemy so as not to be totally obscured from view. When a flame ‘dies’ it is replaced by another at a different location.

Next job was to get the enemy’s health to decrease in a way that made gameplay sense whilst the enemy burnt. I didn’t want health to decrease at the point of impact only, but for this decrease to continue as the ‘burn’ animation played out (to give the impression of the enemy’s health decreasing as they burnt).

What I ended up doing was maintaining a burn_damage variable for each enemy which stores how much it’s health should be depleted by over the course of a burn, and a burn_timer variable which stores the amount of frames the burn animation should last. When the Burn() method is called, burn_damage is increased appropriately and burn_timer set to at least 60 frames (more for very high damage values).

This approach gives a decent ‘slow burn’ effect whilst allowing me to tweak damage values easily to make gameplay sense. I also added something to make the flamethrower particles do less damage the nearer they are to the end of their lifespan.

Dev Time: 2 days
Total Dev Time: approx 119.5 days

previous|next

mockup_3x
The Finished ‘Burn’ Effect

mockup_3x
Enemy Health Depleting On A ‘Slow Burn’

mockup_3x
Flamethrowers At Dawn!

mockup_3x
The Flamethrower Upgrade Icon

Jetboard Joust Devlog #60 – Flamethrower Blues pt. 1

Been far too long since I updated the devlog, it’s not that I’ve been slacking but that there simply hasn’t been enough progress made to warrant writing anything. I’ve had my hands full with a big chunk of contract work and haven’t really been able to face yet more coding on my ‘off’ days, preferring to try and get the new Muleskinner Jones album finished instead. No luck with that yet either! Now I’m beginning to understand why so many #indiedev projects never reach completion, as well as feeling like I used to when I’d try and keep a diary and end up trying to write three month’s worth of entries in one go.

Anyway – there has been some progress. Now that the alpha’s done I’m starting to work on new weaponry and the first up is the flamethrower. I deliberately started with what I thought would (probably) be the hardest weapon to get right and it hasn’t disappointed on that score, hence splitting this entry into two parts. Firstly we’re going to deal with getting the flamethrower to look and feel right (which is as far as I’ve got at the moment), next up we’ll deal with collision detection and actually getting the thing to do damage to enemies.

My first attempts at generating a convincing ‘fire’ effect with particles were pretty ropey, at best they looked like one of those cannons that shoots streamers or confetti rather than flame, some kind of manic party popper. Eventually though, after going down far too many blind alleys, I realised I was superficially trying to recreate what a flamethrower looks like rather than how it actually works. A flamethrower, of course, doesn’t actually shoot flame – it shoots a highly flammable liquid which is ignited as it leaves the barrel.

So, instead of using a single particle emitter to despatch a bunch of particles from the barrel of the weapon, I worked on firing a bunch of imaginary blobs of liquid. Each of these act as individual particle emitters so they appear ‘on fire’.

You can see the first results of this approach on the right, alongside an approximation of the motion of the individual ‘flammable blobs’. At this stage things still looked nothing like a flamethrower but I could tell that I was at least on the right track (believe it or not this was a massive improvement upon my earlier efforts)!

The next step was to vary the intensity of the particles dependent on how long their parent ‘blob’ has been in the air. I imagined a very intense, focussed flame to start with that would gradually get weaker and less focussed as the ‘blob’ burnt out and dispersed. After some tweaking to this effect my flamethrower was actually starting to look pretty convincing!

Last tweak was to give the individual particles a small amount of vertical acceleration, as if the heat was making them rise, and I was now pretty happy with the way things looked. Unfortunately my job was far from done!

Up until this point I’d been testing the flamethrower whilst firing from a static position, of course as soon as I tried it whilst moving everything went horribly wrong! I had been applying ‘correct’ physics to the ‘blobs’ in that, when fired, they are given a horizontal force from the gun as well as a horizontal and vertical force based on the players movement. It just didn’t feel right in practice however and I could see I was going to have to apply some ‘fake’ physics in order to get things to play nice.

I couldn’t find anything much on the Internet to help me but I did find an interesting YouTube video on the physics of the flamethrower in Half-Life 2 which demonstrated that the flamethrower ‘blobs’ always move relative to the player rather than relative to the game world. I reworked my code to operate on this basis, it was a definite improvement but I felt things has now gone too far the other way and the flames felt too rigidly ‘stuck’ to the player, it looked particularly noticeable when the player switched direction.

So I applied a kind of ‘halfway house’ approach instead, keeping the blobs moving relative to the player as long as the player maintains the same direction and keeps ‘fire’ held. When the player changes direction or releases fire the blobs are ‘unstuck’ from the player, ie the force of the player’s currently horizontal and vertical motion is applied and they are left to move relative to the world.

This seemed to be a good compromise approach as it allows for strafing and general playability whilst also looking nice and ‘fluid’ as the player changes direction. Now I just need to figure out the collision detection…

Dev Time: 2 days
Total Dev Time: approx 117.5 days

previous|next


Deconstructing The Flamethrower – Flammable Blobs

mockup_3x
First Attempt With ‘Flammable Blobs’


Adding Particle Dispersion, Getting There…


Adding ‘Heat Rises’ Effect To Particles


Damn! It Looks Dreadful When You’re Moving!


Moving Relative To Player, Better But Too ‘Sticky’


The (Hopefully) Final ‘Halfway House’ Approach

Using A Custom Icon Font in Xamarin.Forms

Anyone who has done much mobile development work knows the pain of managing multiple bitmaps for devices with different screen resolutions. It’s a particular bugbear for Android developers due to the plethora of different devices available and the fact that Google’s default method of choosing appropriate resources (screen density) is not always an accurate indicator of screen size.

It would be much better all round to use vector graphics instead, but as (at the time of writing) native support for SVGs on both iOS and Android is patchy at best it’s no surprise that there’s no vector graphics support in Xamarin.Forms.

Fortunately there’s a decent workaround for monochrome vector graphics – use a custom font instead. You can either use an existing icon font such as Google’s excellent Material Icons set or the ones from Font Awesome, or use a tool such as IcoMoon which enables you to create your own font from SVG files created in Illustrator or similar.

So here’s how you do it, for the purposes of this tutorial we’re going to be applying Google’s Material Icons font to the Xamarin.Forms.Label control but the same approach can be used for different fonts and controls (e.g. Xamarin.Forms.Button).

You can download a .zip file for the project here.

1. Create A Custom Control
Just so we don’t get confused we’re going to create our own subclass of Xamarin.Forms.Label called IconLabel. Add a new empty class file to your shared project like so…

using System;
using Xamarin.Forms;

namespace CustomFontDemo
{
	public class IconLabel:Label
	{
		public IconLabel ()
		{
		}
	}
}

This custom IconLabel will work exactly like a standard Xamarin.Forms.Label on the whole, but for the purposes of this tutorial I’m going to add an instance of it to the page that the default Xamarin.Forms app creates at startup. The resulting XAML looks like this..

<?xml version="1.0" encoding="utf-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" 
			 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
			 xmlns:local="clr-namespace:CustomFontDemo" 
			 x:Class="CustomFontDemo.CustomFontDemoPage">
	<local:IconLabel Text="Welcome to Xamarin Forms!" VerticalOptions="Center" HorizontalOptions="Center" />
</ContentPage>

Nothing remarkable here, if you run the app at this point it should operate exactly like the default Xamarin.Forms app. Now we’re going to get the icon font to work which requires a bit of platform-specific tinkering

2. Import Your Custom Font Into Your iOS Project
Right-click on the Resources directory in your iOS project and select ‘Add Files’. Navigate to the font file you have chosen on your hard drive and add it to the project. Once the file has been added right-click on it and check the ‘Build Action’ is set to ‘BundleResource’.

mockup_3x
Where To Import The Font File On iOS

Now select your ‘info.plist’ file and click the ‘Source’ tab. Right-click anywhere in the editor and select ‘New Key’. You need to change the name of the key from ‘Custom Property’ to ‘UiAppFonts’ and then add an entry where it says ‘String’ for the file name of your font. In this instance ‘materialicons.ttf’.

mockup_3x
Info.plist Settings On iOS

3. Write A Custom Renderer For iOS
Custom renderers are used when you want to override the default behaviour for a particular UI component on a particular platform. In this case we are overriding the default renderer for our IconLabel class to use the font we have just imported.

Add an empty class file to your iOS project and edit like so…

using System;
using UIKit;

using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;

// This informs the compiler that we're using this class to render an IconLabel on this platform
[assembly: ExportRenderer (typeof (CustomFontDemo.IconLabel), typeof (CustomFontDemo.iOS.IconLabelRenderer))]

namespace CustomFontDemo.iOS
{
	public class IconLabelRenderer : LabelRenderer
	{
		public IconLabelRenderer ()
		{
		}

		// sets the font for the platform-specific ui component to be our custom font
		protected override void OnElementChanged (ElementChangedEventArgs e)
		{
			base.OnElementChanged (e);

			double? fs = e.NewElement?.FontSize;
			// Note we're using the font family name here, NOT the filename
			UIFont font = UIFont.FromName ("Material Icons", (int)fs);
			Control.Font = font;
		}

		// Without this strange things happen if you update the text after the label is first displayed
		protected override void OnElementPropertyChanged (object sender, System.ComponentModel.PropertyChangedEventArgs e)
		{
			base.OnElementPropertyChanged (sender, e);
			if (e.PropertyName.Equals ("Text"))
			{
				Label label = sender as Label;
				// Note we're using the font family name here, NOT the filename
				UIFont font = UIFont.FromName ("Material Icons", (int)label.FontSize);
				Control.Font = font;
			}
		}
	}
}

4. Set The Text To The Appropriate Icon
Any custom icon font should come with documentation showing which icon maps to which unicode text character. Usually this is done with HTML-encoded values. For the purposes of this demo I’m going to use the value for the ‘favourites’ icon in Google’s Material Icons font. I can reference this directly in the XAML like so, note I’ve alse increased the font size for the label here too!

<?xml version="1.0" encoding="utf-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" 
			 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
			 xmlns:local="clr-namespace:CustomFontDemo" 
			 x:Class="CustomFontDemo.CustomFontDemoPage">
	<local:IconLabel Text="&#xE87D;" VerticalOptions="Center" HorizontalOptions="Center" FontSize="144"/>
</ContentPage>

Alternatively you can set the text in code using the WebUtility.HtmlDecode() method in the System.Net namespace.

Text = System.Net.WebUtility.HtmlDecode ("&#xE87D;");

Running the above code should give you a label displaying an icon from your custom icon font in iOS. To get things running in Android we have a similar (though slightly different) procedure.

5. Import Your Custom Font Into Your Android Project
Right-click on the Assets directory in your Android project and select ‘Add Files’. Navigate to the font file you have chosen on your hard drive and add it to the project. Once the file has been added right-click on it and check the ‘Build Action’ is set to ‘AndroidAsset’.

mockup_3x
Where To Import The Font File On Android

6. Write A Custom Renderer For Android
Add an empty class file to your Android project and edit like so…

UPDATE: I have discovered that using Typeface.CreateFromAsset in this way is extremely inefficient and can lead to serious performance issues when using a lot of labels etc. I have left the code as it is for the sake of clarity but really you should only initiate your typeface once (I do it in a static class). I would have presumed this type of caching would have been handled at the OS level but apparently not!

using System;
using Android.Graphics;

using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;

// This informs the compiler that we're using this class to render an IconLabel on this platform
[assembly: ExportRenderer (typeof (CustomFontDemo.IconLabel), typeof (CustomFontDemo.Droid.IconLabelRenderer))]

namespace CustomFontDemo.Droid
{
	public class IconLabelRenderer : LabelRenderer
	{
		public IconLabelRenderer ()
		{
		}

		// sets the font for the platform-specific ui component to be our custom font
		protected override void OnElementChanged (ElementChangedEventArgs e)
		{
			base.OnElementChanged (e);
			// Note we're using the filename here, NOT the font family name
			var font = Typeface.CreateFromAsset (Forms.Context.ApplicationContext.Assets, "materialicons.ttf");
			Control.Typeface = font;
		}
	}
}

And that should be job done – you now have scaleable vector-based icons using a custom font running on both iOS and Android in Xamarin.Forms!

You can download a .zip file for the project here.

mockup_3x
Custom Icon Font Running On Xamarin.Forms iOS

mockup_3x
Custom Icon Font Running On Xamarin.Forms Android