Monthly Archives: April 2014

Windows Tile Updater (Part 1 – design)

A walkthrough of creating a Windows Universal App from scratch

There is a new type of project that allows the creation of Windows 8 and Windows Phone apps. I thought I’d run through creating a simple app (I’m also going to try and publish it in the store).

Design

This seems a little extravagant – a design. Having said that (I believe) you should at least be able to state what your program is intended to do in one or two sentences:

My program will display a tile notification on the start screen that can be defined by the user.

You should also try to decide the answers to the following questions:
1. Will all or part of your app be required to run outside Windows?
2. Do you expect to make money, and if so, how?
3. Does your idea have any competition, and if so, why will anyone look at your idea?

My answers are:
1. No – this is a demo app, so it will be entirely Windows. If the answer is yes then research mono, portable class libraries and Xamarin.
2. No. I may however add some advertising in a later post just to show how it’s done (to make money from advertising, you need very high usage of your app – also, at the time of writing, Microsoft’s fill rate for adverts was a little over 30%).
3. Yes – there are other apps that do this. At the time of writing, I hadn’t spotted an app that shared the tiles between phone and desktop – although I’m confident there will be one. The only reason anyone might choose to use this over another one would be because the source code will be publicly available. You might want a more convincing argument than this for your own work.

So, you’ve decided what the app will do, whether and how it will earn you a fortune, and why people will choose your app over the competition. The next thing is deciding what it will look like. Windows doesn’t leave too much scope for imaginative designs here – it needs to look Metro; having said that, I don’t think I’ve ever had an app fail on appearance.

Here’s my design for Windows:

Win8DT

For Windows Phone:

WP8

And:

TileAppDesign

As you can see, this is a complex and detailed design. Although, from my experience, anything more detailed than this back-of-a-fag-packet screenshot and general concept is a waste at this stage. However, there is one more thing that you should probably do:

Minimum Viable Product (MVP)

You need to decide what you can release with. I think this applies regardless of whether you’re a big company or just some bloke on a train writing software for fun. This should be the absolute least that your application can accomplish and still be your application.

In my case, it’s pretty minimalist as it is, so there’s little point, but you should probably decide the features that are necessary:

– Ability to set text for a tile
– Ability to set image for a tile

Maybe my MVP doesn’t need to include an image – just text? If you release and people download, then add the other features. This is basically a fallback for people who can’t or don’t use a product backlog. It’s essentially the same idea, but it doesn’t come with the overhead of the word agile*.

Conclusion

Now we have a design, in the next post, I’ll post some code.

* My opinion of agile is not that it is an overhead – simply that the word carries a lot of misconceptions and assumptions that may detract from its purpose and primary benefits.

Resource File Testing

Admittedly this does sound like a strange one. How or why would you both to test a resource file? The only reason I could think of was this: what if someone adds a resource, and forgets to localise it?

Without a test such as this, the first way you’d know this is when you ran the program in a localised culture and spotted the default culture appearing. This is something that could potentially go unnoticed for a long time. Consider British and American English, or Spanish and Latin-American Spanish.

To set-up the test, create three resource files:

res1

Create two resources in the base resource file (.resx):

res2

And then in each localised file, create one of these; so, in Resource.en-GB.resx create testphraseone (test phrase one english), and in the Spanish: testphrasetwo (prueba frase dos).

We also need to expose the resource manager:

    public class GetRes
    {
        public static ResourceManager GetResMgr()
        {            
            ResourceManager resMgr = new ResourceManager("resourcetest.Properties.Resource", typeof(resourcetest.Properties.Resource).Assembly);
            return resMgr;
        }

The Test

Now that we have the ResourceManager, we can simply call the GetResourceSet function. The third parameter determines whether to try the parent if the resource doesn’t exist, so setting this to false will force it to get the resource from the file in question.

The test could look like this:

        [TestMethod]
        public void TestMethod1()
        {
            ResourceManager resMgr = resourcetest.GetRes.GetResMgr();
            
            var baseList = resMgr.GetResourceSet(CultureInfo.InvariantCulture, true, true).Cast<DictionaryEntry>();            
            var spanishList = resMgr.GetResourceSet(new CultureInfo("es-ES"), true, false).Cast<DictionaryEntry>();
            var britishList = resMgr.GetResourceSet(new CultureInfo("en-GB"), true, false).Cast<DictionaryEntry>();
            
            var missing = baseList.Where(m => !spanishList.Any(s => string.Compare(s.Key.ToString(), m.Key.ToString()) == 0));
            Assert.AreEqual(0, missing.Count());

            missing = baseList.Where(m => !britishList.Any(s => string.Compare(s.Key.ToString(), m.Key.ToString()) == 0));
            Assert.AreEqual(0, missing.Count());
        }

This should then fail every time it encounters a resource in the base list that is not localised. If you needed to see the reverse, you could simply reverse the statement.

Conclusion

If you work in multiple languages, this can prove to be a very useful test. It also means that you can safely decide to delay the translation without being concerned that you’ll miss anything.

Handling both Touch and Mouse Input with Monogame

I’ve already posted a few times on handling input for Monogame. This one’s a little bit different though, and came from the fact that I had a game trying to get through certification that was repeatedly failing. What I was doing was detecting touch capabilities and, where I found them, using them; otherwise, using keyboard or mouse.

What I ended up doing was handling both. At the time this was just to get the game through certification in the Windows Store; but the more I think about it, the better I think the solution is.

Instead of maintaining a single input contoller, and assigning to it via a factory method, I maintain a list of controllers:

List<IInputController> _inputControllers;

Then, instead of an if / else statement to assign to the controllers, I simply add what’s available:

        // Determine how the user will interface with the game
        private void HandleInput()
        {
            // Instantiate the controllers collection
            if (_inputControllers == null) _inputControllers = new List<IInputController>();
            
            if (_inputControllers.Count == 0)
            {
                // Can we handle touch?  If so, add a new controller to handle touch
                Windows.Devices.Input.TouchCapabilities tc = new Windows.Devices.Input.TouchCapabilities();
                if (tc.TouchPresent == 1)
                {
                    _inputControllers.Add(new TouchController());
                }

                // Can we handle Mouse?  If so, add a new controller to handle mouse
                Windows.Devices.Input.MouseCapabilities mc = new Windows.Devices.Input.MouseCapabilities();
                if (mc.MousePresent == 1)
                {
                    _inputControllers.Add(new MouseController());
                }
            }

So, now we’ve got a list (and it doesn’t have to be restricted to 2 elements if, for example, you suddenly decide to support a thought-power interface http://en.wikipedia.org/wiki/Emotiv_Systems).

On the update method of your game, you now simply iterate through them:

foreach (IInputController inputController in _inputControllers)
{
    inputController.HandleInput();
}

Isn’t it a bit messy having the (potentially) giant conditional statement above

Yes. So, how about this.

            // Determine how the user will interface with the game
            if (_inputControllers == null) _inputControllers = new List<IInputController>();
            
            if (_inputControllers.Count == 0)
            {
                TouchController.AddController(_inputControllers);
                KeyboardController.AddController(_inputControllers);
            }

And then add the AddController function as a static method; like so:

        internal static void AddController(List<IInputController> controllers)
        {
            Windows.Devices.Input.MouseCapabilities mc = new Windows.Devices.Input.MouseCapabilities();
            if (mc.MousePresent == 1)
            {
                controllers.Add(new KeyboardController());
            }

        }

I’m unsure if this qualifies as a “Factory” method as such, although effectively that is what it is.

Conclusion

I’m now quite happy with this approach. I can foresee future uses for the logic, so at some point, if I get time, I might transfer it all to a PCL and publish on Codeplex… assuming I can work out how to get the Windows.Devices namespace to work in a PCL.

Detecting Keyboard Gestures Using Monogame

Recently, I got to the stage where I had just about finished one of my games, and suddenly realised that I had done nothing to deal with mouse gestures. Dealing with touch (which I have previously blogged about) can blind you to other input forms. Exactly how you deal with this will, of course, depend on what you’re trying to achieve.

Simple press and click – Touch

Let’s have a look at a piece of code to handle touch gestures:

private TouchCollection _currentTouch;

private void ProcessTouchInput()
{
    if (keypad == null) return;

    _currentTouch = TouchPanel.GetState();
    foreach( var touch in _currentTouch)
    {
        if (touch.State == TouchLocationState.Released)
        {
            keysPressed += keypad.GetKeyAt(touch.Position);
        }
    }
}

Okay, so this was ripped right out of the middle of a game. Most of it doesn’t matter, but `keypad` represents a customised on-screen keypad. So, to find out what’s been pressed, we simply call TouchPanel.GetState() and iterate the returned collection.

If we find that the TouchLocationState to be released then it must have been touched (how can you release something that was never touched?).

It then builds up a string containing the keys.

… And with mouse

Okay, here’s the first thing; this statement:

If we find that the TouchLocationState to be released then it must have been touched (how can you release something that was never touched?).

Is no longer true. `Released` where a mouse state is concerned is simply an absence of being pressed!

So, we need to track what has happened, and when:

private DateTime? _mousePressed;
private MouseState _currentMouse;

private void ProcessMouseInput()
{
    if (keypad == null) return;
           
    _currentMouse = Mouse.GetState();
    if (_currentMouse.LeftButton == ButtonState.Pressed)
         _mousePressed = DateTime.Now;

    if (_currentMouse.LeftButton == ButtonState.Released
       &amp;&amp; _mousePressed != null)
    {
        _mousePressed = null;
        keysPressed += keypad.GetKeyAt( new Vector2(_currentMouse.X, _currentMouse.Y));               
    }
}

Okay, so as far as mouse press is concerned, we have to roll our own. This isn’t particularly complicated code though.

What about gestures?

You can do gestures; it’s not straight-forward and, again, it’s not particularly well supported.

Here’s how I handle dragging:

MouseState mouseState = Mouse .GetState();
Vector2 mousePosition = new Vector2(mouseState.X, mouseState.Y);

// First, work out where and whether the drag has started
if (mouseState.LeftButton == ButtonState.Pressed)
{
if (_lastPressed == null || _lastPressed < _lastRelease) dragStart = null; // The current mouse location must be in a place where it // is acceptable to start a drag if (CheckLocation(mousePosition, acceptableDragStart, 60)) { if (dragStart == null) { dragStart = mousePosition; } } _lastPressed = DateTime.Now; } // Now work out when the drag is released if (mouseState.LeftButton == ButtonState.Released) { // For some reason, ButtonState.Released is // always flagged unless the button is pressed if (_lastPressed == null) return; _lastPressed = null; // Set the last release here _lastRelease = DateTime.Now; // Do whatever it is that you need for drag release DragRelease(mousePosition, dragStart, PlayerPosition); } [/sourcecode] So the code is in two distinct sections; the first being to determine is, and where, the mouse was pressed, and to store that information; the latter to determine if and where it was released. Double tap, hold, and other such gestures make this code more and more complex. It feels a lot like the main issue is the Released state.