Smite is a wooden garden game based on a Northern European game and played around the world.
If you think of a combination of skittles and boules you’ll be pretty much there – but not quite, there are a few twists.
Each player will take turns to throw a wooden ‘smitter’ at 10 numbered wooden pins, arranged in a similar manner to those in 10 pin bowling.
Knock over a single pin and you score the number on that pin.
Knock over two or more pins and you score the number of pins that fall; knock over four pins and you score four points.
Before the next players turn the pins are stood back up but remain where they fell, they are not returned to their original location.
Miss all the pins three turns in a row and you are ‘smitten’ and out of the game.
If any players score exceeds 50 points they are returned to 25..!
When a player scores exactly 50 points the game will end when the round completes – all remaining players will complete the round. There can be more than one winner!
It sounds simple but when the pins start to spread out the game becomes much harder – I can personally attest to this, as can many members of my family..!
Keeping score is not difficult but games can go on longer than expected and you soon find yourself scrabbling around for scraps of paper to continue the scoring.
Having run out of paper on many occasions I decided to create a simple app to keep score and apply the simple rules above. The ability to take player photos to use as avatars and ensuring that game state is saved when the app is backgrounded (lunch and dinner frequently interrupt a ‘a few quick games of Smite’) add some nice functionality and coding challenges.
Written using Xamarin.Forms there are Android and iOS versions of the app with around 95% of the code being shared – only a couple of small platform specific classes were required.
I currently have a few testers looking at the release candidate version – with a few more being recruited at the upcoming Smite World Championships.
It’s a pretty straightforward app and nowhere near as complicated as the likes of my other apps, FillLPG or Motorhome Stopover, but I fully expect to have a few bugs to fix and features to add.
I’ve finally managed to get some time to look at the Smite Scoreboard application that I’m using as a vehicle to dive into Xamarin.Forms (XF) and it’s been a fraught time (see bottom of post).
Between incompatible nuget packages, mismatched Windows and iOS configurations and finding that XF didn’t actually support what I wanted to do I was pretty close to saying, “you know what, to hell with it – I’ll just use the native Xamarin approach instead”.
Anyway – getting back to the Smite Scoreboard app and what is basically the first User Story.
As a user I want to be able to create a list of players, adding, editing and removing as appropriate.
Now, I know what I wanted to do to implement this story – a simple ListView with an ‘Add Player’ button which would open a modal dialog . The dialog would contain a ‘Player Name’ field with OK and Cancel buttons. Entering a name and tapping OK would add a new row to the ListView. Simple huh.
Well no, not really. While XF does support modal pages, which take up the whole screen, it does not support modal dialogs.
I tried a couple of approaches including the creation of a layout with an Entry field above the ListView which would replace the field I was going to put in the dialog. I had this partly implemented but really didn’t like how it was working and decided to bite the bullet and find a way or make a way!
And this is what I came up with (iPhone on the left, Android on the Right):
Yes – it’s not pretty but it shows me that I can do what I want to be able to do. Making it look nice is a job for later, lets get it working first ?
So, on to the code. I decided to address the initial problem – how do I create a modal dialog (or the impression of a modal dialog) which will allow data entry? I didn’t worry about the ListView integration as I’m happy enough that I can make this work.
Basically he uses an AbsoluteLayout which will hold the ‘normal’ page elements as well as a ContentView which will form an overlay that the user can see through but crucially not tap through. The ContentView is initially loaded with it’s IsVisible property set to false.
The skeleton xaml file looks like this:
<AbsoluteLayout><!-- Normal Page Content --><StackLayoutAbsoluteLayout.LayoutBounds="0, 0, 1, 1"AbsoluteLayout.LayoutFlags="All"><!-- Normal Page Content --></StackLayout><ContentViewx:Name="overlay"AbsoluteLayout.LayoutBounds="0, 0, 1, 1"AbsoluteLayout.LayoutFlags="All"IsVisible="False"BackgroundColor="#C0808080"Padding="10, 0"><!-- Overlay --></ContentView></AbsoluteLayout>
With this in place I added a button to the StackLayout and bound the Click event to a handler in the code behind which flipped the IsVisible property of the ContentView to True, thus displaying the overlay.
All I had to do now was to create a layout within the ContentView which looked something like a dialog. I came up with this:
<StackLayoutOrientation="Vertical"BackgroundColor="White"HeightRequest="175"WidthRequest="300"HorizontalOptions="Center"VerticalOptions="Start"Margin="0,20,0,0"><LabelBackgroundColor="Black"FontSize="18"TextColor="White"HorizontalOptions="Fill"Text="Add a Player"/><Entryx:Name="EnteredName"Placeholder="Player Name"TextColor="Black"VerticalOptions="CenterAndExpand"HorizontalOptions="Center"WidthRequest="250"/><StackLayoutOrientation="Horizontal"HorizontalOptions="Center"><ButtonText="Cancel"FontSize="Large"VerticalOptions="CenterAndExpand"HorizontalOptions="Center"Clicked="OnCancelButtonClicked"/><ButtonText="OK"FontSize="Large"VerticalOptions="CenterAndExpand"HorizontalOptions="Center"Clicked="OnOKButtonClicked"/></StackLayout></StackLayout>
Wiring the buttons up to flip the IsVisible property of the overlay back to false and, in the case of the OK button, access the entered value was straightforward enough.
It should be noted that I had issues when I attempted to update to the latest version of Xamarin.Forms via Nuget. The version installed with the ‘File > New Project’ did not seem to like the Overlay configuration and while the semi-transparent background was visible the ‘dialog’ controls were not. Only by updating from 18.104.22.16882 (installed by default) to 22.214.171.124 (latest at time of writing) was I able to get this working. But it was not that simple (of course). Version 126.96.36.199 has dependencies on specific version of the Xamarin.Android.Support packages, 23.3.0, but I’d already updated those packages to their latest versions (188.8.131.52). This meant that I had to revert those updates and install 23.3.0 instead.