Category Archives: Development

Lerp Camera Motion Smoothing Tutorial and Example Code

Recently I’ve been revisiting at the way the camera works in Jetboard Joust (wishlist on Steam here!) something that has been a continual thorn in my side throughout the project.

When researching how to make the camera movement better I came across many references to Lerp smoothing but I found few, if any, detailed explanations as to how this works in practice and (particularly) ways to get around its significant limitations. Cue this post, by the end of which we’ll have a class that’ll move an object smoothly towards a target point and ‘brake’ so it reaches it exactly no matter how often and by how much the target is changed.

I’m just concentrating on one axis of movement here for simplicity but this approach can easily be applied to 2D or 3D vectors. For those of you with short attention spans you can just download the final class here.

So… Lerp is a quasi-acronym for ‘linear interpolation’ and used to create smooth movement between two points. It’s often used to smooth out camera movement but can equally be applied to sprites or anything else in 2D or 3D space. The basic equation for Lerp is very simple, it takes a position and target, works out the difference between them and then returns a value a specified amount along that path. Only values >0 and <1 are generally meaningful.

public static float Lerp(float position, float target, float amount)
{
     float d = (value2 - value1) * amount;
     return value1 + d;
}

If you are using this equation to move an object and each frame call it with the object’s current position (keeping the other values the same) the object will move a smaller distance each frame which results in a ‘slowing down’ effect as the objects reaches its target. Here’s an example of this type of motion applied to a sprite. In this case the sprite is moving approx 480 pixels at a frame rate of 60fps with a Lerp value of 0.025.


Basic Lerp Smoothing

Now this looks pretty good already but, as you’ve probably figured out, there are issues. The first one is that using this approach the object will never actually reach its destination – this can result in a slightly jerky looking motion as it reaches the end of its trajectory as well as presenting potential issues if you want to do something when the destination is reached.

One way of resolving this is to implement a minimum amount of movement per frame. This can be anything you want but for many applications it makes sense for this to be one pixel.

Here’s a simple ‘Lerper’ class that implements this – each frame the amount of movement (LerpVelocity) is calculated and, if the absolute value of this is less the minimum velocity we clamp it at the minimum velocity. Of course this means that the object might now be in danger of moving beyond its target point so we check for this at well and make sure it doesn’t.

public static float Lerp(float position, float target, float amount)
public class Lerper
{
    public Lerper()
    {
        Amount = 0.025f;
    }

    // Returns the amount of movement at this stage of the lerp
    private float LerpVelocity(float position, float target)
    {
        return (target - position) * Amount;
    }

    public float Lerp(float position, float target)
    {
        float v = LerpVelocity(position, target);

	// If this is less than the minimum velocity then
        // clamp at minimum velocity
        if ( Math.Abs(v) 0) ? MinVelocity : 0 - MinVelocity;

	position += v;
	// Now account for potential overshoot and clamp to target if necessary
        if ( (v= target))
        {
            position = target;
        }
        return position;
    }

    public float Amount
    {
        get;
        set;
    }

    public float MinVelocity
    {
	get;
	set;
    }
}

Here’s an example of this in action. As you can see it looks much better…


Lerp With Minimum Velocity Applied

Still we have limitations though if we’re looking for really smooth movement. The next glaringly obvious one is that Lerp is ‘ease out’ only, the object will be moving fastest at the start of the sequence which makes it look like it’s being fired from a slingshot rather than smoothly accelerating from rest.

To resolve this I’m going to apply an ‘Acceleration’ property to my Lerper class. This ensures that, if the object is increasing in speed, the increase doesn’t exceed a specified amount. This requires a variable to store the amount of movement each frame.

public class Lerper
{
    private float previous_velocity;

    public Lerper()
    {
        Amount = 0.025f;
        Acceleration = float.MaxValue;
    }

    // Returns the amount of movement at this staget of the lerp
    private float LerpVelocity(float position, float target)
    {
        return (target - position) * Amount;
    }

    // Returns the next position with lerp smoothing
    public float Lerp(float position, float target)
    {
        // get the amount to move
        float v = LerpVelocity(position, target);
        // don't allow increases in velocity beyond the specifed acceleration
        if ( v>0 && previous_velocity>=0 && v-previous_velocity>Acceleration )
        {
            v = previous_velocity + Acceleration;
        }
        else if (v < 0 && previous_velocity  Acceleration)
        {
            v = previous_velocity - Acceleration;
        }
        // If this is less than the minimum velocity then
        // clamp at minimum velocity
        if ( Math.Abs(v) 0) ? MinVelocity : 0 - MinVelocity;
        }
        // Remember the previous velocity
        previous_velocity = v;

        // Adjust the position based on the new velocity
        position += v;
        // Now account for potential overshoot
        if ( (v= target))
        {
            position = target;
        }
        return position;
    }

    public float Amount
    {
        get;
        set;
    }

    public float MinVelocity
    {
        get;
        set;
    }

    public float Acceleration
    {
        get;
        set;
    }
}

Here’s an example of this in action – now we have a nice ‘ease in’ to our Lerp motion. Here I’m using an acceleration value of 0.25f.


Lerp With Maximum Acceleration ‘Ease In’ Applied

There’s one other problem I’m going to address though. This ‘ease in’ effect works nicely if the object is initially at rest or moving in the same direction but if the object had previously been moving in the opposite direction we’re still going to get a nasty jolt. Here’s an example where I’m changing the destination to the opposite side before the previous Lerp has reached the end of its trajectory.


Sudden Changes In Direction Result in A Nasty Jolt

So we’re going to check for this in the code and again apply a maximum amount by which the velocity can change each frame. Remember that because we’re changing direction the absolute value of the current velocity at the point of change is the sum of the absolute value of both the current and previous velocities, ie a change in direction from 10 to -10 would result in a new velocity of -20.

A side-effect of this is that the object will probably end up moving away from the target until it’s gathered enough momentum to change direction. As the code that clamps to the target position assumes we are moving towards the target we have to max out the target value if this happens.

We also have a special case check for our minimum velocity here as we need to make sure that if the minimum velocity is applied its applied in the direction that moves towards the target (otherwise the object could get stuck moving in the wrong direction).

public class Lerper
{
    private float previous_velocity;

    public Lerper()
    {
        Amount = 0.025f;
        Acceleration = float.MaxValue;
        MinVelocity = 0;
    }

    // Returns the amount of movement at this staget of the lerp
    private float LerpVelocity(float position, float target)
    {
        return (target - position) * Amount;
    }

    // Returns the next position with lerp smoothing
    public float Lerp(float position, float target)
    {
        // get the amount to move
        float v = LerpVelocity(position, target);
        // don't allow increases in velocity beyond the specifed acceleration (ease in)
        if ( v>0 && previous_velocity>=0 && v-previous_velocity>Acceleration )
        {
            v = previous_velocity + Acceleration;
        }
        else if  (v  Acceleration )
        {
            v = previous_velocity - Acceleration;
            // we might actually end up moving away from the target
            // here in which case we adjust the target so we don't get
            // clamped to it later
            if (v  0 && previous_velocity  Acceleration )
        {
            v = previous_velocity + Acceleration;
            // we might actually end up moving away from the target
            // here in which case we adjust the target so we don't get
            // clamped to it later
            if (v > 0-MinVelocity)
                v = MinVelocity;
            else
                target = float.MinValue;
        }

        // If this is less than the minimum velocity then
        // clamp at minimum velocity
        if ( Math.Abs(v) 0) ? MinVelocity : 0 - MinVelocity;
        }
        // Remember the previous velocity
        previous_velocity = v;

        // Adjust the position based on the new velocity
        position += v;
        // Now account for potential overshoot and clamp to target if necessary
        if ( (v= target))
        {
            position = target;
        }
        return position;
    }

    public virtual void OnTarget(){}

    public float Amount
    {
        get;
        set;
    }

    public float MinVelocity
    {
        get;
        set;
    }

    public float Acceleration
    {
        get;
        set;
    }
}

Here’s what happens when you suddenly change the Lerp target with this code applied – as you can see we now have a nice smooth movement no matter how often we change the target value.


Lerp With Maximum Acceleration ‘Ease In’ Applied

And that’s pretty much it. You can download the final class file here – in the final version I’ve also added a MaxVelocity property, a delegate to be called when the object reaches its destination, and tidied up the code so its not quite so verbose.

If you are in the process of coding a camera for a 2D game I highly recommend you check out this excellent article.

If you are looking for something to move smoothly between two points over a specified number of frames then you’re probably better off using some kind of tweening rather than Lerp. Check out Robert Penner’s excellent tweening/easing functions or the ‘smoothstep’ algorithm approaches described here.


These articles take a lot of time and effort to put together. If you found this useful and would like to help me create more content like this like you can support me below – I really appreciate it!

Buy Me a Coffee at ko-fi.com

Granny Bait – The Making Of “Skateboard Joust”

Granny Bait: A term used back in the day to describe a game that had virtually no redeeming features but, because it had something ostensibly ‘youth’ in the title (and was cheap), would be bought in droves by clueless older folk as gifts for their disappointed grandchildren.

A while ago I wrote a post about ‘Subterranean Nightmare‘, my first commercial release for the ZX Spectrum. Whereas ‘Subterranean Nightmare‘ was something of a labour of love and represented a genuine attempt to create a decent game, my next title (I am somewhat ashamed to admit) was executed in a rather more mercenary manner. I can’t remember exactly what age I was when I started work on ‘Skateboard Joust’ but I was heading into my late teens. I was losing interest in videogames and starting to become far more interested in guitars, girls and beer. Guitars, girls and beer cost money though – and the best way I knew of to make a quick buck was to churn out another budget Spectrum title.

I never had the slightest interest in skateboarding but tying the game in with something that was relatively fashionable seemed like a good idea. I’d also never played ‘Joust‘, but I’d seen screenshots and knew it was made by the some people that made ‘Defender‘ (which I still rate as one of the finest videogames of all time) so it was bound to be pretty cool.

The central mechanic of the game involves destroying enemies with your skateboard which you can only do if you are mid-jump (not actually riding the board) and I still think this is a pretty sound gameplay concept. It’s not executed very well however and is extremely difficult to get the hang of (‘totally unplayable’ might be a better description). Then there’s the fact that, aside from a few pretty unimaginative powerups, this central mechanic is pretty much all there is to the game making it a fairly tedious experience.

The worst thing about the game though is that what appear to be the level backgrounds are actually in the foreground and serve no purpose other than to obstruct your view of a game that’s hard enough to play as it is. Making gameplay harder by simply obscuring what’s going on must surely be one of the most laughably bad game design ideas ever!

I remember borrowing chunks of code from my brother Tim (of I-Ball fame) who was always a much better coder than me, and recycling some of the graphics from ‘Subterranean Nightmare‘. I also added some of the most embarrassingly ‘wrong’ skate slang between the levels. Not my finest hour but I was paid a £2.5k advance by Silverbird which paid for a lot of beer.

The game was justifiably slated by Crash Magazine at the time, though in recent years some people have been rather kinder to it, notably the vg-junk blog. There’s also some drunk guy on YouTube who plays the game for around five minutes without realising that you can jump off your skateboard!

Bizarrely though the game had some devoted fans despite its awfulness – in the comments for this video there’s someone who seems to take great offence when people suggest that it might be a tad shit! I also ‘met’ the person who did the C64 version in this thread, turns out they got paid considerably more than I did for writing the original!

And no, I have no idea what I was thinking of when I designed those ‘extra’ life icons! They do look like some kind of demented frog!

World Of Spectrum entry here.

30 years later I’m now working on a sequel, ‘Jetboard Joust’, in order to balance out my karma for forcing such a terrible game onto the unsuspecting public. ‘Jetboard Joust’ builds on the central ‘Jetboard of Death’ mechanic and adds a whole lot more besides – you can wishlist it on Steam here and read about the development here.

30 years Later – The Sequel…
Read the instructions you fool!


The C64 Version (With At Least One Devoted Fan)!

cornflower
Recycled Graphics on Skateboards

cornflower
Yes, All That Shit Just Gets In The Way!

cornflower
Attack of The Roast Chickens

Creating Custom “Clicked” Event Handlers in Xamarin.Forms

Something I needed to do in a recent Xamarin.Forms project was to create a subclass of Image that had a custom ‘Clicked’ event handler attached. In other words, I simply wanted to be able to set Clicked=”MyHandler” in the XAML description of the image and have MyMethod called when the image was clicked – much the same as the Xamarin.Forms.Button class currently works.

Whilst I was used to catching touch events using TapGestureRecognizer, the syntax for setting up a custom event handler that could be set from XAML eluded me for quite some time and, as it was tough to find any decent examples online, I decided to create my own.

So here’s a simple ClickableImage subclass of Image with a custom Clicked handler added. The code is extremely straightforward so you could very easily copy and paste to create a similar ClickableLabel subclass of Label, or a custom ContentView, or whatever…

using System;
using Xamarin.Forms;

namespace Com.Bitbull.Examples
{
    public class ClickableImage:Image
    {
        // This is the event handler that will be set from your XAML
        public event EventHandler Clicked;

        public ClickableImage()
        {
            // Set up a gesture recognizer to respond to touch events
            TapGestureRecognizer tap = new TapGestureRecognizer();
            tap.Command = new Command(OnClicked);
            GestureRecognizers.Add(tap);
        }

        // Called every time the image is clicked
        public void OnClicked(object sender)
        {
            if (Clicked != null)
            {
                // Call the custom event handler (assuming one has been set)
                //
                // You could always subclass EventArgs to send something more useful than
                // EventArgs.Empty here but more often than not that's not necessary
                this.Clicked(this, EventArgs.Empty);
            }
        }
    }
}

These articles can take a lot of time and effort to put together. If you found this useful and would like to help me create more content like this like you can support me below – I really appreciate it!

Buy Me a Coffee at ko-fi.com

Creating Bindable Properties in Xamarin.Forms v3.0+

This is an updated version of what has proven to be one of the most popular posts on this site – a simple ‘cut and paste’ solution to create custom bindable properties in Xamarin.Forms. The original post can be found here.

Unlike many other online examples, this one allows you to set the property both programmatically and via XAML. I’ve updated the code to make it more ‘cut,paste,search,replace’ friendly and to get rid of the generic types which will be deprecated in future versions of Xamarin.Forms.

A lambda expression is used to route the PropertyChanged call back to the originating object – generally I’ve found this approach more useful than a static callback. Please excuse the gratuitous casting!

To use simply replace MyClass with the name of your containing class (which will be a subclass of BindableObject), FooBar with the name of your property, and the references to bool to the type of your property.

Hopefully the inline comments make the code self-explanatory. If you run into any problems or just find this useful please leave a comment!

#region foobarproperty
// Creates the bindable property using a lambda expression to route the PropertyChanged 
// handler back to the containing class
public static readonly BindableProperty FooBarProperty = BindableProperty.Create(   
    nameof(FooBar), 	// The name of the property you are creating
    typeof(bool), 	// The type of the property you are creating
    typeof(MyClass), 	// The type of your containing class
    false, 		// The default value of the property you are creating
    propertyChanged: (BindableObject bindable, object old_value, object new_value) => 
    {
    	((MyClass)bindable).UpdateFooBar((bool)old_value, (bool)new_value);
    });

/// Used to set your property programatically
public bool FooBar
{
    get
    {
        return (bool)GetValue(FooBarProperty);
    }
    set
    {
        SetValue(FooBarProperty, value);
    }
}

/// Called when the value of your property has been updated
/// 
/// Note that this method is only called when the property has CHANGED, not
/// if it has been set to the same value - take not of the default value!
private void UpdateFooBar( bool old_value, bool new_value )
{
    // Do whatever you need to do when the property 
    // has been set here. By the time this method is
    // called FooBar will already hold the updated value
}
#endregion

If you found this helpful I always appreciate more followers on Twitter!

Jetboard Joust Devlog #84 – Along Came A Spider…

I’m pretty resigned to the fact that these bosses are going to take me ages now, and the fact that I’ve finally come to this realisation weirdly makes the process of creating them considerably easier to deal with. Also I think I’ve made all the edits that the code needs to cope with enemies with multiple ‘hit spots’ and the like so I’m no longer having to go back and rework old code, this alone makes the process considerably less frustrating.

So, whilst this one took me knocking on six days and was still really hard work it felt like the easiest of the lot. I think a large contributing factor to this was the fact that the art came together really quickly (I was done in just over a day) and I feel much more in my comfort zone when I’m coding rather than pushing pixels.

I based the spider’s head and abdomen on ‘real’ reference material, though I also referenced much more stylised representations. I took the layout and proportion of the legs from a robot spider image I found somewhere on the net but changed the look and feel completely to fit in with the overall game style.

Animating the legs, mandibles and abdomen was done in code. This wasn’t difficult but was extremely time consuming as there’s so many moving parts (24 leg sections) which, as MonoGame is pretty ‘raw’, all have to be lined up and connected manually by working out pixel grid references and such. This is a pain in the arse – I guess engines like Unity and Unreal have ‘drag and drop’ tools that make this type of process much easier but generally I don’t like the bloat and overhead that comes with those types of tools and prefer the fact that MonoGame is pretty low level.

I’m calling this enemy the ‘spinner’ and it has three attack phases…

Stage One
In this stage the spinner is attached by a web strand to the top of the screen. It tracks the player very fast horizontally when in its ‘retracted’ state or attempts to divebomb the player when the player moves beneath it. This is the only way to get it to expose it’s fleshy, pulsating abdomen which must be destroyed in order to move to the next stage. When it hits the ground after a divebomb attack it spits out a burst of fireballs.

Stage Two
With its abdomen destroyed the spinner detaches from its web and begins to chase the player very aggressively. At regular intervals it will fire off bursts of a triple laser beam. In order to move to the next stage the player must shoot off all of its legs – its head and body are invulnerable until this happens.

Stage Three
Now legless, the spinner alternates between a mad spin attack in which it fires off a single laser at increasing speed, and a kamikaze style attack where it attempts to ram the player (its mandibles do a lot of damage). All of its body parts are now vulnerable to attack.

Generally I’m really pleased with this boss. There’s still something about the ‘lightbulb’ on its abdomen in stages two and three I’m not sure about so I may rework this but generally I think all the attacks are working pretty well, just need to be balanced in-game properly. I even had some time to add some custom audio for the lasers and fireballs, still need to go back and add this for the other bosses.

And I still need to add boss-sized bones and explosions!

Dev Time: 6 days
Total Dev Time: approx 185 days

previous | next

mockup_3x
The Final Art With All 24 Moving Leg Joints

Battling The Spinner – All Attack Stages In Action

Jetboard Joust Devlog #83 – Somethin’ Fishy Goin’ On…

God, these big enemies are hard!

I thought six days on the last one was extreme but this one has taken me pretty much eight full days. Probably over 50% of that time spent on the art. Basically these have pretty much morphed into ‘miniboss’ type creatures with multiple attack patterns (and in this case even spawning smaller enemies) which was never my intention but I feel like I have to kind of go with the flow. I am really struggling with motivation now though, this project is dragging on and on and ON and to be spending so much time on one thing at this late stage is extremely demoralising. I need to be earn some sodding money. Enough of my moaning though…

I decided to make this enemy a giant deep sea fish as deep sea creatures are weird, alien and creepy looking and have already been used for inspiration on some of the other enemies such as the squocket. My main source of inspiration was a fish called the fangtooth which seemed to have the right balance between looking weird and dangerous whilst maintaining an iconic fishy shape. I’m calling it the ‘snapper’.

Creating the basic shape in pixelart wasn’t too difficult and I didn’t go down nearly as many dead-ends as I did with the stinger so the process, whilst just as time-consuming, wasn’t nearly as frustrating. Most of the time I always felt like I was making progress. The scales were the hardest part to get right – it’s large area to cover and it’s tough to get the balance right. Not enough detail and things look flat and boring, too much detail and things look too ‘photographic’ and don’t gel with the rest of the game’s style. When the scales were defined as a simple filled pattern they looked too ‘flat’, like I’d obviously filled a stencilled area. If I applied too much shading to them they almost looked too ‘3D’ and ‘realistic’. In the end I offset the scales based on a pattern of concentric circles to give a slightly rounder shape to the body, limited myself to three different scale tones and didn’t allow a change of tone within an individual scale. This took forever but it finally seemed to give me the right degree of detail whilst maintaining a sense of stylised simplicity.

I thought the teeth and gills would be hard to draw but actually those parts came together really quickly, as did the ‘skull’ for the zombie attack phase. The spikes on the spine were rather more finicky and still need a bit of tidying up.

The other reason this took so long was that collision detection on an enemy of this size gets rather more complex. When I began work on the game I didn’t have ‘boss’ type enemies in mind so assumed I could implement a simple ‘one size fits all’ collision detection system. Unfortunately this doesn’t cut it when you have enemies that are complex shapes, some areas that act as ‘hot spots’ for damage, and other areas that you may want to collide with the player but not actually take damage themselves. I needed to find a way to allow for all this whilst avoiding having to go back and redo old code (particularly checking all the weapons again).

In the end I came up with a ‘CollisionProxy’ class. A CollisionProxy is spawned from a parent (the main sprite) and will both take and inflict damage on behalf of its parent (or not depending on the configuration). It also renders with a custom shader in sync with its parent when taking damage. Any sprite can have any number of proxies. So far this system seems to work well and I’ve hardly had to change any of my core code to implement it.

There’s also polygon-based collision detection on this enemy. Up until now I have been able to get away with simple rectangle-based collision detection. Thankfully I had already implemented SAT-based collision detection for convex polygons when I first ported my game engine to MonoGame so I had no extra work to do there – Thank God!! I think trying to add something like that at this stage would probably have killed me!

In its final(?) incarnation the snapper has three attack phases…

Stage One
Tracks the player fairly slowly. Unleashes either an aggressive charge/snap attack or spawns electric jellyfish from its mouth. Its jaws do more damage than the rest of its body and it will only take damage if you fire directly into its mouth (this was a PITA to implement collision-wise).

Stage Two
Loses its flesh and becomes a steampunk zombie fish. In this mode tracking of the player is faster and it’s two mounted ‘shredder‘ weapons are armed and fully dangerous. You need to destroy the engine mounted on its side to proceed to the next phase.

Stage Three
Now on its last legs (if it had any) the snapper tracks the player very quickly. It’s only defence at this point is a very aggressive kamikaze charge attack.

And that, at last, is it. Painful, but I think it was probably worth it. I’ve had some of the best feedback for the game so far from some of these images on Twitter. There’s still a few things I’m not 100% happy with. Art-wise the final phase needs some more engineering where the engine used to be and I might try getting rid of the eyeball on the zombie skull and replacing with a more skull-like eye socket. The second phase is also a bit weird – at the moment the whole enemy can take damage but it recharges until the engine is destroyed (so there’s a separate health meter for the engine). This is confusing. I should probably have the main enemy not take damage at this point and only have a health meter for the engine.

The difficulty will need some tweaking but I’ll have to do that in the context of the game more. Generally, I must admit, I am not a big fan of boss fights as they are often done so badly. In my opinion a good boss fight should seem ridiculously tough at first but be relatively straightforward once you’ve worked out a strategy. You shouldn’t die before you’ve even had a chance to get a decent look at the boss and it shouldn’t be a schlep to get there on every retry either. Though I thoroughly enjoyed both Dark Souls and Demon Souls to the point of obsession I found the ‘rinse and repeat’ style run to the bosses immensely tedious. I gave up at the final boss on both games because of this – life was simply too short! The bosses in this game will be optional and protect hefty rewards/upgrades rather than blocking your progress in the game.

I also still need to add some larger explosions befitting an enemy of this size!!

Dev Time: 8 days
Total Dev Time: approx 179 days

previous | next

mockup_3x
Fours Days Of Pixel-Pushing In Fifteen Seconds

mockup_3x
Fun With Collision Proxies

mockup_3x
Entering The Zombie Phase

Whoops – I Accidentally Added Boss Battles!

Jetboard Joust Devlog #81 – On A Roll!

In the late 1970s, when kids played with proper toys rather than tablets and smartphones, there was this marvellous toy called ‘BigTrak‘. I always wanted one, but they were way too expensive to buy and probably cost around £10k per year in batteries. I’m sure the reason there’s so many SUVs on the roads today is that all these 40-something-yr-old men are buying them as some kind of mid-life BigTrak substitute. I still think the BigTrak design looks pretty cool even today.

This enemy, the ‘crawler’, was very much inspired by BigTrak, but it wasn’t just a nod to seventies nostalgia. At the moment gameplay seems to gravitate very much towards the top of the screen and I wanted something other than pickups to take the player closer to the ground and amongst the buildings. A ground-based enemy seemed the logical choice to do this.

Usually I’d work on the art first but in this case I thought I’d run a few code tests first to see if the ‘tank’ type enemy I had planned had any kind of hope of succeeding. Maths is not my strong point, and as this vehicle would have to perform the impossible feat of traversing vertical slopes and 90° changes of gradient I needed to make sure it wasn’t going to look like arse before I wasted loads of time on the art.

To my surprise my initial tests worked very well. There’s no ‘physics’ at play here, the wheels (working independently) simply traverse the outer edge of the terrain in the most basic way. I then work out the angle between the wheels (i.e. the axle) and place and orientate the chassis based on this. It’s not physically ‘correct’ by any means as the distance between the wheels changes depending on the terrain but, as it’s performing impossible feats anyway, I didn’t think this mattered – I could get away with a telescopic axle! In the final version I added something to make the wheels roll more nicely around corners but other than that I stuck with my first approach, I made a couple of attempts to make things more ‘realistic’ but both ended up looking worse than the original.

Satisfied that I could make this work I then began work on the art. There were two keys things I had to bear in mind here. Firstly, the design needed to be such that the distance between the wheels could change without looking ridiculous as described above, and secondly that the vehicle could travel in either direction. I think you can get away with simply flipping sprites for left/right when they’re small but with larger sprites like this that approach can look pretty ropey.

At first I was working on a ‘tank’ type idea that was similar to BigTrak. I spent several hours on this but wasn’t happy with anything I came up with. Everything looked too clunky or too much like a motorbike. So I started experimenting with some radical changes and in the ended settled on a kind of armoured ‘push me/pull you’ design that I felt worked much better. It’s a complex affair though, the final unit comprises eleven different sprites, so getting these all lined up and positioned correctly was a very fiddly business!

Getting the guns to track the player was also fairly tortuous as one has to consider the rotation of the vehicle as well as the previous rotation of the gun to make things work smoothly. People with more of a maths brain probably find this stuff easy. I don’t, but I got there in the end.

The AI wasn’t simple either. For individual vehicles it’s pretty straightforward, but when they appeared in batches I was getting issues (as with the Squocket enemy) of them overlapping too much. In the end I created a ‘hive mind’ class that acts as a controller for a bunch of vehicles. This class works out the ideal positioning of each vehicle and then the individual vehicles track to this position.

Lastly I have the pilots of the vehicle man jetboards and make a last-ditch attempt to attack the player when their vehicle is destroyed. There’s a specific class for this type of enemy too (I’m calling it the Kamikaze) but it’s pretty much one of the basic minions with tweaked parameters.

EDIT: Aaarggh – I thought I was done but whilst working on some screengrabs for this post I ran into a hideous bug to do with the world wrapping (remember I talked about that here?). I was getting all sorts of problems caused by the vehicle wrapping at a different time to any of the buildings it was in contact with. Very difficult to find a solution for this so in the end I’ve settled on a bit of a hack whereby the vehicle stops moving if it’s very close to the edge of the world. This seems to work OK and I don’t think it will be too obvious in practice.

So, the most complex enemy to date but I’m pleased with the end result. I think I only really need a couple more like this and I can move on…

Dev Time: 4 days
Total Dev Time: approx 166 days

previous | next



Abandoned Art Direction – ‘Tank’

mockup_3x
The Finished Design – ‘Push Me/Pull You’

Guns Tracking Player And A Nicer Rolling Action Round Corners


Using A Variety Of Weapons To Dispatch Two Crawlers (Enlarged 150%)

Jetboard Joust Devlog #79 – Space Invaders

In my last post I wrote about maybe recycling the old ‘Evil Mother’ enemy into something based on the classic ‘Space Invaders‘ aliens, and that’s exactly what I’ve ended up doing!

I like the idea of including a few homages to the classic arcade shooters of yesteryear in Jetboard Joust, and as ‘Space Invaders’ was really the granddaddy of them all it’s an obvious choice. I wasn’t sure whether the formation/movement of the invaders would work within the horizontal/scrolling format of Jetboard Joust but, with a few tweaks, it actually seemed to work out pretty well.

It wasn’t too tricky to code either. I was worried that get the whole batch of invaders to move together around buildings and stuff would be a pain but it was pretty straightforward in the end.

What I do is move all the invaders as a batch rather than treating them as individual sprites. Collision detections are still handled individually and, when an invader collides with a building, it sends a message back to the batch telling it to change direction. When the batch is initiated I make sure it doesn’t take up more vertical space than the space between the highest building and the top of the screen so I know it’s never going to get stuck.

Probably the trickiest thing was deciding how to treat a batch of invaders when attacked by the ‘Gravity Hammer‘ weapon. Moving the whole batch at once would just look dumb so I needed a way of having individual enemies break formation when hammered and then return to the appropriate position once they recover.

To achieve this I have a property for each invader that stores its location within the batch separate from its position on screen. If the invader is forced to break formation it is relatively simple for it to return to its batch position. Though it wasn’t strictly necessary I also decided to have individual invaders track horizontally with the batch even when hammered (so only their vertical position is displaced). It just seemed to look better this way.

In keeping with the original I have the invader’s speed and rate of fire increase as individual invaders are destroyed.

Dev Time: 1 day
Total Dev Time: approx 160 days

previous | next

mockup_3x
Admit It – You’ve Always Wanted To Play ‘Space Invaders’ With A Flamethrower!

Using The Plasma Rifle To Dispense With A Batch Of Invaders


Jetboard Joust Devlog #78 – Return of the Evil Mothers

Too long since the last update. Had a lot of shit on – decided to fight a parking ticket issued by one of those fascist private parking companies and it ended up in court. I beat the tossers but it took so much time preparing the defence and everything I’m not sure if it was worth it, just did it on principle really as I don’t like scammers or bullies. Turns out these scumbags didn’t even have the right to operate on the land on which the ticket was issued in the first place!

Anyway, back on topic, the first major ‘new’ enemy is actually an ‘old’ enemy redone, but I don’t think there’s any shame in that. If you’ve been following this for some time you may remember the ‘Evil Mother‘ enemy. Well, I’d come to the conclusion that this enemy just wasn’t big enough and would work better (and make more sense) as some kind of mini mothership that spilled out its occupants when destroyed.

So I spent quite some time designing a kind of ‘bathysphere’ type craft. It’s actually several different sprites in one, the ship itself, the pilot, the ‘antennae’ on the top which acts as a weapon, plus the various lights. I’m pretty pleased with the result though a little worried it looks a bit too ‘2D’ and could do with some more shading or something to make it appear more ’rounded’.

I also increased the size of the enemies that spill out when the craft is destroyed and spent quite some time working on a much improved bullet that tracks the player’s movement in a similar way to the Limpet Mine. There’s also a ‘tell’ that the ship is going to fire as you can see the antennae at the top charging up.

The shaking effect is achieved by applying an offset to the ships position each frame. These offsets are always evenly distributed and chosen at random so it’s a very predictable type of brownian motion.

I think I’m going to use the original enemy design as more of a ‘swarm’ type enemy with a movement type that’s an homage to the original Space Invaders!

Dev Time: 3 days
Total Dev Time: approx 159 days

previous | next

Jetboard Joust Devlog #71 – (Black) Hole In One!

This was the first weapon that I really didn’t have much of a clue what I was going for when I started it and, ironically, it’s probably turned out to be the one I’m most pleased with!

When I set up the placeholder for this one ages ago it was called ‘Storm Bringer’ and I had an idea it was going to involve some kind of ‘particle storm’ type effect, a bit like those fireworks you get that fire out a ton of different sparks that go off in different directions.

However, I’ve already changed the ‘Spreader‘ weapon to be called ‘Particle Storm’ and, as that now does something very similar to what I intended this weapon to do, differentiating this weapon proved difficult.

I tried a series of variations with a bunch of particles moving in a constrained and stuttery ‘Brownian Motion’ type manner but this all looked shite and, to be honest, given that I’ve done so many of these weapons now I was beginning to feel like I was running out of ideas and motivation.

Then came a random source of inspiration. In my very skunkworks home studio I have a rack for audio gear that I’ve cobbled together over the years from various shitty pieces of Ikea furniture and stuff. In an attempt to make this more uniform (as nothing matched and my workmanship was so terrible) I covered the entire piece with Jack Kirby art from a bunch of old Spiderman and Fantastic Four comics I had as a kid.

On one small section of this there’s an image of a character disappearing into a kind of black hole, the image is drawn in negative and looks really striking. I had vaguely considered a weapon called ‘Black Hole’ (though I was worried it would be too similar to the ‘Sonic Boom‘) so I decided, largely out of desperation, to try switching the particles I was using to very dark circles with a light outline. I thought this would look ridiculous but, to my surprise, it actually looked kind of cool!

It’s not a single black hole though, so I hit upon the concept of a weapon that fires a series of mini black holes that suck the life force from enemies. Stephen Hawking would probably turn in his grave but I liked the idea. I’m calling it the ‘Black Hole Blaster’ which, thankfully, just about fits in the space I’ve reserved for weapon names in the HUD!

I worked on this ‘negative space’ effect some more, adding a layering system to my particle code so that I could draw all the white outlines ‘behind’ the black circles, this gave the effect of a unified black mass with a white outline which looked much better than a bunch of circles overlaid. As usual there was a lot of tweaking and messing around here (I didn’t really have any point of reference for the effect I was trying to create other than that one comicbook panel) but I’ve ended up with something I think works.

There’s five layers of particles in the final version two sets of black circles with light outlines (one smaller than the other) and the concentric circles you see overlaid which (I think) help to give the impression of some kind of black hole rather than simply black smoke. It was difficult to get these concentric circles subtle enough to suggest ‘black hole’ without overwhelming things, I had to do a lot of messing around with the frequency and distribution of them. It’s possible that I’ve erred to much on the side of caution and could do with a few more of them. It does look a bit like some kind of weird satanic flamethrower but I don’t think that’s necessarily a bad thing!

Lastly, whilst working on the collision detection (which was very straightforward) I thought it might be a nice touch if these mini black holes exerted a small gravitational force, actually sucking enemies towards them. This was pretty fiddly to code, and my initial version was ludicrously powerful, but it did seem to work and help to differentiate this weapon nicely from some of the others.

So I think I’m pretty much done with this one now. I’m really pleased with it, both in the way it looks, but also for the fact I’ve never seen a weapon quite like it in any other game (though some smartarse will no doubt point one out to me)!

Only two weapons left to go!!

Dev Time: 2 days
Total Dev Time: approx 140.5 days

previous | next

mockup_3x
The Jack Kirby Panel That became My Inspiration

mockup_3x
An Early Draft Of The Weapon

mockup_3x
The Final(ish) Version

mockup_3x
Too Much Suction!

mockup_3x
Black Hole Dogfight!