Nonoku - SpriteKit Shader

A quick one because I was having trouble with this:

let node = SKShapeNode(rectOf: CGSize(width: 100, height: 100), cornerRadius: 5)
        let dashedShader = SKShader(source: "void main() {" +
            "float diff = u_path_length / 5.0;" +
            "float stripe = u_path_length / diff;" +
            "float distance = v_path_distance;" +
            "int h = int(mod(distance / stripe, 2.0));" +
            "gl_FragColor = vec4(h, h, h, h);" +
            "}")

        node.strokeShader = dashedShader

        node.fillColor = SKColor.clear
        node.lineWidth = 2

I've not done much with shaders before so when it didn't work I was short on tools to debug it. In the end it was a bunch of little things I had to solve, from converting the original version to one that would work against the iOS GL ES version, to making sure I converted to int before setting the colour.

Acquisition: Live on the App Store

So I started with (not so) grand ambitions of walking through the process of reviving Acquisition. What actually happened was a few flurries of activity which eventually got it working again across all device sizes in a way that will hopefully hold up. The only real pain point in the end was fixing the iPad issues. Since I couldn't change from a universal app to an iPhone only one (intended as a temporary fix since resolving the iPhone issues was slightly easier and would ensure that everyone has a working version) I had to get it all working in one go.

The most important thing is that it's working properly, again (and has been for a couple of months now). So far, no crashes.

You can download it from the app store.

 

Swift: Initialising a 2D Array

I have a struct called Tile, which has (for now) a position defined as a tuple:

struct Tile {
    let pos: (Int, Int)
}

And a class called Board, which has a 2D array of Tile objects:

class Board {
    let tiles: [[Tile]]
    
    init() {
        var tilesArray = [[Tile]]()
        for row in 0..<Board.rows {
            var rowTiles = [Tile]()
            for column in 0..<Board.columns {
                let tile = Tile(pos:(column, row))
                rowTiles.append(tile)
            }
            tilesArray.append(rowTiles)
        }
        
        tiles = tilesArray      
    }
}

This works, though it feels a little messy... I'll have to come back and look at this again.

Xcode 7 and Swift 2: Unit Testing (again)

Some follow up from creating a new project and adding tests.

This turned out to be important...

This turned out to be important...

I hadn't really noticed in the last one but I hadn't added the new classes to the test target, as I would under Obj-C. In Swift 2 there's a new @testable keyword. I found it blogged by Natasha the Robot when I started looking to find out why I wasn't seeing any code coverage showing up for my classes.

Then I started wondering why I was getting Undefined Symbol errors. I could resolve them by including the classes, but then I wouldn't get coverage and everything I saw on @testable assured me I didn't need to include them. Finally, I remembered I'd been getting a bit click happy earlier. I'd disabled Allow testing Host Application APIs.

One checkbox later and I'm a happy camper...

Okay, not a lot done tonight but I feel like a few pieces fell into place.

Unity & Playmaker - Building a Keypad

Update: There's an updated version of this post, complete with source code and the full project here: http://www.stephen-gurnett.org/unlikely-objects/2014/11/20/unity-playmaker-building-a-keypad

I've been experimenting with Unity for making games and prototypes more quickly. One of the things I picked up in the recent Unity sale was Playmaker. When I first started out programming I wanted to do everything myself. I'm in two minds about the benefits of this. On the one hand, I learnt a lot of things (mostly what not to do but that is kind of useful as well). On the other, now I know those things I also know I don't have the time to spend on them. 

I want to put together a quick project to provide as a little birthday gift to someone. It's little more than an animated card but I wanted to put some interactivity in there just to provide a little entertainment. It's also a good excuse to learn putting how to work with Unity (and Blender as well).

The view in game (debugging shows the state of the FSM on the Game Object).

The view in game (debugging shows the state of the FSM on the Game Object).

The GUI is built from standard Unity components. The keypad is represented by the small box on the wall. When the player gets close enough it triggers automatically. This could be refined but works well enough for testing.

The Finite State Machine in Playmaker's editor window.

The Finite State Machine in Playmaker's editor window.

And here's the Finite State Machine (FSM) as depicted in Playmaker's editor. It starts in the 'Off' state. On entering the triggering state we progress to 'On'. This state handles drawing the GUI and also fires an event to the player controller to enter an 'interacting' state which freezes the player in place and enables the mouse cursor.

On pressing a number button a modified version of Playmaker's GUIButton class is called. This sets a string on a specified variable equal to that of the number of the button. We go to Error Check to see if the current value should be cleared, and, finally, append the number string to the code. On pressing OK we validate the entered code by comparing it to the correct version, and, if it's correct, we open the doors. We go to the Exit state from there so we can send an event to restore motion to the player and they can exit the area of the trigger. Once done, the FSM is reset and will trigger again if the player hits the trigger. If the code does not match, we update the display to show an error message and set a flag so we know to clear the display when the user presses another button.

There's some small improvements that could be made but, otherwise, this is working nicely. It's easy to modify and could be used in a number of places if required. Overall, it was a useful learning exercise and picking something slightly more complicated than a light switch forced me to learn a few different ways of using Playmaker.