Posts Tagged ‘xna’

How to create a silverlight xna game (using silverarcade)

Monday, March 1st, 2010

Also, useful if you want to convert your existing XNA game to a silverlight app.

The silverarcade libraries help you keep most of you existing XNA code intact. I’ll assume that you are using Visual Studio and have all the proper Silverlight SDK stuff installed (if you haven’t, good luck. It took me way too long to figure that out. Maybe I will post details if I ever recover).

I typed up these instructions after my first conversion and have followed them to get few of my own games converted. So hopefully they will help you, too:

  • In Visual Studio, Choose new project > Silverlight > Silverlight Application. Click NO to the prompt about “Host as a new web site”
  • Open MainPage.xaml and add the following the <UserControl> tag as an atribute:
    
    xmlns:game="clr-namespace:[your project name here]"
    
  • In MainPage.xaml, Add the following to the <Grid> contents:
    
      <Canvas>
        <game:Game2D x:Name="Game1"/>
      </Canvas>
    
  • Right click on project name in Solution Explorer > add > class…
    Call the class Game2D.cs
  • In Game2D.cs, replace the “using…” lines with:
    
    
        using System;
        using System.Collections.Generic;
        using System.Linq;
    
        #if(SILVERLIGHT)
        using SilverArcade.SilverSprite;
        using SilverArcade.SilverSprite.Audio;
        using SilverArcade.SilverSprite.Content;
        using SilverArcade.SilverSprite.GamerServices;
        using SilverArcade.SilverSprite.Graphics;
        using SilverArcade.SilverSprite.Input;
        using SilverArcade.SilverSprite.Media;
        using SilverArcade.SilverSprite.Storage;
        #else
        using Microsoft.Xna.Framework;
        using Microsoft.Xna.Framework.Audio;
        using Microsoft.Xna.Framework.Content;
        using Microsoft.Xna.Framework.GamerServices;
        using Microsoft.Xna.Framework.Graphics;
        using Microsoft.Xna.Framework.Input;
        using Microsoft.Xna.Framework.Media;
        using Microsoft.Xna.Framework.Net;
        using Microsoft.Xna.Framework.Storage;
        #endif
    
  • In Game2D.cs, replace the class declaration with:
    
        public class Game2D : SilverArcade.SilverSprite.Game
    
  • In Game2D.cs, Add global variables:
    
            GraphicsDeviceManager graphics;
            SpriteBatch spriteBatch;
    
  • In Game2D.cs, add constructor:
    
            public Game2D()
            {
                graphics = new GraphicsDeviceManager(this);
                Content.RootDirectory = "Content";
                graphics.PreferredBackBufferWidth = 1000;
                graphics.PreferredBackBufferHeight = 600;
            }
    
  • In Game2D.cs, Add initialize method:
    
            protected override void Initialize()
            {
                // TODO: Add your initialization logic here
    
                base.Initialize();
            }
    
  • In Game2D.cs, Add loadcontent method:
    
            protected override void LoadContent()
            {
                // Create a new SpriteBatch, which can be used to draw textures.
                spriteBatch = new SpriteBatch(GraphicsDevice);
                // TODO: use this.Content to load your game content here
            }
    
  • In Game2D.cs, Add unloadcontent method:
    
            protected override void UnloadContent()
            {
                // TODO: Unload any non ContentManager content here
            }
    
  • In Game2D.cs, Add update method:
    
            protected override void Update(GameTime gameTime)
            {
                // Allows the game to exit
                if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                    this.Exit();
                // TODO: Add your update logic here
                base.Update(gameTime);
            }
    
  • In Game2D.cs, Add draw method:
    
            protected override void Draw(GameTime gameTime)
            {
                GraphicsDevice.Clear(Color.Gray);
                spriteBatch.Begin();
                spriteBatch.End();
                base.Draw(gameTime);
            }
    
  • Add silversprite.dll to project by right clicking on references and add existing item and choose your silversprite.dll (probably put this in debug or release folder or wherever).

Important notes:

When adding content you must click each image file/etc. and go to properties and change Build action to Content.

.wav files are not allowed as silversprite audio, must use mp3 or wav

Don’t need graphics.applyChanges() line when requesting preferred size

Super Transformation wins G4LI Game Design Challenge 2009

Friday, December 18th, 2009


super transformation menu screen shot

Super Transformation won the grand prize ($1000) tonight at the Games for Leaning Institute’s Game Design Challenge 2009. Fellow designers Murphy Stein, Yongming Hong and I are super excited about the honor. It was a fun night seeing the competition and letting people play our game. Almost better than winning the competition was seeing a young boy get so into our game that his father had to pull him away from it. We also got to show our game at the Fall 2009 NYU Computer Science Department Showcase.

Play Super Transformation in your browser right now with Silverlight

Super Transformation (new Silverlight/XNA game)

Sunday, December 13th, 2009


super transformation help screen

Super Transformation is a new in-browser XNA/Silverlight game written by Murphy Stein, Alec Jacobson and Yongming Hong with music by Midicent. The player draws gestures with the mouse to drop transformation portals into a 2D world. The player must use these portals to navigate to each level’s exit door.

We submitted this game to the Games 4 Learning Institute Game Design Challenge 2009.

Super Transformation aims to teach 2D transformations as they appear on the New York State 8th grade Standardized Math Test. Through demonstration and experimentation in the first few levels of Super Transformation, players become aware of the effects of simple horizontal and vertical reflection and clockwise and counter-clockwise rotation. In later levels — as the game play becomes more challenging — the understanding of and familiarity with these transformations builds. Players reinforce their own learning because 2D transformation (aka the learning task) is not only built
into the gameplay, it is the gameplay.

This game uses animations I posted earlier: dude and worm.


Play it now!
Leave suggestions etc. below this post.

New erutnevdAtxeT story arcs added

Wednesday, November 18th, 2009


new erutnevdatxet story arcs

I’ve added some new story arcs to erutnevdAtxeT, the backwards text adventure game I’ve posted recently. Check it out and see if you can get to the beginning of the game. Or try to find all different causality pasts. I’ve added a “refresh” or “reveal the future you just chose feature” (just hold SPACE) to help keep track of your current arc as you play.

Still hoping to convert this to an in browser silverlight app sometime…

erutnevdAtxeT: a backwards text adventure game

Wednesday, November 11th, 2009

erutnevdAtxeT is my new backwards text adventure game for Windows. The idea is that when you “End a new game”, you are presented with the last screen of a text adventure. You’re told what happened to you. You can disagree (“No I didn’t”) or agree and continue backwards through the narrative (“Yeah, but what’d I do before that”). The goal is to reach the beginning screen of the text adventure: “New game…”


Play erutnevdAtxeT

Create buttons menu in xna, quickly and easily

Thursday, November 5th, 2009

In my xna games, I’m often reusing the simple code that allows me to create a menu of buttons rather effortlessly and painlessly. I like this method because I don’t need to maintain heavy classes, just a few global arrays. Here’s a short tutorial showing how I make three-state buttons:

Step 1:

Assuming you have opened/created your XNA game project in Visual Studio, add the following to your global variables just under the public class Game1 : Microsoft.Xna.Framework.Game line:


        // Global variables
        enum BState
        {
            HOVER,
            UP,
            JUST_RELEASED,
            DOWN
        }
        const int NUMBER_OF_BUTTONS = 3, 
            EASY_BUTTON_INDEX = 0,
            MEDIUM_BUTTON_INDEX = 1,
            HARD_BUTTON_INDEX = 2,
            BUTTON_HEIGHT = 40,
            BUTTON_WIDTH = 88;
        Color background_color;
        Color[] button_color = new Color[NUMBER_OF_BUTTONS];
        Rectangle[] button_rectangle = new Rectangle[NUMBER_OF_BUTTONS];
        BState[] button_state = new BState[NUMBER_OF_BUTTONS];
        Texture2D[] button_texture = new Texture2D[NUMBER_OF_BUTTONS];
        double[] button_timer = new double[NUMBER_OF_BUTTONS];
        //mouse pressed and mouse just pressed
        bool mpressed, prev_mpressed = false;
        //mouse location in window
        int mx, my;
        double frame_time;

Step 2:

Add the following to the protected override void Initialize() method:


            // starting x and y locations to stack buttons 
            // vertically in the middle of the screen
            int x = Window.ClientBounds.Width/2 - BUTTON_WIDTH / 2;
            int y = Window.ClientBounds.Height/2 - 
                NUMBER_OF_BUTTONS / 2 * BUTTON_HEIGHT - 
                (NUMBER_OF_BUTTONS%2)*BUTTON_HEIGHT/2;
            for (int i = 0; i < NUMBER_OF_BUTTONS; i++)
            {
                button_state[i] = BState.UP;
                button_color[i] = Color.White;
                button_timer[i] = 0.0;
                button_rectangle[i] = new Rectangle(x, y, BUTTON_WIDTH, BUTTON_HEIGHT);
                y += BUTTON_HEIGHT;
            }
            IsMouseVisible = true;
            background_color = Color.CornflowerBlue;

Step 3:

add new content folder to xna project
add existing images to xna project
Add your button images to your content. Right-click on “Content”. Select “Add > New folder”, call the new folder “images”. Right click on “images” and select “Add > Existing item…” and add your images. Here are the images I’ll be using:
medium buttonhard button

Step 4:

Add the following to the protected override void LoadContent() method:


            button_texture[EASY_BUTTON_INDEX] = 
                Content.Load<Texture2D>(@"images/easy");
            button_texture[MEDIUM_BUTTON_INDEX] =
                Content.Load<Texture2D>(@"images/medium");
            button_texture[HARD_BUTTON_INDEX] = 
                Content.Load<Texture2D>(@"images/hard");

Step 5:

Add the following to the protected override void Draw(GameTime gameTime) method:


            GraphicsDevice.Clear(background_color);

            spriteBatch.Begin();
            for (int i = 0; i < NUMBER_OF_BUTTONS; i++)
                spriteBatch.Draw(button_texture[i], button_rectangle[i], button_color[i]);
            spriteBatch.End();
            base.Draw(gameTime);

You should now be able to run your game and see your (static) button textures draw in the right place.

static xna buttons

Step 6:

Add the following 5 methods to your main game class:


        // wrapper for hit_image_alpha taking Rectangle and Texture
        Boolean hit_image_alpha(Rectangle rect, Texture2D tex, int x, int y)
        {
            return hit_image_alpha(0, 0, tex, tex.Width * (x - rect.X) / 
                rect.Width, tex.Height * (y - rect.Y) / rect.Height);
        }

        // wraps hit_image then determines if hit a transparent part of image 
        Boolean hit_image_alpha(float tx, float ty, Texture2D tex, int x, int y)
        {
            if (hit_image(tx, ty, tex, x, y))
            {
                uint[] data = new uint[tex.Width * tex.Height];
                tex.GetData<uint>(data);
                if ((x - (int)tx) + (y - (int)ty) * 
                    tex.Width < tex.Width * tex.Height)
                {
                    return ((data[
                        (x - (int)tx) + (y - (int)ty) * tex.Width
                        ] &
                                0xFF000000) >> 24) > 20;
                }
            }
            return false;
        }

        // determine if x,y is within rectangle formed by texture located at tx,ty
        Boolean hit_image(float tx, float ty, Texture2D tex, int x, int y)
        {
            return (x >= tx &&
                x <= tx + tex.Width &&
                y >= ty &&
                y <= ty + tex.Height);
        }

        // determine state and color of button
        void update_buttons()
        {
            for (int i = 0; i < NUMBER_OF_BUTTONS; i++)
            {

                if (hit_image_alpha(
                    button_rectangle[i], button_texture[i], mx, my))
                {
                    button_timer[i] = 0.0;
                    if (mpressed)
                    {
                        // mouse is currently down
                        button_state[i] = BState.DOWN;
                        button_color[i] = Color.Blue;
                    }
                    else if (!mpressed && prev_mpressed)
                    {
                        // mouse was just released
                        if (button_state[i] == BState.DOWN)
                        {
                            // button i was just down
                            button_state[i] = BState.JUST_RELEASED;
                        }
                    }
                    else
                    {
                        button_state[i] = BState.HOVER;
                        button_color[i] = Color.LightBlue;
                    }
                }
                else
                {
                    button_state[i] = BState.UP;
                    if (button_timer[i] > 0)
                    {
                        button_timer[i] = button_timer[i] - frame_time;
                    }
                    else
                    {
                        button_color[i] = Color.White;
                    }
                }

                if (button_state[i] == BState.JUST_RELEASED)
                {
                    take_action_on_button(i);
                }
            }
        }


        // Logic for each button click goes here
        void take_action_on_button(int i)
        {
            //take action corresponding to which button was clicked
            switch (i)
            {
                case EASY_BUTTON_INDEX:
                    background_color = Color.Green;
                    break;
                case MEDIUM_BUTTON_INDEX:
                    background_color = Color.Yellow;
                    break;
                case HARD_BUTTON_INDEX:
                    background_color = Color.Red;
                    break;
                default:
                    break;
            }
        }

The purpose of these methods are to determine a true button hover or click: hovering or clicking on the button texture that did not fall on a transparent pixel. Then take an action on buttons just clicked.

Step 7:

Add the following to the protected override void Update(GameTime gameTime) method (be sure it is above the line: base.Update(gameTime);):


            // get elapsed frame time in seconds
            frame_time = gameTime.ElapsedGameTime.Milliseconds / 1000.0;

            // update mouse variables
            MouseState mouse_state = Mouse.GetState();
            mx = mouse_state.X;
            my = mouse_state.Y;
            prev_mpressed = mpressed;
            mpressed = mouse_state.LeftButton == ButtonState.Pressed;

            update_buttons();

You should now have working buttons!

Here's some screen shots:

hover xna buttons


down xna buttons


released xna buttons

Step 8 (optional):

I like to support redundancy with the keyboard. Here's how I support keyboard shortcuts to my buttons:

Add the following to your global variables:


        // for simulating button clicks with keyboard
        KeyboardState keyboard_state, last_keyboard_state;

Add the method to your main class:


        // Logic for each key down event goes here
        void handle_keyboard()
        {
            last_keyboard_state = keyboard_state;
            keyboard_state = Keyboard.GetState();
            Keys[] keymap = (Keys[])keyboard_state.GetPressedKeys();
            foreach (Keys k in keymap)
            {

                char key = k.ToString()[0];
                switch (key)
                {
                    case 'e':
                    case 'E':
                        take_action_on_button(EASY_BUTTON_INDEX);
                        button_color[EASY_BUTTON_INDEX] = Color.Orange;
                        button_timer[EASY_BUTTON_INDEX] = 0.25;
                        break;
                    case 'm':
                    case 'M':
                        take_action_on_button(MEDIUM_BUTTON_INDEX);
                        button_color[MEDIUM_BUTTON_INDEX] = Color.Orange;
                        button_timer[MEDIUM_BUTTON_INDEX] = 0.25;
                        break;
                    case 'h':
                    case 'H':
                        take_action_on_button(HARD_BUTTON_INDEX);
                        button_color[HARD_BUTTON_INDEX] = Color.Orange;
                        button_timer[HARD_BUTTON_INDEX] = 0.25;
                        break;
                    default:
                        break;
                }

            }
        }

Finally add a call to that method in the protected override void Update(GameTime gameTime) method (be sure it is above the line: base.Update(gameTime);):


            handle_keyboard();

Now you should have keyboard redundant buttons. Here's a screen shot:


keyboard xna buttons

Note:
Most xna game projects have button classes and event managers, but I find that since buttons are usually not the focus of my game I'd rather just have four lightweight arrays and essentially two methods called on each update. Using rectangles instead of vectors to define positions for the buttons makes it really simple to stack and pack buttons vertically and horizontally. It's also nice to not really worry about the raw button image's width and height.

Update:
I've put up the finished product as a compiled Windows app.

Update:
I've uploaded a zipped folder of the Visual Studio project. I imagine you might have to change any absolute paths sprinkled in the files...so it might be easier to just copy from the above.

t9 scramble: version 2.0

Wednesday, November 4th, 2009


t9 scramble revised

After a wave of great comments and suggestions on the Games For Learning Institute’s website, I have revised my windows puzzle game, t9 scramble.

Note: Because the new version of t9 scramble scrapes txts dynamically from textsfromlastnight.com, the game is
somewhat explicit.

t9 scramble: windows puzzle game using “Texts from last night”

Wednesday, October 21st, 2009

t9 scramble screen shot

I finished an XNA (windows only) puzzle game. The idea is that you are presented with somebody’s poorly entered t9 txt msg. You job is to decipher the t9 words. Your guess needs to match the t9 digits of the scrambled words.

The phrases used for the scrambled t9 txt msgs are from http://www.textsfromlastnight.com/. Maybe they’ll buy the game? (or sue me…)