for those of you familiar with farseer , I have a question regarding collision detection. I´ve read a lot of stuff and watched an excellent video tutorial on XNAtutorial by Joran Omark. Unfortunately he used an older version of farseer( a 2006 version ) , so I had to tweak a little to get mine to work. Now everything works except my collision detection. I just can´t seem to get those to work. I decided to go for the screenmanager approach and therefore create nice seperate classes.
My GameplayScreen looks like this
public class GamePlayScreen : GameScreen
{
Texture2D stewieTexture;
Texture2D floorTexture;
Sprite stewie;
Sprite floor;
World world;
public GamePlayScreen()
{
world = new World(new Vector2(0, 9.81F));
EnabledGestures = GestureType.Flick;
}
public override void LoadContent()
{
stewieTexture = ScreenManager.Game.Content.Load<Texture2D>("playerStewie");
floorTexture = ScreenManager.Game.Content.Load<Texture2D>("Floor");
this.stewie = new Sprite();
this.floor = new Sprite();
this.stewie.LoadGraphicsContent(ScreenManager.SpriteBatch, this.stewieTexture, world);
this.floor.LoadGraphicsContent(ScreenManager.SpriteBatch, this.floorTexture, world);
// very ugly unfortunately for now like this.. We need Textures for our sprite that's why
this.stewie.Initialize(world, BodyType.Dynamic ,new Vector2(16000,1500));
this.floor.Initialize(world, BodyType.Static, new Vector2(1500, 16000));
}
public override void HandleInput(InputState input)
{
foreach (GestureSample gesture in input.Gestures)
{
if (gesture.GestureType == GestureType.Flick)
{
stewie.PhysicsBody.ApplyForce(Vector2.Divide(gesture.Delta, 0.5f));
}
}
}
public override void Update(GameTime gameTime, bool otherScreenHasFocus, bool coveredByOtherScreen)
{
world.Step((float)gameTime.ElapsedGameTime.TotalSeconds);
this.stewie.Update(gameTime, world);
this.floor.Update(gameTime, world);
base.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen);
}
public override void Draw(GameTime gameTime)
{
// TODO: Add your drawing code here
ScreenManager.SpriteBatch.Begin();
this.stewie.Draw(gameTime);
this.floor.Draw(gameTime);
ScreenManager.SpriteBatch.End();
base.Draw(gameTime);
}
}
And my Sprite class
public class Sprite
{
private Animation graphicsImage;
private Body physicsBody;
//Fixture test
//private Fixture fixtureBody;
private Vector2 _screenCenter;
private float pixelsPerMeter = 50; //needed to convert pixels per meter , because the gesture.position is in meters
public Body PhysicsBody { get { return physicsBody; } }
public Sprite()
{
this.graphicsImage = new Animation();
}
/// <summary>
/// Initialize the sprite sets up position , creates rectangle from bodyfactory
/// </summary>
/// <param name="world"> takes a reference to the worldobject</param>
public void Initialize(World world, BodyType bodyType,Vector2 position)
{
this.graphicsImage.Initialize();
this.physicsBody = BodyFactory.CreateRectangle(world, this.graphicsImage.Size.X / pixelsPerMeter, this.graphicsImage.Size.Y / pixelsPerMeter, 1f);
this.graphicsImage.Position = position / pixelsPerMeter;
this.physicsBody.Position = this.graphicsImage.Position;
this.physicsBody.BodyType = bodyType;
// this.fixtureBody = FixtureFactory.AttachRectangle(this.physicsBody.Position.X / pixelsPerMeter, this.physicsBody.Position.Y / pixelsPerMeter, 3f, new Vector2(100, 100), this.physicsBody);
//this.physicsBody.Restitution = 0.7f;
Debug.WriteLine("Initialize Sprite");
Debug.WriteLine(this.graphicsImage.Position);
}
/// <summary>
/// LoadGraphicsContent for the sprite call this function in the LoadContent ( initialize also works )
/// </summary>
/// <param name="spriteBatch">takes a reference to a spritebatch</param>
/// <param name="texture">takes a reference to texture2D</param>
public void LoadGraphicsContent(SpriteBatch spriteBatch, Texture2D texture, Wor开发者_如何学Pythonld world)
{
this.graphicsImage.LoadGraphicsContent(spriteBatch, texture);
}
/// <summary>
/// Update sprite for graphicsImage position , and rotation needs to be called in the main Update function of the game
/// </summary>
/// <param name="gameTime">reference to gameTime</param>
/// <param name="world">reference to worldobject</param>
public void Update(GameTime gameTime, World world)
{
this.graphicsImage.Update(gameTime);
this.graphicsImage.Position = this.physicsBody.Position;
this.graphicsImage.Rotation = this.physicsBody.Rotation;
}
/// <summary>
/// Draw sprite method needs to be called in the main Draw function of the game
/// </summary>
/// <param name="gameTime"></param>
public void Draw(GameTime gameTime)
{
this.graphicsImage.Draw(gameTime);
}
}
}
As I already stated, is that my collision isn´t working. I´ve looked at the current samples that use Farseer 3.3 (just like I do). For instance here http://farseerphysics.codeplex.com/releases/view/64108 and then the HelloWorld example. I´ve read the stuff about the GeomFactory that was being used in the previous versions for collision. However that has changed with the new version of Farseer where the bodyfactory can handle a whole bunch of stuff. So does anyone have any idea why my collision isn´t working?
Yeah you're positioning is off because from what I have gained from playing around with the engine it uses the screen coordinates in Meters. Which means your screen can only be 10x16(ish) meters (480x800 pixels) because that is what Microsoft has their screen resolution capped at. So when you pass in the positions of 16000,1500 pixels and divide it by 50 you are really putting the bodies at 320m and 30m, which is way off the screen for the bodies but on the screen for the Draw function because it thinks those values are in pixels.
Also from what I saw in the HelloWorld example that is on their site you should be using 64 to divide by not 50. I'm not sure why that is exactly but I can guess it's because 64 is a factor of 2 and computers love factors of 2 lol so if you use 50 you might get some off collision happening.
精彩评论