Author: David

How to create an Alphabet bitmap in CSharp

How to create an Alphabet bitmap in CSharp

Letters generated by the programHere’s another short utility. I have been looking for a decent alphabet to look in my next game (called HogWash) . As before, I want to create a sprite sheet with letters. But every alphabet set that I found had issues with kerning. I kid you not, usually but not always with M, W, or even Q.

Even when I put together a sprite sheet manually, the editor didn’t quite get it right and letters didn’t quite fit the grid. So to simplify it, here;’s a 50 line C# program that takes the letters you supply in a string, combined with a font (Liberation Mono- from Red Hat) and a brush (black solid). It does a double loop that I exit with a goto (shock horror!) when it reaches the a terminating * in the string I supplied.

That is the graphic file above that the program below generated. As you can see the letters are far enough apart so no overlapping. Just put in your path where I have for the source and dest consts. You can use this technique for building sprite sheet.

// Author D. Bolton Learncgames.com You are free to use and copy this program as you wish but please leave this line in.
using System;
using System.Drawing;
using System.Drawing.Imaging;

namespace buildfont
{
    class Program
    {
        const int LetterWidth = 100;
        const int LetterHeight = 120;
        const string source = "Your path"
        const string dest = @"YourPath\letters.png";

        static Bitmap allLetters = new Bitmap(LetterWidth * 8,LetterHeight * 5);

        static void Main(string[] args)
        {
            BuildOneImage();
        }

        private static void BuildOneImage()
        {
            var font = new Font("Liberation Mono",95);
            var brush = new SolidBrush(Color.Black);
            var str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ*";
            Console.WriteLine("Creating letters.png");
            var aty = 0.0f;
            using (Graphics g = Graphics.FromImage(allLetters))
            {
                var strindex = 0;
                for (var y = 0; y < 5; y++)
                {
                    var atx = 0.0f;
                    for (int x = 0; x < 6; x++)
                    {
                        string aLetter = str[strindex++].ToString();
                        if (aLetter == "*") goto Done;
                        g.DrawString(aLetter, font, brush, atx, aty);
                        atx += LetterWidth;
                    }
                    aty += LetterHeight;
                }
            }
            Done:
            allLetters.Save(dest, ImageFormat.Png);
        }
    }
}
A spot of market research

A spot of market research

Raspberry-Pi
Image by Benjamin Nelan from Pixabay

This is market research for a side-project I’m working on. I’m developing a server and mobile clients to play multi-player games over WiFi. The server software would cost about $15/£12 and 1$ for the game client on Android/iOS. It will come with 8-10 games including card games such as Texas Holdem, and a board game or two. All games will be single-player as well (well not poker!). If it takes off I’d like to licence popular board games.

There will also be an SDK for creating new games and some financial arrangements for games to be sold through a “Pi bakery” i.e. app store. Games can either be included in the standard package or low cost add-ons.

I’m just trying to assess if there would be demand for it. If you have any comments or thoughts, I’ve posted this on the Raspberry Pi forums. as well.

It is often said that you shouldn’t give away ideas but I’ve decided to anyway. I really need to find out if anybody would buy this. If not then I have a plan B side-project waiting in the wings. But I do like this and I’ve already gone down the implementation route a bit.

Update

Sadly I have decided to ditch this side-project. I didn’t get great response; although there are 31 million Pis out there, getting people together especially with Covid is not easy. So I’m mothballing this for now. There is a B2B commercial possibility but I’ll come back to that in a year or two. Instead I am going onto my next project a mobile MMO.

A graphics editor in C

A graphics editor in C

Screenshot of grafX2 As the picture shows, no one has ever accused me of being artistic! Hey I can’t be good at everything (sometimes it feels like anything but it passes!) and I’ve long ago accepted that I never will be an artist.

But I can get by with graphics as I hope all the pictures on this site show. Either they are screenshots or comes from sites like pixabay.com and unsplash.com. Both are excellent sources of free images.

Sometimes though I have to do a lot of editing. MonoGame requires bitmaps for fonts. So I’ll take a free monospaced font and choose a size and create a sprite sheet from it.

But sometimes the tools I use are less than perfect. I never mastered or bought PhotoShop. Instead I used software like PhotoDraw 2 (from Microsoft in the early 2000s) or before that Macromedia Fireworks. But these are quite old and instead I’ve been looking around for something a bit newer.

There are quite a few open source graphics editors and if you look closely at my er artwork you can see at the bottom that this was taken from one such package called GrafX2. One reason for including it is that it’s coded in C and it reminds me of the granddaddy of drawing packages : Dpaint. As we’re talking over 30 years ago, I don’t know how many will remember it.

Monogame 3.8 is now out

Monogame 3.8 is now out

Monogame 3.8 releasedThese don’t come that often and this one has quite a few changes. You can read all about it on their What New page.  The main changes as far as I am concerned is the .NET Core support, templates in VS 2019 (finally!) and distribution via Nuget.

Interesting though that the Pipeline tool is dead, Long live the Pipeline! It’s now called the MCGB tool. I think it’s more a rebranding than completely new or maybe it is (apologies if that’s the case). And I notice that text is a resource type that you can add BUT on Android, no point in compressing things because apks are compressed anyway. Here’s a big secret, apk files, like Java .jar files are just zip files.  Yes you can view their contents with WinZip!

If you are a 3.7 MonoGame user (as I am), you should probably readthe migrating from 3.7 web page.

 

Geomorphing for the masses

Geomorphing for the masses

Geomorphic village by davesmapper.comThis is very clever. The website Davesmapper.com lets you create different type of geomorphic terrain maps, whether it be dungeons, city or village or even the interior of a spaceship.  You get a choice of tile sets according to what type of terrain you’ve picked. If you are artistic, you can upload your own designs. This mixing and mashing of tile sets can lead to some very odd looking cities with each tile a different style!

The view options controls lets you change how many tiles wide and high your map is, but watch out, the tiles are quite big so go above say 16 x 16 and you start to generate maps that are too big to export.  The village at the top of the post was 2100 x 2100 pixels when exported.

The terrain maps generated are very nice. If you think these look a bit rough, it’s probably my fault. To speed up this website all images are both shrunk to typically 350-450 pixels wide and compressed and some images are possibly not quite as nice looking as their uncompressed originals.

This city below shows you the type of thing with two greenish tiles and a bluish one. You can untick the tile sets that you don’t want.

Geomorphic city from davesmapper.com

Geomorphic means it’s made of tiles that are almost always square and they fit together so that doors or passageways always join up.

Back in my D & D (Dungeons and Dragons, not drunk and disorderly!) dungeon mastering days (about 1979) I use to have a set of physical geomorph tiles. They were great but sadly lost along with my D & D toolbox that had all my figures.

There are some computer games where you might use geomorphic graphics; perhaps a procedurally-generated dungeon crawler.

Now for some mobile networking

Now for some mobile networking

Early taxi app screenshotNot the face to face type but actual networking. This is needed because I’m working on a game server. My mobile game (Manana Banana) will become networked enabled and thus multiplayer.  C# is ideal for this type of thing but I’m not using the networking capability of MonoGame instead managing the whole lot myself.

Back a few years ago when I was a full-time mobile developer I wrote an app that was used by taxi drivers. It was a conversion of an Android App (I wrote it from scratch running on an iPhone based on the Android source code).  There’s a curious architecture with such apps because not only is the a user interface but in the background the app was “chatting” over 3G to a central server (written in VB6 I kid you not) which sent an “are you alive?” message every six seconds to every driver’s phone.

It was not a traditional client-server architecture but the kind of system where the driver could send a message to the server or the server could send a message to the driver. 

What this meant was the app was always keeping one eye on the 3G, getting messages and then it might for instance popup a screen saying “There’s a job from x to y. Do you want it?”. If the driver said yes then the app would receive details and show the driver the route to the pickup point. If the driver didn’t respond within 30 seconds or said no then the program would pass that back to the server,

What is a ConcurrentQueue?

C# has an advanced data structure called a ConcurrentQueue<t> which is a thread safe generic queue. I used two of these, one for a receive queue and one for a transmit queue in conjunction with a thread that never finished. All the 3G stuff was done using C# TCP/IP clients and ran in this thread. Messages that came in were put on the receive queue and could be popped off and processed in the main program. Messages to send out from the main program were put on the transmit queue and sent out in the thread. It was a very clean way of separating the main application running in the main thread from the 3G running in a background thread. 

Compared to the Android program which was all running in one thread and polled the 3G, I was told by my drivers that my app felt much more responsive!   The screenshot above was a very early image of it. It had a very simple UI where each screen of controls (Views in iOS parlance) was built up dynamically.  

Also C#/Xamarin has a way of getting from a thread to the main thread on iOS. You cannot update any controls from any thread only from the main UI thread.  There’s a method called InvokeOnMainThread for the Xamarin iOS controls. See this Microsoft/Xamarin documentation on how to use it. So that’s what I’ll be doing in my networked game.  

Interestingly because I’m managing everything, the TCP/IP messages can be very small, under 20 bytes each. This allows a very high throughput. 

Some awesome listings

Some awesome listings

Awesome stamp
Image by Pete Linforth from Pixabay

It has become a thing to label a big collection (usually open source) as awesome and there are several such collections around for many programming languages. In fact the C code collection’s first entry is to one of them.

That said they are pretty awesome, often having links to many related and useful open source projects. My only problem with the likes of GitHub and SourceForge etc. is the sheer quantity of excellent stuff on there. These awesome links are one way to “tame” them.

So now there’s a new link up top for C# and MonoGame links and a couple of entries to start it off.

 

MonoGame – How to make a clickable button

MonoGame – How to make a clickable button

Clear Button with one card clickedI’m using this in Android games but the principle applies to any MonoGame game. Here clickable and touchable mean the same.

You need three things to make something clickable.

  1. The area. For simplicity sake this will always be rectangular.
  2. The Action. When you touch (or click it), you want it to run code.
  3. An id of sorts. If you have multiple buttons etc, you meed to distinguish them.

We’ll use an int for 3. Use const ints to give it a name rather than being a magic number.

 

When you click whatever, the Event should include the ide so let’s define the event Type first.

public class ButtonClickedEventArgs : EventArgs
{
    public int Id { get; set; }
}

Not rocket science is it!

Now lets define a ClickButton class.

public class ClickButton
{
    public int Id { get; set; }
    public Rectangle TouchArea { get; set; }
    public Action<object, ButtonClickedEventArgs> AnAction { get; set; } = null;

    public ClickButton(int id)
    {
        Id = id;
        TouchArea = new Rectangle(0, 0, 0, 0);
    }
}

Again nothing too complicated. There’s an int Id which which is set in the Constructor, a Rectangle TouchArea and an Action which is defined to include our ButtonClickedEventArgs.

Here;’s some example code. I’ve defined a graphic for a Clear button in my game and this is loaded as usual in the LoadContent().  I’ve also defined the button in Class declaration.

ClickButton ClearButton;

In LoadControl(), this is also initialised. Here’s it’s two line. It could be done in one, by altering the constuctor.

ClearButton = new ClickButton(1);  // 1 is the id
ClearButton.AnAction += ClearCards;

ClearCards is a method that does something when the button is cleared. This matches our Event handler as it has the usal two parameters for an Event except the args is our ButtonClickedEventArgs.

private void ClearCards(object sender, ButtonClickedEventArgs args)  {
   // all the code here, not shown
}

Where is the TouchArea defined?

So are we all setup ready to rock’n’roll? Well not quite. We haven’t said exactly where the TouchArea is. That of course depends on where we draw the button. In my game, the ClearButton moves across. It’s absent when all six cards are present but as soon as one has been touched and a back card touched to move it, the Clear Card appears. In the top image you can see it to the right of the five top cards. I had clicked the seven of clubs when it was in the top row then the first back on the top row of the three rows.

For my next move I clicked the ten of diamonds and the second back on that first row where the ten of diamonds no wit. It now looks like this and the Clear Button has moved over.  If I click the Clear button it will move the seven clubs and ten diamonds back to the top row and replace them in the first row with backs.

Second clickTo set the TouchArea of the ClearButton, I do it in the Draw method. It’s as simple as this:

if (hand.Count < 6) // Draw ClearButton on end
  {
    spriteBatch.Draw(clearButton, new Rectangle(x, y, cardWidth, cardHeight), 
        new Rectangle(0, 0, cardWidth, cardHeight), Color.White);
    ClearButton.TouchArea = new Rectangle(x, y, cardWidth, cardHeight);
  }

There’s actually a small bug visible. When you click a top row card, the game highlights it by reducing its opacity to 0.5. If you look at the ten of diamonds, you can see it still has that reduced opacity; it should have been restored to 1.0 when it was moved to the first row. The same is true in the top picture for the seven clubs! Easily overlooked but just a one-line fix.

Some Touchy Code

The very last bit is to fire touch detection and this is done in the Update() method. When you touch the screen, calling Touchpanel.GetState() returns a collection of touches. This is my code. It cycles through the touches collection, gets the X, Y position of each touch and adjusts it to match the virtual screen coordinates. (Drawing to a virtual screen means this looks the same on every Android irrespective of its physical screen sizes and resolution).

touchState = TouchPanel.GetState();
foreach (var touch in touchState)
{
   if (touch.State == TouchLocationState.Pressed)
    {
         var x = touch.Position.X / xRatio; // adjust for virtual screen
         var y = touch.Position.Y / yRatio;
         CheckClickedTop(x, y, hand);
         if (pickedCard == null) return; // no point checking further...
         for (var i = 0; i < 3; i++)
            CheckClickedBottom(x, y, commonCards[i], true);
            if (hand.Count == 6) continue; // All top cards so no ClearButton visible
            // Check if Clear button
            if (ClearButton.TouchArea.Contains(x, y))
              {
                  ClearButton.AnAction(ClearButton, new ButtonClickedEventArgs() { Id = ClearButton.Id }); 
              }
      }
}

The top cards are held in a class called hand and the bottom three rows are held in CommonCards[3] each of which is a hand. The CheckClicked.. methods cycle through the cards in the hand comparing coordinates to see which card if at all has been clicked. If it has it calls the AnAction Event for the one clicked. The very last if shows how this works to check if the ClearButton was clicked. I’ll simplify this code by moving it into a ClickButton method.

In praise of Hyper-V

In praise of Hyper-V

Hyper-V Manager screen I’ve been using virtual machines for years. Originally I started with VirtualBox, the free VM manager from Oracle. I’m not sure why I switched to Hyper-V, about five or six years ago but I’ve been on Hyper-V since then. You need to be on Windows Pro and have at least 8 GB though the more RAM the better. I have 64 GB and the most I’ve ever had in use at one time is 29 GB. I always try to keep RAM use below 50% as there’s less disk swapping.

VMs are an excellent way to try out other Operating systems, install software and venture outside the comfort zone of a Windows PC and Windows 10.  Many of the screenshots published here in earlier posts have come from Ubuntu 18.04 LTS running in Hyper-V. It takes a minute to fire it up and connect then login.

I learnt to use Linux that way, both via the Ubuntu GUI and terminal commands and much of my 2nd Ebook has been tested on a Raspberry Pi OS running in a VM. Of course it lacks the hardware of the real Pi, so I have to test programs on both, but it’s quite a bit quicker doing a screen grab using the commercial Snagit on my Windows 10 PC.

I can do screen grabs on a PI using scrot, but then I have to upload the image using WinSCP or Putty. It’s not the end of the world but when you are doing a lot, having the image in the Snagit editor ready to copy/paste is a time saver. Also in a similar way, make sure you can do copy/paste via the clipboard and can resize the guest OS (as it’s called). It makes a difference.

I have mine configured so its uses RDP and you can just see the corner of the RDP bar in the Ubuntu image below where I’ve just launched Visual Studio Code.

Ubuntu 18.04 LTS running in an RDP session on Windows 10 in Hyper-V

From a terminal I did ifconfig and got

eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.21.212.121  netmask 255.255.240.0  broadcast 172.21.223.255
        inet6 fe80::2b71:6d6b:9a09:9aae  prefixlen 64  scopeid 0x20
        ether 00:15:5d:38:01:03  txqueuelen 1000  (Ethernet)
        RX packets 47317  bytes 69248755 (69.2 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 27622  bytes 1791175 (1.7 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

and on Windows

C:\Users\David>ping 172.21.212.121

Pinging 172.21.212.121 with 32 bytes of data:
Reply from 172.21.212.121: bytes=32 time<1ms TTL=64
Reply from 172.21.212.121: bytes=32 time<1ms TTL=64
Reply from 172.21.212.121: bytes=32 time<1ms TTL=64
Reply from 172.21.212.121: bytes=32 time<1ms TTL=64

This makes it very handy for testing network servers or if you do web development running a web server locally.

A simple Rock, Paper, Scissors game

A simple Rock, Paper, Scissors game

Rock, Paper, Scissors
Image by OpenClipart-Vectors from Pixabay

One of the easiest games to program is Rock, Paper, Scissors. All you are doing is a simple comparison, but programming it so the computer player can win more games than the player is not quite so easy.

The easiest strategy is always guess paper as Rock is apparently the most often chosen. That might work for the first couple of games but after that… A better strategy is count what the player plays each time to try and detect a bias. Guess randomly but make the %age of guesses favour the move that defeats the players most common move. If the player pays paper 50% of the time, guess scissors 50% of the time.

Then there’s variations on this, try and analyse past moves to give an edge. That could get quite complicated. You have to program it for pattern recognition. If the player favours scissors after losing with rock etc.

Here is a simple implementation of RPS in C.