Migrating to a VPS

After having pretty stagnant websites costing me $10/month for years and years on shared hosting, I’m finally in the process of migrating to a VPS hosted by DigitalOcean. I was pushed over the edge by the fact that my shared host of 10+ years (Dreamhost) runs Ruby 1.8.7, and I had no way to upgrade. The prospect of administering my own web server is a bit daunting, but heck, I write websites for a living, I should be able to figure it out.

So how does one go about moving one’s digital life?

The one good thing about my shared hosting provider was that they were a “one stop shop.” I had my domain registration, email, web hosting, version control, everything in one place. Moving to a VPS means that all my services are all over the place. Such is life, I guess. Hopefully being able to run modern webapps for $5/month will make me feel better.

The first step for me was to migrate my old email into my Gmail account, which I’ve been using for about 10 years. Fortunately, email has an “Import from POP3” option right in Settings -> Accounts and Import. I grabbed all my old messages, labeled them, and called it a day.

Next was to move all my crummy, half-baked SVN repositories over to GitHub. Most of these are pretty worthless, but I’m a digital packrat (as well as physical), so I followed this tutorial from the Git Book. I’ll have to go back and delete most of them later, as they are of no use to anyone, least of all myself.

I moved my domain names over to Google Domains. Seems a bit sketchy since it’s in the perpetual “Google Beta,” but the offered email forwarding, and the last thing I want to do is deal with an email server to handle my legacy email address.

Lastly, I converted my Wordpress blog over to Jekyll, a static site generator. Conveniently enough, there’s a Wordpress importer which I used to grab my existing posts. After installing nginx and Ruby on my shiny new VPS, I created a Git post-receive hook to rebuild the site every time I push to the remote repo.

So far it’s been pretty fun to muck around with these things – I feel like I don’t know nearly enough about system administration, so hopefully I’ll pick up a few things.

Comments · Posted by Posted by Nathan at 00:04 · Tags internets


Buttons in Sprite Kit using Swift

For all the helpful things that Apple added to Sprite Kit, one of the most glaring omissions is that most basic of user interface elements, the button. Not really sure why that is, but fortunately it’s pretty easy to create something that “just works.” The gist of the solution is to create a subclass of the SKNode class. Since each node in Sprite Kit can contain any number of other nodes, we just have to create a button container which holds two sprites: one for the default button state and one for the “active” button state.


import SpriteKit

class GGButton: SKNode {
    var defaultButton: SKSpriteNode
    var activeButton: SKSpriteNode
    var action: () -> Void
    
    init(defaultButtonImage: String, activeButtonImage: String, buttonAction: () -> Void) {
        defaultButton = SKSpriteNode(imageNamed: defaultButtonImage)
        activeButton = SKSpriteNode(imageNamed: activeButtonImage)
        activeButton.hidden = true
        action = buttonAction
        
        super.init()

        userInteractionEnabled = true
        addChild(defaultButton)
        addChild(activeButton)
    }

    /**
        Required so XCode doesn't throw warnings
    */
    required init(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}
  

Here we create that subclass of SKNode and give it three properties: the default button image, the active button image, and the action that the button should take if pressed. Passing in two strings to the constructor handles initializing the button images, and we also store a reference to the button action function. Note of course that we hide the “active” button by default, waiting for user interaction to reveal it.

After the call to super.init(), the button container has access to methods inherited from SKNode. We then set the userInteractionEnabled property to true, which lets this node respond to input, and also add both buttons as children so they’ll be drawn to the screen.

Now let’s deal with user input. We want to handle three cases: user touches the button, user moves their finger around, user lifts their finger off the button. Fortunately the user interaction methods provided by SKNode give us exactly that, if you add the following three methods to the button class definition.

  
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
    activeButton.hidden = false
    defaultButton.hidden = true
}
  

This first method is pretty obvious: if a user starts touching the button, show the “active” state.


override func touchesMoved(touches: NSSet, withEvent event: UIEvent) {
    var touch: UITouch = touches.allObjects[0] as UITouch
    var location: CGPoint = touch.locationInNode(self)

    if defaultButton.containsPoint(location) {
        activeButton.hidden = false
        defaultButton.hidden = true
    } else {
        activeButton.hidden = true
        defaultButton.hidden = false
    }
}

This next method is a bit more complex. We have to determine if a user moved their finger on or off the button, so as to show the appropriate highlight state. Fortunately, SKNode-derived objects have a method containsPoint(), which lets us do some easy collision detection.


override func touchesEnded(touches: NSSet, withEvent event: UIEvent) {
    var touch: UITouch = touches.allObjects[0] as UITouch
    var location: CGPoint = touch.locationInNode(self)

    if defaultButton.containsPoint(location) {
        action()
    }
    
    activeButton.hidden = true
    defaultButton.hidden = false
}

Finally, we re-use the containsPoint() method described earlier in order to determine if the button was actually tapped. If it was, we call the “action” function that was provided to the constructor. Then we set the highlighted button state back to hidden, ready to be shown again on the next tap. Put it all together, and here’s how you’d use the button in a game:


var button: GGButton = GGButton(defaultButtonImage: "button", activeButtonImage: "button_active", buttonAction: goToGameScene)
button.position = CGPointMake(self.frame.width / 2, self.frame.height / 2)
addChild(button)

I hope this was helpful. Feel free to ask questions in the comments section, and I’ll do my best to answer.

Comments · Posted by Posted by nathan at 06:09 · Tags iOS tutorial apple swift sprite kit


Intro to Sprite Kit using Swift

Have you started looking at Apple's Objective-C replacement, Swift, yet? If not, now's the time. You'll use the same APIs with Swift, but the language syntax is similar to that of JavaScript or Ruby, which makes it a bit easier to write. While Apple provides some Swift tutorials, I'm mostly interested in using it with Sprite Kit, Apple's home-grown casual game framework. The documentation provided on Apple's developer gives an intro to using Sprite Kit with Objective-C, but I thought I'd translate that into Swift for your enlightenment and education.

Setup

To start off, open Xcode 6, and choose "Create a new Xcode project." Select "Single View Application" for your application template, and then name your project. I'll name mine "SwiftDemo." Once you choose a location for the project files to be saved, you'll be plopped into the "General" settings panel for the app. The next step is to add SpriteKit.framework to the project. Scroll to the bottom of the panel and find the section titled "Linked Frameworks and Libraries," and click the plus icon. Type "SpriteKit" in the search input, select SpriteKit.framework, then click "Add."

The next task is to set up the app's view controller to use Sprite Kit. Select `Main.storyboard` from the project pane to open it. It has a single view controller and view. Click the large white box, which represents the view. In the Utilities pane on the right side of the window, change the class of the view to SKView. Next, select the ViewController.swift file from the project pane to open it. Change the import UIKit statement to import SpriteKit right below the copyright comment. Next, add some code to the controller's viewDidLoad() method to show some Sprite Kit diagnostic info:


override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    var spriteView:SKView = self.view as SKView
    spriteView.showsDrawCount = true
    spriteView.showsNodeCount = true
    spriteView.showsFPS = true
}

We're now ready to add the first SKScene to the app. Scenes correspond to the various sections of functionality in your game, such as title, level select, options, and actual game play. Right-click on the project pane and select "New File." Select "Swift" for the file type, and name it HelloScene.swift. The newly created file will be empty, except for an import Foundation line. Change it to import SpriteKit, then create an empty subclass of SKScene:


class HelloScene:SKScene {
}

Now let's go back to the view controller and have it present the newly-created (and empty) scene.


override func viewWillAppear(animated: Bool) {
    var helloScene:HelloScene = HelloScene(size: CGSizeMake(768, 1024))
    var spriteView:SKView = self.view as SKView
    spriteView.presentScene(helloScene)
}

Try to build and run the project. You should see a blank screen on the simulator with diagnostic information at the bottom.

Now we'll work on actually adding content to the scene we just created. Add the following into the HelloScene class:


var contentCreated:Bool = false
    
override func didMoveToView(view: SKView!) {
    if !contentCreated {
        createSceneContents()
        contentCreated = true
    }
}

During the course of your game, scenes will be instantiated, and shuffled around, and deallocated when no longer needed. When the scene moves into view, you want to ensure that it contains your content, but only if it hasn't yet been created. If the scene stays in memory and is re-presented, your initialization code could run twice, which is why we keep track of it with a boolean. Let's implement the createSceneContents() method.


func createSceneContents() {
    backgroundColor = SKColor.blueColor()
    scaleMode = SKSceneScaleMode.AspectFit
    addChild(newHelloNode())
}

This function does a few things. It changes the background color (obvious), sets the scale mode, and then adds the return value of a newHelloNode() function to the scene. The scaleMode attribute can have two values, SKSceneScaleMode.AspectFit or SKSceneScaleMode.AspectFill. Both modes will ensure your game's aspect ratio stays intact, but "AspectFit" will shrink the view to fit the scene (common side effect: letterboxing), while "AspectFill" fills the scene (but some content might be cut off). It's up to you to decide what technique best fits your game.

Next let's implement the newHelloNode function that adds actual content to the scene. It's pretty straightforward, just creating a label, giving it some properties, then returning it.


func newHelloNode() -> SKLabelNode {
    var helloNode:SKLabelNode = SKLabelNode(fontNamed: "Chalkduster")
    helloNode.text = "Hello, World!"
    helloNode.fontSize = 42
    helloNode.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame))
    return helloNode
}

Now when you build and run the project, you should see a blue background with the text "Hello, World!" centered in the screen (notice the letterboxing due to our use of SKSceneScaleMode.AspectFit).

Animation

Fluid animation is absolutely necessary in any game. While it might not directly affect game play, its' presence makes the game that much more engaging and "juicy." We'll add some animation to the label node in our scene. Add the following line to the newHelloNode() function:


helloNode.name = "helloNode"

All nodes have a "name" property, which you can use to identify or find them after they are initialized. Next, override the touchesBegan(touches: NSSet!, withEvent event: UIEvent!) method, and add the following:


override func touchesBegan(touches: NSSet!, withEvent event: UIEvent!) {
    var helloNode:SKNode = childNodeWithName("helloNode")
    if helloNode != nil {
        helloNode.name = nil
        
        var moveUp:SKAction = SKAction.moveByX(0, y: 100, duration: 0.5)
        var zoom:SKAction = SKAction.scaleTo(2, duration: 0.25)
        var pause:SKAction = SKAction.waitForDuration(0.5)
        var fadeAway = SKAction.fadeOutWithDuration(0.25)
        var remove = SKAction.removeFromParent()
        var moveSequence = SKAction.sequence([moveUp, zoom, pause, fadeAway, remove])
        helloNode.runAction(moveSequence)
    }
}

This method finds a node named "helloNode," then runs a bunch of actions on it. Build and run the project, then click anywhere on the screen to make the method execute. There's a good sampling of what's available in the SKAction class here, but it's always good to check out the SKAction class reference just to see what's possible.

Scene Transitions

As I mentioned earlier, you'll probably have multiple scenes in your game, and you'll obviously need to switch between them. Fortunately, Sprite Kit allows you to do that quite easily, and add some fancy transition effects at the same time. Create a new scene called SpaceshipScene.swift and give it the following implementation:


class SpaceshipScene:SKScene {
    var contentCreated:Bool = false
    
    override func didMoveToView(view: SKView!) {
        if !contentCreated {
            createSceneContents()
            contentCreated = true
        }
    }
    
    func createSceneContents() {
        backgroundColor = SKColor.redColor()
        scaleMode = SKSceneScaleMode.AspectFit
    }
}

Now, go back to HelloScene.swift, comment out the code inside of touchesBegan(touches: NSSet!, withEvent event: UIEvent!), and replace it with the following:


var spaceshipScene:SKScene = SpaceshipScene(size: self.size)
var transition:SKTransition = SKTransition.doorsOpenVerticalWithDuration(0.5)
view.presentScene(spaceshipScene, transition: transition)

Build and run the project. You should see text on a blue background again. Click anywhere, and HelloScene will transition to SpaceshipScene with a cool "doors" effect. Again, check out the SKTransition class reference for a list of all the effects you can use.

Adding more content

Next we're going to add an object to SpaceshipScene that's comprised of multiple Sprite Kit "nodes." Add the following code to the createSceneContents method in SpaceshipScene:


var spaceship:SKSpriteNode = newSpaceship()
spaceship.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame) - 150)
addChild(spaceship)

Next, implement the newSpaceship() method:


func newSpaceship() -> SKSpriteNode {
    var hull = SKSpriteNode(color: SKColor.grayColor(), size: CGSizeMake(64, 32))
    var hover:SKAction = SKAction.sequence([
            SKAction.waitForDuration(1),
            SKAction.moveByX(100, y: 50, duration: 1),
            SKAction.waitForDuration(1),
            SKAction.moveByX(-100, y: -50, duration: 1)
        ])
    hull.runAction(SKAction.repeatActionForever(hover))
    return hull
}

Build and run the project to see a gray box moving back and forth indefinitely. Next let's add "lights" to the spaceship. Insert the following right after declaring the hull variable in the newSpaceship method:


var light1:SKSpriteNode = newLight()
light1.position = CGPointMake(-28, 6)
hull.addChild(light1)

var light2:SKSpriteNode = newLight()
light2.position = CGPointMake(28, 6)
hull.addChild(light2)

Then implement the newLight() method:


func newLight() -> SKSpriteNode {
    var light:SKSpriteNode = SKSpriteNode(color: SKColor.yellowColor(), size: CGSizeMake(8, 8))
    var blink:SKAction = SKAction.sequence([
            SKAction.fadeOutWithDuration(0.25),
            SKAction.fadeInWithDuration(0.25)
        ])
    light.runAction(SKAction.repeatActionForever(blink))
    return light
}

Build and run the project. You should now see two blinking lights on the "spaceship."

Physics

To wrap up, we'll add some physics interactions to SpaceshipScene. I'll leave the reasons why you might want a realistic physics simulation in your game as an exercise to the reader (*cough*Angry Birds*cough*). First of all, change the newSpaceship() method slightly to add a physics body to the ship hull:


hull.physicsBody = SKPhysicsBody(rectangleOfSize: hull.size)
hull.physicsBody.dynamic = false

We set dynamic = false so the ship isn't affected by the physics system's gravity. Otherwise it would fall off the screen, since there's no floor in the game to stop it. Next add some code in createSceneContents() to generate rocks that will bounce off the ship.


var makeRocks:SKAction = SKAction.sequence([
        SKAction.runBlock(addRock),
        SKAction.waitForDuration(0.1, withRange: 0.15)
    ])
runAction(SKAction.repeatActionForever(makeRocks))

And implement addRock():


func addRock() {
    var rock:SKSpriteNode = SKSpriteNode(color: SKColor.brownColor(), size: CGSizeMake(8, 8))
    rock.position = CGPointMake(self.size.width / 2, self.size.height - 50)
    rock.name = "rock"
    rock.physicsBody = SKPhysicsBody(rectangleOfSize: rock.size)
    rock.physicsBody.usesPreciseCollisionDetection = true
    addChild(rock)
}

Build and run the project and you'll see a bunch of rocks being generated and bouncing off the spaceship. While Apple's tutorial has you manually removing rocks that fall off the screen, apparently some changes to the Sprite Kit API now do that for you automatically (you'll notice the "node" count stays constant while the app is running).

And that's it! A very basic overview to both Sprite Kit and Swift. Try playing around with the project and see what else you can come up with. Happy hacking!

Comments · Posted by Posted by nathan at 07:09 · Tags tutorial apple swift spritekit


Arcadia + Game Center for Cordova

It’s been a slow couple of months. A bit of “real life” upheaval (in the form of having to find a new job) has prevented blog updates. I haven’t been completely idle during this time, though, and have been working on a few small projects, two of which I’ll detail here.

The first is a Game Center plugin for Apache Cordova. I wanted to learn how to write a Cordova plugin, and as far as I know, no one else has written a plugin for Game Center. I’m probably the only person who is stupid enough to write such a thing. It’s not a 100% complete implementation, but has support for leaderboards, achievements, and turn-based multiplayer games. To test the plugin out, I wrote a simple reversi game, which will allow users to play via asynchronous multiplayer. The game itself isn’t quite done (I hit a roadblock in that I only had one iOS device to test on), but I’m hoping to get back in and finish it soon.

The other project is a minimalistic <canvas>-based game framework. What started as some experimentation with the canvas tag turned into something more like a full-fledged game framework. I use the term “full-fledged” pretty loosely, of course. It has support for game scenes, shape-based sprites, and particle emitters, and handles keyboard/mouse/touch input. My big source of inspiration was the Flash-based games of developer Kenta Cho. While it’s relatively easy to create a simple 2D game in Flash, a lot of the boilerplate code you might want is missing from JavaScript. This framework might help you out in creating prototypes that can be easily embedded into your website for quick feedback. If you end up wanting to publish the game (on mobile, for example), you can set an option when instantiating the game container that causes the canvas to scale to fit the size of the window, which means you could publish across multiple screen sizes pretty easily. I’m currently experimenting with making a simple dual-stick shooter using the framework.

As always, comments and suggestions are welcome. Keep programming!

Comments · Posted by Posted by nathan at 07:06 · Tags javascript cordova vectr


Invading the Firefox Marketplace

Another day, another marketplace to list your apps in. This time it's the Firefox Marketplace, the new hotspot for "HTML5" apps. I recently registered as a developer and uploaded Nonogram Madness and Shikaku Madness.

Not really much to report, I had to make a few tweaks to both games to ensure they ran OK on the Firefox OS simulator, but aside from that it was easy to create an account and get both apps approved. Yes, your apps have to be vetted in the Firefox Marketplace, which is kind of annoying, but I guess it makes sense to have some level of curation to weed out malware, useless software, etc. My positive experience was that while both my apps had an initial bug (only counted iOS + Android as having touchscreen support, not Firefox OS), I fixed the problem and didn't have to wait another week for them to be reviewed again; they were live that same day.

One kinda cool thing is that if you download Firefox Aurora (the "beta" version of the next Firefox release), you can install webapps locally on your computer; they get a native app wrapper, so you can launch them just like regular programs. Give it a shot, Mozilla has been doing a lot of cool things recently, so it's worth checking out Firefox again.

Comments · Posted by Posted by nathan at 23:04 · Tags nonogram madness shikaku madness mozilla firefox