The Making of Pong: A Tutorial Series for XNA and Windows Phone 7; Part 1

If you came here for a tutorial on XNA and game programming, look no further. What better way to learn than to create a simple Pong Game for Windows Phone 7!

The first thing that you are going to do to is to import the assets that we will be using during this tutorial, you can Download them here. Now that you've downloaded the needed tools, let's get our environment set up! This game will be in Landscape mode so place this in your Game1 Constructor:

More...

Tags: , ,
Categories: Windows Phone 7 | WP7 | XNA

Permalink E-mail | Kick it! | DZone it! | del.icio.us Comments (0) Post RSSRSS comment feed

Creating a Simple Car using Box2D XNA for Windows Phone 7

So for this, we are making a 2D very simple car that has wheels and rotates. This example can be expanded on by implementing a 2D camera and creating hills then have the car go over obstacles and react to the environment that you have setup. So stay tuned to the upcoming post where I will show you how to do it.To have this example working make sure you have Windows Phone 7 Beta tools and you click on Page Up to activate the keyboard. Use the Left and Right key to move. Download the Assets Here 

Here is the Video

Here is the code

public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
 
        private Texture2D simpleBackground;
        private Texture2D wheelTexture;
        private Texture2D bodyTexture;
        private World physicsWorld;
 
        private Body FrontWheelBody;
        private Body BackWheelBody;
        private Body boardBody;
 
        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
 
            // Frame rate is 30 fps by default for Windows Phone.
            TargetElapsedTime = TimeSpan.FromTicks(333333);
            graphics.IsFullScreen = true;
            graphics.SupportedOrientations = DisplayOrientation.LandscapeRight;
            graphics.ApplyChanges();
        }
 
        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
          
            physicsWorld = new World(new Vector2(0,10),true);
            base.Initialize();
        }
 
        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);
            simpleBackground = Content.Load<Texture2D>("carbackground");
            wheelTexture = Content.Load<Texture2D>("wheelCopy");
            bodyTexture = Content.Load<Texture2D>("board");
            CreateGround();
            CreateCar();
 
        }
 
        private RevoluteJoint frontWheelJoint;
        private RevoluteJoint backWheelJoint;
        private void CreateCar()
        {
            var bodyDef = new BodyDef {type = BodyType.Dynamic};
 
            var wheelShape = new CircleShape {_radius = wheelTexture.Width/2f*0.01f};
 
            var wheelFixture = new FixtureDef {shape = wheelShape, density =1f,restitution=.2f,friction=.5f};
 
 
            FrontWheelBody = physicsWorld.CreateBody(bodyDef);
            BackWheelBody = physicsWorld.CreateBody(bodyDef);
 
 
            FrontWheelBody.Position = new Vector2(2.9f, 1.41f);
            BackWheelBody.Position = new Vector2(3.9f, 1.41f);
            
            
            FrontWheelBody.CreateFixture(wheelFixture);
            BackWheelBody.CreateFixture(wheelFixture);
 
 
            boardBody = physicsWorld.CreateBody(bodyDef);
            var bodyShape = new PolygonShape();
            bodyShape.SetAsBox(bodyTexture.Width/2f*0.01f, bodyTexture.Height/2f*0.01f);
 
            var bodyFix = new FixtureDef() {friction = 1.0f, shape = bodyShape, density = 1.0f, restitution = .1f};
            boardBody.Position = new Vector2(3.4f, 1.41f);
            boardBody.CreateFixture(bodyFix);
 
            var rj = new RevoluteJointDef();
            rj.Initialize(boardBody, FrontWheelBody, FrontWheelBody.GetWorldCenter());
            rj.enableMotor = true;
            rj.maxMotorTorque = .1f;
           
 
 
            var rj2 = new RevoluteJointDef();
            rj2.Initialize(boardBody, BackWheelBody, BackWheelBody.GetWorldCenter());
            rj2.enableMotor = true;
            rj2.maxMotorTorque = .1f;
          
            frontWheelJoint = (RevoluteJoint) physicsWorld.CreateJoint(rj);
            backWheelJoint = (RevoluteJoint)physicsWorld.CreateJoint(rj2);
 
 
        }
 
        private void CreateGround()
        {
            var bodyDef = new BodyDef();
            bodyDef.type = BodyType.Static;
            
            var bodyShape = new PolygonShape();
 
            var bodyFix = new FixtureDef();
            bodyFix.density = 0.0f;
            bodyFix.friction = 1.0f;
 
 
 
            var topLeft = physicsWorld.CreateBody(bodyDef);
            bodyShape.SetAsEdge(new Vector2(0, 4.0f), new Vector2(2.0f, 4.0f));
            bodyFix.shape = bodyShape;
            topLeft.CreateFixture(bodyFix);
 
            var sideLeft = physicsWorld.CreateBody(bodyDef);
            bodyShape.SetAsEdge(new Vector2(2.0f,4.0f), new Vector2(2.0f,4.8f));
            bodyFix.shape = bodyShape;
            sideLeft.CreateFixture(bodyFix);
            
            var ground = physicsWorld.CreateBody(bodyDef);
            bodyShape.SetAsEdge(new Vector2(2.0f,4.6f), new Vector2(6.0f,4.6f));
            bodyFix.shape = bodyShape;
            ground.CreateFixture(bodyFix);
 
 
            var topRight = physicsWorld.CreateBody(bodyDef);
            bodyShape.SetAsEdge(new Vector2(6.0f,4.0f), new Vector2(6.0f,4.8f));
            bodyFix.shape = bodyShape;
            topRight.CreateFixture(bodyFix);
            
            var sideRight = physicsWorld.CreateBody(bodyDef);
            bodyShape.SetAsEdge(new Vector2(6.0f,4.0f), new Vector2(8.0f,4.0f));
            bodyFix.shape = bodyShape;
            sideRight.CreateFixture(bodyFix);
        }
       
 
        protected override void Update(GameTime gameTime)
        {
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();
            
            physicsWorld.Step(1/30f, 10, 10);
           
            HandleKeyDown();
            base.Update(gameTime);
        }
 
        private KeyboardState prevKeyboardState;
        private void HandleKeyDown()
        {
            var state = Keyboard.GetState();
         
            if (state.IsKeyDown(Keys.Left) && prevKeyboardState.IsKeyDown(Keys.Left))
            {
 
                frontWheelJoint.SetMotorSpeed(-10f);
                backWheelJoint.SetMotorSpeed(-10f);
            }
            if (state.IsKeyDown(Keys.Right) && prevKeyboardState.IsKeyDown(Keys.Right))
            {
 
                frontWheelJoint.SetMotorSpeed(10f);
                backWheelJoint.SetMotorSpeed(10f);
            }
           
            prevKeyboardState = state;
 
        }
 
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);
 
            spriteBatch.Begin();
            spriteBatch.Draw(simpleBackground, Vector2.Zero, Color.White);
            spriteBatch.Draw(wheelTexture, FrontWheelBody.Position/0.01f, null, Color.White, FrontWheelBody.Rotation,
                             new Vector2(wheelTexture.Width/2f, wheelTexture.Height/2f), 1, SpriteEffects.None, 0);
            spriteBatch.Draw(wheelTexture, BackWheelBody.Position / 0.01f, null, Color.White, BackWheelBody.Rotation,
                             new Vector2(wheelTexture.Width / 2f, wheelTexture.Height / 2f), 1, SpriteEffects.None, 0);
 
            spriteBatch.Draw(bodyTexture, boardBody.Position/0.01f, null, Color.White, boardBody.Rotation,
                             new Vector2(bodyTexture.Width/2f, bodyTexture.Height/2f), 1, SpriteEffects.None, 0);
 
            spriteBatch.End();
 
            base.Draw(gameTime);
        }
Tags: , ,
Categories: Windows Phone 7 | WP7 | XNA

Permalink E-mail | Kick it! | DZone it! | del.icio.us Comments (0) Post RSSRSS comment feed

Varying the restitution in Box2D XNA

Here is a quick example of what it means to vary the restitution or bounce in Box2D.XNA.  There are 12 balls and their restitution value starts at 0 and goes to 1.2. There isn’t much else to say, so like always Download The Assets here.

The Video

The Code

public class Game1 : Microsoft.Xna.Framework.Game
   {
       GraphicsDeviceManager graphics;
       SpriteBatch spriteBatch;
 
 
       private Texture2D ballTexture;
       private World physicsWorld;
      
       public Game1()
       {
           graphics = new GraphicsDeviceManager(this);
           Content.RootDirectory = "Content";
 
           // Frame rate is 30 fps by default for Windows Phone.
           TargetElapsedTime = TimeSpan.FromTicks(333333);
           graphics.IsFullScreen = true;
           graphics.SupportedOrientations = DisplayOrientation.LandscapeRight;
           graphics.ApplyChanges();
       }
 
     
       protected override void Initialize()
       {
           // TODO: Add your initialization logic here
           physicsWorld = new World(new Vector2(0, 10), true);
           bodyLists = new List<Body>();
           base.Initialize();
       }
 
      
       protected override void LoadContent()
       {
           // Create a new SpriteBatch, which can be used to draw textures.
           spriteBatch = new SpriteBatch(GraphicsDevice);
           ballTexture = Content.Load<Texture2D>("ballPlayer");
 
           CreateWalls();
           CreateBalls();
       }
 
       private List<Body> bodyLists;
       private void CreateBalls()
       {
           var bodyDef = new BodyDef();
           bodyDef.type = BodyType.Dynamic;
 
           var bodyShape = new CircleShape();
           bodyShape._radius = (ballTexture.Width/2f)*0.01f;
 
           var fixtureDef = new FixtureDef();
           fixtureDef.shape = bodyShape;
           fixtureDef.density = 1.0f;
           for(var i=0;i<12;i++)
           {
               fixtureDef.restitution = i/10f;
               var body = physicsWorld.CreateBody(bodyDef);
               body.Position = new Vector2(.4f*i+1.5f, 1f);
               body.CreateFixture(fixtureDef);
               bodyLists.Add(body);
           }
 
 
       }
 
       private void CreateWalls()
       {
           var bodyDef = new BodyDef();
           bodyDef.type = BodyType.Static;
 
 
           var bodyShape = new PolygonShape();
         
           var bottomBody = physicsWorld.CreateBody(bodyDef);
           bodyShape.SetAsEdge(new Vector2(0, 4.8f), new Vector2(8.0f, 4.8f));
           bottomBody.CreateFixture(bodyShape, 0.0f);
 
 
       }
 
       protected override void UnloadContent()
       {
           // TODO: Unload any non ContentManager content here
       }
 
       /// <summary>
       /// Allows the game to run logic such as updating the world,
       /// checking for collisions, gathering input, and playing audio.
       /// </summary>
       /// <param name="gameTime">Provides a snapshot of timing values.</param>
       protected override void Update(GameTime gameTime)
       {
           // Allows the game to exit
           if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
               this.Exit();
 
 
 
           physicsWorld.Step(1/60f, 10, 10);
           base.Update(gameTime);
       }
 
       /// <summary>
       /// This is called when the game should draw itself.
       /// </summary>
       /// <param name="gameTime">Provides a snapshot of timing values.</param>
       protected override void Draw(GameTime gameTime)
       {
           GraphicsDevice.Clear(Color.CornflowerBlue);
 
           spriteBatch.Begin();
           foreach (var body in bodyLists)
           {
               spriteBatch.Draw(ballTexture, body.Position / .01f, null, Color.White, body.Rotation,
                            new Vector2(ballTexture.Width / 2f, ballTexture.Height / 2f), 1, SpriteEffects.None,
                            0);
           }
           spriteBatch.End();
           base.Draw(gameTime);
       }
   }
Tags: , ,
Categories: Windows Phone 7 | WP7 | XNA

Permalink E-mail | Kick it! | DZone it! | del.icio.us Comments (0) Post RSSRSS comment feed

Collision Detection and Management with Sensors for Box2D XNA and Windows Phone 7

So here is yet another simple concept game that could be fun if implemented using an Accelerometer and better graphics. For now, I am using the Keyboard so you need to have Windows Phone 7 Beta tools. Make sure when you launch the phone you press Page Up on your keyboard to be able to use the keys. Download the Assets Here

Here is the Video

More... Tags: , ,
Categories: Windows Phone 7 | WP7 | XNA

Permalink E-mail | Kick it! | DZone it! | del.icio.us Comments (0) Post RSSRSS comment feed

Totem Prototype using Box2d and XNA for Windows phone 7

I am sure everyone has played this game before or at least a game a with a similar idea. If you have not Click Here To Play It. The object of the game is to destroy the non-black blocks while being careful and not letting the idol fall to the ground. Seems simple enough right? So I created a very simple prototype to get started. When you click on the green blocks they get destroyed and the ball/board react to the environment. Now of course there is a lot of work left to be done, like determining when the ball hits the ground (Changing its Color), creating levels, having different types of material varying the level of friction and bounce ( Wood, Ice, Metal,Rubber).  So over the next couple of weeks, I will be creating a simple Totem clone that you may wish to build on and sell. Stay Tuned!. Download the Assets Used

 

Here is the video. You may notice that there is some pixilation of the assets when they are moving. Don’t worry about it, it is from my end. The video goes thru 4 different scenarios.

 

More...

Tags: , ,
Categories: Windows Phone 7 | WP7 | XNA

Permalink E-mail | Kick it! | DZone it! | del.icio.us Comments (0) Post RSSRSS comment feed

Moving or Dragging Objects Using Box2D and XNA for Windows Phone 7

So for this, all it shows is how to move or drag any objects you want using the Mouse and getting realistic physics simulation with Box2D.XNA. I will update the example soon when I have a Touch monitor or get a phone to use the TouchPanel class.Obviously with the touch you can move more than one box at a time if you have two or more fingers on it, so stay tuned but this is a good example to get you started. Download the Asset here

Here is the Video


More...

Tags: , ,
Categories: Windows Phone 7 | WP7 | XNA

Permalink E-mail | Kick it! | DZone it! | del.icio.us Comments (0) Post RSSRSS comment feed

Box2D and XNA for Windows Phone 7- A Beginner Guide

I will assume for this post that you are a beginner using Box2D. Read the manual if your unfamiliar with what Box2D is. For this tutorial, we will be creating a very simple game. This game will have 4 walls (Top,Right,Bottom,Left borders) and a ball that will bounce around. Each time you click on the screen another ball will be created and bounce and so on. It will give a good foundation of basic Box2D. 

Here is the video:

 

So let’s get started.

More...

Tags: , ,
Categories: Windows Phone 7 | WP7 | XNA

Permalink E-mail | Kick it! | DZone it! | del.icio.us Comments (1) Post RSSRSS comment feed

Rag Doll for Windows Phone 7 using XNA and Box2D

So there isn’t really much to explain in this other than it is a rag doll. I am not an artist so if you can’t see the doll then use your imagination Smile. I wrote this a while ago, you can probably use it to get started on your own Doodle rag doll game. Basically, you hold the head and you can move the body and hit it against the 3 Walls (Right, Bottom,Left) and it will behave like a rag doll is suppose. If I had a phone, I would move it with an Accelerometer and give a more detailed picture but for now the mouse will do. Anyways here is a video of what it looks like.

 

/// <summary>
   /// This is the main type for your game
   /// </summary>
   public class Game1 : Microsoft.Xna.Framework.Game
   {
       GraphicsDeviceManager graphics;
       SpriteBatch spriteBatch;
       private World world;
 
     
       public Game1()
       {
           graphics = new GraphicsDeviceManager(this);
           Content.RootDirectory = "Content";
 
           // Frame rate is 30 fps by default for Windows Phone.
           TargetElapsedTime = TimeSpan.FromTicks(333333);
 
           // Pre-autoscale settings.
           graphics.PreferredBackBufferWidth = 480;
           graphics.PreferredBackBufferHeight = 800;
       }
      
       protected override void Initialize()
       {
           // TODO: Add your initialization logic here
           world = new World(new Vector2(0, 10), true);
           base.Initialize();
       }
 
 
 
       private Texture2D headTexture;
       private Texture2D torsoTexture;
       private Texture2D upperArmTexture;
       private Texture2D lowerArmTexture;
       private Texture2D upperLegTexture;
       private Texture2D lowerLegTexture;
       private float scaleFormat = 100f;
 
 
       private Ground ground;
       private Body headBody;
       private List<Body> ballBodies = new List<Body>();
       /// <summary>
       /// LoadContent will be called once per game and is the place to load
       /// all of your content.
       /// </summary>
       protected override void LoadContent()
       {
           // Create a new SpriteBatch, which can be used to draw textures.
           spriteBatch = new SpriteBatch(GraphicsDevice);
 
           headTexture = Content.Load<Texture2D>("head");
           torsoTexture = Content.Load<Texture2D>("torso");
           upperArmTexture = Content.Load<Texture2D>("upperarm");
           lowerArmTexture = Content.Load<Texture2D>("arm2");
           upperLegTexture = Content.Load<Texture2D>("leg");
           lowerLegTexture = Content.Load<Texture2D>("leg2");
           ground = new Ground(world);
 
           var box = new PolygonShape();
           var bd = new BodyDef();
           var jd = new RevoluteJointDef();
           var fixtureDef = new FixtureDef();
 
 
           // BODIES
           // Set these to dynamic bodies
           bd.type = BodyType.Dynamic;
 
           var circ = new CircleShape();
           circ._radius = 12.5f/scaleFormat;
           fixtureDef.shape = circ;
           fixtureDef.density = 1.0f;
           fixtureDef.friction = 0.4f;
           fixtureDef.restitution = 0.3f;
           bd.position = new Vector2(100/scaleFormat, 105/scaleFormat);
 
           headBody = world.CreateBody(bd);
           headBody.CreateFixture(fixtureDef);
           headBody.SetUserData(headTexture);
 
 
 
           ballBodies.Add(headBody);
 
 
 
           //Torso1
           box = new PolygonShape();
           box.SetAsBox(15/scaleFormat, 10/scaleFormat);
           fixtureDef.shape = box;
           fixtureDef.density = 1.0f;
           fixtureDef.friction = 0.4f;
           fixtureDef.restitution = 0.1f;
           bd.position = new Vector2(100/scaleFormat, 128/scaleFormat);
           var torso1 = world.CreateBody(bd);
           torso1.CreateFixture(fixtureDef);
           torso1.SetUserData(torsoTexture);
 
           ballBodies.Add(torso1);
 
 
           //Torso2
           box = new PolygonShape();
           box.SetAsBox(15/scaleFormat, 10/scaleFormat);
           fixtureDef.shape = box;
           bd.position = new Vector2(100/scaleFormat, 143/scaleFormat);
           var torso2 = world.CreateBody(bd);
           torso2.CreateFixture(fixtureDef);
           torso2.SetUserData(torsoTexture);
 
 
 
           ballBodies.Add(torso2);
           //torso3
 
           box = new PolygonShape();
           box.SetAsBox(15/scaleFormat, 10/scaleFormat);
           fixtureDef.shape = box;
           bd.position = new Vector2(100/scaleFormat, 158/scaleFormat);
           var torso3 = world.CreateBody(bd);
           torso3.CreateFixture(fixtureDef);
           torso3.SetUserData(torsoTexture);
 
           ballBodies.Add(torso3);
           //upperarm
           fixtureDef.density = 1.0f;
           fixtureDef.friction = 0.4f;
           fixtureDef.restitution = 0.1f;
 
 
           box = new PolygonShape();
           box.SetAsBox(18/scaleFormat, 6.5f/scaleFormat);
           fixtureDef.shape = box;
           bd.position = new Vector2(70/scaleFormat, 120/scaleFormat);
           var upperArmL = world.CreateBody(bd);
           upperArmL.CreateFixture(fixtureDef);
           upperArmL.SetUserData(upperArmTexture);
 
 
           ballBodies.Add(upperArmL);
 
           //r
           box = new PolygonShape();
           box.SetAsBox(18/scaleFormat, 6.5f/scaleFormat);
           fixtureDef.shape = box;
           bd.position = new Vector2(130/scaleFormat, 120/scaleFormat);
           var upperArmR = world.CreateBody(bd);
           upperArmR.CreateFixture(fixtureDef);
           upperArmR.SetUserData(upperArmTexture);
 
           ballBodies.Add(upperArmR);
 
           // LowerArm
           fixtureDef.density = 1.0f;
           fixtureDef.friction = 0.4f;
           fixtureDef.restitution = 0.1f;
 
 
 
           //l
           box = new PolygonShape();
           box.SetAsBox(17/scaleFormat, 6f/scaleFormat);
           fixtureDef.shape = box;
           bd.position = new Vector2(43/scaleFormat, 120/scaleFormat);
           var lowerArmL = world.CreateBody(bd);
           lowerArmL.CreateFixture(fixtureDef);
           lowerArmL.SetUserData(lowerArmTexture);
 
           ballBodies.Add(lowerArmL);
           //r
           box = new PolygonShape();
           box.SetAsBox(17/scaleFormat, 6f/scaleFormat);
           fixtureDef.shape = box;
           bd.position = new Vector2(157/scaleFormat, 120/scaleFormat);
           var lowerArmR = world.CreateBody(bd);
           lowerArmR.CreateFixture(fixtureDef);
           lowerArmR.SetUserData(lowerArmTexture);
           ballBodies.Add(lowerArmR);
 
 
 
 
 
 
           // UpperLeg
           fixtureDef.density = 1.0f;
           fixtureDef.friction = 0.4f;
           fixtureDef.restitution = 0.1f;
 
 
 
           // L
 
           box = new PolygonShape();
           box.SetAsBox(7.5f/scaleFormat, 22f/scaleFormat);
           fixtureDef.shape = box;
           bd.position = new Vector2(92/scaleFormat, 185/scaleFormat);
           var upperLegL = world.CreateBody(bd);
           upperLegL.CreateFixture(fixtureDef);
           upperLegL.SetUserData(upperLegTexture);
           ballBodies.Add(upperLegL);
 
           box = new PolygonShape();
           box.SetAsBox(7.5f/scaleFormat, 22f/scaleFormat);
           fixtureDef.shape = box;
           bd.position = new Vector2(108/scaleFormat, 185/scaleFormat);
           var upperLegR = world.CreateBody(bd);
           upperLegR.CreateFixture(fixtureDef);
           upperLegR.SetUserData(upperLegTexture);
           ballBodies.Add(upperLegR);
 
 
 
 
           // LowerLeg
           fixtureDef.density = 1.0f;
           fixtureDef.friction = 0.4f;
           fixtureDef.restitution = 0.1f;
 
 
 
 
           box = new PolygonShape();
           box.SetAsBox(6f/scaleFormat, 20/scaleFormat);
           fixtureDef.shape = box;
           bd.position = new Vector2(92/scaleFormat, 220/scaleFormat);
           var lowerLegL = world.CreateBody(bd);
           lowerLegL.CreateFixture(fixtureDef);
           lowerLegL.SetUserData(lowerLegTexture);
           ballBodies.Add(lowerLegL);
 
           box = new PolygonShape();
           box.SetAsBox(6f/scaleFormat, 20/scaleFormat);
           fixtureDef.shape = box;
           bd.position = new Vector2(108/scaleFormat, 220/scaleFormat);
           var lowerLegR = world.CreateBody(bd);
           lowerLegR.CreateFixture(fixtureDef);
           lowerLegR.SetUserData(lowerLegTexture);
           ballBodies.Add(lowerLegR);
 
 
 
 
 
 
 
 
 
 
           // JOINTS
           jd.enableLimit = true;
 
           // Head to shoulders
           jd.lowerAngle = (float) (-40f/(180/Math.PI));
           jd.upperAngle = (float) (40/(180/Math.PI));
           jd.Initialize(torso1, headBody, new Vector2(100/scaleFormat, (100 + 15)/scaleFormat));
           world.CreateJoint(jd);
 
           // Upper arm to shoulders
           // L
           jd.lowerAngle = (float) (-85/(180/Math.PI));
           jd.upperAngle = (float) (130/(180/Math.PI));
           jd.Initialize(torso1, upperArmL, new Vector2((74)/scaleFormat, (120)/scaleFormat));
           world.CreateJoint(jd);
           // R
           jd.lowerAngle = (float) (-130/(180/Math.PI));
           jd.upperAngle = (float) (85/(180/Math.PI));
           jd.Initialize(torso1, upperArmR, new Vector2((118)/scaleFormat, (120)/scaleFormat));
           world.CreateJoint(jd);
 
           // Lower arm to upper arm
           // L
           jd.lowerAngle = (float) (-130/(180/Math.PI));
           jd.upperAngle = (float) (10/(180/Math.PI));
           jd.Initialize(upperArmL, lowerArmL, new Vector2((55)/scaleFormat, (120)/scaleFormat));
           world.CreateJoint(jd);
           // R
           jd.lowerAngle = (float) (-10/(180/Math.PI));
           jd.upperAngle = (float) (130/(180/Math.PI));
           jd.Initialize(upperArmR, lowerArmR, new Vector2((145)/scaleFormat, (120)/scaleFormat));
           world.CreateJoint(jd);
 
           // Shoulders/stomach
           jd.lowerAngle = (float) (-15/(180/Math.PI));
           jd.upperAngle = (float) (15/(180/Math.PI));
           jd.Initialize(torso1, torso2, new Vector2(100/scaleFormat, (135)/scaleFormat));
           world.CreateJoint(jd);
           // Stomach/hips
           jd.Initialize(torso2, torso3, new Vector2(100/scaleFormat, (150)/scaleFormat));
           world.CreateJoint(jd);
 
           // Torso to upper leg
           // L
           jd.lowerAngle = (float) (-25/(180/Math.PI));
           jd.upperAngle = (float) (45/(180/Math.PI));
           jd.Initialize(torso3, upperLegL, new Vector2((92)/scaleFormat, (172)/scaleFormat));
           world.CreateJoint(jd);
           // R
           jd.lowerAngle = (float) (-45/(180/Math.PI));
           jd.upperAngle = (float) (25/(180/Math.PI));
           jd.Initialize(torso3, upperLegR, new Vector2((108)/scaleFormat, (172)/scaleFormat));
           world.CreateJoint(jd);
 
           // Upper leg to lower leg
           // L
           jd.lowerAngle = (float) (-25/(180/Math.PI));
           jd.upperAngle = (float) (115/(180/Math.PI));
           jd.Initialize(upperLegL, lowerLegL, new Vector2((92)/scaleFormat, (205)/scaleFormat));
           world.CreateJoint(jd);
           // R
           jd.lowerAngle = (float) (-115/(180/Math.PI));
           jd.upperAngle = (float) (25/(180/Math.PI));
           jd.Initialize(upperLegR, lowerLegR, new Vector2((108)/scaleFormat, (205)/scaleFormat));
           world.CreateJoint(jd);
 
 
 
 
 
 
 
 
 
 
 
       }
 
       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
           world.Step((float)1 / 60, 10, 10);
 
           HandleClick();
           base.Update(gameTime);
       }
 
       private MouseState prevState = Mouse.GetState();
       private MouseJoint joint = null;
       private void HandleClick()
       {
           MouseState state = Mouse.GetState();
           var mouseVector = new Vector2(state.X, state.Y) * 0.01f;
 
           if (prevState.LeftButton == ButtonState.Pressed && state.LeftButton == ButtonState.Pressed)
           {
 
               if(joint==null)
               {
                   var mouseDef = new MouseJointDef();
                   mouseDef.bodyA = ground.GroundBody();
                   mouseDef.bodyB = headBody;
                   mouseDef.maxForce = 1000;
                   mouseDef.collideConnected = true;
                   mouseDef.target = mouseVector;
                   joint = world.CreateJoint(mouseDef) as MouseJoint;
               }
               else
               {
                   joint.SetTarget(mouseVector);
               }
 
           }
 
           if (state.LeftButton == ButtonState.Released && prevState.LeftButton == ButtonState.Pressed)
           {
 
               if(joint!=null)
               {
                   world.DestroyJoint(joint);
                   joint = null;
               }
 
           }
 
           prevState = state;
       }
 
 
      
       protected override void Draw(GameTime gameTime)
       {
           GraphicsDevice.Clear(Color.CornflowerBlue);
           spriteBatch.Begin();
           // TODO: Add your drawing code here
           foreach (var body in ballBodies)
           {
               var myTexture = body.GetUserData() as Texture2D;
               spriteBatch.Draw(myTexture as Texture2D, body.Position * scaleFormat, null, Color.Blue, body.Rotation,
                                new Vector2(myTexture.Width/2f, myTexture.Height/2f), 1, SpriteEffects.None, 0);
           }
           spriteBatch.End();
           base.Draw(gameTime);
       }
   public class Ground
   {
       private Body _groundBody;
       public Ground(World world)
       {
           var bottomGrounDef = new BodyDef();
           bottomGrounDef.type = BodyType.Static;
 
           var grounBottomShape = new PolygonShape();
           grounBottomShape.SetAsEdge(new Vector2(0, 8), new Vector2(4.8f, 8.0f));
 
           _groundBody = world.CreateBody(bottomGrounDef);
           _groundBody.CreateFixture(grounBottomShape, 0.0f);
 
 
 
           var leftGrounDef = new BodyDef();
           leftGrounDef.type = BodyType.Static;
 
           var leftGrounShape = new PolygonShape();
           leftGrounShape.SetAsEdge(new Vector2(0, -8), new Vector2(0f, 8.0f));
 
           var leftBody = world.CreateBody(leftGrounDef);
           leftBody.CreateFixture(leftGrounShape, 0.0f);
 
 
 
 
           var rightGrounDef = new BodyDef();
           rightGrounDef.type = BodyType.Static;
 
           var rightGrounShape = new PolygonShape();
           rightGrounShape.SetAsEdge(new Vector2(4.8f, -8), new Vector2(4.8f, 8.0f));
 
           var rightBody = world.CreateBody(rightGrounDef);
           rightBody.CreateFixture(rightGrounShape, 0.0f);
       }
        public Body GroundBody()
       {
           return _groundBody;
       }
   }

The Assets used.

Tags: , ,
Categories: Windows Phone 7 | WP7 | XNA

Permalink E-mail | Kick it! | DZone it! | del.icio.us Comments (0) Post RSSRSS comment feed

Box2D XNA and Windows Phone 7- A platformer

I will be showing you how to get a head start on creating a platform game with real physics using Box2D.

A disclaimer is needed on box2D,  this took me a while to figure out so let’s get it out of the way. 

“Box2D is tuned for meters-kilograms-seconds. Your moving objects should be between 0.1 - 10 meters. Do not use pixels as units! You will get a jittery simulation.”

So what does that mean? Basically whatever asset you import you have to use some type of scaling value. For Example : Suppose you have a character that is 20X80 pixels. This would need to be scaled down. Let’s use a scaling factor of .01, this means that your object would be .2x.8 in box2D (Don’t worry if you don’t get it right now, when you see the code it will sink in. Just know that you shouldn’t use pixels in Box2D).  Before you move on Familiarize yourself with what Box2D is by reading http://www.box2d.org/manual.html

 

Here is a Video of what you will be doing

 

 

Here is the code, commented so I don’t need to explain in writing what I did and bore you.

 

 
    public class Game1 : Game
    {
        readonly GraphicsDeviceManager _graphics;
        SpriteBatch _spriteBatch;
 
        
        /**
         * OUR Textures
         */
        private Texture2D _ballTexture;
        private Texture2D _boxTexture;
        private Texture2D _floorTexture;
        private Texture2D _playerTexture;
        //list of stacked boxes that we can throw a box at.
        private List<Body> _stackableBodies;
      
 
        /**
         * Two Textures will need their own Box2D Body
         */
        private Body _ballBody;
        private Body _groundBody;
        private Body _playerBody;
 
        private RenderTarget2D _renderTarget;
        /**
         * Create a world Variable, this is what is responsible for all our physics
         */
        private World _world;
 
        /**
         * THis is used to launch our box after 5 seconds
         */
        private const float GameFrame = 5000;
        private float _gameElapsed;
        private bool _gameStarted;
 
        public Game1()
        {
            _graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
 
            // Frame rate is 30 fps by default for Windows Phone.
            TargetElapsedTime = TimeSpan.FromTicks(333333);
 
            // Pre-autoscale settings.
            _graphics.PreferredBackBufferWidth = 480;
            _graphics.PreferredBackBufferHeight = 800;
            _graphics.IsFullScreen = true;
        }
 
       
        protected override void Initialize()
        {
            
            _stackableBodies = new List<Body>();
          //create gravity in the Y axis.
            _world = new World(new Vector2(0,10), true);
            //don't worry about this, since XNA April CTP doesnt support Landscape, this is a fix for now.
            _renderTarget = new RenderTarget2D(GraphicsDevice, 800, 480, false,
                        GraphicsDevice.PresentationParameters.BackBufferFormat, GraphicsDevice.PresentationParameters.DepthStencilFormat);
 
            base.Initialize();
        }
 
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            _spriteBatch = new SpriteBatch(GraphicsDevice);
 
            //load the content
            _ballTexture = Content.Load<Texture2D>("ball");
            _boxTexture = Content.Load<Texture2D>("box");
            _floorTexture = Content.Load<Texture2D>("ground");
            _playerTexture = Content.Load<Texture2D>("player");
            
            /**
             * So for Every Content, you must define a BodyDef, I also like to define a
             * Shape Definition, and a Fixture Definition
             * read more here http://www.box2d.org/manual.html
             */
 
 
            /*
             * Lets start by creating the ground first, The ground is made up
             * of two parts. The floor and the side Rectangle
             * The floor is at Y=400, and the right rectangle has a Width of 200x100
             */
 
            var groundDef = new BodyDef {type = BodyType.Static};
            var groundShape = new PolygonShape();
            //since we are doing  Landscape for this tutorial, i am going to set
            //the ground at about 400 pixels down.
            groundShape.SetAsEdge(new Vector2(0, 4.0f), new Vector2(8.0f, 4.0f));//notice the scaling down
            //since the phone is 480*800 or in landscape 800*480, and we are using a scale of 0.01, then it will be
            //8*4.8.
 
            _groundBody = _world.CreateBody(groundDef);
            _groundBody.CreateFixture(groundShape, 0.0f);//give ground density of 0
 
 
            //left side edge
            //reuse groundshape
            groundShape.SetAsEdge(new Vector2(0, 0), new Vector2(0, 4.8f));
            var leftBody = _world.CreateBody(groundDef);
            leftBody.CreateFixture(groundShape, 0.0f);
 
 
            //create the right side platformer
            var platformDef = new BodyDef {type = BodyType.Static};
 
            var platformShape = new PolygonShape();
            //platform is 200x100, and we are scaling by 0.01 it will be 2x1 and box2d takes half
            //the height and width so it will be 1 for width .5 for height
            platformShape.SetAsBox(1f, .5f);
 
            var platformBody = _world.CreateBody(platformDef);
            platformBody.CreateFixture(platformShape, 0.0f);
            //set the postion far right, box2D postions are relative to the center 
            platformBody.Position = new Vector2(7f, 3.5f);//on top of our ground
 
 
            //create a ball
            var circleDef = new BodyDef {type = BodyType.Dynamic};
 
            var circleShape = new CircleShape {_radius = 0.2f};
            //our ball is 40x40 so radius is 20 with scale conversion it will be .2
 
            _ballBody = _world.CreateBody(circleDef);
 
            _ballBody.Position = new Vector2(3, 2);//just some random postion
 
            var ballFixture = new FixtureDef
                                  {
                                      shape = circleShape,
                                      density = 1.0f,
                                      restitution = 0.3f,
                                      friction = 0.3f
                                  };
 
            _ballBody.CreateFixture(ballFixture);
            
           
            var boxDef = new BodyDef {type = BodyType.Dynamic};
            //box is 25x25
            var boxShape = new PolygonShape();
            boxShape.SetAsBox(.125f, .125f);
            var boxFixture = new FixtureDef {shape = boxShape, restitution = 0.1f, density = 1.5f};
            //create a stack of boxes
            for(var i=1;i<4;i++)
            {
                for(var j=1;j<11;j++)
                {
                    var body = _world.CreateBody(boxDef);
                    body.CreateFixture(boxFixture);
                    body.Position = new Vector2((5+(.125f*i)),0.25f*j);
                    _stackableBodies.Add(body);
                }
            }
 
            
            //create the box that will be thrown at the boxes
            var playerDef = new BodyDef {type = BodyType.Dynamic};
 
            var playerShape = new PolygonShape();
            playerShape.SetAsBox(.5f, .5f);
 
            _playerBody = _world.CreateBody(playerDef);
 
            var playerFix = new FixtureDef {shape = playerShape, density = 1.0f};
 
            _playerBody.CreateFixture(playerFix);
            _playerBody.Position = new Vector2(2, 1);
 
        }
        
        protected override void Update(GameTime gameTime)
        {
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                Exit();
          
            _world.Step(1/60f, 10, 10);//this is what gets the physics going
            _gameElapsed += (float)gameTime.ElapsedGameTime.TotalMilliseconds;
            //Why am i doing this? Well I would create a mouseJoint and have the mouse work
            //but it is kinda screwy, so this shows you what you can do. 
            if(_gameElapsed > GameFrame && !_gameStarted)
            {
                _playerBody.ApplyLinearImpulse(new Vector2(50, 0), _playerBody.GetWorldCenter());
                _gameStarted = true;
            }
 
 
            base.Update(gameTime);
        }
 
      protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.SetRenderTarget(_renderTarget);
            _graphics.GraphicsDevice.Clear(Color.White);
 
            _spriteBatch.Begin();
 
 
            _spriteBatch.Draw(_playerTexture, _playerBody.Position / 0.01f, null, Color.Orange, _playerBody.Rotation,
                             new Vector2(50f, 50f),
                             1, SpriteEffects.None, 0);
            //notice we have to divide by 0.01 which is our scale factor to get the position back
            //to pixels. Also BOX2D does everything relative to the center so the origin will be
            //ball center which is 20,20. Now if you want to do this the right way probably have a constant so you
          //dont have to divide by 0.01. 
            _spriteBatch.Draw(_ballTexture, _ballBody.Position/0.01f, null, Color.Green, _ballBody.Rotation,
                             new Vector2(20, 20), 1, SpriteEffects.None, 0);
 
 
            //Draw those red boxes.
            foreach (var stackableBody in _stackableBodies)
            {
                _spriteBatch.Draw(_boxTexture, stackableBody.Position/0.01f, null, Color.Red, stackableBody.Rotation,
                                 new Vector2(12.5f, 12.5f), 1, SpriteEffects.None, 0);
            }
            
            _spriteBatch.Draw(_floorTexture,Vector2.Zero, Color.White);
           
            _spriteBatch.End();
            
            base.Draw(gameTime);
            
          // unset the rendertarget
            GraphicsDevice.SetRenderTarget(null);
 
            // clear the backbuffer
            GraphicsDevice.Clear(Color.Black);
 
            // draw the render target to the screen, rotated into portrait 
            // mode
            _spriteBatch.Begin();
            _spriteBatch.Draw(
                _renderTarget,
                new Vector2(240, 400),
                null,
                Color.White,
                MathHelper.PiOver2,
                new Vector2(400, 240),1f,
                SpriteEffects.None,
                0);
            _spriteBatch.End();
        }
    }


The assets for download

Tags: , ,
Categories: Windows Phone 7 | WP7 | XNA

Permalink E-mail | Kick it! | DZone it! | del.icio.us Comments (0) Post RSSRSS comment feed