 What is up everybody? Welcome back to another C++ and SDL programming tutorial. In the last video, we were looking at how to cap the frame rate. We got this nice little function here. I'm actually going to code-fold that, and you'll know that we run that at the very bottom of our main event loop in our program. So I'm going to go ahead and save a new file right here. I'll call mine 06a underscore sprites. And actually, that's exactly what we're going to be doing. We're going to be adding sprites to our code. And when I say sprites, I just mean an image or anything that we can kind of add to the screen. Now, I'm basing a lot of this series off of the Pygame Python programming series I've released earlier. So kind of the code and the logic flow of this series is going to be pretty similar to that one. And the way that Pygame actually organizes all the code and the facets of the game and the program. Pygame does a really good job of organizing stuff between sprites and sprite groups. And the way that it manages sounds and resources and that sort of thing. So I'm going to try and build a pretty similar framework with SDL. Because SDL doesn't really offer a sprite class or a sprite group class. So we're going to try and build something of our own. Now, in this video, it's going to be pretty simple. Just going to be looking at a basic class with a sprite, and we'll add that to the window. So we're going to be learning some new functions, and we're going to be doing some object-oriented programming. Before we get started, I realized I forgot to fire up my terminal. So I'm going to open that up actually and make sure it's ready. Just changing to Cwork and SDL. So, okay. Now we've got my 06A sprite. There we go. Cool. So let's get to the code here. We're going to be wanting to create a new class. And I'm going to put this under my cap frame rate function and above the main function, obviously. So it's a class. Class is the keyword to use to get that started. And of course, it's just a sprite. We're not going to go ahead and inherit anything. So we just want our opening and closing code brackets. And don't forget your semicolon at the very end there. Okay. Now, remember in C++, we have some special keywords to use because we're working with private variables and public variables. Of course, everything by default is private, so we don't really need this one up here. But if we're going to do it for public, it might as well be good practice to include it for private. So that's good enough for us. I'm going to use a bit more indentation just so we have white space. You can do whatever you want. It's your code. Now, the properties and variables that we need to keep track of for this object and for this class are obviously the image of the sprite itself. And we've been working with a bunch of these. We know we've been using an SDL surface. They're always going to be pointers. So let's set up a variable called SDL surface. That's the type. And it's an image. We're just going to declare that variable because we're just looking at the private stuff right now. We're going to do things with it in our constructor. Now, every surface, as we know, has a rect or a rectangle that comes along with it. So we want a variable that will be able to keep track of that for the sprite in the object and game itself. So, SDL rect. And I'm just going to call mine rect. You can do whatever you'd like, of course. Now, this is more for later stuff, at least with, I want to say the origin anyway, but I do want to keep track of the width and the height of the sprite just so we can access that whenever we need to. We might be able to do it from the rectangle itself. Actually, let's check on that. Good thing we have documentation. Let's just head on over to the internet. And you'll notice that everything is online at lib.sdl.org, not .sdl.org, sorry, libsdl.org. Hop on over to your documentation, head over to the wiki. And we should be at the front layer here. Now, let's look at SDL rect. It does include the x and y, and it includes the width and the height. Okay, so we don't really have to store the width and the height, but you'll notice I have an ending comma here because I want to add more things. Let's actually have an origin x and y, and we'll do some good stuff with that. All right, now let's go into our public data access stuff. And we obviously want a constructor. Now, that constructor has no return type. It's just a name of the class with the arguments and parameters that it takes. So this thing, for now as anyway, is just going to be a simple block that is filled with a color. We'll get into adding images and adding pictures and cool multimedia stuff very, very soon, but for now we're just going to use a simple color. And for all the colors we've been dealing with before, you'll probably remember we've been using this type, the unsigned integer with 32 bits, uint32. So let's do that right over here. For the color, it's uint32. And of course, we want some coordinates to actually put this here into x and into y. And let's get width and height here. Let's use w, and I'm going to set a default value for this. Default value 48 and the height into h, and that can be 64. Obviously, it can be whatever you'd like. This is just the stuff that I'm setting myself. Okay, now let's get into a new function because we want to be actually doing something with this image. We want to create the sprite with the image itself. So we've got to assign something to this SDL surface and the variable that really represents the back end of this object, of this class, the sprite. Now, image is going to be set to a new function that we'll be learning with SDL. And at least I think it's a new function. I don't think I've showed you this before. It has been a while since I've created a video. I will tell you that. SDL creates RGB surface. All right, no one researched for that. The first result here, create RGB surface. This is the function that will allocate a new RGB surface. Obviously, pretty similar to the freaking name of the function. Cool, so the syntax, this is everything that takes. It can take a few flags that we'll be able to pass in. It takes a default width, a height, and a depth, and r mask, g mask, b mask, and a mask values that all have to do with colors and stuff. So, the function premmers for a bit more information. The flags are unused and should be set to zero. Well, okay, that does away with the first argument. We don't really have to worry about that. Width, we already know, because we're passing that into our constructor. We have that in the function itself. And same with the height. Depth of the surface in bits, see remarks for details. All right, let's head on over down there. Okay, it looks just shows an example that we can look at above here. But if the depth is four, eight bits, an empty palette is allocated to the surface. If the depth is greater than eight bits, the pixel format is set to the RGBA mask parameters. That, I don't know. I don't really care. Let's see what they do in their example. That's always a good way to do it. So the return value will return the new SDL surface structure that's created or null if it fails. It might call SDL get error if you need more information. So they set up a function and they use some variables for the R mask, G mask, B mask, and A mask stuff. Looks like, whoa, I set up some pretty crazy values for these. R mask, G mask, B mask. I don't know if I want to bother with that. I'm sure you don't want to bother with that. That's weird stuff. Let's see. It creates the surface with zero. Just like I said, width and height, 32 bit depth. R mask, G mask, B mask, A mask. Use the default mask for the depth. Oh, okay, that's cool. Surface equals SDL create RGB surface to zero by default, width, height, 32. Okay, I guess that's a good standard. And zero, zero, zero, zero. That does everything the default way it needs to be. Okay, so I will admit I've played around with this before. Just doing some testing to get the video ready for you guys. And what we actually do later on will clear the color up for us. So we don't have to worry about these R mask, G mask and B mask values. We can just pass it in zero, zero, zero, zero. 32 is what we want for the depth though. So let's go over here and actually write out that code. SDL underscore creates RGB surface. And remember the order of the parameters. You need the flags, zero, width, which we know is the value W in this case, height, which is H, 32 for the depth, and zero for R mask, zero for G mask, and zero for B mask as well as zero for A mask. Cool, so there it goes. There we just create the surface that we need. We've got our image. Now we want to actually fill it with the color because we created that. Well, why not include it? SDL fill rect with the image that we've been using. Fill the entire thing. We don't need to clip any rectangles out of it. So we're going to use null here and we'll pass in the color that we actually want. Remember this function, SDL fill rect. We use that in a few videos back to change the color of the screen. We change it to white. You might have seen an earlier example. It was red, other different colors. And okay, now we can actually go ahead and work with the rectangle. Rect is going to equal. Now what rect is going to equal, you'll notice over on our SDL surface class and object, it actually has data fields for the format. We've used that before to map RGB values and let's see, we have the width and the height obviously and more information. Oh, we have the clip rect. And what that is is the SDL rect structure that's used to clip bits the surface and that can be set by SDL clip rect and that's another function. But anyway, we can access the rectangle for the surface which means we can kind of and manipulate where it is in the world. Awesome. So because SDL surface or the image is a pointer, we're going to be using the pointer data associator which is the hyphen in the arrow. So it makes kind of a nice little arrow here and we want to be getting the value of the clip rect and that's just what we'll do there. Awesome. Now rect.x can equal the x coordinate that we've passed into the function and let's subtract origin x and rect.x can equal, sorry, rect.y can equal y minus origin y. I don't know if I, I don't know if I really want to bother with those origins right now. I'll set up values for them but they'll just be zero. Origin x can equal origin y which can equal zero. I think that'll work in C++. I'm just going to be, I'm just going to play it safe do it in two lines. I've been used to Python so whatever. Okay, now we have some other functions that we can add to our sprite class in the object. This is going to have like I told you the kind of Pythonic framework back end. Pygame always had a nifty function called update. That'll be void in this case because it's not going to return anything. A lot of the sprite objects that we actually inherit from the sprite base class we'll use this. So right now I'm just going to leave a comment in here that says can be overridden because we can do more stuff for this pretty soon but right now it can be blank and empty for us. The next one is draw and the draw function will obviously draw onto the screen or any surface that we want to. So we're going to have to take a parameter or an argument for that. That's going to need a destination. Everything in an SDL service is a pointer so remember to include your asterisk. Now the function we'll be using here is a, again, I believe a new function and that's called blitz, SDL, SDL blitz surface. Sorry, I screwed that up here. I don't know if I've showed you this before. Honestly, I don't remember but it needs a source and it needs a rectangle that's actually kind of shopping out of. It's going to crop a rectangle that if you want to pass something in there. And the destination where actually you want the source surface to be put onto that's the surface structure that is the blitz target and then the destination rectangle which is actually the coordinates and where it needs to be. So that actually is a pointer itself so we need to pass in the actual value of that. Okay, code example, surface, source rect, temp surface, null. It is a bit of a different order than we do. What we're going to do, you can read more about this in the documentation if you'd like, what we are going to do is go ahead and SDL, blitz surface. We want the image, the actual image of this sprite, that's the source and we're not going to put it anywhere, we're not going to kind of change the size of the screen or try and crop the screen because the destination is typically going to be the screen and that's what we're actually going to pass in next. The screen will be the destination value that we want and for the actual coordinates of this image we're going to use its rectangle. Remember using the ampersand there to get the reference or the actual place in memory. So that's the code that we need to run for that line. Okay, I believe we're good. I think we're good for the sprite class. Let's find out because honestly, I played with some prototype code for this earlier and speaking of the word prototype, I should mention with the C++ object oriented programming I've done everything in this class or in this file even, 06asprites.cpp. It might be a good idea if you want to include these things in another file, in a header file. It might be a good idea to prototype your functions and then use C++'s scope operator to actually kind of separate the class declaration and then the sprite and the object function definitions. It all depends on what you want to do. I'm going to keep everything in line because the compiler will let me do that and it keeps all of my code in one file and for tutorial purposes that's a good way to do it because everything's all in one spot and you don't have to see me jumping from file to file. Anyway, we're good for right now. Let's go on and do some new things over in our main function. Now that we have this sprite object we can work with. I'll code-fold that and I'm going to create a new color just plain old red map RGB screen format R everything else need to be 0. Okay, we've got our starting ticks and everything going just fine. I'm going to hop over to my terminal actually and just kind of compile this. Make sure I can. G++ 06 asprites that stuff package config C flags libraries Sdl2 please, please, please, fingers crossed. No, you went 32. I spelled unit 32. Good thing I did that before we kept going. Okay. You guys should have caught me on that. You should have told me. You should have warned me. All right, let's move this over here. Good. Good, good, good. We just got a simple white window. Now let's try and add that sprite little box to it. Let's go ahead and create a new sprite before we update the window. So we've got our object class, the class name sprite, I'll call mine object and this of course needs to run with a constructor. The color should be red. The coordinates can be window width divided by 2 and window height divided by 2. I don't believe I asked for any more arguments. Did I? Let's check. Color, X and Y and width and height are optional. So cool. Let's see what happens next. If I run this code. Oh, I should draw it on the screen for sprites. Yeah, actually, I'll show you what happens if I try and run the code. Hopefully it'll compile. Thank God, it does. Obviously, our sprite is not here. What the heck? Because we haven't drawn it to the screen yet. Remember, we created that object. We created that draw function in our object class and everything so we can actually draw. And we're gonna be doing that explicitly right here. Object.draw onto the screen. And we've got the screen variable right over up here. Hop over, compile one more time, run, bring us over and boom, we got our red block on the screen. Simple sprite, simple, simple sprite. Now I'll actually see if I can get the origin to work. I'll just put its... I shouldn't use rect.width divided by two. And I'll use rect.height divided by two. Now I see if this will work. Cool, so now it's in the very, very center of the screen because it's putting the object and the center of the screen relative to its origin and the origin of the sprite and the object is actually at the center of itself. So everything is centered and that works just well for us. Awesome. Thank you for watching, everybody. Pretty long video for a pretty simple class, but I hope you understand everything that we did in this video and you understand this concept because we're going to be moving on soon. We're actually going to be expanding this class framework and actually building a new class framework to actually kind of organize all the sprites that we might be creating. Sprite groups. Okay, cool. Thank you for watching again, guys. If you're enjoying the series, please like, please comment. If you're willing, please subscribe. That really helps me out and I'll see you in the next tutorial. Adios.