 in Australia, as you can probably tell. I work at a small consulting firm that helps government and private businesses manage assets and energy and that type of thing. Absolutely nothing to do with games. But I have been using SpriteKit since it was introduced about 11 months ago. It was at that time that I sat down and I thought, you know what, I really want to make a game. SpriteKit came out at just the right time. And it kind of blended development, which I was doing with Ruby Motion, but also my love of iOS games, which I'm a bit of an addict. So the name of the talk is SK Fun, or Ska Fun, as my wife refers to it. So I guess just a question to kick it off. How many of you have got an idea for a game or got into programming because they had an idea for a game? Yeah. Put your hand down if you actually made the game. I will put your hand back up if you made the game. Okay, so a lot of people get into programming because they want to make games, but not many of them actually do make the game. So what I kind of hope that you leave with here is a basic understanding of how easy and how exciting and how fun it can be to make a game with SpriteKit and Ruby Motion. So what is SpriteKit? Well, SpriteKit is a 2D sprites and animation framework. So we've all played 2D games. We grew up with games like Mario and Alex the Kid. And then you move on to games on iOS like Cannibal, Sword and Sorcery, those types of games. An example of Cannibal there, one of the first really kind of big 2D games on the iOS. Now many of the games that you see on consoles these days are 3D based. So Halo, Call of Duty. But there's been a bit of a resurgence in independent developed 2D games. And this is really great. And SpriteKit really fills this gap that it has on iOS if you want to code in an Apple framework. And it makes it really easy and really fun and it's nicely implemented. The good thing about SpriteKit is that it can run on both OS 10 and iOS. So if you're really careful about how you create your game, you'll be able to deploy to two targets with the one game. Just being aware of things like NS for Mac and UI for iOS. So I said I started looking at this 11 months ago. So I wanted to share with you 11 things that I wish I knew 11 months ago. And to do this I'm gonna use a game that you might have heard with. It was a huge critical success, but an utter financial failure. And in the end the guy pulled it, Flappy Bird. I'm not sure if you've heard of it. Now why would I use this as an example? Well, because it's very easy to understand. When I say there are pipes, when I say there's the ground, when I say the bird flaps his wings, you all get that image of what's happening in your head. So lesson number one, the coordinate system. So in a typical iOS app, the coordinate system looks a bit like this. Well in SpriteKit that's flipped. And you'll figure that one out pretty quickly. And it's what I like to call or what you may like to call, down under mode. So it's actually easier for us three who live in Australia. Number two, there's one UI view. And this is perfectly acceptable. In fact it's recommended by Apple that you only have one UI view throughout your whole game. And this is because SpriteKit is built on a concept of nodes. And this will start to make sense as we kind of continue down the path. But all the view does is manage the presentations of these nodes as your game is being built and as your game is being played. And this is the kind of typical setup of a new view. So you can see that it inherits from SKView. And that's really all you need. So this is really all this view is gonna do. Yoala, you initialize your scene, passing in the size. And you see that you can do things like shows frames per second to true. And this is great because you wanna keep a high frame weight. So you wanna see how many nodes am I drawing? What's my draw count? Things like that. Especially why you're developing the game. Apple suggests that you try and keep your game as close to 60 frames per second as you can. On the simulator you'll generally see 30 frames per second. But as soon as you put that on the device it'll jump back up to 60. And you might think that this is a bit mad having only one UI view. But it starts to make sense when we look at lesson number three. You're gonna have many scenes. So scenes kind of encapsulate what's going on in our game. So you'll have a scene for each type of screen or level within your game. So if you think of a game that you've played you might have a fire level, a nice level, credits, cut scene menu. So each of these parts is encapsulated by a different scene within your game. And you wanna subclass commonality. So you wanna create classes for your characters that represent your characters, what do they look like, what are they wearing, what do they shoot, how do they die. All those types of things you create classes so you can just pop them into these scenes as you go along. So really the view is only responsible for the transition between and rendering of our scenes frames. So the view is a static thing. So you think of a TV showing TV shows. Probably the best analogy I can come up with. And this is the typical scene setup. So you see here that it did move to view so much like a view did load or other similar methods. And you get the view that loaded the scene. And then we just call some basic methods here. So there's nothing crazy going on. We're just calling some methods that will eventually add some nodes to our scene. So once the scene has moved to the view, SpriteKit will start and it'll kick into gear what it calls the game loop. So I want you to kinda think about maybe a Simpsons episode or any other type of animation that you watch. Each frame is drawn individually. So to make up one second of footage the artist will draw 24 frames if you're in Australia. Each frame is drawn individually and then put together those are rendered to the screen. So this is very similar to how SpriteKit works. Our scene will calculate what's gonna happen in that frame and eventually the view will render it to the iPhone screen. And this is what SpriteKit's game loop looks like. There are four places where we can hook in and where SpriteKit will carry out code for us. The first one you can see here is update. And this is before anything has happened. So this is called at the start of every single new frame. Then the actions are run and then we can say where are the actions up to? And actions we'll talk about in a bit. Then physics are simulated. So are things bouncing off each other? Where did this object that was falling end up? Has it collided with another body? And then finally the view will render that frame to the screen. So ideally this loop is happening about 60 times every second. There's a lot to manage there but luckily SpriteKit makes it fairly easy. And these are the three methods that we are able to hook into in that game loop. So the first one update. Then these other two are delegate methods that belong to every scene. And you'll notice that these happen after the fact. So after the actions have been evaluated and after the physics have been simulated. So what I found was that when I was building Flappy Bird again, I didn't really need to use these methods. You might for more complex games but for Flappy Bird it wasn't really needed. And I think this kind of says something about how SpriteKit is built and how easy it is to get going and build any type of game. So during the setup you saw that I was calling methods like addSkyline and addGram. So I wanna show you what they're all about. So the SK node class. It's probably the most commonly used class throughout your entire game. Even a scene itself is a node. So what I would suggest is that you, when you're creating your characters and things like that, they're probably gonna inherit from SK node. So this is the class that you will inherit from when you create those characters. Now there are many different types of node. There are shapes, particles, labels, videos. And these all share some common behavior. But I really strongly encourage having a look at the different types of nodes that exist out there. But there is one node that you'll use more often than any of these nodes. And that's the Sprite node. So these are the characters within our game. These are the birds, these are the men and the women of our game. The main characters, the things that drive the story. So really what they do is they display a textured image and creation of these is very easy. And that's good because you'll use them quite a lot and you see them everywhere in games. So you can see here that I pull out an image and this is just an image that's stored in my resources folder. And then I create a bird using SK Sprite node with Sprite node for image name, with image name. And you'll see these types of class methods quite a lot within SpriteKit. So rather than the traditional allocate and then initialize, you'll see these class methods which makes it a little bit more Ruby-ish. So we're almost there. And then I pass in the image and then I give the bird a name. And this is really important because giving a node a name means that we're able to go back down through the scene graph and then pull that node back out from wherever it is currently sitting. So give things that you're going to want to reference again a name, makes it really easy to get them back. And then much like adding sub-views and to your normal UI views, we do scene.addChild and pass in that node. And this is typically how you would add a node to a scene. So Sprite nodes can also be animated with actions. So actions are these great things that you're going to use quite a lot as well. And the first one that I want to show you is an animation because that's pretty important. You want to give your characters a little bit of life on the screen. So Sprite animation. And we'll see two new concepts in action here. Textures and actions. So I've got a method here called flap. And what this method is going to do is it's going to make our bird flap. So if you've played Flappy Bird, basically what happens is his wings flap up and down as he travels across the screen. So the first thing I'm going to do is I'm going to load in three textures. And each of these textures represents a state of that bird in the flap action. So we've got one, two, and three. So wings up, middle, and down. And then I pop those into an array. And then I'm creating an action called animation. And this is typically how actions are created. So the action that I'm using here is animate with textures. So SpriteKit gives us this ability to animate our sprites using actions. It gives us this, all we need are the textures and it'll look after the rest. As long as you're passing them in in the order that you want them to happen in the array, then they'll maintain that state. So I'm passing the textures here and I say here are my textures, here's the time per frame that I want you to spend on this animation. And SpriteKit will look after that. And then all I need to do is, okay bird, repeat this action forever. And I'm passing that action. I don't have to come back to that. I don't have to maintain it. I don't have to do anything else to do with that. I can stop it if I want later on. But from here SpriteKit will take this and it'll run with it. And this is great about actions. We don't have to maintain actions. We can set and we can forget. So actions are really powerful. You can do a lot with them. And one particularly useful mechanic while you're building a game is scrolling images or parallax effect. You see this a lot in 2D games. After a bit of research, basically this was the best way that or the most common way of solving this issue was to have two images. So you can see here that I've got two background images, one right next to each other. And this means that we have a really low node count, which means really high frame rates. But it also means we don't have to keep drawing the same image. We can just reuse these images. So we don't have to do any expensive operation to reload or add new nodes to our scene. So the basic idea is that you load the images next to each other. And then as the game progresses, as the game loop runs, then the screens actually scroll. And then as soon as this one here gets to the left and off the screen, we remove it and then we move it back to its original starting position and then restart the scroll. So without actions, this was messy and it was definitely not fun. So it wasn't long before I kind of looked at actions. And I learned this in number five. Actions are magical. So you can accomplish a lot with actions. And with using actions, this became a much easier task. So you can see that I have a method here add skyline. I load in a texture and because I wanna add these images twice, I do it in a loop here. I calculate a position to make sure that one is on the screen and one is slightly off to the right. And then I create a sprite node with that texture. I set its position using the calculation that I ran above. And then I pass in an action using run action. We'll have a look at that action next. And then after that I add the sky to the scene using that same add child method. And I do that for both. So I do that all within that one loop. Let's have a look at that action. So the basic part of this action is those three parts in the middle. So I'm actually creating three more actions here. And that's what's really great about actions. You can create actions, you can knock actions into other actions, you can sequence actions. So here I create two more actions and then I sequence them. So I'm saying move by X. So this is a special action that will actually move the screen as we saw, the one on the left and the one on screen, to the left on an X axis. And then I sequence them together. So what this means is I'm putting these two actions that I've created. So the move action and the reset action which takes that first screen and moves it back onto the right. So I sequence those in array and I create a new action from that. And then I tell and then I create a final action called repeat action forever. And I pass in that sequence. So sequencing is really important because it allows us to queue up actions that will happen in a certain order every single time. And that's really all that's needed for that parallax effect. And with repeat action forever, this will run forever. SpriteKit will look after this for us. We never have to go back to it before I was in the update method trying to calculate deltas and trying to move it myself. Actions made this a ton of a lot easier. And if we apply this same concept to the ground, so having the two images next to each other and setting a different duration, we can actually get a really nice parallax effect where the background is moving slightly slower than the foreground. Very popular game mechanic and it gives the game a little bit of depth. So you might have noticed back there that I use the texture rather than an image. And this is really important. It actually brings me to number six. Textures are reusable between sprite nodes. So what that means is when I load a texture, I can reuse that same texture in memory for multiple sprite nodes if those sprite nodes need to use the same texture. This will cut down on memory usage and it's a very efficient way to create reusable nodes. And so you can see here that the same texture image will get used for node one and node two. So we have the basics of our world. We've got the ground and we've got the sky. So now I wanna talk about how nodes can be added to other nodes. So nodes can hold multiple nodes. And this works perfectly with our pipes. And it kind of joins into earlier what I was saying about creating classes to represent your world objects. So here I create a class called pipe pair. And I inherit from SK node because I don't want this to be a sprite node yet. I just want this to encapsulate the two pipes. So this is kind of what I wanted to achieve. I have an up pipe and a down pipe. And then I create a single SK node that encapsulates those two smaller nodes. So this way I can manage one node as it moves across the screen rather than two. And this is kind of how this works. So the node or the pipes get added as children of the pipe pair class. So if you think about the scene as a SK node and we're adding children to it, that's the same for this type of thing. So we're adding nodes to another node. So I add the top pipe and the bottom pipe. I set the position so that they're slightly apart and I also set them above each other. And then once I use the actions similar to how we were doing the ground and the background, then we start to have some pipes scrolling across the screen. So you can see here that with very minimal code, just managing a few textures and a few sprites, adding in a couple of actions that we've kind of created, we're almost created flappy bird. Just make sure that your pipes are moving at the same duration as your ground, otherwise that's too much power. So now we've got our pipes, ground, sky, so let's add some physics. And this is done through the physics world. So every scene will come with a physics world attached to it. By default, that exists. You don't have to create it. And this is typically what it looks like. So you first, if you want gravity, you can have no gravity if you're making a space game. But in flappy bird, we have gravity because the bird needs to fall. So we set the physics world, it's speed to one by one at default. I just wanted to explicitly show this too. You can make it slower or faster depending on your game. So if you have a pause menu and you don't want to stop the game, all you have to do is lower the speed. And SpriteKit will automatically look after all of that for it. It'll slow down all the actions, it'll slow down all that type. And then I assign the gravity as Earth. It's not quite Earth's gravity, but it's close enough for birds. So do you see there that I'm using CGvector make? What are CGvectors? Basically, it's a coordinate system. And these are created a little bit differently to how you would typically see them happen in science. So you pass it two numbers and these are two coordinates. And these aren't the coordinates to say I want this object to move to this coordinate. These are coordinates to say, push in this general direction kind of. They're very arbitrary. There's no way to say, move to, if you want to say move to an exact position, you use an action. If you want to apply a kind of general force to an object, then you use CGvector and you apply an impulse to it. So you can see here that I'm creating a vector of negative 20, negative 20. That's going to give it a slight push up and to the left. If I was to make those positive 20, then it would give it a slight push up into the right. This changes the direction. If I wanted to really push it into the top right, then I would give it a much bigger number. And I would really highly suggest you play around with these because they are arbitrary. If you're trying, if you've got two objects and one has a mass of 1,000 and one has a mass of 10, then those impulses and those vectors are going to work differently. So you really want to play with these and figure out what works best. You'll use CGvectors a lot because it's how we apply impulses and forces to physics bodies within our game. Number nine, physics bring life to your nodes. They give the nodes a little bit of character. Can they float? Do they fly? Do missiles hit them and do they bounce off and explode? So physics and physics bodies will dictate what's possible within the world that you're creating as the game creator. And this is typically how a physics body is set up. So any node can take a physics body. So you can apply a physics body to anything. If you have a video playing, you can give it a weight and you can give it a mass and a volume and you can make it float around in the sky if you like. But in the case of our bird, all we need is a simple physics body where we draw a rectangle around him. So what you'll find is that in a lot of games that you play, the physics body that represents that bird doesn't actually draw its way around the whole bird. That's a really expensive operation to do. So we cheat. We draw a tight little rectangle around it and that's kind of what it looks like. See-through, invisible, but not precise because you generally don't need it to be that precise and you don't wanna spend the time calculating your way around the whole bird when you don't really need it. So we set dynamic to true and then we assign the physics body that we just created to the bird. So it's pretty straightforward. There are three different types of physics bodies that you can create in your game. So there's dynamic which we're using for our bird and setting the physics body to dynamic will mean that this physics body can be affected by other physics bodies. So if you imagine I have two balls and both are set to dynamic true, when those balls hit each other, they're both gonna bounce off in different directions. Now if I make those static, so if I have two balls and I make one of those static, what's gonna happen is that one ball will hit it and then it'll bounce off. So the static physics body won't be affected by other bodies within the game but it'll still maintain its volume. So it still won't be able to pass through that body but it'll still be able to be hit by other bodies. And this is great for things like if you've played Mario, so the boxes that float in the air, right? You can jump on them but if Mario jumped on them and then they sank down with Mario. So those are the examples of a static physics body. And the last one there is an edge loop and these represent negative space within our game. So these are great for scene boundaries, walls and things like that. We didn't need these in Flappy Bird, the only one we really needed was dynamic. And physics can be really fun and you can have a lot of fun playing around with physics. So what I would say is, check the results often because you might end up creating the gravity version of Pong. This was a two player game that I built maybe 10 months ago and it failed miserably. No one can win. So iterate often, tighten the feedback loop between your game and what you're setting up in your game for your physics. So with a physics body and world, we can now start applying forces and impulses. And the way we do this in Flappy Bird is with touch. So there are four kind of key methods that you can implement touch with your game. You have touches began, moved, ended and canceled. You can also add gesture recognizers if you want a little bit more complexity but the majority of the time this will be okay. So for Flappy Bird we implemented touches began. So with this you'll get the touches that occurred. And you'll see here that I can pull the node out of my scene using that name that we started earlier. So this is why names are so important because now when I detect a touch, all I need to do is pull the bird out of my scene, reset its velocity to zero because velocities will stack. So if I didn't do that, if I didn't reset his velocity, with each tap he would actually progressively jump higher and higher. And then I apply another impulse. And you'll notice that I see, I use CGVectorMake 0.8. And this means that his y value isn't gonna change only his x value will change. So he'll jump up slightly. And you can see there that when I tap he jumps up slightly, his x value changes. Sorry, his y value changes but his x value remains the same. 10, collision versus contact. And this was probably the bit that really made me flip the table because this is a really hard concept that I struggled with initially. So collision is automatic. So you saw before that we assigned physics bodies to our birds and to our pipe and that type of thing. Well by default, SpriteKit will assume that we don't want these bodies to go through each other. So you don't want a bird to go through a pipe and you don't want a pipe to fall through the ground. So anything with a physics body, by default, will collide with any other physics body. So at this point in our game, with all our physics bodies, with all the setup we've done so far, if I had my bird and I sent him off on his way, he would just bounce around like a pinball. But we can actually choose which collisions to be made aware of. And this is what a contact is. So a contact is voluntary. The contact is used to know when two bodies touch each other. So you use contact when you need to perform game changes or gameplay changes when a collision occurs. Basically you want SpriteKit to tell you when there's a collision. And we can specify which collisions we wanna be made aware about. Because we don't need to know about every collision. Especially if we're trying to run that game loop 60 times per second to calculate a collision every single frame and calculate where our bodies are, is a very expensive operation. So to do this we use what's called categories. You get a maximum of 32 categories per scene. This might seem small at first, but it's actually okay. The reason for this is that the way collisions and contacts are stored is as a 32-bit mask for each scene. So this is typically how I set these up. I create constants, and I do that because I don't want them to change and screw up my game halfway through. So I create one for each. I create one for the bird, I create one for the ground, I create one for the pipe. Now the truth here is that the pipe and the ground can actually use the same bit mask category. But I wanted to really show you kind of how this would work without confusing it too much. But for the sake of the next little bit, I'm gonna assign those both and call them world. So the first thing I do is I set the world bit mask onto my pipes physics body. And I do this through category bit mask. Because I'm saying pipe, you are now my world. I do the same for the ground. So I set the world to the physics body through the category bit mask. Then I do the same for the bird. But this time I give it the bird category bit mask. And then what I can do is I can now tell SpriteKit when my bird's physics body hits the world, so my pipe or my ground, tell me about it. And I set this up through contact test bit mask. So I'm saying SpriteKit, I want you to test this contact. Test when this happens and let me know about it. Now you might remember when we set up the original scene, we set up the physics world contact delegate as self. This is fine, you can set up another class to represent the contact delegate. But there's not too much going on in this contact delegate. So now what happens is, as I'm playing my game, if I come along and hit a pipe, SpriteKit's gonna go, oh, a bird hit the world. And it's gonna fire off this delegate method, did begin contact. And that contact method actually passes in the two physics bodies that are currently in a point of collision. There's no way to actually determine which body is which from those two, which was convenient because for Flappy Bird, we didn't have to. There are some ways you can do it, but I didn't need to do it for Flappy Bird. And it's a really complex thing. But basically what happens is when we begin, when we detect a contact, we just restart the bird, we reset the pipes, and off we go. So this is kind of where we're at with Flappy Bird. Flaps across the screen, goes through the pipes. My version is really slow because I really sucked at it. And then eventually what will happen in, Flappy Bird is he will hit a pipe, and then the scene restarts. So number 11, controllers are awesome. I picked up a controller a couple of months ago and I'm having a great time with it. There are three different types of controllers. And if you're making a game, I would really highly suggest that you implement controllers in it because it can bring a whole type of new dynamic. Especially if you consider where the Apple TV is going, with AirPlay, and you can plug your iPad into the TV. I would love it if we could recreate the days of Gold and I sitting around with your brothers and sisters or your friends trying to shoot odd job. So you have three different types of controllers here. So the first one on the top right there is a standard controller. It's the bare minimum. It has a couple of buttons, it has two shoulder buttons. Wraps around the phone, so you've probably seen these Logitech Make one where the phone sits inside that little gap there. The one just below that is the extended controller. So that has the addition of two extra shoulder buttons, but also two joysticks, and wraps around the phone again. So these are connecting through the lightning port. And then the one over here on the far left is the standalone extended. So this is the same as the extended, the two shoulder buttons or four shoulder buttons, the two extra joysticks, but it's Bluetooth. So the game controller framework will actually supply us with profiles for these, excuse me, which we can use in our game to access the various buttons and controls on these controllers. And really all you have to do is add this framework to your game. And that's it. This will look after the rest. This will look after detecting when the controller is attached via Bluetooth. You don't have to do that. But it also gives you the ability to offer something that no other app can do, and no other kind of framework can do either. And that's manage the Bluetooth setup. So you can actually in your game detect when there's a controller nearby and then guide the user through the Bluetooth setup. So if a friend shows up with a new controller, you don't have to quit the game, go into settings, tap the controller, do all that kind of mess. You can create a really unique experience for both those people. And then this is all I had to add to Flappy Bird. Check controller. So I run this in my update method. So every time a frame is about to be rendered, I find my bird. I load in the controllers that are currently connected. I assign that to controllers. Then I load the profile, right? So I spoke about these before. Every controller has a different profile through game controller. I access the first controller because I only need one controller. This isn't a multiplayer version of Flappy Bird. But it is possible to have up to four controllers. And these are stored in an array and they'll always maintain their index within that array. So you can tell which player belongs to which character on the scene. I load in the profile. And then all I have to do, if the controller, if the button A is pressed, then reset the velocity and apply the same impulse. And that's it. That's controllers managed with Flappy Bird. So you can implement, say a space game, you can implement one that uses the joysticks to guide the ship around. The one thing that I would say about controllers is that you really need to remember the touchscreen. So the iPad, iOS devices are first and foremost touch devices. But I think this actually makes it really quite unique because you can create a game that has a wraparound controller that also incorporates things like the touchscreen that can really give your game a big difference. But what I would also say is, if you do implement a controller, don't forget about the touchscreen and those people who don't have controllers. And likewise for the people who are playing with controllers, don't forget about those who just wanna play with touch. So you'll need to implement both types of gameplay. So these are a couple of resources that I've put together. I would say the Linda course is brilliant. It's only about three and a half hours long and it covers a lot of stuff within the SpriteKit framework. Pragmatic programmers have a great book written on SpriteKit that's currently in beta. And the Apple documentation itself is brilliant. They've got a couple of demo apps up there that you can have a look at and see how they're implemented. I've also got three or four up on my GitHub account as well, which is just WillRacks. Does anyone have any questions?