 |


 |
|
 |
 |
 |
 |
|
 |
 |
Ahh, sometimes things are just too easy. This is going to be the first Episode where nothing difficult happened at all. Everything was smooth sailing thanks to a few hints and references from the folks over at Creators.XNA.com. The whole basis of this episode was to add some text to the top of the screen to display the words “Life,” “Power,” “Score,” and the Level. I also wanted to add a “life” bar and a “power” bar to the screen. So, the first thing I did was find a good library for creating text on the screen (though supposedly XNA will have this feature included in the next update). So, I found Nuclex (http://www.nuclex.org/framework/fonts) and followed the easy installation and use instructions that they have up there. VERY easy. Didn’t have a single snag with it. They have instructions there as to how to use their code, so I won’t repeat them here. But suffice to say, I added my words to the top of my page extremely easily. I’ll just post here the code that I used: There are very specific instructions on how to install the Nuclex font pipeline add-in. After I followed those, I added the DLL to the project. I then added two .ttfimport files, one for Papyrus font and one for Ariel. I set Papyrus (using Nuclex XML format and instructions) to a size of 20, and Ariel to a size of 18. Then I added the following to the Using statements region after adding the Nuclex.Fonts reference to the project. using Nuclex.Fonts; In my declarations section I added two bitmap font objects //Font Objects BitmapFont ArielFont; BitmapFont PapyrusFont; I also added a couple of variables to hold the player’s score. I used a number and a string as I will hold the actual score in the number, but use the string to display that number so I can lead the lower scores with the appropriate number of “0’s” at the beginning. //Score Int16 iScore = 0; string sScore = "000000"; In my Load Graphics Content function I added the lines: //Load Fonts this.ArielFont = content.Load<BitmapFont>(@"content\Fonts\Ariel"); this.PapyrusFont = content.Load<BitmapFont>(@"content\Fonts\Papyrus"); This is basically the same process that is used to load 2D textures to the code. With the fonts loaded all I did then was put the following code into my draw function after the MainSpriteBatch.End() statement. this.PapyrusFont.DrawString(new Vector2(0.0f, 20.0f), "LIFE:", Color.Red); this.PapyrusFont.DrawString(new Vector2(0.0f, 60.0f), "POWER:", Color.Red); this.PapyrusFont.DrawString(new Vector2(400.0f, 20.0f), "SCORE:", Color.Red); this.PapyrusFont.DrawString(new Vector2(550.0f, 20.0f), sScore, Color.Red); this.ArielFont.DrawString(new Vector2(380.0f, 90.0f), "Level 1", Color.Blue); And BAM! I’ve got working text on my screen. Awesome! Ok, so that’s the text. Easy enough. Next I wanted to add the life and power/magic bars. I first though about doing something like the health bars in fighting games, where the bar decreases in size when you get hit. But instead, I thought that a list of discrete health “nodes” would be better. Since every time you get hit will take the same amount of life from you, there is no reason to get all fancy with it just yet. The same goes for the magic. You will be able to do one thing with your magic, and that’s always going to take one bar away. You will be able to get more magic one bar at a time. So, that being said, I made a single little vertical green…pill I guess, in Photoshop. I saved it through the DirectX texture tool and imported it as “Health.dds”. I then colored it purple in photoshop and went through the process again and imported it as “Magic.dds”. Once again, there is just some really basic code here. I started out with some variables to help me along. int BarOffset = 20; //Health int Health = 3; Texture2D HealthBar; //Magic int Magic = 4; Texture2D MagicBar; First I created my bar offset variable, to set the distance between the x position of one bar and the x position of the next. I then set a health variable and set it to 3. I figured that would be a good starting health for display purposes. Then I created the Health Bar texture, which would hold that one little vertical slash of color that I just imported. I did the same thing for Magic and set the magic to 4 and created a texture for it. Then I added the following code into my LoadGraphicsContent function right after the code for loading my floor image. this.HealthBar = content.Load<Texture2D>(@"content\Textures\Health"); this.MagicBar = content.Load<Texture2D>(@"content\Textures\Magic"); These just load the textures I just created. Ok, so with those there, it’s really just a matter now of drawing them to the screen. So, without further ado, the code that I placed in my Draw function right before the code to end the sprite batch draw. //Draw Health bars depending on how much health the player has for (int i = 1; i <= Health; i++) { this.MainSpriteBatch.Draw(HealthBar, new Rectangle(100 + (i *BarOffset), 0, 10, 30),Color.White); } //Draw Magic bars depending on how much Magic the player has for (int i = 1; i <= Magic; i++) { this.MainSpriteBatch.Draw(MagicBar, new Rectangle(100 + (i * BarOffset), 40, 10, 30), Color.White); } Basically what this code does is to count from 1 to the amount of life a person has. Each time it does, it draws a bar up on the screen offset by the number of previous bars that have been drawn. The same thing happens with the magic. The end result with words and images is this:  So, that’s it. It was extremely easy to do, thanks especially to the folks over at Nuclex. Next episode will be dealing with some things that glitter, and some things that burn. See you then. Tags: game development, games, ultimage king shooter, umks, xna
|
 |
 |
 |
 |
|
 |
 |

 |
|
 |
 |
 |
 |
|
 |
 |
Ok, so with those in the project, I turned to my code. I added two variables which would be used throughout the game loop to deal with my walls. //Wall objects Walls WallsCollection; Wall DrawWall; The WallsCollection object will hold each individual wall. This is one reason why I like to name the collection “Walls” instead of “WallsCollection.” It allows me to name the variable that without confusing myself as to whether I’m calling a class type or my actual object. The DrawWall object is used in the Draw function to cut back on calls to the collection (not something that will be an issue for a game as small as this, but I think this will help in larger games). Ok, so with that done, I modified my Initialize function to include two new lines. protected override void Initialize() { // TODO: Add your initialization logic here this.graphics.PreferredBackBufferHeight = 600; this.graphics.PreferredBackBufferWidth = 800; this.Window.Title = "UltiMage King Shooter"; recPlayerLocation = new Rectangle(250, 250,50,50); WallsCollection = new Walls(); InitializeWalls(); base.Initialize(); } Setting the WallsCollection to a new Walls object actually calls the constructor of the class. I then called the Initialize Walls function, something I whipped up to deal with actually creating walls. protected void InitializeWalls() { //create new wall by adding it to the collection. //Interior Walls WallsCollection.Add(new Wall(new Rectangle(220, 120, 10, 140), @"content\Textures\VerticalWallNormal")); WallsCollection.Add(new Wall(new Rectangle(570, 120, 10, 140), @"content\Textures\VerticalWallNormal")); WallsCollection.Add(new Wall(new Rectangle(220, 440, 10, 140), @"content\Textures\VerticalWallNormal")); WallsCollection.Add(new Wall(new Rectangle(570, 440, 10, 140), @"content\Textures\VerticalWallNormal")); WallsCollection.Add(new Wall(new Rectangle(20, 280, 140, 10), @"content\Textures\HorizontalWallNormal")); WallsCollection.Add(new Wall(new Rectangle(640, 280, 140, 10), @"content\Textures\HorizontalWallNormal")); WallsCollection.Add(new Wall(new Rectangle(20, 440, 140, 10), @"content\Textures\HorizontalWallNormal")); WallsCollection.Add(new Wall(new Rectangle(640, 440, 140, 10), @"content\Textures\HorizontalWallNormal")); //Exterior Walls WallsCollection.Add(new Wall(new Rectangle(0, 580, 800, 20), @"content\Textures\UMBottomOuterWall")); WallsCollection.Add(new Wall(new Rectangle(0, 100, 800, 20), @"content\Textures\UMTopOuterWall")); WallsCollection.Add(new Wall(new Rectangle(0, 100, 20, 500), @"content\Textures\UMLeftOuterWall")); WallsCollection.Add(new Wall(new Rectangle(780, 100, 20, 500), @"content\Textures\UMRightOuterWall")); } What’s happening here Is that for every wall I want to place on the screen, I’m adding a new wall to the collection, defining its rectangle, and its texture location. With such a small program and only one level to worry about, I chose to go with this very simple route. However, in future I’m planning on saving all of this data to XML at first, then to binary code. That way it can be separate from the code itself and easily editable if we create a level editor (which is planned for a later episode). Here you can see that I’ve loaded the eight interior walls and the four exterior walls. In episode 2.5, the walls were rendered through the use of 8 objects (4 textures and 4 rectangles). Here I simply use one Wall object and add it to a wall collection object. Much neater and cleaner. Next I edited my LoadGraphics Content function to include all of the walls in the collection. protected override void LoadGraphicsContent(bool loadAllContent) { if (loadAllContent) { this.MainSpriteBatch = new SpriteBatch(graphics.GraphicsDevice); this.Background = content.Load<Texture2D>(@"content\Textures\UMBackground"); this.AvatarImages = content.Load<Texture2D>(@"content\Textures\Main-Character"); this.Floor = content.Load<Texture2D>(@"content\Textures\Floor"); //Load Walls for (int i = 0; i < WallsCollection.Count; i++ ) { WallsCollection[i].Texture = content.Load<Texture2D>(WallsCollection[i].TextureName); } this.IsMouseVisible = true; } } As you can see, the highlighted area is where I cycled through each wall in the collection and loaded the texture for it using the texture name that we stored earlier. This is where that indexing feature came in handy. I have to say that this was the piece of the code that gave me the most trouble out of everything, because I’m not nearly as familiar with C#’s way of doing these kind of things as I am with VB.Net’s. Ok, so with the graphics loaded, I suppose we’re just going to have to go ahead and draw them now, aren’t we? Well, I guess we better go do that then. So, in keeping with that plan, I modified the draw function to look like this. protected override void Draw(GameTime gameTime) { //Clear device graphics.GraphicsDevice.Clear(Color.CornflowerBlue); //Begin SpriteBatch this.MainSpriteBatch.Begin(SpriteBlendMode.AlphaBlend); Vector2 bgPosition = new Vector2(0, 0); this.MainSpriteBatch.Draw(Background, bgPosition, Color.Black); this.MainSpriteBatch.Draw(Floor, new Rectangle(0, 100, 800, 500), Color.White); //Draw the walls in the collection for (int i = 0; i < WallsCollection.Count; i++ ) { DrawWall = WallsCollection[i]; this.MainSpriteBatch.Draw(DrawWall.Texture, DrawWall.Rect, Color.White); } //Draw the Player Rectangle CharRect = new Rectangle(iWalkAnimationFrame * iWalkAnimationFrameOffset, iWalkAnimationRow * iWalkAnimationFrameOffset, 60, 60); this.MainSpriteBatch.Draw(AvatarImages, recPlayerLocation, CharRect, Color.White); MainSpriteBatch.End(); base.Draw(gameTime); } } The highlighted area shows you what I added. I just cycled through each wall object and drew it using the “Rect” property of the wall which stores the rectangle. So, with all of that rendering nicely, we only have collision detection left. I found a great tutorial on collision detection (per-pixel) on Ziggyware (http://www.ziggyware.com/readarticle.php?article_id=48) . Unfortunately, the way he does the detection there doesn’t seem to work for me. At least the per-pixel stuff doesn’t. The basic detection does, and so I removed the collision detection I had before and replaced it with the following code. Boolean CollisionDetection() { foreach (Wall CollideWall in WallsCollection) { if (Intersects(recPlayerFutureLocation, CollideWall.Rect) == true) { return true; } } return false; } public static bool Intersects(Rectangle a, Rectangle b) { // check if two Rectangles intersect return (a.Right > b.Left && a.Left < b.Right && a.Bottom > b.Top && a.Top < b.Bottom); } And that was that. Because the code returns false or true under the same circumstances as my previous code, I didn’t have to change anything in the Update function. There’s a lot less code here than before, and it’s able to handle every wall for every direction. Much thanks to those at Ziggyware. So that’s basically it. A quick note. I have a video of gameplay, but unfortunately I can’t get it down below 260MB. That’s a bit big for Livejournal or for someone to download. So, I am looking for a good screen capture program that will allow me to compress to reasonable file size with audio. If anyone knows of one, please let me know. In lieu of that, here is a screenshot of the board with walls.

|
 |
 |
 |
 |
|
 |
 |

 |
|
 |
 |
 |
 |
|
 |
 |
So, when the reaction to the shocking news of UMKS1 (Ultimage King Shooter 1) having its graphics changed finally settled down, I was able to sort through some of the comments and really get a feel for what you guys wanted out of the game. Um…ok, that’s not true at all. There was no reaction, and there were no comments. It’s all a lie. I actually showed it to one of my friends and he was like “I’m not sure what I’m looking at.” Indeed. Well, that being said, I will continue to describe what I’m doing here for the few of you who happen to stumble onto this site. One addition. I recorded a “game play” video (which is really just the UltiMage walking around). At the moment I am trying to compress it from it’s whopping 260 MB file size. Ok, so the idea here was really to add a few walls and have our avatar bump into them. Perhaps not the nicest thing we could subject him to, but it’s a necessary evil in a game where you don’t want one of his powers to be the ability to walk through solid objects (he’s not that kind of sorcerer). So, the first thing I did was make a simple gray bar in paint and then save it as a Jpeg. I then rotated it 90 degrees and saved it again as another Jpeg. I opened them both in Photoshop, applied the same effects I did to the big walls from episode 2.5, and now I had vertical and horizontal wall textures for my game. Ok, so I’m going to move pretty quickly into the code here. First things first. I made two new classes. One called Wall and one called Walls. Now, the programming community seems to be of two minds when doing type safe collections. Some people would like to call the collected class “Wall” and the Collection class “WallCollection.” Me, I’m of the other mind. I like my class names to be as short as possible. So, for a “Wall” object, I like to call the class “Walls.” I do see the merit in the other naming convention, but, well…I’m both lazy and stubborn, so change is a foreign and scary thing to me. The Wall class is as follows: using System; using System.Collections.Generic; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Audio; using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using Microsoft.Xna.Framework.Storage; namespace Ultimate_King_Shooter_1 { class Wall { #region "Texture Name" private string mTextureName; public string TextureName { get { return mTextureName; } set { mTextureName = value; } } #endregion #region "Texture" private Texture2D mTexture; public Texture2D Texture { get { return mTexture; } set { mTexture = value; } } #endregion #region "Rectangle" private Rectangle mRect; public Rectangle Rect { get { return mRect; } set { mRect = value; } } #endregion public Wall(Rectangle Rect, String TextureName) { mRect = Rect; mTextureName = TextureName; } } } I’ll go over the basics of what I did here. I added three fields and three properties, one public property for every private field. First I added mTextureName and TextureName. The idea here was to store the texture name string for the object until it was time to load it into the content pipeline. The next was the mTexture and Texture members. They are to hold the actual texture once it is loaded into the pipeline. The last are mRect and Rect. This holds the sprite’s rectangle for location and size. Next I added a Walls class, as shown below. using System; using System.Collections.Generic; using System.Text; namespace Ultimate_King_Shooter_1 { class Walls : System.Collections.CollectionBase { public Wall this[int index] { get { return ((Wall)(List[index])); } set { List[index] = value; } } public int Add(Wall Wall) { return List.Add(Wall); } public void Insert(int index, Wall Wall) { List.Insert(index, Wall); } public void Remove(Wall Wall) { List.Remove(Wall); } public bool Contains(Wall Wall) { return List.Contains(Wall); } } } The class is a basic strongly typed collection class. I had a bit of difficulty with this, as the whole concept of Indexers is new to me. My VB.Net experience did not prepare me for the wonders and horrors of that little double square bracket. Tags: game development, games, ultimage king shooter, umks, xna
|
 |
 |
 |
 |
|
 |
 |

 |
|
 |
 |
 |
 |
|
 |
 |
In the process of preparing for Episode 3 (adding a collection of walls and doing per pixel collision checking) I decided that I wanted to see something a little nicer while I was playing with the UltiMage. So, as I’m not yet proficient in painting in Photoshop, I decided to use a program that I know infinitely better…Microsoft Paint. Now, my original idea was simply to make some gray walls (which I did initially in Photoshop, but they were just gray rectangles without even the hint of perspective). I wanted to add a “perspective” slice to the side and bottom of the walls that I was making, so that there was just the most rudimentary hint that there was some depth to them. As I was playing with it, I realized I was going to have to import them to Photoshop to convert them to PNG files so that the Direct X Texture tool could consume them correctly. So, importing them, I remembered a little trick that I used on the UltiMage himself. I opened the effects page and played around with one of the walls. I went from this:

To this, just using some effects:
 This inspired me…so I drew up a floor for the map in paint and imported it to Photoshop and did some more effects on it. With everything packaged together, I had a much better looking game than I started with, if I do say so myself! Here is what UltiMage King Shooter 1 looked like in the first two episodes:
Here is the look that it will have from now on: 
Pretty cunning, don’t ya' think? I should have the next blog up by the end of the weekend, as I already know how to do exactly what I want in VB.Net, now I just have to port that knowledge to C#. Tags: game development, games, ultimage king shooter, xna
|
 |
 |
 |
 |
|
 |
 |

 |
|
 |
 |
 |
 |
|
 |
 |
My original intent was to make it so that my character could move around and stop when he hit a part of the map that was red. I followed the instructions for a color mapping tutorial found at XNA Resources (http://www.xnaresources.com/pages.asp?pageid=8) which worked very well, except that my walk cycle was messing things up with the color detection. So, I decided, after much frustration, that for this phase of development, I would work simply with numeric limits to where my character could walk. I will be revamping the background image for the next tutorial, and creating a series of “wall” objects that will actually be instantiated and have collision detection. But that’s next time. For now, I decided to find out what the limits were of this little box I call the “game” board, and set them as the walking limits. Now, before I go any farther, I know what you’re thinking. “Why was the second season of Lost so bad?” I know, I’m wondering that too, but I am also considering that I haven’t gone over the code that I used to create the walking functionality. But bear with me a little and I’ll get to that. I want to establish where we can walk first. So, after a bit of trial and error, I determined what the limits of the screen were (the pixel limits I set in the screen buffer didn’t seem to work quite right for some reason). Then I declared them in variables at the beginning of the program. //Board constraints int BorderTop = 62; int BorderLeft = 5; int BorderBottom = 548; int BorderRight = 750; I have a board that I put up as 800 x 600, and there was a blank space at the top for score and such, so the limits weren’t exactly intuitive. Either way, these numbers worked for me. Now to the walking and animation part. For this I relied heavily on another XNA Resources (see link above) tutorial where running water is animated. I started by declaring a number of variables for my walk cycle. // Walk Animation int iWalkAnimationFrame = 0; // The current frame of animation we are on. int iWalkAnimationFrameCount = 4; // The total number of frames in our animation int iWalkAnimationFrameOffset = 60; // The number of pixels to offset when pulling the main character animation int iWalkAnimationRow = 0; // The row of the animation to find, indicating the direction the player is facing. int iWalkSpeed = 8; First I declared a variable to let the program know what frame we are on of the animation. Then I declared one to say how many frames were in the animation. Both of these are used in the process of finding out which animation (or which column of our avatar image) we should use. Here a value of 0 in iWalkAnimationFrame is equivalent to an avatar from column 1. A value of 1 is the same as saying “column 2” and so on. The next two variables also help to determine where on the image the program should look for the correct avatar image. The iWalkAnimationFrameOffsest is used to determine the size of the rectangle that will be pulled out of the image. All of our images are spaced in 60 x 60 pixel areas, and centered in the middle of them over an alpha layer. Therefore, if a 60 x 60 area is taken out starting at 0,0 pixels, the first avatar in the first row will be pulled out. The next variable was the iWalkAnimationRow which informs us as to what direction the avatar is facing. Here again a value of 0 equals the first row, 1 equals the second row, and so forth. However, here it is not a matter of what frame of animation that determines which is picked, but the direction the avatar is walking that does. We will see in a moment how clicking left will set the animation row to 1, and clicking right will set it to 3. Finally the walk speed is set to 8 which determines how far the avatar will move on the screen each cycle. Ok, so the variables are set. Next I needed to set a variable for the texture itself. I simply added Texture2D AvatarImages; right after the declaration for the background image. I also added a definition for the player’s location as a rectangle. // Player Location Rectangle recPlayerLocation; //Holds the player's location after collision detection is resolved. And two to set up a button press delay (courtesy of XNA Resources) // Button press delay float fKeyPressCheckDelay = 0.25f; float fTotalElapsedTime = 0; The idea behind the delay is to keep the button presses from triggering multiple events too quickly. Put a quarter second of a delay in the game, and you have a pretty good button-push rate (not a real term J ). Ok, so with the variables set, I set up the Update Function. This is where the layout of my image came in handy. The idea basically was to have each row in the image represent a direction, and each column represent a step in the walk cycle. This way, when the program detects which arrow button is being pushed, it knows which row to go to to get the image. The walk animation frame counter will iterate up for every button press, letting the program know which column to look at. The update code looks like this: protected override void Update(GameTime gameTime) { // Allows the default game to exit on Xbox 360 and Windows if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) this.Exit(); // TODO: Add your update logic here float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds; fTotalElapsedTime += elapsed; ksKeyboardState = Keyboard.GetState(); //process if enough time has elapsed if (fTotalElapsedTime >= fKeyPressCheckDelay) { if (ksKeyboardState.IsKeyDown(Keys.Up)) { iWalkAnimationFrame += 1; iWalkAnimationRow = 0; if (iWalkAnimationFrame >= WalkAnimationFrameCount) { iWalkAnimationFrame =0; } if (recPlayerLocation.Y - iWalkSpeed > BorderTop) { recPlayerLocation.Y -= iWalkSpeed; } fTotalElapsedTime = 0.0f; } else if (ksKeyboardState.IsKeyDown(Keys.Left)) { iWalkAnimationFrame += 1; iWalkAnimationRow = 1; if (iWalkAnimationFrame >= WalkAnimationFrameCount) { iWalkAnimationFrame = 0; } if (recPlayerLocation.X - iWalkSpeed > BorderLeft) { recPlayerLocation.X -= iWalkSpeed; } fTotalElapsedTime = 0.0f; } else if (ksKeyboardState.IsKeyDown(Keys.Down)) { iWalkAnimationFrame += 1; iWalkAnimationRow = 2; if (iWalkAnimationFrame >= WalkAnimationFrameCount) { iWalkAnimationFrame = 0; } if (recPlayerLocation.Y + iWalkSpeed < BorderBottom) { recPlayerLocation.Y += iWalkSpeed; } fTotalElapsedTime = 0.0f; } else if (ksKeyboardState.IsKeyDown(Keys.Right)) { iWalkAnimationFrame += 1; iWalkAnimationRow = 3; if (iWalkAnimationFrame >= WalkAnimationFrameCount) { iWalkAnimationFrame = 0; } if (recPlayerLocation.X + iWalkSpeed < BorderRight) { recPlayerLocation.X += iWalkSpeed; } fTotalElapsedTime = 0.0f; } } base.Update(gameTime); } So, first we do a check of the time since the last action. If it is after the time of the last action plus our key press check delay, then it fires our code. If not, then it skips past it. If the time is past our buffer time, then it checks for which key is down. Right now I only have the four arrow keys set. Each key does the same five things. First it itterates the walk animation frame forward by one. This tells the program which column to take the image from. The next thing it does is tells it which row it is on. This is purely based on how I laid the picture out when I made it. Up is 0, left is 1, down is 2, and right is 3. It then checks to see if the walk animation frame is greater than the walk animation frame count. If it is, then I reset it to 0. (Note here that I don’t just put in “3” for the frame count. This is a general programming practice of putting a variable in in the place of a static number. This way, if I want to change my walk animation by adding more steps to it, all I have to do is load my new picture and change the variable back at the beginning of the code and then it will work fine. The idea here is to have to make a change in only one place for the entire code. If I increased the image to hold 10 steps instead of 4, and I had put “3” in every place where I currently have “WalkAnimationFrameCount” then I would have to change every place where I put “3.” Now, if I want to change, I only make one change at the beginning of the code. Simple programming 101.) So, after it checks the animation frame, it then checks to see if the move destination (the current location plus the move speed in the appropriate direction for that button) is outside of the limits I set for the game. If is isn’t outside of the limits, it sets the player’s location to the new coordinates. It then resets the elapsed time to 0 so that the buffer time can start again. We then run the update game function. Ok, now for the final bits of code. First, we should look back to the LoadGraphicsContent Function. Where we loaded the map image before, we will be adding the character sprite map now. I simply added the following line after the line to add the game background. this.AvatarImages = content.Load<Texture2D>(@"content\Textures\Main-Character"); This was, of course, after I had imported the DirectX modified image into my graphics pipeline by including the file in my Textures folder. The last piece of coding was in the Draw function. The idea here was to take the information that we modified in the Update function (the player location and the location of the current sprite) and draw the appropriate thing to the screen. The first part of the function I used was: graphics.GraphicsDevice.Clear(Color.CornflowerBlue); this.MainSpriteBatch.Begin(SpriteBlendMode.AlphaBlend); Vector2 position = new Vector2(0, 0); this.MainSpriteBatch.Draw(Background, position, Color.White); This is the same kind of thing I used before, and I’m finding it to be the basic building block of all of the draw methods that I use when I try different things. You clear the graphicsdevice, then begin your sprite batch. The Position and background draw are extra. The Position is going to be the position of the player’s avatar. The Background is what I did in the previous step. Now, this code isn’t exactly neat and organized, so I figured I would nice it up a bit in the next step. For now, it’s messy. So, after that, I did the following. //draw the main character Rectangle CharRect = new Rectangle(iWalkAnimationFrame * iWalkAnimationFrameOffset, iWalkAnimationRow * iWalkAnimationFrameOffset, 60, 60); this.MainSpriteBatch.Draw(AvatarImages, recPlayerLocation, CharRect, Color.White); MainSpriteBatch.End(); // TODO: Add your drawing code here base.Draw(gameTime); Ok, the first thing I do is create a new rectangle, and I set it’s x coordinate by taking the walk animation frame and multiplying it by the walk animation frame offset which we set at the beginning to 60. So, if the animation frame is 0, x will be 0. If it’s 1, x will be 60 and so on. Next, I set the y coordinate by multiplying the Walk Animation Row (set by the directional arrows in the update function) by the walk animation offset. I then set the height and width to 60 each. This rectangle represents a 60x60 pixel location on the character sprite map that I want to draw on the screen. Next I use the spritebatch to draw the rectangle that I chose from the avatar map onto the location of the game board using the “recPlayerLocation” variable. I then ended the batch and used base.Draw. And that’s it. The final result is a guy who can walk around the screen with a cheesy walk animation. Still, I love it.

So, for next time, I’m going to take a few steps back, redo the board, and create some real obstacles for the player to run into instead of just mapping out numerically where the wall limits are. Until then, peace. Josh Tags: game development, games, ultimage king shooter, xna
|
 |
 |
 |
 |
|
 |
 |

 |
|
 |
 |
 |
 |
|
 |
 |
Had to break this into two parts for size...part 1 is about the graphics, part 2 about the code.
So here is the second installment in the creation of a crappy top down 2D shooting game called Ultimage King Shooter. This installment is about the creation of our Avatar, Theldan the UltimMage. Theldan is a powerful and awe inspiring character, so, to his credit, we’ll create a sprite made basically out of four ovals in Photoshop. Basically I just made a horizontal blue oval with a skin-tone colored circle in the middle and a small blue oval going perpendicular to the first. The horizontal oval is Theldan’s body, the circle is his head, and the perpendicular blue oval is his hat. Simple. This is the main avatar in standing position when looking “up” on the screen. Next I created a ridiculously simple walk cycle for him. Rotating the collection of items about 30 degrees clockwise, I then added a small brown oval and placed it under the others to represent his foot kicking out to walk. I then copied the standing position again and then copied the “walk” position. I flipped the walk position horizontally to create the other leg position. With these four, I was ready to test my avatar. Now, I’m going to skip what I did next to keep this tutorial split into the “art” section first, and then the code section after. (I put art in quotes because there is very little artistic about a four oval character). Ok, so what I found was that the character could move up very nicely, and I had the animation worked out as well as could be expected for a four frame animation. But I also realized that I had no way to show him turning or walking in other directions. So I went back to PhotoShop and made three copies of that first set of images. Basically I rotated them at 90 degrees each time to come up with a left facing set, a down facing set, and a right facing set. I spaced each avatar out by 60 pixels using guide lines so that my code would work later on. I also placed all of the top facing avatars in the first row, the left facing in the second, the bottom facing in the third, and the right facing in the fourth rows. This is all so that we can basically reference where on the image the program should be looking to represent the avatar at any given time. Ok, so when was finished, I had this…
This is the image that I saved as a .PGN file. I did this so I could open the file in the Direct X Texture tool. I created a new image there that was the same size as the image I had just created and then did a “File->Open onto This surface” and chose the file I just created. I then saved the file as “Main-Character.dds.” So that’s basically it for the art part. Next for the coding. Tags: game development, games, ultimage king shooter, xna
|
 |
 |
 |
 |
|
 |
 |

 |
|
 |
 |
 |
 |
|
 |
 |
Episode 1: Game Background and a Background for the Game Ok, so I’m going to make this game which I’m calling “Ultimage King Shooter” (I couldn’t think of anything cheesier, unless I was making a sequel then it would have been “Ultimage King Shooter 2: The Magestic Return”). This is going to be a basic top down 2D 80’s style shooting game. The point of each level is simply to kill the enemies on the screen. Since this is “Ultimage” the avatar is a powerful sorcerer who has a whopping two spells at his command, Fireball and Dome of Flames. The Fireball spell will be your “gun” for the game, and the Dome of Flames will be a “force-field” that you can activate when you collect enough power gems. Along the way you’ll be fighting the goblins that infest an ancient tower where these power gems are hidden. Why did you go there in the first place when all you’re going to get is silly power gems that you’ll end up using while you fight creatures you could have avoided by simply not going to the tower? Hmmm, well, perhaps there is a surprise at the end of the game. The basic layout will be ten levels, each getting harder as you go through. To beat a level, you must defeat all of the creatures. The creatures will (hopefully) get “smarter” as the levels get harder, and they will take more of a beating before they die. Ok, well, that’s all pie in the sky right now. First we need to make a background for our crappy cheesy game. So, first things first, let’s open up our edition of Photoshop and make a background.  This is about as basic as it gets. We have a black background and a red border. The red border will help us to figure out where the player can go later on (or so we hope). The idea is that when the player moves, we check the map to see if the location of his or her move is red. If it is, we don’t call the move code. You’ll also notice that I left a blank area at the top. That will be where we put the level number, the score, the player’s current energy level and lives. There will be no “health” bar for this game, as we’re following the rules of Pac Man and snipers everywhere, one hit, one kill. Your enemies will be a bit more fortunate as they will eventually get stronger throughout the game. Ok, so we have a background. Now, I’m not expert at Photoshop. Hell, I’m barely a beginner, so if I did this wrong, I’m open to suggestions. However, I took my image, saved it and then saved it for the web. I used the settings for the highest JPEG there was and called it Level-1.jpg. So that’s all of the art for this first episode. Now we move on to the code. A bit of my coding background first. I’m a .Net programmer who has worked mainly in VB.Net 2003 and 2005. I dabbled a bit in C++ in college and I’ve done some web pages in Javascript. So, the layout of C#’s syntax isn’t totally unfamiliar to me, and the .Net framework is what I do for a living, so that’s all well and good. However, XNA has a pipeline that I’m just getting to know, so again, if I’m doing something wrong, or going far out of my way to do something that’s actually done much simpler, then I would appreciate any suggestions. Ok, so to get started, I created a new program that I called “Ultimage King Shooter” in my XNA Game Studio Express 1.0 IDE. The whole point of this first step is just to get the background up and viewable. So, with that in mind, I declared some variables at the beginning of my program. SpriteBatch MainSpriteBatch; Texture2D Background; MainSpriteBatch is the sprite batch for this project. The Background texture will hold our simple background. I declared these variables right after the default declarations of the Graphic Device Manager and the Content objects. Next I set my screen size in the Initialize function. I used 800x600 because that was the size I set for the image I created in Photoshop. I also set the title of the game window here. protected override void Initialize() { // TODO: Add your initialization logic here this.graphics.PreferredBackBufferHeight = 600; this.graphics.PreferredBackBufferWidth = 800; this.Window.Title = "UltiMage King Shooter"; base.Initialize(); } Next I added my texture to the graphics pipeline. To do this I added the “Content” folder under the main project in the solution explorer by right clicking on the project name and going to “Add->New Folder” and naming it “Content.” I then added the “Textures” folder under content by right clicking on the Content folder and choosing “Add->New Folder” there as well, and renaming that “Textures.” One more right click and we’re done with adding the texture. Right clicking on Textures allwed me to “Add->Existing Item.” This brought me to a screen where I could find the Level-1.jpg that I saved earlier. I double clicked on the file and it was added to the pipeline. I clicked on the item to see what its Asset Name was (this is how to refer to it in game) and saw that it was “Level-1.” This is typically the way I’ve experienced XNA names assests so far, by stripping off the file extension. Ok, now with that in the pipeline, I can load it into the game’s memory. So, I edited the LoadGraphicsContent function to read thusly: protected override void LoadGraphicsContent(bool loadAllContent) { if (loadAllContent) { this.MainSpriteBatch = new _ SpriteBatch(graphics.GraphicsDevice); this.Background = _ content.Load<Texture2D>(@"content\Textures\Level-1"); } // TODO: Load any ResourceManagementMode.Manual content } You can see here that I set the MainSpriteBatch (Which we declared earlier) to a new sprite batch with the graphics.GraphicsDevice as its argument. As well, I loaded our image into the this.background object. Now, I’m not totally sure how the SpriteBatch works yet. Yes, I know, I’m writing a tutorial about this and yet I don’t know how the thing works yet, right? Wrong. This isn’t a tutorial, this is a sad, pathetic walk through of a game that may or may not ever get finished. I’m learning just as much, if not more, than you are by doing this. So, there will probably be a lot of things that I do based on help documents and tutorials, that I don’t totally understand. But then, that’s how I started programming at all, getting things to work and understanding them later. That’s the difference, I think, between those of us who are self-taught programmers and those who have degrees. Well, that and a lot of free time to spend on learning something like programming. Ok, so anyway, back to the code. With my SpriteBatch (which I do know is used in the write function) and background initialized, I can move on to the (only slightly) aforementioned Write function. I modified the code to look like this… protected override void Draw(GameTime gameTime) { graphics.GraphicsDevice.Clear(Color.CornflowerBlue); this.MainSpriteBatch.Begin(SpriteBlendMode.AlphaBlend); Vector2 position = new Vector2(0, 0); this.MainSpriteBatch.Draw(Background, position, _ Color.White); MainSpriteBatch.End(); // TODO: Add your drawing code here base.Draw(gameTime); } Here I started the SpriteBatch in AlphaBlend mode (yep, not sure what that does either) and declared a new vector, setting it to 0,0. I then drew the background texture at the new vector and set the tint color to white (which gives you the true color of the image). Then I ended the SpriteBatch and ta-da! We’re done. Ok, so after all of that, we have a working game with ten levels, walking monsters, lasers, shields, a score, collision detection, and leader boards. Wait…we don’t? We went through all of that to get what? Hold on, let me hit F5 here and see what we get. Ok, so the image that comes up is…
Uh, yeah, that’s right…it’s the background for the game. Crap, well, looking back now I relize that was indeed my intention for this whole first episode. Man. Ok, well, that’s that I guess. It’s a start and we have a long, long way to go before there is anything worth looking at here. But, every great journey begins with one single step. So do crap journies where you end up breaking your ankle and falling in a ditch, so let’s not wax too poetic just yet about something that is for all intents and purposes a black box with a red box in the middle. For accomplishing the background code here, I have to thank Glenn Wilson for his tutorial on that very topic which can be found at http://msmvps.com/blogs/mykre/archive/2006/11/02/Drawing-a-Basic-Background-in-XNA.aspx Ok, well, next time we’ll be…um, probably making an avatar to run around the screen. That might be broken up into two bits though, the art and the programming. Any comments or help that anyone has about this would be greatly appreciated. Tags: game development, games, ultimage king shooter, xna
|
 |
 |
 |
 |
|
 |
 |

|
 |
 |
 |
 |
 |
 |
 |
 |
 |
|
 |
 |
 |
 |
 |
 |
 |
 |
|
 |
 |
 |
 |
 |
 |
 |
 |
 |
 |
 |
 |
 |
|
 |
 |
 |
 |
 |
 |
 |
 |
 |
April 2007 |
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | | 8 | 9 | 10 | 11 | 12 | 13 | 14 | | 15 | 16 | 17 | 18 | 19 | 20 | 21 | | 22 | 23 | 24 | 25 | 26 | 27 | 28 | | 29 | 30 |
|
 |
 |
 |
 |
 |
 |
 |
 |
 |
 |
 |
 |
 |
|
 |
 |
 |
 |
 |
 |
 |
 |
|
 |
 |
 |
 |
 |
 |
 |
 |
 |
 |
 |
 |
 |
|
 |
 |
 |
 |
 |
 |
 |
 |
|
 |
 |
 |
 |
 |
|
 |