Problems with integration

Topics: User Forum
Jun 7, 2012 at 5:05 PM
Edited Jun 7, 2012 at 5:06 PM

Hello everyone. There is a problem with integration farseer engine. What I did to integrate farseer into sample windows phone 7 project (shooter from XNA tutorial site):

1. I opened "Farseer Physics XNA WP7.csproj"

2. I builded it.

3. I went into folder "...\Farseer Physics Engine 3.3.1 Samples XNA\Farseer Physics Engine 3.3 XNA\bin\Windows Phone\Debug\"

4. Copied file "FarseerPhysicsXNA.dll" into folder of my project.

5. In Visual Studio (with my project opened in it) I clicked "Project -> Add Reference" and then selected file "FarseerPhysicsXNA.dll"

6. At last I clicked "Add to Reference..." in Object browser.

Is that alright with my way to add farseer into game? I ask this question because it does not work.

My code:

 

  Body _circle;
        Texture2D testText;
        World world;

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

        protected override void Initialize()
        {
            player = new Player();
            playerMoveSpeed = 8.0f;
            TouchPanel.EnabledGestures = GestureType.FreeDrag;
            base.Initialize();
        }

        protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(GraphicsDevice);
            world = new World(Vector2.Zero);
            Vector2 playerPosition = new      Vector2(GraphicsDevice.Viewport.TitleSafeArea.X,  GraphicsDevice.Viewport.TitleSafeArea.Y +    
GraphicsDevice.Viewport.TitleSafeArea.Height / 2);

            Vector2 _position = new Vector2(445f, 205f);
            world.Gravity = new Vector2(0, 20);
            _circle = new Body(world);
            _circle.Position = _position;
            _circle.BodyType = BodyType.Dynamic;
            System.Diagnostics.Debug.WriteLine(world.Gravity);
            
            // Load the player resources            
            player.Initialize(Content.Load<Texture2D>("player"), playerPosition);
            testText = Content.Load<Texture2D>("player");

        }

        protected override void Update(GameTime gameTime)
        {
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            // Save the previous state of the keyboard and game pad so we can determinesingle key/button presses
            previousGamePadState = currentGamePadState;
            previousKeyboardState = currentKeyboardState;

            // Read the current state of the keyboard and gamepad and store it
            currentKeyboardState = Keyboard.GetState();
            currentGamePadState = GamePad.GetState(PlayerIndex.One);


            //Update the player
            UpdatePlayer(gameTime);


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

            // Start drawing
            spriteBatch.Begin();

            // Draw the Player
            player.Draw(spriteBatch);

            spriteBatch.Draw(testText, _circle.Position, Color.White);

            //Stop drawing
            spriteBatch.End();

            base.Draw(gameTime);
        }
But body doesn't move.

Can anyone help me and say - where is the problem?

Jun 7, 2012 at 7:49 PM

Do you call World.Step() in your UpdatePlayer method because you don't call it in the main Update. Should be called somewhere each timestep. Also don't use pixels as physics units - use meters and convert to pixels in your Draw(). It is not even clear that your _circle has a fixture attached at all (does not in the code snippet at least). Without a fixture it's more like a point mass or rather has no mass at all like an infinitely small point in space. 

I'd suggest looking at the Farseer samples and especially the TestBed to get a feel for the engine and what it can do. The samples has even a comprehensive screen system that could be adapted to mobile. Myself I usually build most of my simulation standalone using the DebugDraw as a graphics renderer and only add in graphics when the physics is done. This way you can see what's going on more easily without risking graphics bugs masking the physics bugs.

Jun 8, 2012 at 2:57 PM

Big thanks to your tips. Now physics works properly. But there is problem with collisions. I worked on it all this day, but i did not found how to make two bodies collide. Is that alright with my code below? These two bodies are not collide with together. Code:

        Body playerBody;
        Body platformBody;
        EdgeShape platormShape;
        Fixture fixture;
        Fixture secondFixture;

in LoadContent:

         
            Vector2 _position = new Vector2(445f, 205f);
            playerBody = BodyFactory.CreateBody(world, _position);
            playerBody.BodyType = BodyType.Dynamic;
            playerBody.CollidesWith = Category.All;
            playerBody.CollisionCategories = Category.All;

            circleShape = new CircleShape(0.5f, 1f);
            circleShape.Position = _position;

            fixture = playerBody.CreateFixture(circleShape);

            Vector2 _secondPosition = new Vector2(475f, 387f);
            platformBody = BodyFactory.CreateBody(world, _secondPosition);
            platformBody.CollidesWith = Category.All;
            platformBody.CollisionCategories = Category.All;
            platformBody.IsStatic = true;

            Vector2 startPosition = new Vector2(475f, 387f);
            Vector2 endPosition = new Vector2(89f, 380f);

            platormShape = new EdgeShape(startPosition, endPosition);

            secondFixture = platformBody.CreateFixture(platormShape);

Jun 8, 2012 at 7:47 PM

First  you need to correct your units. Farseer is a physics system and as such all units are metric. i.e. meters, kg, etc. Since the display is in pixels, you need to convert screen locations into meters. There are some helper functions in the ConvertUnits class which you would use as follows:

 

Vector2 _position = ConvertUnits.ToSimUnits(new Vector2(44f, 205f));

 

I agree with jerrysb, its best to enable the DebugView with DebugViewXNA so that you can see whats really going on.