Help My Rectangle does not seems "Rectangular"

Topics: Developer Forum
Oct 27, 2010 at 8:02 PM
Edited Oct 27, 2010 at 8:04 PM

I'm a newb in the world of FPE, and this is my first time testing it.

I found a beginner's problem. When I applied a rectangle body to the world, making it static as a platform, it seemed that the object slipping from its edge shows that the platform was not really a rectangle. It just slipped off, not from the platform's edge.

It may be confuse a bit, so I recorded my screen here:  http://www.youtube.com/watch?v=NhYv7l80fKU

I'd like to ask you what is the possible causes of this kind of problem, so that I could check and correct it. 

Thanks Anyway, 

Dome

 

 

using System;
using System.Collections.Generic;
using System.Linq;
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 FarseerPhysics.Factories;
using FarseerPhysics.Dynamics;

namespace Imaginia
{
    //Main class of the game
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        private GraphicsDeviceManager _graphics;
        private SpriteBatch _spriteBatch;

        //physics engine part
        private World _physicsWorld;
        private Fixture _objectFixture, _platformFixture;
            /* convert pixels to meter in farseer physics engine */
        private const float pixelToMeter = 100f;

        //testing textures
        private Texture2D _object, _platform;

        private Vector2 _objectPos, _platformPos;

        public Game1()
        {
            _graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }

        protected override void Initialize()
        {
            //setting screen resolution
            _graphics.PreferredBackBufferWidth = 1024;
            _graphics.PreferredBackBufferHeight = 600;
            _graphics.ApplyChanges();

            //initialize physics world with gravity <0,9.8>
            _physicsWorld = new World(new Vector2(0, 9.8f));


            base.Initialize();
        }

        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            _spriteBatch = new SpriteBatch(GraphicsDevice);

            //load textures
            _object = this.Content.Load<Texture2D>(@"domeavatar");

            _objectFixture = FixtureFactory.CreateRectangle(_physicsWorld, ConvertUnitToPhysicsWorld(_object.Width),
                ConvertUnitToPhysicsWorld(_object.Height), 1f);
            _objectFixture.Body.Position = ConvertVector2ToPhysicsWorld(new Vector2(300f,0));
            _objectFixture.Friction = 0.5f;
            _objectFixture.Body.Mass = 10;
            _objectFixture.Body.BodyType = BodyType.Dynamic;

            _platformFixture = FixtureFactory.CreateRectangle(_physicsWorld, ConvertUnitToPhysicsWorld(_object.Width),
                ConvertUnitToPhysicsWorld(_object.Height), 1f);
            _platformFixture.Body.Position = ConvertVector2ToPhysicsWorld(new Vector2(300f, 500f));
            _platformFixture.Friction = 0.5f;
            _platformFixture.Body.BodyType = BodyType.Static;
        }

        protected override void UnloadContent()
        {
        }

        protected override void Update(GameTime gameTime)
        {
            KeyboardState kState = Keyboard.GetState();

            Vector2 force = Vector2.Zero;
            if (kState.IsKeyDown(Keys.Up))
            {
                force.Y -= 100.0f;
            }
            if (kState.IsKeyDown(Keys.Right))
            {
                force.X += 40.0f;
            }
            if (kState.IsKeyDown(Keys.Left))
            {
                force.X -= 40.0f;
            }
            _objectFixture.Body.ApplyForce(force);
            _objectPos = ConvertVector2ToDisplayWorld(_objectFixture.Body.Position);
            _platformPos = ConvertVector2ToDisplayWorld(_platformFixture.Body.Position);

            _physicsWorld.Step((float)gameTime.ElapsedGameTime.TotalMilliseconds * 0.001f);

            base.Update(gameTime);
        }

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

            _spriteBatch.Begin();
            _spriteBatch.Draw(_object, _objectPos, Color.White);
            _spriteBatch.Draw(_object, _platformPos, Color.White);
            _spriteBatch.End();

            base.Draw(gameTime);
        }

        //use for converting units between physics engine unit and display unit back and forth
        private float ConvertUnitToPhysicsWorld(float unitInDisplayWorld)
        {
            return unitInDisplayWorld / pixelToMeter;
        }

        private float ConvertUnitToDisplayWorld(float unitInPhysicsWorld)
        {
            return unitInPhysicsWorld * pixelToMeter;
        }

        private Vector2 ConvertVector2ToPhysicsWorld(Vector2 vector2InDisplayWorld)
        {
            return new Vector2(vector2InDisplayWorld.X / pixelToMeter,
                vector2InDisplayWorld.Y / pixelToMeter);
        }

        private Vector2 ConvertVector2ToDisplayWorld(Vector2 vector2InPhysicsWorld)
        {
            return new Vector2(vector2InPhysicsWorld.X * pixelToMeter,
                vector2InPhysicsWorld.Y * pixelToMeter);
        }
    }
}

 

Oct 31, 2010 at 7:28 PM

Alright, so I'm really new to all this, but I have something for you to try; it shouldn't take long at all which is why I don't feel guilty talking when I am still experimenting myself.

It looks to me like your rectangle is indeed falling off like it should, but you aren't taking into account the rotation of the rectangle when you draw your sprite. As you can imagine, the rectangle would rotate clockwise as it falls off the ledge.

Try changing your spriteBatch.Draw() for your object to something like this:

_spriteBatch.Draw(_object, _objectPos, null, Color.White, _objectFixture.Body.Rotation, Vector2.Zero, 1.0f, SpriteEffects.None, 1.0f);
This requires a bunch of other parameters, but basically what I did is null all of them appropriately except for the rotation parameter. See if this gets you results that make more sense.