In this second lecture in Module Eight, we continue using mouse input. And before we talk about the details, here's a reminder of the learning objectives for this module. So last time, we learned how to use the mouse location to move a character arund in the window, including clamping that character so it stays in the window. This time, we're going to learn how to use a mouse button for input to change the character to some other random character. So let's go to the project. Sorry. Let's not go to the project quite yet. Let's have you do an in lecture quiz first based on your recollection of the things that are contained in the mouse state object that gets returned when we call get-state. Now lets go to the project, and we are going to just be starting from where we were before. And so we've got a character, I'll run it again so we can see how it works. We've got a character that follows the mouse around the screen, staying clamped in the screen so they can't go outside the bounds. Let's actually talk for a minute or two through the documentation, to see how we can use a mouse button. So I'm going to search on mouseState again, just like I did last time, although perhaps I'll spell it correctly so that we actually get a hit, so we have these mouse state members as we saw before. Five different buttons is what XNA provides for us. And some other stuff too, that location that we used last time. So let's look at the left button. Because this description says it returns the state of the left mouse button. And when we look at that we see that it returns something called button state. Now button state is an enumeration. And an enumeration. Now lets go look at button state so we can see how it really works. [SOUND] And enumer. And enumeration is a new data type that only has specific values. So, if we have button state, which is what gets returned from left button, the left button property of the mouse state, then that returned value. Can only be one of two different values. It can be ButtonState.pressed, or it can be ButtonState.released. So I mentioned in passing in one of the previous lectures, about enumerations and how they Are going to be very useful to us in the future. Well now is the future, and so you should actually answer an in lecture quiz about enumerations, and then we'll go back to the code. So now that we know. That the left button property of the mouse state gives us either button state.pressed or button state released. We see that we can actually compare the current mouse state to, for a particular button to pressed or released, and do something interesting. So I want to be clear, that this code is commented left mouse press code bad. So that you don't think I thought this all worked and everything. But here's what we're going to do. We're going to take the current state of the mouse, we'll access the left button. We'll access the left button property and then we'll compare it to pressed. And if the left mouse button is pressed then we're going to randomly generate another character number, and by the way the next method in the random class The number we provide is. . The number we provide is in fact. It's exclusive. It will not ever return four for this call. It'll only return zero, one, two, or three. So, that trips people up sometimes. So be aware of that. This upper bound, if you will, is a maximum, but it's an exclusive upper bound. Okay, and then we use if statements like you've seen before. So if the number we generated is zero, we're going to set the current character to that sprite. Otherwise if it's one, we're going to do one, otherwise, two, otherwise three. So that's how that code works. Now it turns out that the character sprites that we're using here are not all the same within height. So after we've picked the new texture 2D we want to modify the draw rectangle to make it match the character's texture 2D. The new one we just picked. So, this is bad code, and let me show you why. So we still get the drag around, but if I press left, oh dear. I'm getting a bunch of different characters, and that's kind of fun and I can drag them around and so on. However, The problem is as follows. This update method right here in our game one class class gets called 60 times a second. And so, if I'm holding the mouse down, every 60th of a second it's saying yes the left mouse button is pressed, so I should change. And that's why we're getting all those changes that are happening. So what I need to do instead, is, well I'll tell you what. Go do a in lecture quiz, and then come back. And then I'll tell you what we're going to do. So, what we want to do, is we want to change on a click. Not on a press. So how do we know about a click, what is a mouse click, what, what a philosophical question. What is a mouse click? Well, a mouse click is a sequence of two things. It's, the mouse was pressed previously, and now it's released. And so, our, excuse me. Our if statement cannot just be, if it's pressed, in fact, it won't be if it's pressed. So what we really need, is we need if it's currently released. And it was previously pressed. And here, you know, I'm poised to type, but there's nothing to type. Because there's no way for me at this point to know whether it was previously pressed or not. The good news is, that we know how to store information, we store information in variables. And so if we declare another variablbe to keep track of what the previous button state was. Then we can use that to determine or to detect when the mouse has been clicked. The left mouse button has been clicked. So, I'll declare a new variable here at the top of the game one class. And it's going to be a button state variable. These enumerations are a data type. And so we can declare variables of this data type. So I'll call this previous button state, because it's the previous button state. Some of you who type slowly or are lazy. Programmers are lazy in general, [LAUGH] but those of you who type slowly or are lazy my say PBS, means, you know, previous button state. Don't do that. Use descriptive variable names because it really helps with readability. All right. So we can pick between one of two possible values to start with here. We can start the previous button state as pressed or released. Well it is reasonable to assume when somebody starts our game That they're not holding down the left mouse button so let's say we start at released. Okay. So we are now going to keep track of the previous button state so that here in update we can now say, if the button state is released and previous button state was pressed. So now we've detected a click. It's now released and it was pressed on the last update, then we'll do this stuff. So not too much of this stuff. We'll do this stuff. So, I'll copy and paste it here, and I'm going to comment this bad code out because otherwise it will obscure what's really happening for us. So now, I'm checking if it's currently released and it was previously pressed, change the character. So now when I run the codes drags are on like usual Oh dear I'm clicking away and nothing good is happening, this is a debugging problem. Right. And the debugging problem is that something is going around here obviously. Right. It's not catching or detecting that mouse click. Well you should realize with some thought That previous button state is never going to be pressed. Because, because we can find out why. I'm going to right click on this variable, and then I'm going about halfway down, and I'm picking the option that says find all references. When I do that, This window down on the bottom gives us every single reference to this particular variable. And so, we're here, at well, we're here at this one. If we double click the other one we see we're checking against it. But if we look at those two things those are the only two places in our entire game where this variable is accessed. What that means though is this is the only assignment which in turn means this variable always says the button state is released. So what we need to do is we need to update that previous button state on every update. And we'll do this outside the if statement. [SOUND] Really what we're saying is we want to store this variable, we want to store the current state, into a previous button state. Let me explain that in a minute. So previous button state is equal to mouse.leftbutton So, basically what we're doing is, think of this as on the first update. We come here, we get the current mouse left button, and we store it into previous button state because we're going to leave this update method. And then on a 30th, sorry, a 60th of a second later, We're going to come back here again, and the previous button state stores what the button state was last update. And so in this way we can store basically the button state from the last call to update so we can look at it on this call to update. And now when I run the code you'll see if I click I get a change to a different character. Now, if you're listening carefully to the clicks, you may say well sometimes you're clicking and its not changing. And that is actually not true, it just appears to be that way. Here's the thing, when we generate a random number here, say we're currently have displayed character one. It's certainly possible, with a chance of one in four, that we're going to generate a one again, and if we do, we do this part, and then we move on. And so it's possible that on a click we get the same character we're currently displaying. The code is not brokenm it's doing what we said it should do. It randomly picks a character. But sometimes that random pick character is the same character we currently have. The randomness is really an ineresting thing in games. Because when we do things, purely, randomly from a math perspective. It is easy sometimes, for players to perceive that the game is broken. That it is not random, that there's a bug. And if you had a coin flipping game, it is certainly within the realm of possibility that you'd flip ten heads in a row. And that no gamer playing that game would believe that you did it right. They would say it's broken, that can't be done and you know the post on the forums and you'll jump on and say obviously you don't understand math and that just a ridiculous approach as a game developer. Right? So what we do as game developers is we actually don't do pure randomness. We do the appearance of randomness, such that players like our game. And, you know, math purity can be saved for the mathematicians. We fake randomness a lot. I'm not going to fix that here. That's, sort of, something that you could figure out on your own. And in fact, once we learn about iteration in the next week, of lecturers. With, we'll actually see a way that we could, in fact, make this better, so that it doesn't pick the same character. But, for now, we'll just live with it, but understand that those things can in fact be a problem. Alright, and that's it for the code for today too, right. And in fact we're done with mice. We have learned how to use the mouse location. We've learned how to use the mouse buttons. We've learned that mouse clicks, and mouse presses, are in fact not the same thing. And so, We are, next time, going to move on to using 360 controllers for input in our XNA games.