This is our last lecture for module seven, where we've been talking about the selection control structure. Here are the learning objectives for the module. So over the last two lectures, we've talked about the different variance of if statements, and about switch statements, and how we use those to implement the selection control structure, how we make decisions in our program. In this lecture, we're actually going to look in detail at how selection works when we actually implement games. So, I'm going to start up a project that I've already built to demonstrate this. We won't be building code today. We'll be looking at code that I've already created. So when I F5, we see that we have teddy bears moving outward. And then bouncing off the walls. So let's immediately go to an in-lecture quiz where you tell me about how you feel about bouncing off walls. If we look at, now this is not a screenshot of what you just saw. This is a screenshot using slightly different sprites that show the draw rectangles. Around these teddy bears as well. So, if we think about what it means to bounce off the walls and how we might do it, one way we could think about it is if, in fact, this guy comes all the way over here. And the edge of his draw rectangle goes outside the edge of the window, whoops, sorry about that, goes outside the edge of the window, then, in fact, we should bounce him. Right, he's leaving the game world. Same with this one, except that this is the edge that we'd worry about. And of course he might bounce back. Back and forth and so on. So, the big idea behind how we can do this is we can check the draw rectangle for each of the sprites and see if they're outside of the window. Now let's go back to the code. When we talked about the teddy bear class last time. Sorry, not last time. When we were doing a more XNA practice, we had to hand in the window width and window height to the teddy bear when we constructed it, and we did that and we saved it into these fields here. So let's look at how one of the bounces work. We'll do left-right because that's the one that, that we just saw. And I'll zoom in, and we'll look at bounce left-right. So this is the method that actually bounces the teddy bear. So let's see how it actually works. Here's an if else-if. Remember, we said if we have else-ifs, we don't necessarily have to have else's. They're optional. But if the draw rectangle.x, so that's the upper left-hand corner of the draw rectangle. If that is less than 0, that means that the drawRectangle is at least partially outside the left-hand side of the window. And what a horrible comment. Let's add an e there. So we're going to bounce off of the left side of the window. We will immediately do this. Remember, drawRectangle is a rectangle structure which exposes an x property. That we can set so we set it to zero. We, if the teddy bear has gone off the left hand side we immediately bring it exactly to the left hand side. Velocity in the x direction, we're going to multiply by woops, let me not do that. We're going to multiply by negative one. So in other words, if the x velocity was negative. When it went outside on the left. And we actually know it was negative when it went outside on the left, because it was moving to the left. We then multiply by negative one so now we've turned the velocity into a positive component in the x direction, so now the teddy bear is. At the very left edge of the window and has started moving to the right. Which is exactly how we bounce it. We have this else if because the teddy bear could also be going out the right hand side of the screen. Here it gets a little more complicated. This code says drawRectangle.x plus drawRectangle.Width which is an intuitive way to think about it. Right, so the left-hand side, drawRectangle.X, plus the width of the draw rectangle gets us to the right-hand side. And if that's greater than window width, we do this other stuff. Now, I will tell you, just because you ought to know, that drawRectangle also exposes a right property. Which is the x location of the right hand side of the draw rectangle. So that might even seem more intuitive to you. Is that we're checking if the right hand side of the draw rectangle is greater than window width. If it is, we're going to bounce off, notice though we have to change the left hand, upper left hand corner of the draw rectangle to be at window width minus the draw rectangle width. We can't just set it to WindowWidth because then we'd be guaranteeing that the entire drawRectangle is outside the window on the right-hand side. So we start at the WindowWidth and we back-up the full width of the drawRectangle, so that now the whole drawRectangle is still in the window, right up against the right-hand side. And then we reverse the x velocity again. So that's the first example of using selection. We've got this if else if in our game, where we're in fact doing the bouncing off the walls thing. I very carefully stopped the game when I did before. Now I'm going to let it go a little bit longer. So you can see what really happens. Oh my gosh. Very sad. So, you should now do an in-lecture quiz about collision detection. Back to our picture of these two bears again. You should be able to realize, I guess, that when the bears ran into each other, we detected that they had collided. That's the collision detection thing. And then we played the explosion that's called the collision resolution. It's how we resolved that particular collision. So how did we detect that the teddy bears had collided with each other? Well. The easiest way is to say, well how do we know that this guy is colliding with this guy. Well the easiest way is to say, well if their rectangles overlap in any way, then we'll call that a collision. Now that is not perfect because you'll notice there are some spaces inside these sprites where they're transparent even though it's inside the draw rectangle so that's not a perfect way to do it. And of course there is a perfect way to do it with 2D graphics and it's called pixel perfect collision detection because we do it pixel by pixel. Beyond of the scope of this particular class, but not rocket science either. I mean this is a solved problem. We're going to just handle the rectangles overlapping because that let's us just use what we know at this point. But obviously there are more complicated and better ways to do ultimately collision detection. Although almost all of them, even pixel-perfect collision detection, uses the rectangle-overlapping test first. Because if the draw rectangles don't overlap, there's no way there can be a collision. There's no need to do any extra complicated math. Okay. So let's go look at the code and see how this actually works in practice. So we need to go to the part where we have the collision detection in our code, and that happens in game one in this particular instance. So, zooming in. And by the way, here's where I created those game objects, notice that I used the other teddy bear constructor overload, where I get to provide a velocity. Otherwise we have two teddy bears with random velocities and we watched them for long time potentially before they finally run into each other and explode. And I wanted that gratification as quickly as possible. Okay, so in update, here's where we're doing that collision detection. Now, both teddy bears expose a property called active. So this property is true if the teddy bear is active and false if the teddy bear is not. And this is a fairly common pattern you'll see in game development, where we activate and deactivate particular objects. So we only want to check for a collision if both bears are active. If one or both of them are inactive, we don't care. If they collide. Here is the part where we check that overlapping of rectangle things. So bear zero is a teddy bear object. He's exposing the teddy bear class, exposes. A collision rectangle object and notice that the property is calling collision rectangle even though we're just providing the draw rectangle. Why? Because, it's really going to be used for collisions outside of this class. And we can call this property anything we want and in fact we could calculate this property in here every time if we wanted to and because we have information hiding, it's great. The consumer of this class doesn't care. All they care is they get a rectangle that they can use to check collisions. So we've called this CollisionRectangle here to hide the fact that it's also the draw rectangle inside the class. Okay, so this is therefore a rectangle object. We call the intersects method, you'd have to go check the documentation but intersects is a method. For the rectangle class, where we hand it another rectangle, and it returns true if the rectangles intersect and false if they don't. Which is exactly what we need. So if the rectangles intersect, and both bears are active, we're going to deactivate the bears. We don't care about their collisions or anything anymore. And we're going to play the explosion. And we're going to play the explosion approximately at the point where the collision occurred. So this is actually a really good time for us to go back and do an in lecture quiz about what collision resolution. Needs because that's what this whole block of code is, is collision resolution. THis is the detection part. Sorry, all three lines. That's the detection part. That's the resolution part. Okay. So now, we're going to play the explosion. You should look at the, I'm going to post this code on the course website so you can just look at this part of the code here. Basically, it figures out where the, where the collision rectangle is, the whole overlap between those two rectangles, you should read the Intersect, not intersects with an s, the Intersect without an s. Method documentation to see how that works. And then we play this explosion. And that's all well and good, but what does it mean to play the explosion? So let's actually step aback and think about how animations work in 2-D games. So here on the right, you see something called a sprite strip. It's a strip of frames for an animation that we will use to play the animation. And given that cool term, sprite strip, you should do another in-lecture quiz. So how do we actually use a sprite strip? Conceptually, before we look at the code, how do we use this sprite strip to actually play an animation? Well, clearly, we don't put a semi-transparent, magenta box over it. However, that's just for us to look at how we really play animations. And the way we really play animations is, this is just a seqeunce of frames. And what we want to do is we want to display the zeroeth frame for a while. And then when we should move on, we want to move on to the first frame. And then once we should move on, we want to move on to the second frame, and then to the third frame, and so on throughout the animation. So what we do is. We display a particular portion of the sprite strip for some period of time. And then we move on to the next one, and move on to the next one, and move on to the next one, and so on. So that's the idea behind playing animations. And it turns out that this magenta thing right here, that I've been moving over different parts. Of this texture 2Dm because that's what it's going to be, it's going to be a texture 2D we load into our game, is something called a source rectangle. So let's go take a look in the code itself. So we need to go to the explosion class in this particular case. And make it bigger. And what we're going to care about. We'll look at a number of different things. We have a drawRectangle. That's where the explosion actually gets drawn. Here's the strip name. I just have one explosion. The Texture2D for the explosion, like I said. We keep track of frame-within-frame height. We're not going to cover all the details in this class, but you can look at it later. And here's the key part based on the conceptual stuff I was talking about. We have the source tan, rectangle, that magenta rectangle we move around on the sprite strip. We keep track of our current frame, we keep track of how long we want each frame to last, and we keep track of how long we've been showing the current frame. So there's this sort of deeper, more generally applicaple idea here that we're going to sort of have a timer. And when the timer goes off, we're going to do something and restart the timer. In this particular case, what's going to happen is, when the timer goes off, we're going to move to the next frame in the animation, and start the timer again. So that we know when it's time to move on to the next frame, and so on. But, the approach we're going to use, which is an update. Is going to be generally applicable whenever you need a timer. Okay, so we're only going to update if it's playing, this is a Boolean variable. And here's what we do. We take the elapsed frame time, how long the animation frame has been playing so far. And we take this game time parameter. And we extract from it the ElapsedGameTime since update was last called. So this is sort of the delta between the last time update was called and this time. And we'll convert that or extract the milliseconds property which will tell us exactly how many milliseconds it's been. With a fixed frame rate, it's going to be 16 milliseconds all the time. But it's worth checking just in case. If you write your code generally applicable this way, then it will work whether you're running fix time step or not. Okay. So we add to the ElapsedFrameTime. And here's, wow, another if statement. If the ElapsedFrameTime is greater than how long we should show each frame. It means, it's time to move on to the next frame. So we reset the frame timer, because now we're starting to display a new frame, and we advance the animation. And we advance the animation with another if statement, just to make sure we don't try to run past the end of the sprite strip. So we set the current frame while we check to see if the current frame is less than num frames minus 1 because it's zero based. If it is, there's another frame to show. So we add one to the current frame counter and then we call this method that you can go look at on your own. But this method right here is the thing that moves that magenta rectangle. So that's what happens if there's still more frames to show. If there aren't, here's the else part, if there aren't, we set playing to false, because we're done showing the animation. So, one more in-lecture quiz for you. And to recap, we looked at numerous different uses of the if statement here. We looked at bouncing, we looked at collision detection We looked at how we can play animations, and this particular case is part of collision resolution but we could do it sort of anytime we want. There are actually some other if statements in there as well that you may have noticed that, you know, if something is active we do something, if the animation was playing we update it. So, we saw a whole bunch of different ways, that we can use selection in actual game scenarios, where there's very small, still no user interaction game. Good news, we're at the end of module seven. Even better news, in module eight, we'll finally start learning how to get user input in an XNA game so that the player can interact with the game world.