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.

 

Here is the code, There are no comments since It builds on the other posts, so If you don’t understand anything look at the other posts and read the Box2D manual.

public class Game1 :Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
 
 
        private Texture2D ballTexture;
        private Texture2D groundTexture;
        private Texture2D boxTexture;
        private Texture2D boardTexture;
 
 
        private World world;
        private Body BallBody;
        private Body BoardBody;
 
 
        private List<Body> boxBodies;
        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
 
 
            Application.Current.Host.Settings.EnableFrameRateCounter = true;
            // 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()
        {
            
            world = new World(new Vector2(0, 10), false);
            boxBodies = 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>("ball");
            boardTexture = Content.Load<Texture2D>("board");
            boxTexture = Content.Load<Texture2D>("box");
            groundTexture = Content.Load<Texture2D>("ground");
 
 
            CreateGroundAndWalls();
            CreateBallBody();
            CreateBoardBody();
            CreateBoxBodies();
 
 
 
 
        }
 
        private const float ScaleFactor = 0.01f;
        private void CreateBallBody()
        {
            var bodyDef = new BodyDef();
            bodyDef.type = BodyType.Dynamic;
 
 
            var circleShape = new CircleShape();
            circleShape._radius = .3f;
 
 
            var ballFixture = new FixtureDef();
            ballFixture.shape = circleShape;
            ballFixture.restitution = .5f;
            ballFixture.density = 1.0f;
            BallBody = world.CreateBody(bodyDef);
            
            BallBody.CreateFixture(ballFixture);
 
            BallBody.Position = new Vector2(2.5f, .5f);
 
 
 
        }
        private void CreateBoardBody()
        {
            var bodyDef = new BodyDef {type = BodyType.Dynamic};
 
 
            var boardShape = new PolygonShape();
            boardShape.SetAsBox(((boardTexture.Width/2f)*ScaleFactor), ((boardTexture.Height/2f)*ScaleFactor));
 
 
            var boardFixture = new FixtureDef {shape = boardShape, density=1.0f, friction = 0.1f};
 
            BoardBody = world.CreateBody(bodyDef);
            BoardBody.CreateFixture(boardFixture);
 
            BoardBody.Position = new Vector2(2.5f, 1.0f);
            
 
        }
        private void CreateBoxBodies()
        {
            var bodyDef = new BodyDef {type = BodyType.Dynamic};
 
            var bodyShape = new PolygonShape();
            bodyShape.SetAsBox(.25f,.25f);
 
            var boxFixture = new FixtureDef {restitution = .4f, density=1.0f, shape = bodyShape};
 
            for(var i=1;i<6;i++)
            {
                var boxBody = world.CreateBody(bodyDef);
                boxBody.CreateFixture(boxFixture);
                boxBody.Position = new Vector2(1.5f, 7.0f-i);
                boxBody.SetUserData("Box");
                boxBodies.Add(boxBody);
 
            }
 
            for(var i=1;i<6;i++)
            {
                var boxBody = world.CreateBody(bodyDef);
                boxBody.CreateFixture(boxFixture);
                boxBody.Position = new Vector2(3.5f, 7.0f-i);
                boxBody.SetUserData("Box");
                boxBodies.Add(boxBody);
            }
 
 
        }
 
 
        private void CreateGroundAndWalls()
        {
            var grounDef = new BodyDef {type = BodyType.Static};
 
            var groundFix = new FixtureDef {restitution = 0.0f, density = 0.0f};
 
 
            var groundShape = new PolygonShape();
 
            groundShape.SetAsEdge(new Vector2(0, 7.5f), new Vector2(4.8f, 7.5f));
            var groundBody = world.CreateBody(grounDef);
            groundFix.shape = groundShape;
            groundBody.CreateFixture(groundFix);
 
 
 
 
            groundShape.SetAsEdge(new Vector2(0, 0), new Vector2(0f, 8.0f));
            var leftBody = world.CreateBody(grounDef);
            groundFix.shape = groundShape;
            leftBody.CreateFixture(groundFix);
 
 
 
 
            groundShape.SetAsEdge(new Vector2(4.8f, 0), new Vector2(4.8f, 8.0f));
            var rightBody = world.CreateBody(grounDef);
            groundFix.shape = groundShape;
            rightBody.CreateFixture(groundFix);
 
 
            groundShape.SetAsEdge(new Vector2(0, 0), new Vector2(4.8f, 0));
            var topBody = world.CreateBody(grounDef);
            groundFix.shape = groundShape;
            topBody.CreateFixture(groundFix);
 
 
        }
        
       
        protected override void Update(GameTime gameTime)
        {
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();
 
 
            world.Step(1/60f, 10, 10);
            HandleClick(); 
 
            base.Update(gameTime);
        }
 
 
        private MouseState prevState;
        private void HandleClick()
        {
            var currentState = Mouse.GetState();
 
           
            if(prevState.LeftButton==ButtonState.Released && currentState.LeftButton==ButtonState.Pressed)
            {
                //lets find the closest box
                Fixture choosenFixture = null;
                var mousePosition = new Vector2(currentState.X, currentState.Y)*ScaleFactor;
 
                var aabb = new AABB();
                aabb.upperBound = new Vector2(mousePosition.X+.01f, mousePosition.Y+.01f);
                aabb.lowerBound = new Vector2(mousePosition.X-.01f, mousePosition.Y-.01f);
 
 
                world.QueryAABB(found =>
                {
                    if (found.GetBody().GetUserData() != null)
                    {
                        if(found.TestPoint(mousePosition))
                        choosenFixture = found;
                        return true;
                    }
                    return false;
 
                }, ref aabb);
              
                if(choosenFixture!=null)
                {
                        var bodyToKill = choosenFixture.GetBody();
                        bodyToKill.SetAwake(true);
                        world.DestroyBody(bodyToKill);
                        boxBodies.Remove(bodyToKill);
                   
                }
 
            }
 
            prevState = currentState;
        }
 
       
        /// <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 boxBody in boxBodies)
            {
                spriteBatch.Draw(boxTexture, boxBody.Position / ScaleFactor, null, Color.YellowGreen, boxBody.Rotation, new Vector2(boxTexture.Width / 2f, boxTexture.Height / 2f), 1, SpriteEffects.None, 0);
            }
            spriteBatch.Draw(boardTexture, BoardBody.Position/ScaleFactor, null, Color.Blue, BoardBody.Rotation,
                            new Vector2(boardTexture.Width / 2f, boardTexture.Height / 2f), 1, SpriteEffects.None, 0);
            spriteBatch.Draw(ballTexture, BallBody.Position/ScaleFactor, null, Color.Red, BallBody.Rotation,
                             new Vector2(ballTexture.Width/2f, ballTexture.Height/2f), 1, SpriteEffects.None, 0);
            spriteBatch.Draw(groundTexture, new Vector2(0, 750), Color.White);
 
            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

Comments

Add comment




  Country flag

biuquote
  • Comment
  • Preview
Loading