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

Jetboard Joust Devlog #59 – Alpha Launch!

Woohoo – major milestone alert!!

I’ve finally got things to the state where I feel like I can release a playable alpha. Yes, there are still a few bugs and things I need to refine in the game design but I think we’re pretty much there. What’s also great is, thanks to the great flexibility of MonoGame, I can also release a MacOS version. The MacOS port only took me just over a day and I may detail that in another post.

For those of you who just want to cut to the chase and download the thing click here!

And for those of you who are actually interested in the devlog here’s a list of the significant additions in this final round of tweaks, many thanks to the folks who gave me feedback at the pre-alpha stage…

Pistol Range
It became obvious from user feedback that the range on the pistol (the default weapon) simply wasn’t enough. Players found they had to get unnaturally close to enemies to kill them which often meant they crashed into them by accident. Consequently I have increased the initial range of the pistol by about 75%, though to compensate I have made the damage done tail off as the bullet reaches the end of its range.

Its better than it was but I’m not convinced I’ve yet solved this issue. It’s a bit of a delicate balancing act as I want the weapon to be meaningfully upgradeable, yet also powerful enough to start with and not overpowered later on. Also, because the enemies use identical weapons to the player increasing a weapon’s range/damage also increases the difficulty of those enemies that use it!

Another more radical solution I’m considering is to significantly increase the pistol’s range yet further (and maybe give it unlimited ammo) yet not allow it to be upgraded. This would make the start of the game considerably more approachable for new players and increase its difficulty later on as players wouldn’t have a strong default weapon to fall back on. It would also put more emphasis on managing ammo levels later in the game which could be a good thing.

Playing Catch
It has always been a feature of the game that catching an enemy’s jetboard before it hits the ground give both an ammo and a shield boost and is therefore preferable to waiting until it hits the ground (generating only one type of pickup). I didn’t feel this was very clear though so I have added mini shield/ammo icons to the enemy jetboards as they fall which will hopefully communicate that there’s goodies on board and these things are worth collecting. The player also gets a ‘nice catch’ message if they do this indicating that it’s a good thing to do (catching jetboards is also the way to unlock new weapons)!

Extra Life / Jetsuit Indicators
Picking up your abandoned jetsuit after you lose a life is a central game mechanic as it’s the way to recover lost cash and not lose out on valuable upgrades. Similarly extra lives in the game are pretty rare so when they do appear the player isn’t going to want to miss out on them. I talked about adding pickup indicators and detectors for other bonus items here and decided I had to do the same for jetsuits and extra lives as they are arguably the most valuable pickups in the game!

Microsite
Yeah, not really part of the game dev but I thought I’d include it anyway. I needed a microsite or landing page to distribute the alpha so went ahead and built one. I’ve included a simple signup for for a mailchimp list. Goodness knows whether anyone will use it but hopefully it’ll server some purpose.

Update Tracking
I’ve added a very simple way for the game to poll the web server, check whether an optional or mandatory update is available and notify the player appropriately. The alpha build will also expire after a set date (currently the end of June so plenty of time to play).

I may now take a break from gamedev for a bit as I have had to take on some appdev contract work (fortunately a pretty nice project) to top up my dwindling coffers. I will have to try and get a youtube promo done over the next few weeks though, and hopefully get the word out about the alpha.

Thanks for watching and please stay tuned…

Dev Time: 4 days (inc microsite build)
Total Dev Time: approx 115.5 days

previous

mockup_3x
Making It More Obvious That There’s Booty On Falling Jetboards

mockup_3x
Pointing Out The Player’s Abandoned Jetsuit


You Don’t Want To Miss Out On An Extra Life Either!

Jetboard Joust Devlog #58 – Almost At Alpha!

So for the last couple of days or so I’ve been doing an awful lot of playtesting and making what should be the final round of tweaks, improvements and bugfixes for the playable alpha. A large amount of this has been general tweaks to difficulty levels and the like which would be too numerous to list here but here’s a few specifics as to what’s been included…

Weapon Stashing
In order to prevent the player from overpowering one weapon and simply sticking with that I now switch to the default weapon on losing a life and completing a level. This isn’t such a big deal at the moment as there are only three weapons but there will be a lot more in the final game. In addition to this, weapons are no longer automatically reloaded when ‘swapped out’ meaning it’s possible to stash an empty weapon. As a consequence I’ve also made weapon crates display the amount of ammo in the included weapon. Stashed weapons retain their ammo between levels.

Controls
I’ve tweaked the controls a bit so that they are a bit less ‘binary’ and it’s easier for the player to make smaller movements. There’s a fine line here between being able to make subtle movements and being able to move quickly when necessary. I’ve moved to using lerp-based interpolation for the player’s vertical speed and also added the ability to ‘brake’ (cancel horizontal motion) by pulling directly down on the controller.

Camera
Slight improvements to make the camera track better when running away from enemies (ie not track as if you’re trying to attack an enemy that’s behind you). Again there’s a fine line here as sometimes you are ‘dogfighting’ with an enemy that’s behind you so what I do is make a decision based on how long the player has been moving in the same direction. Rapid changes of movement tend to mean dogfighting, continuous movement tends to mean running away!

Input And UI Labelling
I’ve checked all the dialog buttons in the game for keyboard and controller input and labelled them appropriately depending on the input method being used. If the game receives any controller input I presume the player is playing with a controller, otherwise I assume a keyboard is being used. I’ve also made dialog buttons and a few other UI elements respond to mouse input just for a ‘belt and braces’ approach. the game itself can’t be played with a mouse though.

Instructions
I’ve added some pretty minimal (but hopefully sufficient) instructions and a diagram of controls for both keyboard and controller input.

Enemy Randomizer
I’ve made yet more tweaks to the code that generates the levels so there’s a much better distribution of enemies. I’ve added a ‘Config’ class that contains all the definitions for enemy/weapon intro levels and difficulty settings in one place so it’s much easier to edit.

Baiters/Bastards
These are the enemies that appear when the player is taking too long to complete a level. Originally I had it so they didn’t need to be destroyed in order to complete a level (as in Defender) but I thought it was a bit weird getting the ‘all enemies destroyed’ message when there were enemies still present. Now the baiters have to be destroyed too but no additional baiters will appear once all other enemies have been defeated.

Bugfixes
Fixed a bunch, one of the most amusing ones was where an enemy’s jetboard would continue to fire after the enemy had been killed (if it was armed with an automatic weapon). This was funny but I couldn’t leave it in.

Now I have to decide whether I’m going to create a proper installer for the alpha (and build it if so) or just distribute a zip file – then you should be able to have a go!

Dev Time: 2.5 days
Total Dev Time: approx 111.5 days

previous|next

mockup_3x
Weapon Crates Now Display The Amount Of Ammo Inside

mockup_3x
Alpha Instructions

Jetboard Joust Devlog #58 – Music, Maestro!

Well, the background music’s finally done and it’s taken what seems to be an indeterminable amount of time.

It’s partly because I had to put a proposal together for some contract work in the middle of it – which made the process seem to drag on longer than it should, but also because I decided I had to sort out the ridiculous mess of cabling (of various varieties) that had overtaken my studio and was making it difficult to work. Each of those tasks took at least two days.

I guess 8.5 days total dev time isn’t too bad for the amount of background audio that’s in there but, even accounting for the aforementioned increased in elapsed time, it still seems to have been a rather lengthy and unnecessarily painful process. Here’s how it went down (and sorry for the crackling in some of this audio – seems to be problem with running Windows on a Mac)…

1. Main Theme
I knew from the get go that I was going to utilise the same approach for the background music that I had for the in-game FX, ie all analog synths for the sounds and as few software plug-ins as possible when mixing. I needed to have a rough idea of the style of music I was going for though so started by playing the game alongside a few different tracks to see what worked best. I tried a number of different electronic artists, eventually settling on the ‘Detrimentalist’ album by Venetian Snares as my favourite, with particular reference to the tracks ‘Kyokushin’ and ‘Bebikukorica Nigiri’, the latter featuring a bunch of ‘chiptune’ type sounds which seemed particularly appropriate.

Once I had a general ‘vibe’ in mind I started creating some drum patches and banging out some beats on The DSI Tempest trying to get something that worked, using a combo of the Moog Sub 37 and Mother 32 for bass and lead duties. As often as possible I’d try and listen to what I was creating alongside a recording of the in-game fx so I could try and create sounds that weren’t going to mask and/or fight against each other to much. I found this pretty difficult to be honest.

After about a day I had a simple loop that I was generally happy with and began to work up some variations on it. I probably spent a couple of days playing around with different variations, whilst running into various technical difficulties syncing up all my gear in the process (ah – the joys of MIDI and analog)!

Then I started trying to combine all these variations into a single cohesive piece of music and this is where I started to run into problems. It didn’t work. I think this was partly because my variations were all too different and didn’t ‘flow’ together, and partly because I was trying too hard (and with too little talent) to ape Venetian Snares and the result was too full-on and tuneless.

I was getting pretty frustrated by this point. Four days in and I still didn’t have anything resembling a main theme. Then I remembered a piece of music I’d written ages ago for a J2ME game called ‘Battle Snake’ that I had always been rather fond of. I decided to dust this off and see if it would work for Jetboard Joust – fortunately it seemed like it might!

The (as it stands) final theme is a mash-up of ‘Battle Snake’ (with new sounds) and some of the variations I originally created for ‘Jetboard Joust’. I’m still not entirely happy with all the sounds here, particularly some of the more distorted ‘guitary’ type synth sounds which seem to conflict too much with the in-game fx. I may well replace these with something less harmonically rich.

Thankfully I could also use some of my original variations for the other sections of game audio so that time wasn’t entirely wasted…

2. Baiter Theme
The player has approximately two minutes and twenty seconds to complete each level in Jetboard Joust before the pace is upped and the ‘Bastard’ enemies (equivalent to the Baiters in Defender) start to attack. I thought my original (rather full-on) loop would work better for this section of the game and so created a separate piece of music for this that’s more ‘high-tension’.

3. Lost Life / Level Complete
These are short sections based on the repeated section of ‘Battle Snake’ that now forms the ‘hook’ of the main theme. An ascending progression for ‘level complete’ and a descending progression for ‘lost life’.

4. Planet Ambience
OK so this isn’t a piece of music as such but I wanted some kind of background audio during the ‘quiet’ periods of the game such as at the start of each level before enemies attack and at the end of each level once all enemies are destroyed. I’ve gone for a sort of retro sci-fi spooky ambience here with analog wind effects and vintage ‘sample and hold’ type noises that trigger seemingly randomly. I also added a weird interference loop which was the sound of some of my gear accidentally wired up incorrectly that I kind of liked. I think the planet ambience gives a nice contrast to the more full-on background music.

5. Upgrade Theme
One of the variations on my original theme was a type of minimal ‘spooky’ loop with bell-like synth effects and a lot of vintage delay. In the end this didn’t work as part of the main theme (it was too downbeat) but it seemed to work really well over the upgrade screens. I also added the wind noises from the planet ambience in here too.

6. Title Theme
I quite liked this being underplayed as well so stuck to just using the ‘planet ambience’ here with a bunch of samples of the ‘bell’ sounds from the ‘upgrade theme’ triggered randomly (all part of the same minor scale though so not entirely random). Again this has a kind of ‘vintage sci-fi’ feel which I liked. I also added spot fx for ui actions on the menu.

Now that I’ve written all that up it seems like rather a lot of work so I don’t feel quite so bad about it taking eight days or so to complete – bearing in mind I had to code all these into the game as well and managed to fix a couple of other bugs whilst I was at it. I’m bloody glad to be moving on from it though…

Dev Time: 8.5 days
Total Dev Time: approx 109 days

previous | next

mockup_3x
And This Is After I Sorted Things Out…

mockup_3x
The Original Loop – Way Too Loud For The FX!

mockup_3x
Main Theme – Jetboard Joust / Battle Snake Mash Up

mockup_3x
The Baiter Theme – High Tension Using Original Loop

mockup_3x
Upgrade Theme – Minimal And Spooky

mockup_3x
Main Menu And Planet Ambience

How To Use Google Maps In Xamarin.Forms

Recently I’ve been putting together an app development proposal for a potential client. It’s the sort of app that I think would suit Xamarin.Forms very well, only it has a large mapping component for which the client wants to use Google Maps on both Android and iOS.

At the time of writing the ‘built in’ Xamarin.Forms Map view has limited functionality and defaults to using Apple Maps on iOS. This makes it unsuitable for this project which meant I had to find and (roughly) test out an alternative before I could put a proposal together with any degree of confidence.

I managed to get it working in the end, but not without hitting all sorts of snags which I’ll document here in the hope it might make the process easier for someone else. Most of this information is scattered about the web but it’s difficult to find it all in one place.

1. Find A Suitable Library
Fortunately there’s a third-party open source Google Maps API in development for Xamarin forms which you can access here. Xamarin.Forms.GoogleMaps seems to be pretty full-featured so, rather than trying to reinvent the wheel, this is what I decided to use. Thanks very much to GitHub user amay077 for making this available.

2. Get It To Compile
Once downloaded from GitHub the next step is to get the Xamarin.Forms.GoogleMaps sample project to compile. This was pretty straightforward apart from a few error messages – you may run into the following on iOS:

This version of Xamarin.iOS requires the iOS 10.2 SDK (shipped with Xcode 8.2) when the managed linker is disabled. Either upgrade Xcode, or enable the managed linker. (MT0091) (XFGoogleMapSample.iOS)

To get round this either upgrade Xcode (groan) or do what I did and go to Project Options->Build->iOS Build and set linker behaviour to ‘Link Framework SDKs only’ which should fix it (you may have to clean and rebuild).

On Android you may get something like the following:

Could not find android.jar for API Level 23. This means the Android SDK platform for API Level 23 is not installed. Either install it in the Android SDK Manager (Tools > Open Android SDK Manager…), or change your Xamarin.Android project to target an API version that is installed.

A rare helpful error message this – to fix either do as the message says and go to Tools->SDK Manager and install the appropriate level SDK or go to Project Options->Build->General and select an SDK that you do have installed (I set it to Android 5.0 and it worked fine).

3. Install Google Maps On A GenyMotion Device
OK – I’m going to assume that a) you want to use an emulator for development and b) you are using GenyMotion as it’s by far the fastest. If you try and run the Xamarin.Forms.GoogleMaps sample project as is you will probably see a grey square where the map should be with ‘Xamarin.Forms.GoogleMaps’ in black text. This is because Google Play Services (which includes Google Maps) is not installed on GenyMotion by default. To do this I followed the instructions here (scroll down the page to where it says ‘Setup Google Play Services’). I was using an Android 5.0 GenyMotion device and did not need to do the first step (ARM Translation Installer).

Once you have flashed your virtual device you will get all sorts of irritating popup messages saying ‘Google Play Services Has Stopped’ and the like but if you just soldier on through this and update google play services and google maps via Google Play you should be OK. If you can get the standard Google Maps app running on the device you are sorted.

4. Create An Android API Key
So, assuming you have Google Maps running OK on your GenyMotion emulator, if you now try and run the Xamarin.Forms.GoogleMaps sample project you will just get what looks like a blank map (or a ‘barren featureless desert’ for Black Adder fans). This is because you haven’t supplied a valid API key – if you look through the Application Output of the app in Xamarin Studio you will see something like the following:

Authorization failure. Please see https://developers.google.com/maps/documentation/android-api/start for how to correctly set up the map.
In the Google Developer Console (https://console.developers.google.com)
Ensure that the “Google Maps Android API v2” is enabled.
Ensure that the following Android Key exists:
API Key: your_google_maps_android_api_v2_api_key
Android Application (;): FF:4B:77:38:AB:3A:F3:A8:42:CC:03:27:74:AA:CB:5F:66:A1:5F:D0;net.amay077.xfgooglemapsample

Copy the long hex string (SHA-1 certificate) and package name from this error message as this will save you faffing around with keystore commands later.

Now go to your Google Developer Console. On your Dashboard click ‘Enable API’ and select the Google Maps Android SDK. Now go to ‘Credentials’, click on ‘Create Credentials’ and select ‘API Key’ followed by ‘Restrict Key’.

You should now get a list of restriction options. Select ‘Android apps’ and enter the package name and SHA-1 certificate from the error message I told you to note down earlier. The API key can now be saved.

Note that you will have to enable access for both the ‘Debug’ and ‘Release’ versions of your app as they are signed differently and therefore have a different SHA-1 certificate. Simply run the app in both configurations and grab the application output as above to get the appropriate SHA-1 key for each.

Whilst you’re at it you may want to create an iOS API key (see step 5). It takes a few minutes for these to take effect so, once done, I suggest you go and make yourself a well-earned cup of coffee.

Now you need to embed your API key in your app. The way I suggest doing this is consistent with all the documentation on the matter – go to your AndroidManifest file and enter the following inside the tag:

<meta-data android:name=”com.google.android.geo.API_KEY” android:value=”YOUR_API_KEY” />
<meta-data android:name=”com.google.android.gms.version” android:value=”@integer/google_play_services_version” />

Replace ‘YOUR_API_KEY’ with your actual API key of course. Now your manifest file should look something like this:

<manifest xmlns:android=”http://schemas.android.com/apk/res/android&#8221; android:versionCode=”1″ android:versionName=”1.0″ package=”net.amay077.xfgooglemapsample”>
<uses-sdk android:minSdkVersion=”15″ />
<uses-permission android:name=”android.permission.ACCESS_FINE_LOCATION” />
<uses-permission android:name=”android.permission.ACCESS_LOCATION_EXTRA_COMMANDS” />
<uses-permission android:name=”android.permission.ACCESS_COARSE_LOCATION” />
<uses-permission android:name=”android.permission.ACCESS_CHECKIN_PROPERTIES” />
<uses-permission android:name=”android.permission.ACCESS_WIFI_STATE” />
<uses-permission android:name=”android.permission.ACCESS_NETWORK_STATE” />
<uses-permission android:name=”android.permission.ACCESS_MOCK_LOCATION” />
<uses-permission android:name=”android.permission.INTERNET” />
<application android:label=”OpenHouse”>
<meta-data android:name=”com.google.android.geo.API_KEY” android:value=”AIzaSyDJ7qxHOOh_4A1PodKyU0MlkhFIsyZsNJ7″ />
<meta-data android:name=”com.google.android.gms.version” android:value=”@integer/google_play_services_version” />
</application>
</manifest>

Just one more step – in the Xamarin.Forms.GoogleMaps sample project the API key isn’t entered in this way so you will need to delete the ‘dummy’ API key that been placed there. Do do this simply open MyApp.cs and remove the following line:

[MetaData(“com.google.android.maps.v2.API_KEY”,
Value = Variables.GOOGLE_MAPS_ANDROID_API_KEY)]

Hopefully if you now rebuild and run the Android project, and you’ve waited long enough for your API key to activate, you should now be able to see Google Maps correctly displayed in the GenyMotion emulator. Well done – it’s not the simplest process in the world!

5. Create An iOs API Key
This is pretty much the same process as creating your Android API key. Go to your Google Developer Console. On your Dashboard click ‘Enable API’ and this time select the Google Maps iOS SDK. Again go to ‘Credentials’, click on ‘Create Credentials’ and select ‘API Key’ followed by ‘Restrict Key’. This time choose iOS app restriction and enter the bundle identifier from your Info.plist file. For the Xamarin.Forms.GoogleMaps sample project it’s ‘net.amay077.xfgooglemapsample’.

To embed the API key into your iOS application open AppDelegate.cs and pass the API key as a string in the call to Xamarin.FormsGoogleMaps.Init(). This should be all you need to get the app running on iOS.

6. Embed The Xamarin.Forms.GoogleMaps API In Your Own Projects
Assuming you’ve managed to run the sample project successfully it should be fairly simple to get the API working in your own Xamarin.Forms projects. Xamarin.Forms.GoogleMaps is in NuGet so, in a new Xamarin.Forms solution, right-clicking on the ‘packages’ folder and selecting ‘Add Package’ will allow you to add references to the Xamarin.Forms.GoogleMaps packages. Remember to add them to every project in your solution. You may need to enable ‘show pre-release packages’ in the NuGet browser in order to download versions that are consistent with the sample projects.

If you run into strange issues, such as XAML errors when setting properties on a Xamarin.Forms.GoogleMaps.Map view or ‘Could Not Resolve Type’ and ‘BadImageFormatException’ errors when trying to position the map then you most likely have an incompatible version of the various packages somewhere. Check that all your package references (both to Xamarin.Forms and Xamarin.Forms.GoogleMaps) are consistent in all of your projects and ideally the same as the sample project.

I hope this article saves you some of the pain and grief I endured whilst trying to get all the stuff to work. If it does I always appreciate more followers on Twitter here!

mockup_3x
FAIL – Google Maps Not Installed On GenyMotion Emulator

mockup_3x
FAIL – No Valid Google Maps API Key

mockup_3x
SUCCESS – Xamarin.Forms.GoogleMaps Working on GenyMotion Emulator

Jetboard Joust Devlog #57 – Title Deeds

Another fairly quick entry today – I now have a title screen!

This didn’t take too long to put together once I’d designed the logo – most of the time was spent messing around with different motion types. I knew I wanted the logo to move, and each word to move separately, but it took a while to get something I was happy with.

My first attempt had each word moving parallel to the ‘slant’ of the logo but for some reason I found this a bit disturbing, like the words were scraping against each other or something. There was something almost sexual about it and not in a good way. yes, I know that probably makes me weird. maybe it’s too extreme but I found it the visual equivalent of hearing nails scrape down a blackboard (if any of you are young enough to remember blackboards).

My second attempt had each word moving in a less uniform elliptical motion. I preferred this so have stuck with it for now. I did also have to separate each word on the logo and also separate the actual letters from the background which took some pixel-pushing (there’s actually four sprites here).

Adding the parallax was easy as I could pretty much just use the classes that handle this in-game with a few minor tweaks. I’m pretty pleased with the end result and think it’s certainly presentable enough for the alpha version.

Dev Time: 0.5 days
Total Dev Time: approx 100.5 days

previous | next

mockup_3x
This Is The Motion That I found Weirdly Disturbing

mockup_3x
The Final (for now!) Title Screen

Jetboard Joust Devlog #56 – Pointing Out The Obvious

Whoa – 100 days of development under my belt!

Kind of a brief entry this one – I thought I was done with adding extra gameplay stuff for the alpha but watching my son play the game I realised there were a few things that were a little unclear.

The main one was the location of ammo stashes. It’s really annoying when you run out of ammo (I’m still not 100% sure that I shouldn’t give the base weapon unlimited ammo) and sometimes, in the heat of battle, it’s hard to locate the nearest ammo cache onscreen or on the scanner. This is even more of an issue since I added enemy bones which clutter up the battlefield.

So I’ve added two new features to make it easier to locate ammo, shields and rocket pickups – I call these ‘pickup detectors’ and ‘pickup indicators’.

A ‘pickup indicator’ simply indicates the location of the nearest onscreen stash – they don’t appear if the user’s ammo, rockets or shields are maxxed out. Implementing these was fairly straightforward, though I did have a few issues getting the indicator to move nicely between two different stashes. In the end I settled on having the indicator ‘pop out’ and then ‘pop in’ again when the location of the nearest stash changes. In my libraries I have a method that allows one to set a ‘timed event’ on a particular sprite, this is an event that doesn’t get triggered until a certain amount of frames later. This functionality has proved extremely useful for this type of thing.

A ‘pickup detector’ shows the closest route to the nearest stash if it is not onscreen. I settled on a simple arrow at the edges of the screen for this – not subtle but it works. As these would be annoying if they hung around all the time they only appear when the user’s shields or ammo are critically low. The rocket detector appears whenever a rocket pickup is present as these are pretty rare and you don’t want to miss them when they do appear.

The ‘pickup detector’ was also pretty straightforward to implement – the most fiddly bit was getting the arrows to centre correctly depending on how many of them there are, even that wasn’t that much hassle though.

I think these features make the game considerably more playable – plus I just love the look of that tiny pixel text!

Dev Time: 0.5 days
Total Dev Time: approx 100 days(!)

previous


Pickup Indicators In Action


Showing The Pop In / Pop Out As The Closest Stash Changes

mockup_3x
Please Sir – Where’s The Nearest Ammo Stash?

Jetboard Joust Devlog #55 – The Bubblewrap Effect

Everyone loves popping bubblewrap, yet no-one really knows why. For some reason the combination of the sound and tactile response makes it incredibly satisfying despite being utterly pointless. I had a friend who use to refer to this type of action as being ‘urgey’ – once you’ve done it you have the urge to do it again, and again, and again…

I’ve always thought we should aspire to this ‘bubblewrap effect’ when designing games. Most games, even the supposed AAA ones, comprise a fairly limited set of repetitive actions. If you can make those actions an enjoyable experience in and of themselves, regardless of gameplay, then you are onto a winner because no matter how good the player is at playing your game they will be having fun and come back for more.

Recently I’ve seen this loosely referred to as ‘juice’ or ‘game feel’ but these terms are rather vague and are often used to refer to all sorts of things. I’m talking about something pretty specific here – make all your repetitive actions as ‘urgey’ as popping bubblewrap. Usually this is a combination of both visuals and audio.

Now I’d already spent a lot of time on this stuff in Jetboard Joust but, whilst surfing GDC talks on YouTube, I came across this excellent talk by Jan Willem Nijman of Vlambeer on adding these types of elements to your game. I’d already implemented many of the techniques he talks about (camera shake, gun recoil, enemy and player knockback etc) but he made me rethink some aspects and put a bit more effort in to areas that were somewhat lacking.

So – here’s what I’ve been working on as the result of @jwaaaap‘s talk.

1. Bigger Bullets
To be honest a) this would never have occurred to me and b)I never would have thought it would work if it did. I was using little pixel squares for bullets as 1) they seemed appropriate for the size of gun and 2) this worked in Defender so why fix what ain’t broke? But I thought – ‘what the hell?’ and gave it a go. I started increasing the size of the bullets a little and was amazed how much better this felt, so I increased them what I would have thought was a ridiculous amount and it felt even better! It makes no visual sense whatsoever but the pistol (and particularly) the gatling gun are so much more satisfying to shoot now. I haven’t tried playing with the accuracy yet but should really do that too…

2. Camera Knockback
I already have some pretty hefty recoil on weapons but @jwaaaap suggests also recoiling the camera a certain amount when a weapon is fired. This didn’t make a massive difference in Jetboard Joust, probably because the camera is generally moving pretty fast anyway, but it is noticeable under some circumstances so I left it in.

3. Explosion Delay
Adding a very slight delay when an enemy is destroyed adds to the ‘jolt’ effect and makes destroying enemies much more satisfying. It’s subtle but it works. I’m using a delay of 32ms. I had to be careful here to not implement the delay until the next frame (ensuring the first frame of the explosion is drawn before the delay occurs) and also to clamp the delay time so that destroying a bunch of enemies at the same time didn’t result in a massive delay. I also improved the first ‘flash’ frame of the explosion by adding a ‘threshold invert’ to my collision shader and making the circles that briefly appear larger, brighter and less pixelated. Enemies really look like they’re getting nuked now!

4. Permanence
I had been wanting to do something to make battles seem more ‘permanent’ for some time and @jwaaaap‘s talk was the kick up the arse I needed. I talk about adding smoke in my previous post but that’s still not really permanent so I also added bones that fall from enemies when they’re destroyed and collect on the ground as a permanent record of the carnage that’s ocurred there.

Adding the bones was easy, the trouble started when I decided that they were too static and should react if the player hit the ground near them or crashed into a building that they were resting on. I didn’t want to run collision checking on every bone (there can be tons of them by the end of a level) so worked out a system whereby the world is divided into a series of overlapping ‘bone zones’. When a bone is static it is added to a zone and an entire zone can easily be discarded from the collision detection process in one go. I’ve used this approach before and it works well but I got myself into a bit of a flap with it here, plus it took a long time tweaking the various parameters so that the bones seemed to get disturbed by the correct amount. It still looks a little odd sometimes but its much better than having them totally static.

I’d really like to add some permanent damage to the buildings but I haven’t yet figured out a way to do this that would be a) be cpu/memory efficient and b) not involve creating a load more pixel art. I will continue to give this some thought – it could be that I’m underestimating the memory available on modern devices as a spent so long developing for J2ME feature phones!

So I hope that was all worth it and makes my game feel a little more like popping bubblewrap. I’d like to say these were the last gameplay tweaks before I release the alpha but watching my son play it has led me to implement just a couple more things…

Dev Time: 2 days
Total Dev Time: approx 99.5 days

previous|next

mockup_3x
My… What Big Bullets You Have!

mockup_3x
These Bullets Are Ridiculous – But Somehow They Work!

mockup_3x
Explosion Delay (Exaggerated), Smoke, And Improved ‘Flash Frame’

mockup_3x
A Battle Amidst The Bones Of Fallen Enemies

mockup_3x
Bone Bashing – A Stupid Detail That Caused Me Much Grief!

Jetboard Joust Devlog #54 – Smoke & Mirrors

For the past few days I’ve been working on adding some more ‘juice’ to Jetboard Joust – the sort of small details that don’t really add anything to gameplay per se but, when combined, add an awful lot to game feel (hopefully).

I’ll go over most of these in a separate post but one element seemed to deserve a post of it’s own – smoke.

I wanted to add smoke as a way of increasing a sense of ‘permanence’ to the combat. Explosions are over and done in less than a second but smoke could hang around for ten seconds or so and build up depending on how much destruction is going on.

I wasn’t after a ‘realistic’ smoke effect but something more stylised to fit in with the rest of the game art. It seemed logical to use circles as the base for the effect but I felt pretty sure I’d want these circles to increase in size over time, maybe quite dramatically, so I didn’t want to rely on scaling sprites for this. I decided to use custom shaders instead as this should give me much more control.

So the first step was to use a custom shader to draw a simple filled circle. Initially I thought the geometry behind this would be quite complex but, in fact, it’s just simple pythagoras. Here’s the approach in pseudo code…

// get coordinates relative to centre of circle
float x = 0.5-coords.x;
float y = 0.5-coords.y;

// fill the entire space
float radius = 0.5;

if ( x*x + y*y <= radius*radius )
{
// return a color
}
else
{
// discard
}

…I’d be lying if I said I got to this stage quickly though! Though it didn’t take me long to figure out the maths, I spent far too long passing the shader a region of a texture to draw rather than the entire texture and getting confused as to why my results were all off (forgetting that coords.x and coords.y are relative to the entire texture to be drawn, not the region). When I started passing a simple 2×2 image to the texture everything clicked into place.

Once I’d successfully drawn a filled circle it was pretty easy to expand that technique to draw concentric rings and the like, and to animate these by basing their radii on parameters that are passed to the shader and change each frame.

Next step was to find a way of applying motion to these circles that looked suitably smoke-like. I started by simple applying a uniform velocity to several circles distributed across a certain range, e.g. -60d to +60d, as well as increasing the circles size over time.

When I finally got this to work the way I intended it didn’t look too bad as a starting point so I added a couple more parameters to make things more interesting – a ‘deceleration’ parameter (so that the velocity of the circles decayed over time), and a ‘buoyancy’ parameter (so that the circles gradually floated upwards over time). I also decreased the opacity of the circles over time so that they gradually faded out.

This looked much better but the results were still far too uniform, forming very obvious geometric patterns as the circles intersected. To stop this I added a certain amount of randomisation to both the circles initial velocity and their ‘buoyancy’ – this produced a much more smoke-like effect – still stylised but not overly ‘geometric’.

I was almost there now but felt that the smoke cloud was dissipating too quickly and lacked some kind of ‘weight’ to it’s centre. I fixed this by adding additional batches of circles with a decreasing initial spread and velocity with the final one staying pretty much in the same place. This looked a lot better.

Lastly I experimented with adding pixelation to the shader so that the circles were drawn at the ‘game’ pixel resolution rather than the ‘screen’ pixel resolution. Unfortunately I felt this looked pretty crappy – one of those things that ‘should’ have worked but didn’t! So I left things as they were but I did add a gradually increasing amount of pixelation over time so that when the circles have pretty much faded out they kind of ‘dissolve’ out rather than just disappearing.

Actually I couldn’t stop there – I thought the centre of the smoke cloud looked too ‘solid’ to start with so added a small particle effect to imitate ash or something. It’s subtle but it just breaks things up a little.

I’m pretty happy with the final result – watch this space for a mini-tutorial on using shaders to draw geometric shapes. I think I might end up using that technique again in this game…

Dev Time: 1.5 days
Total Dev Time: approx 97.5 days

previous | next

mockup_3x
Successfully Drawing Circles With HLSL

mockup_3x
First Attempt At Multiple Circles – An Interesting Fail!

mockup_3x
Starting To Look More Smoke-Like But Still Too Geometric

mockup_3x
Adding Some Randomisation For A More Natural Effect

mockup_3x
The Final Shader With Pixel Dissolve

mockup_3x
The Final Smoke Effect In Game