craftworkgui_demo1.png

I’ve finished the first iteration of CraftworkGUI for MonoGame. All of the features I planned to implement in one month are working. Does that mean it’s completely finished? Not even close, but it should be ready for use in real game, so that’s what I’m going to do next. Make a game with it.

The code is open source on github and the task list is available on Trello. If you try it out, I’d love to know about it. That’s why it’s open source after all.

There is a quick demo in source control showing how to setup a simple screen and use most of the controls. Here’s a snippet of code showing how the above screenshot is composed.

var screen = new Screen(800, 480);
var dockLayout = new DockLayout();
var gridLayout = new GridLayout(1, 2);
var leftStackLayout = new StackLayout() 
{ 
        Orientation = Orientation.Horizontal, 
        VerticalAlignment = VerticalAlignment.Bottom 
};
var rightStackLaout = new StackLayout() 
{ 
        Orientation = Orientation.Vertical, 
        HorizontalAlignment = HorizontalAlignment.Right 
};
var playButton = CreateButton(playRegion);
var cogButton = CreateButton(cogRegion);
var upButton = CreateButton(upRegion);
var facebookButton = new Button(new VisualStyle(twitterRegion)) 
{ 
        HoverStyle = new VisualStyle(twitterRegion) 
        { 
                Rotation = 0.05f 
        } 
};
var twitterButton = new Button(new VisualStyle(facebookRegion)) 
{ 
        HoverStyle = new VisualStyle(facebookRegion) 
        { 
                Rotation = 0.05f 
        } 
};
var titleImage = new Image(new VisualStyle(titleRegion)) 
{ 
        Margin = new Margin(0, 50, 0, 0) 
};

_timeLabel = new Label() { Height = 32 };

screen.Background = new VisualStyle(backgroundRegion);

dockLayout.Items.Add(new DockItem(playButton, DockStyle.Fill));
dockLayout.Items.Add(new DockItem(gridLayout, DockStyle.Bottom));
dockLayout.Items.Add(new DockItem(_timeLabel, DockStyle.Top));
dockLayout.Items.Add(new DockItem(titleImage, DockStyle.Top));

leftStackLayout.Items.Add(cogButton);
leftStackLayout.Items.Add(upButton);

rightStackLaout.Items.Add(facebookButton);
rightStackLaout.Items.Add(twitterButton);

gridLayout.Items.Add(new GridItem(leftStackLayout, 0, 0));
gridLayout.Items.Add(new GridItem(rightStackLaout, 0, 1));

screen.Items.Add(dockLayout);

_gui.Screen = screen;

I’ve been busy working on the new CraftworkGUI system for MonoGame. I’m really pleased with how it’s coming along and now seems like a good time to show a little of what it can do and how it works.

first_look_craftworkgui.png

So far it has basic buttons used for the likes of social icons, styled buttons with normal, hover and click styles. Labels for displaying text and a basic list box with item selection. Oh and layers.

A control represents it’s behaviour independent from it’s visual appearance. For example a button can be clicked or tapped exposes the ability to customise the visual style for each of it’s states normal, hover and pressed. The style describes how to draw the sprite (colour, scale, rotation and so on).

This is not a tutorial but I’d like to show how the API is coming along. Any suggestions are appreciated here.

The first step is to create a texture atlas with some sprites for the controls and a font texture exported from the BMFont tool like so. The images can be anything you like.

ExampleAtlas.png
ExampleFont_0.png

Then setup the texture atlas, initialise the GUI manager and create a layer:

            var textureAtlas = new TextureAtlas("ExampleAtlas.png");
            textureAtlas.AddRegion("twitter", 0, 0, 64, 64);
            textureAtlas.AddRegion("facebook", 64, 0, 64, 64);
            textureAtlas.AddRegion("button", 128, 0, 256, 64);
            textureAtlas.AddRegion("listBoxItem", 0, 64, 256, 64);

            _gui = new MonoGameGuiManager(GraphicsDevice, Content);
            _gui.LoadContent(new GuiContent(textureAtlas, "ExampleFont.fnt", "ExampleFont_0.png"));
            _gui.LoadTexture("Background.png");

            var layer = new GuiLayer(800, 480);
            layer.BackgroundName = "Background.png";

After that you can start creating controls and placing them on the layers like so:

            _moneyLabel = new Label()
            {
                X = 600,
                Y = 0,
                Width = 200,
                Height = 32
            };
            layer.Controls.Add(_moneyLabel);

            var twitterButton = new Button() 
            { 
                NormalStyle = new TextureRegionStyle("twitter"),
                X = 10,
                Y = 430,
                Width = 32,
                Height = 32
            };
            layer.Controls.Add(twitterButton);

            var listBox = new ListBox()
            {
                ItemStyle = new TextureRegionStyle("listBoxItem"),
                SelectedItemStyle = new TextureRegionStyle("listBoxItem") { Colour = Color.SkyBlue },
                HoveredItemStyle = new TextureRegionStyle("listBoxItem") { Colour = Color.AliceBlue },
                ItemHeight = 64,
                X = 20,
                Y = 50,
                Width = 256,
                Height = 400,
            };
            listBox.Items.Add(new ListBoxItem("Item 0"));
            listBox.Items.Add(new ListBoxItem("Item 1"));
            listBox.Items.Add(new ListBoxItem("Item 2"));
            listBox.Items.Add(new ListBoxItem("Item 3"));
            layer.Controls.Add(listBox);

            _gui.Layers.Add(layer);

The visual styles can be customised easily, and events can be handled in a familiar way:

            var button = new Button() 
            { 
                NormalStyle = new TextureRegionStyle("button"),
                HoverStyle = new TextureRegionStyle("button") 
                { 
                    Colour = Color.LightGray, 
                },
                PressedStyle = new TextureRegionStyle("button")
                {
                    Colour = Color.Gray, 
                    Effect = SpriteEffects.FlipVertically,
                    Scale = new Vector2(0.95f, 0.95f),
                },
                Text = "Click Me",
                X = 50,
                Y = 50,
                Width = 256,
                Height = 64
            };
            button.Clicked += Button_Clicked;

Right now I have no idea what game I am going to do for my March #OneGameAMonth entry. However, I have been thinking about what I want to achieve this year so that the quality can improve and the development time is reduced. In no particular order, this is what I’ve come up with so far.

GUI system

My previous games have fairly minimal GUI’s thrown together fairly quickly to get the game out. Each one has been an improvement on the previous one, but thus far I haven’t pulled this code into a reusbale library. The GUI in Rock Run is a pretty good start. Pulling it out and making it a little more generic seems like a good way to boost productivity in future games.

Achievement system

I really like achievement systems. They make the game a lot more fun and can be applied to nearly every type of game. Each of my previous games could benefit from an achievement system in way or another, so once this is built I should be able to back fill my other games.

Social icons

Nearly every good mobile game on the market has social icons these days. They are a very simple marketing strategy that can be implemented into many games. Until recently, my games have been targeted at toddlers, the one target market that doesn’t use Facebook. From now on though, I think it will be very handy to have a generic component to add social icons to the title screen.

Particle system

I’ve always wanted to do a particle system. They are fun to write and fun to play with, unfortunately, I’ve just never got around to it. That gotta change because particles are awesomely cool.

Soft money

Lately I’ve been enjoying games that include in game money. Usually this means you can buy in game items, but I’d also like to explore trading and selling items too. Perhaps this will lead to some sort of in app purchasing (IAP) model.

Tap for tap integration

Something that’s been on my backlog for a while is integrating the Tap for Tap Mobile Ad Network. It should help get new users by trading clicks with other apps at no cost. I’ll probably need to setup Java to C# bindings to get that working.

Farseer physics

I’d like to do a game with physics and I think the Farseer physics engine is the way to go. I’ve used some 3D physics engines in the past and they have been fun to work with, but since I’ve scaled back to 2D games I’ll need to learn a new API.

Music

It seems like a simple enough task to get music into the game right? I thought so too, but last time I tried to tackle this task with MonoGame I got a number of exceptions and put it to one side. I’m not sure if I was doing something wrong, or if there’s a bug in MonoGame, but in any case I’d like to get this issue sorted.

Spine animation

I recently back the Spine 2D skeletal animation tool on Kickstarter. So it makes sense that I will use it to make one or more of my games. They currently have a generic C# runtime on the Trello to-do list so when that’s ready I’ll do one of my games with it.

That’s it. This should be fun :)

Get it on Google Play
I’ve released my Febuary game for #OneGameAMonth on Google Play. It’s only got a few (but challenging) levels and I plan to release more levels soon. If you play it please rate and review on Google Play.

RockRunScreenShot1.png

The aim of the game is to find a way to collect all of the gems on each level and make your way to the exit. It may sound easy but these levels provide a challenge to even the best of puzzle solvers.

So, we are a week and a half into the February OneGameAMonth entry and I haven’t introduced our game yet. It’s a boulder dash clone called Rock Run, well actually it’s more of a Heartlight clone which was probably a boulder dash clone back in the day.

RockRun5.png

If you would like to try the first build of our game we have an early development release of the fist 10 levels.

Download here:
http://www.craftworkgames.com/downloads/CraftworkGames.RockRun.zip

If you are getting an OpenAL error you might also need to install this:
http://connect.creativelabs.com/openal/Downloads/oalinst.zip