[MUSIC] Okay, let's take the next step in our break out case study. Let's use that information about UI touches and the multi-touch event programming that we learned in the previous lecture, and let's put it into practice in this break out case study. What we're going to do is we're going to try and move a paddle on the existing code that we already have up to this point. That's going to involve, of course, creating the paddle. So we're going to import some graphics assets for that paddle. We'll add multi-touch callbacks. As part of that we're going to keep track of a property in our scene of the touch that's responsible for moving our paddle. We're going to keep track of that touch over the life cycle of our multi-touch events. And we're going to animate our paddle to that touch location. So let's go ahead and do that. Let's go to our code. And let's just run it again to remember what exactly we look like right now. I am running it on a physical device and then we're taking a look at it here through QuickTime so we can see what's happening live. Right now when we launch we get our launch storyboard, very simple. We get our opening screen, which is its own scene. If I physically touch the device we go to our screen that should have bouncing balls on it, but doesn't. So let's take it back. I'm going to, there they go. It took it a second. There are bouncing balls, and if I touch the screen, it should go over to game over mode. So, that's what we wanted to see, so that's good. Stop it. Now what we want to do is add the paddle so let's do that. Let's go to our assets here and let's add the graphics for the paddle. I did that previously, I created them previously off camera, and it should just be a simple matter of importing them now. So let's see if I can do that. I'm going to input the paddle times 2 as our base, go ahead and it move it times 2. I guess it's worth saying here that if you don't put all these different assets in, Xcode is smart enough to just scale them for you. But the reason that you're given the opportunity to put separate graphics into each one of these slots for different screen sizes and different screen resolutions. Is because a simple up-scaling or up-sampling or down-sampling of your graphic may introduce artifacts into your graphics that make it look a little bit not totally professional. And so what this is really enabling you to do is to, through some sort of an artistic process, to create high resolution, high fidelity images for high resolution, high fidelity devices. Not to just do a simple scaling in Photoshop on your own, because that of course is something that Xcode would do for you, but instead to actually put more detail into the high resolution images. And to extract that detail when you have a smaller image that is not as cluttered. Sam had a good analogy, if you're familiar with web development and you're ever trying to put that favicon, that's the image that shows up next to the URL. If you've ever tried to put one of those together, it's a very small image. I think it's 32 pixels by 32 pixels. But if you take, maybe 64 by 64 I don't recall. But if you take a full size square image and try and compress it down to the small size, it becomes kind of a muddy, blurry mess. But if you create an icon specifically for that size, you can get more detail, or a better presentation across. It's the same kind of idea with these paddles. All right, so let's go to our game scene. And what we're going to do is we're going to go ahead and create another object which is going to be our paddle. We're going to create it just like our ball, but of course we'll call it something else. An appropriate thing to call it would be paddle. So, I'm going to do that, and i'm just going to mirror it all down here and then we'll go back and I'll change the properties in a second once I get them all set up. All, right so the first thing we're going to want to do is we're not going to want it to be blue ball, but we're going to make it be paddle_x2.png. And it isn't going to be a circle, it's going to be a body with rectangle instead. And we'll do CGRectangleSeismic, there we go. And the size we want to be will be the paddle-size.width and paddle-size.height. So that will make it so that the bounding boxes on the physics body match the graphics item that we have. Again, in this graphics item, it's very tightly cropped. Should be tightly cropped. So we'll check to make sure it is tightly cropped. Actually, I have a bit of screen real estate there. So what I'm going to do is I'm going to shrink it down. Make sure that it's nice and tightly cropped. The reason I'm doing this is because I don't want that extra space around the outside. Maybe it is cropped already. Let's see that's, I want to see, is this one cropped okay? Let's see. kind of think it's not. Let's go ahead and crop it down. Let's take the small one. And we'll zoom in, and then we will crop it as well. The reason why I'm doing this is because I want the size of the icon to be right up to the edge so that physics appear to collide with the actual graphics themselves. Here we go. All right, and you can kind of see, let's see if we get them all at the right size. If we do actual size, If I had just taken, forget it. Okay. If I'd just taken the smallest image, and I had scaled it up using simple scaling, I would have gotten a lot of aliasing around the edge, but instead you can see that I created this image at high resolution. So, this has a nice, smooth edge when it's a large image. If I take the smallest one and I simply zoom it up, you can see that I get a rough edge as it zooms up. And so that's sort of what the opportunity is for you in using different sized graphics, to make sure that when you have more pixels, you actually render it smoother. So let me close all those. Let me go back to our assets and let me make sure that I use the tightly cropped version three, then two, and then one. Great. Now I go back to my scene code, where I have created a node with the image named paddle_x2. And then the point here is that I was making the size of the physicsBody to match the size of the graphic because objects should bounce right off the edge of the graphic, all right. And to make that compile correctly, I need to give that a close paren, all right Now the paddle actually isn't going to be a dynamic object because I don't want it to bounce around. I want other things to interact with it, but I don't want it to be moved around at all. The only movement that the paddle's going to experience is manually through code as we respond to touches. The position, I'm going to put it at half way through the current frames. Window. Viewport. And I'm just going to put it 100 up from the bottom. I give it no friction. It's a very bouncy paddle. Nothing slows it down. It doesn't rotate anyway. I'm not going to allow it to rotate. I'm going to give it a mass of one. And I'm going to give it an initial velocity of zero. Okay, so far so good. That should put a paddle on our screen, or that's going to create the paddle. But to actually place it on the screen, I'm going to need to add it to our SK node hierarchy, so that it will get rendered and that should be enough to get the physics working and the rendering to happen. This is the joint that's connecting this balls together and so that should get on the screen. So let's run it and see if it does come on the screen, okay? All right, launching. And touch the screen, and we'll wait for the delay. There you go. Fortunately they're recording this. Okay there we go. Paddles there, we've got the balls. It's pretty good. All right. Pretty happy with that. Okay. So let's go back. Let's stop our demo. Now let's go ahead and add that code for the touches. Now we already have some code to handle touches here. We have the touchesBegan of that. We just threw that in for a down and dirty way of just moving through the different screens, so that if we touch the screen we'd go to game over. Now, actually we're going to get rid of that. And we're going to go ahead and we're going to implement all the other ones as well. So we know we have touchesBegan. We know we have touchesMoved. We know we have touchesEnded. And we know we have touchesCancelled. And when I, and Xcode did me no favors here. There's my set, there's my event. That's all I want. All right, it did not do a very good job of code completion, so let's get that cleaned up. Okay, now let's create a property that's going to keep track of the touch that is the one that's motivating the movement of our paddles. So we're going to go ahead and add that up here. We're going to need to add a little local interface for this file. Grab some of the code down here for it. And we will start by adding that up here. So we are just going to add an interface to this game scene. That's straight forward. And we are going to add this property which is going to be our motivating touch object. We're going to keep track of it, and we're going to make it mailable, so that we can ignore it, so that we can allow it to go away if necessary. All right. So now when touchesBegan, we want to capture the most relevant touch and assign our motivating touch to that relevant touch. The way we're going to do that is we're going to loop through each one of the touches that we get. We're going to check to make sure it's in the bottom third of the screen so that touches at the top don't matter. And if it is at the bottom of the third of this screen, we'll just take the last one we got in our setup touches that matches and we'll just call that one the motivating touch. So, if we end up touching multiple places at the bottom of the screen, only one of those touches will be the one that we respond to. All right, so let me grab this. So the first thing that we're going to do, is we're going to create a constant region, which is going to be the place that we're looking for the touch to occur. We'll just create a local variable for that, touchRegion, we'll need that by making the rectangle that goes from 0, 0 to bottom left hand corner, all the way the entire width of the screen and up one-third of the screen, so that's the scenario that's going to be sensitive to touches. Then we're going to do a loop that goes through each one of the touches that have been passed to us, these are all the touches that have begun. We will get a point which is where that touch occurs. So this is the touch that we're getting as we go through our loop, and, for that touch, we're going to find its location relative to the scene that we're currently doing our code with it. We're going to assign that position to p, and so that'll be within the coordinate frame of our scene. We'll then ask ourselves, well, if the rectangle that we just created has p within it, so if it contains p, so if the touch region we just created contains p, then we are going to assign our property equal to that particular touch. And so we're going to keep a reference to it that we can use repeatedly. The last thing that we're going to do is, is we're going to run a method here that we have yet to define, called track paddles to motivating touches. And what that's going to do is, it's just going to tell sprite kit. To animate the paddle from it's current location to wherever the touch is now at. So, when the touch begins the paddle will start sliding over to it. We haven't done that yet. So, let's clean this up. And so far so good. Now, if we find out that the touch has moved, well we have to do something as well. And this might be a little bit surprising, but what we're going to do when the paddle moves is nothing with the data that gets sent to us, all we're going to do is we're going to tell our method that we have yet to create track paddles to motivating touches to animate to where the touch is now. Because the fact that we got a callback saying that touches moves, means that some of the touches move and the one that we are keeping track of will have changed its position. The motivating touch that we set here. We set it there once, but we didn't make a copy of it. We kept a reference to a live changing touch. So, when we find out that something moved, well, whether our touch moved or not, we just go ahead and animate our paddle to wherever our motivating touch is at the moment. All right, so that takes care of those, that code. Now we need to fill in what we're going to do if the touches end. Now the only thing that we care about when the touches end is whether or not the touch that is motivated our paddle movement has ended. And that corresponds to the person having lifted up their finger. If they lift up their finger, well then we no longer want our paddle to move towards that touch because it's basically then, Nullified. So what we're going to do is we're going to look through each of the touches that have been sent to us, and this is the set of touches that have ended. We're going to say, well, if that set contains the touch that we're keeping track of, well, then we're going to go ahead and set the touch that we're keeping track of to nil, saying that there is no touch that we're keeping track of, and so anytime we call track paddles to motivating touches, we just won't move the paddle. Well, if that happens when the touch ends, in fact, we want the exact same thing to happen when touches are cancelled. So that's pretty straight forward. It's interesting to me because the pattern's a little bit unusual, where what you end up using is this call batch, just the signals that you need to reanimate the paddle rather than capturing some of the data that it's sending to you. But it is an architecture recommended by Sam that I'm happy to use. Okay. So, now we're going to implement this code that causes our paddles to move towards wherever we touched. So, the first that we're going to do is we're going to get a reference to our paddle. We're going to do that by looking, searching through the S K node hierarchy. Starting with our S K scene. For the child, whose name is Paddle. And that's funny, because we're not using the seam builder to set up our paddle, we're not going to find anything called paddle because we didn't call our paddle, paddle. So what I'm going to do is up here, after we define our paddle, I'm going to say paddle.name equals. Paddle. And now I'll just give it an identifier so that later we can find it uniquely within our hierarchy. Now that I've given it the name Paddle down here when I search for it, look through the node hierarchy, I will find it. And node will be set equal to the paddle. Then what I'm going to do is I'm just going to check my motivating touch. i'm going to say "you know what, if it's nil," meaning we're not actually tracking a live touch, we're just going to return it, because there's no animation to be done, there's no touch that's controlling this. Then finally, if we do have a touch we're going to move the paddle towards. So again were going to take the touch and its whatever position its currently at, were going to find its location retaliative to the our scene, so call location in of itself, and were just gong to grab the x coordinate of it because the paddle stays on the horizontal line and we don’t want to move it up or down we just want to move it left and right. So we're going to get the actual location of our touch so that we can move our paddle towards it. Then we're going to calculate how long is it going to take us to get it there. Rather than having the paddle just jump over right away, we're going to have it slide over. And it's going to slide over with a constant here that we're actually going to call kTrackPointsPerSecond to reflect What we have learned so far about points and pixels. This is a constant. It's a constant that we haven't defined but we can grab it here and throw it at the top of our class. And we will change it to points per second. [NOISE]. Now, as we track our position, we know how far we have to travel. We have to travel from wherever our paddle currently is on the X axis. We have to travel this many points to where the touch currently is. We don't know whether that's going to be left or right, so we take the absolute value of that distance and so we get a certain number of points that we have to move. We divide it by our speed. So, how many points per second do we want our paddle to move and that ends up giving us seconds and so this time interval duration is going to be the number of seconds that it should take us to move based on the speed of that we have chosen. The last thing that we're going to do is we're going to tell Sprite Kit to animate that move. And we're going to use something called an SK Action tool to do it. This point we haven't talked about SK actions. We have yet to go through and describe how that works, but this is a good place to motivate it. What we're going to do is we're going to tell the node, the paddle node, to run an action. That action is going to be defined by something called an SK action that we haven't really talked about yet. What we want it to do is we want the node to move itself to the position of the touch and take as much time as we just calculated to do that. Alright, so now that should be all the code we need in order to respond to a touch. And it's going to be a little bit hard to show, but I'm going to go ahead and run the code now and switch over to our quick time view. And I'm going to touch the screen once in order to start the game. A little glitch there. I don't know if that will come across in the recording. But now as I touch the bottom of the screen, I'll see if I can hold it up here for you. Let's see, you'll see that in the background and then here's the game in the foreground, and you can see that as I touch it, the paddle moves over left and right. Now, it doesn't always move over the whole way. If I touch it just a little bit of the way it moves to wherever I touch it and as I'm touching it you can see that the balls are interacting with it. Now we haven't added any sort of score keeping yet and so our ability to recognize the balls should have fallen off the bottom hasn't occurred yet. So in summary what we did in this case study was we introduced ew demonstrated how to use that touch life cycle that multi-touch callback life cycle. We're not using multiple touches but we could be suing multiple touches everyone ans instead we just using one touch. You notice that we are screening it, to a particular area on the screen. Meaning we are masking it to a certain region on the screen. When we see a touch there, we move the paddle over to it using an sk action. The details of which we haven't gone over yet. All right, thank you for your attention. Next we are going to cover collision, so that we can identify when our ball has gone off the bottom of the screen. Thanks for your attention. [MUSIC]