Farseer - 粒子不会根据边界移动/反弹

时间:2012-10-11 06:46:56

标签: windows-phone-7 windows-phone-7.1 box2d farseer

我的边界是这样的:

class Maze
    {
        private Body _agentBody;
        private Sprite _box;
        private GameplayScreen _screen;
        private float _offset;

        public Maze(World world, GameplayScreen screen, Vector2 position)
        {
            _agentBody = BodyFactory.CreateBody(world, position);
            _agentBody.BodyType = BodyType.Dynamic;
            _agentBody.IsStatic = true;
            _agentBody.Restitution = 0.2f;
            _agentBody.Friction = 0.2f;

            _offset = ConvertUnits.ToDisplayUnits(1f);
        // spodek
            _agentBody.CreateFixture(new PolygonShape(PolygonTools.CreateRectangle(1f, 0.05f, new Vector2(0f, 1f), 0), 1f));
            // spodek
            _agentBody.CreateFixture(new PolygonShape(PolygonTools.CreateRectangle(1f, 0.05f, new Vector2(0f, -1f), 0), 1f));
            // pravy bok
            _agentBody.CreateFixture(new PolygonShape(PolygonTools.CreateRectangle(0.05f, 1f, new Vector2(1f, 0f), 0), 1f));
            // levy bok
            _agentBody.CreateFixture(new PolygonShape(PolygonTools.CreateRectangle(0.05f, 1f, new Vector2(-1f, 0f), 0), 1f));   
            _screen = screen;

            //GFX
            AssetCreator creator = _screen.ScreenManager.Assets;
            _box = new Sprite(creator.TextureFromVertices(PolygonTools.CreateRectangle(1f, 0.05f),
                                                           MaterialType.Blank, Color.White, 1f));
        }

        public Body Body
        {
            get { return _agentBody; }
        }

        public void Draw()
        {
            SpriteBatch batch = _screen.ScreenManager.SpriteBatch;
            batch.Draw(_box.Texture, ConvertUnits.ToDisplayUnits(_agentBody.Position), null,
                        Color.White, _agentBody.Rotation, _box.Origin + new Vector2(0f, _offset), 1f, SpriteEffects.None, 0f);
            batch.Draw(_box.Texture, ConvertUnits.ToDisplayUnits(_agentBody.Position), null,
                        Color.White, _agentBody.Rotation, _box.Origin + new Vector2(0f, -_offset), 1f, SpriteEffects.None, 0f);

            batch.Draw(_box.Texture, ConvertUnits.ToDisplayUnits(_agentBody.Position), null,
                        Color.White, _agentBody.Rotation + MathHelper.Pi / 2f, _box.Origin + new Vector2(0f, _offset), 1f, SpriteEffects.None, 0f);
            batch.Draw(_box.Texture, ConvertUnits.ToDisplayUnits(_agentBody.Position), null,
                        Color.White, _agentBody.Rotation + MathHelper.Pi / 2f, _box.Origin + new Vector2(0f, -_offset), 1f, SpriteEffects.None, 0f);
        }

    }

这些是我的小颗粒:

for (int i = 0; i < 8; i++)
            {
                _sands[i] = BodyFactory.CreateRectangle(_world, 0.05f, 0.05f, 1f);
                _sands[i].IsStatic = false;
                _sands[i].Restitution = 0.1f;
                _sands[i].Friction = 0.1f;
                _sands[i].Position = new Vector2(1.8f + i * 0.2f, 2.2f);
            }

            _sand = new Sprite(ScreenManager.Assets.TextureFromShape(_sands[0].FixtureList[0].Shape,
                                                                        MaterialType.Dots,
                                                                        Color.SandyBrown, 0.8f));

我这样绘制:

foreach (Body sand in _sands)
            {
                spriteBatch.Draw(_sand.Texture, ConvertUnits.ToDisplayUnits(sand.Position), null, Color.SandyBrown, sand.Rotation, _sand.Origin, 1f, SpriteEffects.None, 0f);
            }
_maze.Draw();

但我无法弄清楚为什么如果我用边框旋转那么为什么部分仍然存在。我尝试改变粒子的恢复,当有1f它们恢复(弹跳)时,我可以旋转边界,它们从边界的新位置恢复但是当我有上面的设置颗粒掉落时,那些在边界内的他们停在底部边界,其他人完全倒下。所以在开始之后我有第一张图片,在我用边框旋转后,我得到了第二张图像。我做错了什么?为什么当我改变恢复原状时,他们会反弹0.2而不是?

After start Try to rotate with borders

修改: 迷宫构造函数中的新行:

agentBody = BodyFactory.CreateBody(world, position);
            _agentBody.BodyType = BodyType.Dynamic;
            _agentBody.IgnoreGravity = true;
            _agentBody.Restitution = 0.1f;
            _agentBody.Friction = 1f;

            _offset = ConvertUnits.ToDisplayUnits(1.5f);

            FixtureFactory.AttachRectangle(3f, 0.1f, 1f, new Vector2(0, 1.55f), _agentBody);
            FixtureFactory.AttachRectangle(3f, 0.1f, 1f, new Vector2(0f, -1.55f), _agentBody);
            FixtureFactory.AttachRectangle(width, 3f, 1f, new Vector2(-1.55f, 0f), _agentBody);
            FixtureFactory.AttachRectangle(width, 3f, 1f, new Vector2(1.55f, 0f), _agentBody);

这是调试视图的外观:

Newest look with debug view

用身体旋转:

public override void HandleInput(GameTime gameTime, InputState input)
{
    if (input == null)
        throw new ArgumentNullException("input");

    // Read in our gestures
    foreach (GestureSample gesture in input.Gestures)
    {
        if (gesture.GestureType == GestureType.HorizontalDrag)
        {
            if (gesture.Delta.X < 0)
            {
                _maze.Body.Rotation += 0.02f;
            }
            else if (gesture.Delta.X > 0)
            {
                _maze.Body.Rotation -= 0.02f;
            }
        }
    }

1 个答案:

答案 0 :(得分:1)

小颗粒物体一旦停止移动就可能正在睡觉。它们周围的框架是静态的,因此发动机不会指望它会移动,但是你正在移动它。在这种情况下,小颗粒体不会被唤醒。

您需要设置小颗粒体,使它们无法入睡,或使它们周围的框架成为动态或运动体。作为一般规则,如果身体要移动,不要使它成为静止的身体。