Hacker News new | ask | show | jobs
by jashmenn 4401 days ago
Author here - I didn't expect to see this here this morning. I'd intended to write a longer post :)

In any case, here's a few things I learned about swift yesterday building this. Please note that I have about 4 hours swift experience, so feel free to correct anything I say that's wrong.

1. To make properties on a class you simply declare the variable on the class e.g.:

    class GameScene: SKScene { 
      var bird = SKSpriteNode()
      // ...
    }
2. The APIs generally have shorter names and it's really nice. E.g.

    SKTexture* birdTexture1 = [SKTexture textureWithImageNamed:@"Bird1"];

becomes

    var birdTexture1 = SKTexture(imageNamed: "Bird1")

If I understand it correctly, any overloading `inits` basically look like calling the constructor on the class, whereas any class functions will be called like this:

    var flap = SKAction.repeatActionForever(animation)

3. You can put inline blocks and it's great

    var spawn = SKAction.runBlock({() in self.spawnPipes()})

4. The typing is really strong - this takes some getting used to. For instance, `arc4random()` returns a 32 bit unsigned integer. This means before you can use any operators on it you have to make sure you're using compatible types. e.g.

    var quarter = UInt32( self.frame.size.height / 4 )
    var y = arc4random() % quarter + quarter;
If we didn't use `UInt32` to convert `quarter` we'd get an error. After you get the hang of this, it's actually really nice.

5. I use `var` everywhere and I'm pretty sure I should be using `let` a lot more. I haven't worked with Swift enough to have a strong intuition about when to use either.

I should also mention that my code is just converted from Matthias Gall's code [1].

I also want to put in a shameless plug that the point of making this was to advertise the "Making Games with Swift" class that auser and I are building. If you're interested, put in your email here: https://fullstackedu.com

I intend to redo this more fully with Playgrounds. I've been looking for a way to teach kids programming for a while now (if you recall, auser and I built Choc [2] a few months back). I think Playgrounds in Swift are finally the tool we've been waiting for.

[1] http://digitalbreed.com/2014/how-to-build-a-game-like-flappy...

[2] http://www.fullstack.io/choc/

EDIT: added choc

4 comments

I don't have XCode to try it out, but according to the book, you can replace

  var spawn = SKAction.runBlock({() in self.spawnPipes()})
with

  var spawn = SKAction.runBlock({self.spawnPipes()})
or even

  var spawn = SKAction.runBlock() {self.spawnPipes()}
or

  var spawn = SKAction.runBlock {self.spawnPipes()}
EDIT: formatting for code
This is awesome and I didn't know this. Thanks for posting it - I don't have much swift experience so I assume there are several things in the code that will be shown to be non-standard.
> I don't have much swift experience…

Considering the language has only been public for <36 hours, I would imagine effectively no one outside of Apple (and its Alpha partners) does.

Which will not stop recruiters from seeking candidates with 5 years experience in Swift.
What about this?

  var spawn = SKAction.runBlock self.spawnPipes
Heh. Reminds me of when I correct people for

  if var == true {...}
or (and I have actually seen this)

  if (<expression> == true) {
      return true;
  } else {
      return false;
  }
I sometimes think that simply giving those 5 lines to a person and observing if they make a face like you've handed them a bucket full of day-old fish is a better test for programming aptitude than anything.

  if var == true {...}
In some languages var might be truthy but not equal to true. The falsy values may be more of a problem at times.

However in the strongly typed swift I don't think it will be a problem as I suspect (but haven't read/tested enough yet to confirm) that only false and nil will be falsy and that comparison with true will throw errors if var isn't of bool type.

Just tried it. In Swift:

  3 == true    // Give an error (operator overload doesn't cover this)
  true == 3    // Returns false
  nil == false // Returns false
You can't use nil or integers directly in an if statement without a function to return a logic value.
Yes, such languages exist, and even in C++ if (x == true) is different from if (x), given that x is any number kind other than boolean, but my comment was only for the case when the two would be equivalent.
I'd argue the second is clearer in many cases. Readability trumps conciseness any day.
I agree that readability trumps shortness of code. I want not for APL nor code run through a javascript minifier.

But the branch and explicit boolean comparison are additional structural complexity (not just "verbosity") and invariably harms readability to me. Care give a poster child example for where it helps readability? Unless it's unclear <expression> results in a boolean - a problem better solved through better naming - code like this forces me to perform the equivalent simplification in my head to understand and reason about the code, a process fraught with error and distraction from my actual task.

Really? In which cases would the previous example be clearer than

    return expression;
What readability does the verbosity add?
Are you sure this should work? I checked the grammar once more and it seems that closure-expression should always be enclosed in { ... }
I think just the fact that you were able to build a game with just 4 hours of learning a new language speaks volumes about Swift's barrier to entry. Well done!
I think it speaks more to the author's prowess, not to the fantastic magic powers of Apple's latest walled garden.
Any up-to-date C# developer already knows Swift.
Any up-to-date Java developer already knows Swift :)
Any up-to-date Swift developer already knows Swift :-p
But the code was just a port/convert, seems relatively non-trivial to do that in 4 hours.
I supposed "relatively" is the key word here. To me, that'd be a great feat. To others, not that special.
"I use `var` everywhere and I'm pretty sure I should be using `let` a lot more. I haven't worked with Swift enough to have a strong intuition about when to use either."

I think you should type let everywhere, except when you cannot get away with it.

So, it is var when declaring a loop variable. Elsewhere you almost always can introduce a new name. So, instead of

   X += 1
do

   let newX = x + 1
Those rules are too strict, but not much so, and you will learn the difference faster if you overcompensate.

If you find yourself creating a newerX, a newestX, etc. you may be better of with a var, but chances also are that you are better of writing your code differently (for example can you iterate over a constant array of values instead of doing x+=1 a few times? If your function needs to create 10+ Local variables, can you factor out a function?)

A couple more interesting swift features that seemed a bit weird to me after skipping through the reference:

1. Strings, arrays and dictionaries are value types (like structs in C# - stored on stack, not on the heap) with special copying rules for arrays.

2. Custom operators - can be defined as a sequence of "/ = - + * % < > ! & | ^ . ~" characters and made prefix, infix or postfix. There is an example in the reference that defines a prefix operator "+++" for vectors