Last time we started working on the module 13 doing textile and XNA so here's a reminder of the learning objectives for the module. We did the keyboard input last time so that we could use the keyboard to control the player. Of course we can use keyboard input for lots of other things as well, letting the player enter their gamer tag into a text box and so on, but we kept it pretty simple for what we're doing in this course. In this lecture we're going to talk about how we can provide text output in our XNA games. Obviously when we had a console application we could just use console.rightline to output stuff but in our XNA games we can't use that approach. We have to do something slightly more complicated and so that's what we're going to cover today. The first thing we need to know is to actually display text in our XNA game we need a special kind of content that we haven't used yet. So I'm going to go over to the content. Project in my solution that I obviously just blasted over to and opened up, and I'm going to add a new item. And when I say I want to add a new item, I get a number of different choices. I can add an XML file which can be really useful for saving. Level design information into XML files but we're not going to do that in this course. I could save an effect file. But I'm going to create a new SpriteFont. So a SpriteFont, and let me just call this [SOUND] Arial. A SpriteFont is a font that will get used within our game. In fact, what we do is, we specify a particular font name here, and this font needs to be installed on your computer so that when it's time to build, it can turn this SpriteFont into an XNB file. Which is compiled XNA content. If you're a MonoGame user, you're not going to be doing any of this. You can't add a SpriteFont, you can't build a SpriteFont. There's no content pipeline in MonoGame at this time. So for this particular lecture I will be providing you with a compiled XNB file for this SpriteFont we're building. But you should understand you can't do it. Right? You have to, you have to build a content pipeline some other way, at this point, within MonoGame. But if you're using Visual Studio and XNA, then you do what I'm showing you here. And you pick the font name, and you can pick a size. And you can do there's lots of stuff you can do. You can make 'em bold or italic. All kinds of things that you can do to specify what this font will look like when you display it in your XNA game. All I wanted to do is change it to Arial so I will Ctrl+s. And I'm going to actually build right now because this would be the point at which, if you said, you know, you had a misspelling, and you said Arialiosity or something like that, then. It would blow up because it can't build the font because it doesn't have it installed on your computer. Okay, so now I have this piece of content that I've built but I still need to, you know, have a variable that holds it and load it and so on. So I'm going to, just as before, I have some commented out stuff that I'm going to uncomment to sort of reveal our solution as we go. So the first thing that we will do is, uncomment this Sprite font field and I will also send you to an in-lecture quiz about. Wow, I don't want to give away the answer. So about content for fonts. So go take that in-lecture quiz. Okay, so I've got this SpriteFont object that was the right answer SpriteFont. I've got this SpriteFont variable or field that I've declared. And I want to come down here and I want to make sure I load it. So that I have that content loaded just like we've loaded texture 2Ds, just like we've loaded sound effects. This time of course, we're loading something different, we're loading a SpriteFont. At this point though, I'm not drawing anything. And so we should now add the rest of the code we need to draw stuff. So, I'll start by showing you a, a sub-optimal way to draw. And then we'll fix it. So, this is not the sub-optimal part. This is a good idea. So we're going to have some position at which we are going to draw the score. And at this point, that position will be WINDOW_WIDTH over 12, and WINDOW_HEIGHT over 12. And I shouldn't have said at this point. Throughout this entire game, that's where it's going to get drawn. So instead of using a draw_rectangle, For the text we're going to draw, we're going to tell it where to draw it. And, and XNA will take it from there when we go to draw it. So let's actually go to draw it. This will be less exciting because I can't actually score at this point, but at least I can draw a string. So I'm going to instead of just uncommenting that because this is the commented code is the better way to do it, lets say I decide to do this, [SOUND] so basically every time I'm here notice I'm doing this slightly differently. Instead of doing a SpriteBatch draw which was for texture 2D's I'm doing a SpriteBatch draw string which is for, not surprisingly, drawing strings. And I can provide it there are a bunch of overloads. I see I'm going to have to open up my declaration of the score variable, so I'll fix that in a moment. I have some overloads, but they're all going to require me to pass in the SpriteFont, because it can't draw it if it doesn't know what font to use. And then I pass it the string, then I pass it where I want it drawn, and then I pass it to color. In this particular overload of draw string just as SpriteBatch draw. Has a lot of overline, overloads. SpriteBatch draw string has a lot of overloads as well. All right. I'm going to get rid of this compilation error here. So I will go up to the top, and start adding a little bit of score support, we're not all the way there yet. So if I F6, I get a build succeeded. If I F5 you can see up here in the upper left hand corner it's hard for, because the mouse is invisible nor should it be because I'm not using the mouse in this game but you can see that its now displaying the score for me in the upper left hand corner. The reason I said this was sub-optimal is because I am creating, remember, because strings are immutable, down here in the draw method, I am creating a new string 60 times a second, and using it for a sixtieth of a second and throwing it away and creating an new one. And that's really not the kind of inefficiency that we should add to our code. So let's optimize that part and then we'll actually add some real scoring. So instead of doing it that way, I want a field called scoreString, way back up at the top. I want a field called scoreString that will hold the current score string and that string will only change when the player scores points. And that way we're not creating new strings 60 times a second, we're only creating new strings each time the player scores. When I did that, I discovered that here in load content I needed to initialize it, and of course now I get a compilation error because it says I don't know what this get score string thing is, because I need to come uncomment this private method that I wrote that gets the score string. So you pass in a score, and it returns a string that includes the prefix concantonated with the actual score. Let me Ctrl+Z a little bit there, there we go, concantonated with the actual score. I wrote this method because we'll see in a couple of moments that I need to do this multiple times in my code. And as soon as you start thinking copy and paste, stop yourself and think private method instead. Alright, so now when I F5, you're not going to see any difference in program behavior. It still looks exactly the same way it did before. This is an example of re-factoring to fix the quality of the code without actually changing its performance. We might have seen some performance hits later on if we had lots of objects and suddenly creating 60 new strings a second caused problems for us. So we just fixed it now and did it in a much more appropriate way. This idea, by the way, is very similar to when I said you shouldn't be creating a new draw rectangle. On every call to draw for the same exact reason. We don't want to create a whole bunch of extra objects that we use very, very briefly and then let the garbage collector go get 'em. Alright, so the only other thing I actually need in this game is to be able to score and so I'll uncomment these two lines of code so this is where the bear collides with the fish. So I'm going to add some score to my current score and this is the point at which I now need to go get a new string. And so I call that get scoreString method that I showed you moments ago. I need to uncomment. My bear score constant that I had commented out up to this point, now I can F6. Now I can F5 and we'll see that if I run into bears I actually get scores so now you know you can play the game and build up your score and try to get on the leader boards for this amazing almost commercial quality but not quite game. So what we didn't do was the other in-lecture quiz where you go tell me how you actually draw a string. So you should go do that now. And that's it for today. So, as a recap, we learned how we use SpriteFonts as content so that we can do XNA text output and we learned how to actually do that text output by calling the drawstring method on the sprite brat, SpriteBatch [LAUGH]. That's the end of this module and that's the end of all the formal modules in the course. There is one more week. And that week is for you to do the optional project, if you choose to do so. For you to study for, if you decide you want to, the final exam. And for you to take the final exam. So, even though there's no sort of official formal lectures with new material nor are there assignments due, you do, next week, need to do your peer evaluation of project increment five for everyone and I'll post some lectures talking about the optional project talking about sort of the core ideas that you should carry with you into the final exam. And closing out the course with some final thoughts.