Archive for the ‘Codesamples’ Category

Small project to show drawing items with the mouse in XNA

Wednesday, February 3rd, 2010

I saw a post today on the XNA Community Forums asking how to give a player the possibility of adding things to a game, and storing the position of the added images.

I made a Downloadlittle project to show how to do this. Basically it adds a Vector2 to a generic List when the left mouse button is pressed and removes a Vector2 when the right mousebutton is pressed.

Here's a small demo:

using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

namespace SmallXNADrawingGame
{
    /// <summary>
    /// Small class to show how to be able to draw and store objects in XNA.
    ///
    /// Jakob "XNAFAN" Krarup - February 2010
    /// http://www.xnafan.net
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;

        //a list to store the dots in
        List<Vector2> positionOfDots = new List<Vector2>();

        //the dot to use for drawing
        Texture2D textureDot;

        //stores half the size of the dot for centering the texture
        Vector2 halfSizeOfDot;

        //stores the current and previous states of the mouse
        //they are used to compare in Update() to make sure
        //a mouseclick is a new one and not just the button being held
        MouseState currentMouse, oldMouse;

        //font for writing instructions
        SpriteFont defaultFont;

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            //set size of screen
            graphics.PreferredBackBufferHeight = 600;
            graphics.PreferredBackBufferWidth = 800;
            Content.RootDirectory = "Content";

            //make sure to display mouse cursor
            this.IsMouseVisible = true;
        }

        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);
            textureDot = Content.Load<Texture2D>("dot");
            //calculate half the size of a dot and store it
            //for drawing the dot centered on the mouseclick (se Draw())
            halfSizeOfDot = new Vector2(textureDot.Width / 2, textureDot.Height / 2);

            //load the font
            defaultFont = Content.Load<SpriteFont>("DefaultFont");
        }

        protected override void Update(GameTime gameTime)
        {
            //store the current state of the mouse (buttons, position, etc.)
            currentMouse = Mouse.GetState();

            //if the mousebutton was pressed between this and last update...
            //this check makes certain that one click doesn't create multiple dots because the button is held down
            if (currentMouse.LeftButton == ButtonState.Pressed && oldMouse.LeftButton == ButtonState.Released)
            {
                positionOfDots.Add(new Vector2(currentMouse.X, currentMouse.Y));
            }

            //if right mousebutton was pressed
            if (currentMouse.RightButton == ButtonState.Pressed && oldMouse.RightButton == ButtonState.Released)
            {
                //and there are still dots left
                if (positionOfDots.Count > 0)
                {
                    //remove the last
                    //"-1" is because the list i zero-indexed,
                    //so a count of 1 would remove the dot at position 1-1 (zero).
                    positionOfDots.RemoveAt(positionOfDots.Count - 1);
                }
            }

            base.Update(gameTime);

            //store the current state in oldMouse
            //to be able to determine when buttons have JUST been pressed
            //by comparing the two states in an update
            oldMouse = currentMouse;
        }

        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);
            spriteBatch.Begin();

            //write instructions
            spriteBatch.DrawString(defaultFont, "Left mousebutton to draw dot", new Vector2(20, 20), Color.White);
            spriteBatch.DrawString(defaultFont, "Right mousebutton to delete dots", new Vector2(20, 40), Color.White);

            foreach (Vector2 position in positionOfDots)
            {
                //draw the dot centered on the position of the mouse
                //by subtracting the Vector
                //which has half the textures width for X and half the textures height for Y
                //from the position stored.
                spriteBatch.Draw(textureDot, position - halfSizeOfDot, Color.White);

                //draw the dot's position
                spriteBatch.DrawString(defaultFont, position.ToString(), position, Color.White);
            }
            base.Draw(gameTime);
            spriteBatch.End();
        }
    }
}

XNA Pixel Robots library

Wednesday, January 20th, 2010

A while ago I came across Dave Bollinger's PixelRobots and PixelSpaceships.


He has invented a way of generating simple, random robot-like or spaceship-like sprites. He has implemented his code in Java, and you can try out an applet there that will generate many different versions of the millions and millions of possible variations.
I really liked the idea, and thought that it would be very nice to have an XNA implementation for anyone who needed generic spaceships or robots in a game.
So I created an XNA version from his description.

Before you go any further I suggest you go and read about PixelRobots and PixelSpaceships, so you understand what the basic functionality of the API is.
You don't have to understand the internals of my API to use it, as everything is wrapped up in simple methods. But all the helpermethods and variables are available for use if you want to create something more advanced.

It can be as simple as this:

using System.Drawing;
using PixelRobots;

namespace XNAFAN.Net
{
    class Sample
    {
        public void Main()
        {
            //create two bitmaps scaled by 5 with different colors
            Bitmap spaceship = PixelMaskGenerator.GetCompletedRandomSpaceshipImage(5, Color.CornflowerBlue);
            Bitmap robot = PixelMaskGenerator.GetCompletedRandomRobotImage(5, Color.LightGreen);
        }
    }
}

The above code would generate the following two images:

If you'd rather generate SpriteSheets and then use them as Content files instead of creating the spaceships runtime there's also support for that. The spritesheet below was created with the following code:

//create spritesheet
//scaled 3 times, 10 rows and 10 columns
//using spaceships in CornFlowerBlue
Bitmap spritesheet =
    PixelMaskGenerator.GenerateRandomSample(3, 10, PixelMaskType.SpaceShip, Color.CornFlowerBlue);
spritesheet.Save(@"C:\spritesheet.png");
spritesheet.Dispose();

Samples spaceships

And then if you need to convert the Bitmaps to Texture2D runtime, it can be done using Cristopher M. Park's excellent method:

//Converts a Bitmap to a Texture2D
//Code found here:
//http://christophermpark.blogspot.com/2008/10/converting-systemdrawingbitmap-to-xna.html
Texture2D BitmapToTexture2D(Bitmap bmp)
{
    Texture2D tx = null;
    using (MemoryStream s = new MemoryStream())
    {
        bmp.Save(s, System.Drawing.Imaging.ImageFormat.Png);
        s.Seek(0, SeekOrigin.Begin); //must do this, or error is thrown in next line
        tx = Texture2D.FromFile(GraphicsDevice, s);
    }
    return tx;
}

Code
The Download code is available here.
The solution includes three projects:

PixelRobots is the main project is the project which contains all the code needed to generate SpaceShips, Robots and SpinedRobots (robots that are ensured a cohesive spine) for your game.
ConsoleTester is a consoleproject which goes through step-by-step what is done behind the curtains. It saves the generated images to disk and displays them in an HTML page.
TestingPixelRobotsInXNA is a little XNA demo which lets you generate spaceships with the left mousebutton and robots with the right mousebutton.

TestingPixelRobotsInXNA

Screenshot from the running TestingPixelRobotsInXNA project

I made a short video presenting the API in use in TestingPixelRobotsInXNA:

Hope it is of use to somebody - it was fun making :)
If you use it for something I'd love to see for what.

More links
Want your own PixelRobot Tee?
Want the code in PHP for your website?
Want to see the PixelRobot idea used in a windowsgame? (non-XNA)

MouseState ExtensionMethod

Wednesday, January 20th, 2010

Just a little helpermethod to get the mouse's position as a Vector2.

For those of you who still haven't gotten started with extension methods here's a quick writeup'n'sample

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;

namespace XNAFAN
{
    public static class MouseStateExtensionMethods
    {

        /// <summary>
        /// Returns the mouseposition as a Vector2
        /// </summary>
        /// <param name="mouse">The current MouseState</param>
        /// <returns>The mouseposition as a Vector2</returns>
        public static Vector2 GetPosition(this MouseState mouse)
        {
            return new Vector2(mouse.X, mouse.Y);
        }
    }
}

This way you don't have to convert x and y every time along the lines of

MouseState mouseState = Mouse.GetState();
Vector2 position = new Vector2(mouseState.X, mouseState.Y);

Instead you just add a reference to the code with the extensionmethod and this enables you to write:

Vector2 position = mouseState.GetPosition();

Nifty - eh...? :-)

BasicStarter – something to get you up and running with XNA :)

Thursday, December 17th, 2009

Based on the input I received from my talk at Aalborg .Net User Group yesterday, I cleaned & commented my code and created a little XNA 3.1 Windows project called BasicStarter to download.

It is a simple start-out class for use in games for beginning XNA coders.
It has basic keyboard movement in four directions, fullscreen setup, black background.
It is possible to pause the game with "P"
It is possible to exit the game with "Esc"
The project also shows how a class called GameSprite which subclasses DrawableGameComponent is used to store image, position and speed of an object in a game.

basicstarterclassdiagram

Some notable pieces of code for the beginner are:

How to get a direction from multiple keypresses

//create a variable to hold which direction to move
Vector2 movement = Vector2.Zero;

//alter the direction according to the keys pressed:
if (keyState.IsKeyDown(Keys.Down)) { movement += Directions.Down; }
if (keyState.IsKeyDown(Keys.Up)) { movement += Directions.Up; }
if (keyState.IsKeyDown(Keys.Left)) { movement += Directions.Left; }
if (keyState.IsKeyDown(Keys.Right)) { movement += Directions.Right; }

//use the combined movement from the keys
//to update the position of the XNA logo
//we multiply by gamespeed to get a reasonable speed onscreen
xnaLogo.Velocity = movement * gameSpeed;

Hope you like it - and send feedback if you can think of improvements :)