Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

My basic implementation of a Farseer world has been behaving very strangely. It seems as though there is a very low maximum velocity, and collisions result in the small spheres involved clipping through each other.

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.Collision.Shapes;
using FarseerPhysics.Common;
using FarseerPhysics.Dynamics;
using FarseerPhysics.Factories;


namespace Farseer_Science_
{
/// <summary>
/// This is the main type for your game
/// </summary>
public class Game1 : Microsoft.Xna.Framework.Game
{
    GraphicsDeviceManager graphics;
    SpriteBatch spriteBatch;

    private World world;
    List<Body> elementList = new List<Body>();
    private Body groundBody;

    private Texture2D textureWater;
    private Texture2D textureMagnesium;
    private Texture2D textureCursor;
    private Texture2D textureGround;

    private Color mouseColor = Color.White;

    MouseState state = new MouseState();
    private Vector2 mousePosition;
    MouseState oldState;


    public Game1()
    {
        graphics = new GraphicsDeviceManager(this);

        Content.RootDirectory = "Content";

        world = new World(new Vector2(0, 2));
    }

    /// <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()
    {
        groundBody = BodyFactory.CreateRectangle(world, 2000f, 50f, 16f, new Vector2(0f, 250f));
        groundBody.IsStatic = true;
        groundBody.Restitution = 0.5f;
        groundBody.Friction = 5f;


        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);
        textureMagnesium = Content.Load<Texture2D>("textureMagnesium");
        textureWater = Content.Load<Texture2D>("textureWater");
        textureCursor = Content.Load<Texture2D>("textureCursor");
        textureGround = Content.Load<Texture2D>("textureGround");


        // TODO: use this.Content to load your game 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();

        // TODO: Add your update logic here
        mousePosition = HandleMouse();
        world.Step(0.1f);
        base.Update(gameTime);
    }

    private Vector2 HandleMouse()
    {

        state = Mouse.GetState();
        if (state.LeftButton == ButtonState.Pressed)
        {
            mouseColor = Color.Red;
            if (oldState.LeftButton == ButtonState.Released)
            {

                elementList.Add(BodyFactory.CreateCircle(world, 16, 100f));
                elementList[elementList.Count - 1].Position = new Vector2(state.X - 16, state.Y - 16);
                elementList[elementList.Count - 1].BodyType = BodyType.Dynamic;
                elementList[elementList.Count - 1].Restitution = 0.5f;
                elementList[elementList.Count - 1].Friction = 1f;
            }
        }
        else
        {
            mouseColor = Color.White;
        }
        oldState = state;
        return new Vector2(state.X, state.Y);
    }

    /// <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 (Body element in elementList)
        {
            spriteBatch.Draw(textureMagnesium, element.Position, Color.White);
        }
        spriteBatch.Draw(textureGround, groundBody.Position, Color.White);
        spriteBatch.Draw(textureCursor, mousePosition, mouseColor);


        spriteBatch.End();    

        base.Draw(gameTime);
    }
}
}
share|improve this question
    
Did you remember to convert to farseer units? Eg, dividing each screen unit/vector by 64f? –  Twitchy Feb 16 '12 at 1:49
    
I remember reading something about that, but I wasn't certain how it worked, or exactly what it did, or even how to implement it. Is that actually how it works? You divide everything by 64 when it's to be displayed? –  PartyMix Feb 16 '12 at 1:53
    
Okay, it appears that I should be drawing using a viewmatrix, and not treating one pixel as one meter, like I do here. Sorry to have such a bloglike question, but this issue was really beginning to grate. –  PartyMix Feb 16 '12 at 2:02
    
Farseer is built on Box2d, and the same rules apply : units are in meters. Everything in your world is probably working fine.. everything is just really, really big. –  Blecki Feb 16 '12 at 2:10
    

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Browse other questions tagged or ask your own question.