Posts Tagged ‘ XNA

A day of updates…

WordPress Update to 2.8, atahualpa update to 3.3.3 and the best one XNA update to 3.1 Avatars and Video :-D

Also we are now working on “Xbox LIVE Indie Games” it’s better that “Xbox LIVE Community Games” but the sooner they drop the LIVE thing the better we’ll all be.

Any-who off to bed now it’s my last day at this job tomorrow :-)

XNA Platformer – Part 1(postmortem)

I have to give a big THANK YOU to @clingermangw and @TehGrumpyDude over on Twitter and MattChristian from the forums @ xna.com also efilnukefesin over @ ziggyware.com and of course zygote for his comment in my tutorial post that started my questioning yesterday.

I posted a question on both the creators forum and on ziggyware which was :-

XNA Platformer – Part 1

Let me know what you think, Ziggy said :-

the article is hard to read in its current format

But I don’t know what I could do to improve it…

Please Help.

And I got some very good feedback regarding the tutorial, mostly that the flow of the article was broken because you have to click the thumbnails to see what I was on about and that I didn’t give any reason for why I was doing what I was doing, and the table layout didn’t help with things and the code wasn’t explained…

This was all good news to me because it gave me something I can work on.  I’m going to put the Platformer on hold for now, I might come back to it at a later date.

So I’m going to go back to my strengths in that I’m going to go through a few of the projects in the XNA content catalog pull them apart and try and tweak them, the one I’ll start with is the chase & evade project, mainly because I used it as a base to test an idea that needed about 1,000 objects and I got about 2fps so it needs some work :-)

Well that’s what I’m going to be working on next, and by the way I got a new job :-D

XNA Platformer – Part 1

This is the first part of many that should build up into a full platformer game that I could release on to XBLCG. As this is the first part I’m only explaining the steps for combining the starter kit that comes with XNA 3.0 with the Network Game State Management Sample from Creators Club Online. Future chapters will go into more detail about the code we’re creating but for this one there is enough information out there on each of the two projects we are using.

My main reason for starting out with the two sample projects is that it will give us a head start on our whole project. We’re not going to get bogged down with details like how to do the animation system, or the falling physics because they are already in to start with. We will be looking at ways to improve the game engine as we go, adding features, changing the data storage, changing the graphics and sound. For now let’s just get the game running with a menu system…

step-001 Create a Platformer Starter Kit, compile it and exit, we’re doing this is so that we have access to the content and code.
step-002 Extract the Network Game State Manager to a new directory.
step-003 Open the solution file from the Network Game State Manager folder you just created.
step-004 Expand the content sub project.
step-005 Add 5 new sub folders called :- Fonts, Graphics, Levels, Sounds, StateManager.
step-006 In the Graphics folder add 4 new sub folders called Backgrounds, Overlays, Sprites & Tiles.
step-007 Move the gamefont.spritefont & menufont.spritefont into the Fonts folder from the root of the content sub project.
step-008 Move the remaining files from the root of the content sub project into the StateManager folder.
step-009 Open an Explorer window at the SharedContent folder for the Platformer project you created in step 1 then open the Sounds folder.
step-010 Select all the WMA files and drag them over to the Sounds folder in your Solution Explorer, When you drop them on this folder they will be added to the solution.
step-011 Now in the Explorer window navigate up two directories and then into the HighResolutionContent Folder where you will find Backgrounds, Fonts, Levels, Overlays, Sprites & Tiles folders.
step-012 Open each of these directories and copy their contents into their corresponding folders in the Solution Explorer.
step-013 Add a new sub folder to the NetworkStateManagementWindows solution called GameClasses.
step-014 Go to your Explorer window, move back up from the Graphics folder to the main solution directory, here you need to select the following files :- Animation.cs, AnimationPlayer.cs, Circle.cs, Enemy.cs, Gem.cs, Level.cs, Player.cs, RectangleExtensions.cs, Tile.cs only.
step-015 Drag and drop these files on to the GameClasses folder, and they will be added to your solution.
step-016 Open up each of the files you just added and change the namespace line from

namespace TempPlatformer

or what ever you called your temp solution back in step one, to

namespace NetworkStateManagement

Why? So we dont have to add a using directive to the game file. VS2008 gives you a real easy way to do this see picture on left.

Expand Screens folder and open GamePlayScreen.cs ready for editing.
Remove the following lines from The fields region :-

Vector2 playerPosition = new Vector2(100, 100);
Vector2 enemyPosition = new Vector2(100, 100);
 
Random random = new Random();
And then add the following lines to the Fields region:-

// Global content.
private SpriteFont hudFont;
 
private Texture2D winOverlay;
private Texture2D loseOverlay;
private Texture2D diedOverlay;
 
// Meta-level game state.
private int levelIndex = -1;
private Level level;
private bool wasContinuePressed;
 
// When the time remaining is less than the warning time, it blinks on the hud
private static readonly TimeSpan WarningTime = TimeSpan.FromSeconds(30);
 
private const Buttons ContinueButton = Buttons.A;
Replace the LoadContent method with this :-

public override void LoadContent()
{
    if (content == null)
        content = new ContentManager(ScreenManager.Game.Services, "Content");
 
    // Load fonts
    hudFont = content.Load<SpriteFont>("Fonts/Hud");
 
    // Load overlay textures
    winOverlay = content.Load<Texture2D>("Graphics/Overlays/you_win");
    loseOverlay = content.Load<Texture2D>("Graphics/Overlays/you_lose");
    diedOverlay = content.Load<Texture2D>("Graphics/Overlays/you_died");
 
    MediaPlayer.IsRepeating = true;
    MediaPlayer.Play(content.Load<Song>("Sounds/Music"));
 
    LoadNextLevel();
 
    // once the load has finished, we use ResetElapsedTime to tell the game's
    // timing mechanism that we have just finished a very long frame, and that
    // it should not try to catch up.
    ScreenManager.Game.ResetElapsedTime();
}
Replace the Update method with this :-

public override void Update(GameTime gameTime, bool otherScreenHasFocus,
                            bool coveredByOtherScreen)
{
    base.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen);
 
    if (IsActive)
    {
        level.Update(gameTime);
    }
 
    #region Network Update
    // If we are in a network game, check if we should return to the lobby.
    if ((networkSession != null) && !IsExiting)
    {
        if (networkSession.SessionState == NetworkSessionState.Lobby)
        {
            LoadingScreen.Load(ScreenManager, true, null,
                               new BackgroundScreen(),
                               new LobbyScreen(networkSession));
        }
    }
    #endregion
}
Replace HandlePlayerInput method with :-

bool HandlePlayerInput(InputState input, PlayerIndex playerIndex)
{
    // Look up inputs for the specified player profile.
    KeyboardState keyboardState = input.CurrentKeyboardStates[(int)playerIndex];
    GamePadState gamePadState = input.CurrentGamePadStates[(int)playerIndex];
 
    // The game pauses either if the user presses the pause button, or if
    // they unplug the active gamepad. This requires us to keep track of
    // whether a gamepad was ever plugged in, because we don't want to pause
    // on PC if they are playing with a keyboard and have no gamepad at all!
    bool gamePadDisconnected = !gamePadState.IsConnected &&
                               input.GamePadWasConnected[(int)playerIndex];
 
    if (input.IsPauseGame(playerIndex) || gamePadDisconnected)
    {
        ScreenManager.AddScreen(new PauseMenuScreen(networkSession), playerIndex);
        return false;
    }
 
    bool continuePressed = gamePadState.IsButtonDown(ContinueButton) ||
                           keyboardState.IsKeyDown(Keys.Space) ||
                           keyboardState.IsKeyDown(Keys.Up) ||
                           keyboardState.IsKeyDown(Keys.W);
 
    // Perform the appropriate action to advance the game and
    // to get the player back to playing.
    if (!wasContinuePressed && continuePressed)
    {
        if (!level.Player.IsAlive)
        {
            level.StartNewLife();
        }
        else if (level.TimeRemaining == TimeSpan.Zero)
        {
            if (level.ReachedExit)
                LoadNextLevel();
            else
                ReloadCurrentLevel();
        }
    }
 
    wasContinuePressed = continuePressed;
 
    return true;
}

[edit]A gotcha has been fixed with the continuePressed check, when you are using the keyboard for input, thanks to DarkChief for finding that one :-) [/edit]

Finaly replace the Draw method with this :-

public override void Draw(GameTime gameTime)
{
    //Platformer code
    ScreenManager.SpriteBatch.Begin();
 
    level.Draw(gameTime, ScreenManager.SpriteBatch);
 
    DrawHud();
 
    ScreenManager.SpriteBatch.End();
 
    // If the game is transitioning on or off, fade it out to black.
    if (TransitionPosition > 0)
        ScreenManager.FadeBackBufferToBlack(255 - TransitionAlpha);
}
Next you need to add some code to handle the HUD and Level re/loading copy the following code block in after the last method in the class :-

#region Hud and Load Level
private void DrawHud()
{
    Rectangle titleSafeArea = ScreenManager.GraphicsDevice.Viewport.TitleSafeArea;
    Vector2 hudLocation = new Vector2(titleSafeArea.X, titleSafeArea.Y);
    Vector2 center = new Vector2(titleSafeArea.X + titleSafeArea.Width / 2.0f,
                                 titleSafeArea.Y + titleSafeArea.Height / 2.0f);
 
    #region Draw time remaining.
    // Uses modulo division to cause blinking when the player is running out of time.
    string timeString = "TIME: " + level.TimeRemaining.Minutes.ToString("00") +
                        ":" + level.TimeRemaining.Seconds.ToString("00");
    Color timeColor;
    if (level.TimeRemaining > WarningTime ||
        level.ReachedExit ||
        (int)level.TimeRemaining.TotalSeconds % 2 == 0)
    {
        timeColor = Color.Yellow;
    }
    else
    {
        timeColor = Color.Red;
    }
    DrawShadowedString(hudFont, timeString, hudLocation, timeColor);
    #endregion
 
    #region Draw score
    float timeHeight = hudFont.MeasureString(timeString).Y;
    DrawShadowedString(hudFont,
                       "SCORE: " + level.Score.ToString(),
                       hudLocation + new Vector2(0.0f, timeHeight * 1.2f),
                       Color.Yellow);
    #endregion
 
    #region Determine the status overlay message to show.
    Texture2D status = null;
    if (level.TimeRemaining == TimeSpan.Zero)
    {
        if (level.ReachedExit)
        {
            status = winOverlay;
        }
        else
        {
            status = loseOverlay;
        }
    }
    else if (!level.Player.IsAlive)
    {
        status = diedOverlay;
    }
 
    if (status != null)
    {
        // Draw status message.
        Vector2 statusSize = new Vector2(status.Width, status.Height);
        ScreenManager.SpriteBatch.Draw(status, center - statusSize / 2, Color.White);
    }
    #endregion
}
 
private void DrawShadowedString(SpriteFont font, string value, Vector2 position,
                                Color color)
{
    ScreenManager.SpriteBatch.DrawString(font,
                                         value,
                                         position + new Vector2(1.0f, 1.0f),
                                         Color.Black);
    ScreenManager.SpriteBatch.DrawString(font, value, position, color);
}
 
private void LoadNextLevel()
{
    // Find the path of the next level.
 
    string levelPath;
 
    // Loop here so we can try again when we can't find a level.
    while (true)
    {
        // Try to find the next level. They are sequentially numbered txt files.
        levelPath = String.Format("Levels/{0}.txt", ++levelIndex);
        levelPath = Path.Combine(StorageContainer.TitleLocation,
                                 "Content/" + levelPath);
 
        if (File.Exists(levelPath))
            break;
 
        // If there isn't even a level 0, something has gone wrong.
        if (levelIndex == 0)
            throw new Exception("No levels found.");
 
        // Whenever we can't find a level, start over again at 0.
        levelIndex = -1;
    }
 
    // Unloads the content for the current level before loading the next one.
    //if (level != null)
    //    level.Dispose();
 
    // Load the level.
    level = new Level(content, levelPath);
}
 
private void ReloadCurrentLevel()
{
    --levelIndex;
    LoadNextLevel();
}
#endregion
Next you need to jump back to the top of the file and add some using statements :-

using Microsoft.Xna.Framework.Media;
using System.IO;
using Microsoft.Xna.Framework.Storage;
Expand GameClasses folder and open Level.cs ready for editing.
Find the Constructor(in the Loading region-Why?) and change the first parameter type from

public Level(IServiceProvider serviceProvider, string path)

to

public Level(ContentManager serviceProvider, string path)
and the line just under it from

content = new ContentManager(serviceProvider, "Content");

to

content = serviceProvider;
step-029 Expand the Levels folder in the content sub project, Select all three text files and change the Build Action property to None and the Copyto Output Directory to Copy if newer.
step-030 Press Ctrl+F to get the Find dialog box up, and enter “Content.Load<Texture2D>” in to the Find what: box and select “Entire Solution” from the Look in: dropdown & make sure the Match Case option is off. For each item you find alter the method parameter to point at it’s new location EG :-

texture = Level.Content.Load&lt;Texture2D&gt;("Sprites/Gem");

Becomes

texture = Level.Content.Load&lt;Texture2D&gt;("Graphics/Sprites/Gem");

Sounds & Fonts should be unaffected….

[Edit]My mistake the line in ScreenManager.cs that loads in it’s font, near line 115, needs updating from “menufont” to “fonts/menufont” thanks to Rives for pointing that one out :-) [/Edit]

Open Game.cs ready for editing from the solution root.
Go to the constructor method and find the lines that set up the screen resolution :-

graphics.PreferredBackBufferWidth = 1067;
graphics.PreferredBackBufferHeight = 600;

And change them both to the following values :-

graphics.PreferredBackBufferWidth = 1280;
graphics.PreferredBackBufferHeight = 720;
Now Compile and run the solution by pressing F5.
Job Done.

Let me know what you liked about this tutorial and what you didn’t…

Bank Holiday XNA Project

This weekend I thought I’d try making a complete game. The quickest way to do this was to use one of the starter kits and tweak it up. I picked the Platformer Starter Kit that comes with XNA 3.0. There’s lots missing from the starter kit this is just a short list of things I want to add in :-

  • A menu system
  • More levels using all the enemies
  • lives
  • better scoring
  • a high score table
  • power ups
  • scrolling levels
  • hazards
  • shooting enemies
  • enemies with different abilities

It’s rather a long list and one I could keep adding to that’s the whole point of the starter kit it’s just to get you started.  I’ve also started writing a how-to guide to accompany the game which has slowed progress a bit, but I’ve started writing XNA code again so that can only be a good thing, more soon ;-)

FloatUnion.approxSqrt By Frank Savage (Development Manager – XNA Tools Team)

I was listening to the GDC09 talks and Mr Savage did his performance talk he mentioned a FloatUnion struct for approximate square root, but I could never find it until now…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
using System.Runtime.InteropServices;
 
[StructLayout(LayoutKind.Explicit)]
public struct FloatUnion
{
	[FieldOffset(0)]
	public float x;
 
	[FieldOffset(0)]
	public int n;
 
	public float approxSqrt()
	{
		n -= 1 << 23;
		n = n >> 1;
		n += 1 << 29;
		return x;
	}
}

This was more for me, but it’s here if you ever need it :-)

Finaly some XNA.

OK I was doing my usual potter around the net tonight when I found “Draw Horizontally Centered Text in XNA” and thought I have to tweak this…

///
/// Take a string and draw it centered horizontally on the screen.
///
public static void DrawCentered(String myText, int ScreenWidth, int yPosition, Color drawColor, SpriteFont spriteFont, SpriteBatch spriteBatch)
{
    // Get the size the spritefont will be drawn on the screen.
    Vector2 textSize = spriteFont.MeasureString(myText);
 
    // Get the position we need to draw the text at for it to be centered.
    int centerXPosition = (ScreenWidth / 2) - ((int)textSize.X / 2);
 
    // Draw the centered text.
    spriteBatch.DrawString(spriteFont, myText, new Vector2(centerXPosition, yPosition), drawColor);
}

I hate passing parameters i don’t need and you should strive to avoid magic numbers so I moved the int ScreenWidth to be a local variable and pulled the required value in from the SpriteBatch with the following line :-

            // pick up the screen width.
            int ScreenWidth = spriteBatch.GraphicsDevice.Viewport.Width;

And as a sort of old school codey kick removed the division from the int centerXPosition calculation and replaced it with some bit shifts to bring us to

            // Get the position we need to draw the text at for it to be centered.
            int centerXPosition = (ScreenWidth &gt;&gt; 1) - ((int)textSize.X &gt;&gt; 1);

so in all my replacement method is :-

        ///
        /// Take a string and draw it centered horizontally on the screen.
        ///
        public static void DrawCentered(String myText, int yPosition, Color drawColor, SpriteFont spriteFont, SpriteBatch spriteBatch)
        {
            // pick up the screen width.
            int ScreenWidth = spriteBatch.GraphicsDevice.Viewport.Width;
 
            // Get the size the spritefont will be drawn on the screen.
            Vector2 textSize = spriteFont.MeasureString(myText);
 
            // Get the position we need to draw the text at for it to be centered.
            int centerXPosition = (ScreenWidth &gt;&gt; 1) - ((int)textSize.X &gt;&gt; 1);
 
            // Draw the centered text.
            spriteBatch.DrawString(spriteFont, myText, new Vector2(centerXPosition, yPosition), drawColor);
        }

Have fun with that, and thanks to Kris Steele for the original article ;-)

But like the murphy’s…

…I’m not bitter, so there’s a new Dodge in the downloads with fixes and no more full screen.

!Warning! XNA RANT !WARNING!

<rant>
Since I published Dodge over a week ago I’ve asked some friends to check it out partly to see if it works, but mostly because like everyone who writes games in XNA I wanted to hear someone say “that was fun.” To get people to try it out I put up a zip file with the .EXE and the graphics and sound files so you just unzip it to a temp directory and run the program simple :-)

I told a bloke in work that I had finished a game and even after I told him how simple it was and that it was my first and generally played it down as much as I could he still asked where he could get it, I was happy. I told him you can download it from my website he nodded I told him you just need DirectX9c, .NET 2.0 and to install the XNA framework and your good to go and he said “I’ve lost all interest already…why do I have to download all that?” and I couldn’t answer him. Later I got an email from a very good friend saying that he would try out dodge I was over the moon because when I showed him the original he said “it’s simple but strangely addictive…” so I was looking forward to hear what he thought of the new one, he replied today and I just wanted to kick him in the nuts, all he could say was…

I’ve tried it out and it works well (apart from one glitch). When you get to final release versions of software is there anyway you can include all the.net stuff etc. in the installer? You can’t really expect people to check down a list of support software to see what they need to install.

…Now if I could write all my software in assembler so that it didn’t need anything else to support them I would but I can’t so I’m not going to try. XNA still seems to be in the realms of “developer only” stuff, not that it’s got bugs in it, but that Microsoft think that only people writing software for XNA will want to see anything written in XNA. Because the people developing in XNA already have everything they need to run XNA there’s no need for the redistributable to actually check that your computer has everything it needs to run.

If I want someone that is not a developer to run what I have written then it’s up to me to build an installer that will do Microsoft’s job for them or I could pay someone for an install packager to make it for me.

This in not something that has been upsetting every developer that works with XNA since day one rather every developer has been happy to only show there work to people that have an interest in XNA and don’t say “well I can’t be bothered to download the support files it’s your job to figure out that I don’t have them and install them for me” quickly followed with “I hate it when installers put loads of crap on my system that I don’t want…”

If I really wanted non tech people to download my stuff I would make an installer that would also wipe there bums for them and install Google Bar, Yahoo Bar & a selection of spyware on their systems but as I have only asked people that apparently know what they are doing I don’t think I need more than I have done.

I know there is the .ccGame thing but you have to have XNA working on your system before you can do that. Microsoft very Kindly tell us exactly which DLL’s are required from DX9c for XNA to work and even tell us the Guid’s for the different versions of XNA but I just want XNA to be supported in the one click publish feature of Visual studio 2005 or even 2008.

I’m not working with XNA because I want to learn how to make installer packages, I want to write Games that other people can play. I can deal with the fact that I need to pay to get it working on an Xbox360 but there needs to be more of an incentive to write for a platform where I know people will download games for a quick play around.

If anyone knows of an install packager that will do this that I don’t have to spend a week figuring out how to make a distributable copy of my game then let me know, I know you won’t but I can ask.
</rant>

WideScreen Joy!

It’s been pointed out to me one more than one occasion that I am a little on the slow side, So imagine my joy when I spotted that Bert was designed to be wide screen.

Stay with me here wide screen is just a non square aspect ratio view, more accurately width longer than height. The screen output for Bert was 320×200 and that gives us 320/200=1.6, so if I keep this aspect ration I can have Bert in it’s original layout and the XNA framework already has a simple scaling system built-in.

At the moment I’m working in 640×400 but with the code I just added I can restrict the screen res to wide screen only and there is no extra code to scale the output to compensate.

“What do I need to play XNA Games?”

I keep forgetting to post this…

A very nice chap known as William Li has written a little utility to detect and install the requirements of XNA, download Requirements Checker/Installer and run it. I’ve run it in Vista and it worked, well it said I had everything I needed, and it correctly identified my graphics card as an ATI-X1950 Pro with Pixel Shader 3.0, It runs as an installer Extracting the exe then running it, I’m almost certain it then deletes the exe when you exit so no mess.