250 likes | 451 Views
MTA-4201 Game Programming Chapter 3: Concept of Game Loop & Using Resources. Outline 3.1 Introduction 3.2 Game Loop Components 3.3 How to Implement in C# 3.4 Adding Image to XNA Project 3.5 Drawing Sprite on the Screen 3.6 Making a Sprite Class 3.7 Using the New Sprite Class
E N D
MTA-4201 Game ProgrammingChapter 3: Concept of Game Loop & Using Resources Outline 3.1 Introduction 3.2 Game Loop Components 3.3 How to Implement in C# 3.4 Adding Image to XNA Project 3.5 Drawing Sprite on the Screen 3.6 Making a Sprite Class 3.7 Using the New Sprite Class 3.8 Positioning the Sprite 3.9 Drawing Multiple Sprites
3.1 Introduction • Basically, from programmer’s perspective, a video game is a continuous loop that performs logic and draws an image on the screen. • In that aspect, video game is very similar to how a movie is displayed, except that you are creating the movie as you go.
3.2 Game Loop Components “Game Loop” is consist of eight sections. • Initialization • Enter Game Loop • Retrieve Player Input • Perform AI and Game Logic • Render Next Frame • Synchronize Display • Loop • Shutdown
Initialization • Allocate memory • Load files • Build tables Main event loop call windows stuff Init timing Exit? Handle windows events • Cleanup • Reallocate • Close files Keyboard Loop Retrieve player input Joystick Mouse Exit to O/S • Main logic • Game AI • Collision detection • Physics Time sync lock to 30 FPS Off-screen memory Render next frame to off-screen buffer Copy image to display Wait General Game Loop Architecture
Game Init Game Menu Game Starting Game Restart Game Run Game Exit All game loops pretty much follow this State transition diagram State transition diagram for a game loop
3.3 How to Implement in C# • The following is a more detailed version of what a C# game loop might look like in real code.
3.4 Adding Image to XNA project • The image types you can add that are supported by the Content Pipeline are .bmp, .jpg, .png, .tga, .dds and a few texture file formats. • I would recommend to stick with .png files to take advantage of the transparency those files provide. The images you add to your projects may either be single images of objects or spritesheets which contain multiple images and are often used for creating animations or used for tiles. Adding the images to your project makes them available to the XNA framework's Content Importer. This will compile them as ".xnb" files when you build your game.
3.4 Adding the image • right-click on the Content Folder (the Content Folder is created automatically in your project when you make a new XNA game project) and select "Add -> Existing Item" from the right-click menu. This will open the "Add Existing Item - Content" dialog. • Next, navigate to the location of your images. You can select a single image or select multiple images to add to your project at once. Then click the "Add" button. • If you look at the project tree, you should see the image or images that you added listed there as well under the "Content" node. 4) Adding the images to the game project does not immediately start drawing them to the screen, you will need to do that later with some code.
3.5 Drawing the Sprite on the Screen Create some objects • Add this code to the top of the Game1.cs class. Vector2 mPosition = new Vector2(0, 0); Texture2D mSpriteTexture; • Vector2 is a object provided by the XNA framework. It is used to store 2D positional information. Texture2D is another object provided by the XNA framework. It is used to hold image content. Both Vector2 and Texture2D objects will be used a lot in 2D game development with the XNA framework so it's good to become very familiar with them.
3.5 Drawing the Sprite on the Screen • Load the content • To load the texture. We’ll do this by adding some code to the “LoadContent” method. You don't need to create the "LoadContent" method, it's already created as part of your Game1.cs class when you create your Windows game project. We will just be adding a new line of code to this method to load our sprite texture. protected override void LoadContent() { // Create a new SpriteBatch to draw textures. spriteBatch = new SpriteBatch(GraphicsDevice); // TODO: use this.Content to load your game content here mSpriteTexture = this.Content.Load<Texture2D>("SquareGuy"); } • The line we added, uses the Content Manager to load the "SquareGuy" image we added to the project into our Texture2D object.
3.5 Drawing the Sprite on the Screen • Draw the sprite • With the Texture2D object loaded, we can now draw our sprite to the screen. All of your drawing should be done in the "Draw" method in your Game1.cs • Add the following code to the "Draw" method. • protected override void Draw(GameTime gameTime) { graphics.GraphicsDevice.Clear(Color.CornflowerBlue); // background color // TODO: Add your drawing code here spriteBatch.Begin(); spriteBatch.Draw(mSpriteTexture, mPosition, Color.White); spriteBatch.End(); base.Draw(gameTime); } • The spriteBatch object is automatically created when you make a new Windows game. SpriteBatch objects are what is used to draw 2D images to the screen. To use them, you first have to initiate "drawing" by calling "Begin". • Next, you draw all the images you want. In our case, we're currently just drawing a single sprite to the screen, but some games might have hundreds or thousands of "Draw" calls. With our "Draw" call, we pass in the sprite texture we want drawn. The position in the game screen we want it drawn in (our current position is X=0 and Y=0) and what color we want to shade our sprite (using White, tells the SpriteBatch object that you don't want to apply any shading to the texture). • Finally, you tell the SpriteBatch object that you've added all the things to the scene that you want drawn and you tell it to go ahead and draw them all by calling "End".
3.5 Drawing the Sprite on the Screen • Build your gameand give it a go. You should see the Square Guy sitting in the upper left of the game window. Just click the Close button on the game window to stop the game.
3.5 Drawing the Sprite on the Screen Changing the Position of the Sprite Change this line of code. Vector2 mPosition = new Vector2(250, 100);
3.6 Making a “Sprite” Class • A "Sprite" object makes it easier for us to work with multiple sprites. Start by right-clicking on the project, pick Add -> New Item. • Select "Class" from the "Add New Item" dialog and then type in the name "Sprite" into the Name text box. Click the "Add" button when you are finished. • When you created the new class, the code window for the class should have opened. We are going to be working with some XNA Framework objects, so we will need to add the following "using" statements to the top of the class file. using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework.Graphics;
3.6 Making a “Sprite” Class • Next, just like we did in the Game1.cs class when we were learning to draw an image to the screen, we are going to add two storage objects to the Sprite class to be used in the same way. • Add the following code to the top of the Sprite class class Sprite { //The current position of the Sprite public Vector2 Position = new Vector2(0,0); //The texture object used when drawing the sprite private Texture2D mSpriteTexture; • You can see that there is a little difference for how we declared our objects. We made the Position object Public and the Texture2D object private. This means that the Position can be changed by things outside of the class and the Texture can not.
3.6 Drawing the Sprite on the Screen • We are now going to mimic the Game1.cs class a bit and create our own "LoadContent" method for our sprite class. This method will do for the sprite exactly what the LoadContent method does for the Game1.cs class. • Add the following method to the Sprite.cs class. //Load the texture for the sprite using the Content Pipeline public void LoadContent(ContentManager theContentManager, string theAssetName) { mSpriteTexture = theContentManager.Load<Texture2D>(theAssetName); } • You can see that the LoadContent method for our Sprite class takes in some parameters. The Sprite class does not have a ContentManager to do it's loading so it "asks" for one. It also wants to know the name of the asset that it should load into it's Texture2D object. Both of those values will be passed in when the LoadContent method is called. • So now our content is loaded for the sprite, we now need to Draw it. We will once again copy the way the Game1.cs class works and add a "Draw" method to our Sprite class.
3.6 Drawing the Sprite on the Screen • Add the following method to the Sprite.cs clas //Draw the sprite to the screen public void Draw(SpriteBatch theSpriteBatch) { theSpriteBatch.Draw(mSpriteTexture, Position, Color.White); } • We have now created our Sprite class. You should be able to Build the project with no errors now and the Image should still draw BUT it's not being drawn by our new Sprite class.
3.7 Using the new Sprite Class • We will now modify the Game1.cs class to use the new Sprite object we have created. To begin with, delete the following lines of code from the top of the Game1.cs class. Vector2 mPosition = new Vector2(250, 100); Texture2D mSpriteTexture; • Now, add the following line of code to the Game1.cs class. This will be our Sprite object. Sprite mSprite; • Next we want to "create" our Sprite object so that it's ready to be used in our Game1.cs class. To do that, add the following line of code to the "Initialize" method. The Initialize method is another one of those methods already created for you when you make a new Windows game. protected override void Initialize() { // TODO: Add your initialization logic here mSprite = new Sprite(); base.Initialize(); }
3.7 Drawing the Sprite on the Screen • Modify the LoadContent method to look like this. protected override void LoadContent() { // Create a new SpriteBatch to draw textures. spriteBatch = new SpriteBatch(GraphicsDevice); // TODO: use this.Content to load your game content here mSprite.LoadContent(this.Content, "SquareGuy"); }
3.7 Drawing the Sprite on the Screen • Calling that will load the SquareGuy asset into the Texture2D object in our Sprite class. Now we just need to Draw the Sprite to the screen. To do that, modify the Game1.cs Draw method to look like this. protected override void Draw(GameTime gameTime) { graphics.GraphicsDevice.Clear(Color.CornflowerBlue); // TODO: Add your drawing code here spriteBatch.Begin(); mSprite.Draw(this.spriteBatch); spriteBatch.End(); base.Draw(gameTime); }
3.8 Positioning the Sprite Object • This changes the Position of the sprite so that when the Sprite draws itself, it uses the new positioning information you gave it. You can also change just an individual X and or Y position of the Sprite by writing code like this. mSprite.Position.X = 200; mSprite.Position.Y = 300; • Just another way of accessing and changing the positioning information of your sprite. With the new positioning information you have given the Sprite, go ahead and Build now and watch where the Sprite is drawn.
3.9 Drawing Multiple Sprites • Add a new Sprite object to the top of the class, maybe call this one mSpriteTwo. Sprite mSpriteTwo; • Instantiate a new instance of the Sprite in the Initialize method of the Game1.cs class. mSpriteTwo = new Sprite(); • Call the LoadContent method of your new sprite object in the LoadContent method of the Game1.cs class. mSpriteTwo.LoadContent(this.Content, "SquareGuy"); • Give the new sprite a new position (if you give it the same position, you won't see it since they will be drawn on top of each other). mSpriteTwo.Position = new Vector2( 300, 100); • Call the Draw method of your sprite object in the Draw method of the Game1.cs class. mSpriteTwo.Draw(this.spriteBatch); • Now go ahead and Build your game, you should now see two sprites drawn to the screen in the locations you have given them. Do you think you could add a third?