使用旋转在XNA中绘制2D线

时间:2013-01-26 19:30:18

标签: xna rotation 2d line

我试图从玩家到目标小行星画一条线作为" Grapple"钩子,我发现了一些在xna中用2D做这个的例子,但是我的"位置"和"起源" vector2似乎会根据使用者和使用时间而改变。在线条的情况下,它们看起来在目标的相反方向上绘制并位于右侧(大约100个像素),并在玩家移动时围绕目标左侧的某个原点旋转。

这里是播放器代码,包括抓取代码和目标分配

namespace Sparatius.Sprites
{
    public class PlayerSprite : BaseSprite
    {
        ControlInput controlInput;

        Texture2D Grapple;

        SpriteFont font;

        bool LeftGrapple = false, RightGrapple = false;

        int GrappleRange = 300;

        Sprites.AsteroidSprite LeftTarget, RightTarget;

        public BoundingSphere grappleHitBox
        {
            get { return new BoundingSphere(new Vector3(Position.X + Origin.X, Position.Y + Origin.Y, 0), GrappleRange); }
        }

        public float speed
        {
            get { return Speed; }
        }

        public PlayerSprite(Vector2 spriteLocal)
            :base(spriteLocal)
        {
            this.Rotation = 0;
            this.Speed = 0;
            this.FrameCount = new Point(4, 2);
            this.ColorTint = Color.White;
            this.controlInput = new ControlInput();
        }

        public void LoadContent(ContentManager content)
        {
            Texture = content.Load<Texture2D>("Sprites/PinballSpin");
            font = content.Load<SpriteFont>("Fonts/Font1");
            Grapple = content.Load<Texture2D>("Sprites/Grapple");
            FrameSize = new Point((int)Texture.Width / FrameCount.X, (int)Texture.Height / FrameCount.Y);
            Origin = new Vector2(FrameSize.X / 2, FrameSize.Y / 2);

            Animation = new Animation(Texture, FrameSize);
        }

        public override void Update(GameTime gameTime)
        {
            base.Update(gameTime);

            controlInput.GetControlStates();

            if (controlInput.JustPressed(Keys.W))
                Speed += 2;
            else if (controlInput.JustPressed(Keys.S))
                Speed -= 2;

            if (controlInput.IsHeld(Keys.A))
                Rotation -= 0.05f;
            if (controlInput.IsHeld(Keys.D))
                Rotation += 0.05f;

            if (LeftTarget != null)
            {
                LeftTarget.Distance = Vector2.Distance(Position, LeftTarget.Position);
                if (LeftTarget.Distance > GrappleRange)
                {
                    LeftTarget.isTarget = false;
                    LeftTarget = null;
                }
                if (controlInput.IsHeld(Keys.Q))
                {
                    LeftGrapple = true;
                }
                else
                    LeftGrapple = false;
            }
            if (RightTarget != null)
            {
                RightTarget.Distance = Vector2.Distance(Position, RightTarget.Position);
                if (RightTarget.Distance > GrappleRange)
                {
                    RightTarget.isTarget = false;
                    RightTarget = null;
                }
                if (controlInput.IsHeld(Keys.E))
                {
                    RightGrapple = true;
                }
                else
                    RightGrapple = false;
            }
        }

        public override void Draw(SpriteBatch spriteBatch)
        {
            base.Draw(spriteBatch);

            if (LeftGrapple)
            {
                float leftRotation = (float)Math.Atan2(LeftTarget.Position.Y - Position.Y, LeftTarget.Position.X - Position.X);
                //spriteBatch.Draw(Texture, Position, null, ColorTint, leftRotation, Position, 1f, SpriteEffects.None, 0f);
                spriteBatch.Draw(Grapple,
                    new Rectangle((int)Position.X, (int)Position.Y, 2, (int)LeftTarget.Distance),
                    null, Color.Blue, leftRotation, Position, SpriteEffects.None, 0f);
            }
            if (RightGrapple)
            {
                float rightRotation = (float)Math.Atan2(RightTarget.Position.Y - Position.Y, RightTarget.Position.X - Position.X);
                //spriteBatch.Draw(Texture, Position, null, ColorTint, rightRotation, Position, 1f, SpriteEffects.None, 0f);
                spriteBatch.Draw(Grapple,
                    new Rectangle((int)Position.X, (int)Position.Y, 2, (int)RightTarget.Distance),
                    null, Color.Blue, rightRotation, Position, SpriteEffects.None, 0f);
            }

            spriteBatch.DrawString(font, "Player Rotation: " + Rotation, Position, Color.Red);
            spriteBatch.DrawString(font, "Player RoationDegree: " + (int)MathHelper.ToDegrees(Rotation), origin, Color.Blue);
        }

        public void GrappleCheck(AsteroidSprite target)
        {
            float targetTragectory = (float)Math.Atan2(Position.Y - target.Position.Y, Position.X - target.Position.X);

            if ((targetTragectory < (rotation - (float)MathHelper.PiOver4)) && ((targetTragectory > (rotation - (float)MathHelper.Pi + (float)MathHelper.PiOver4))))
            {
                target.Distance = Vector2.Distance(Position, target.Position);
                if (LeftTarget != null)
                {
                    if (LeftTarget.Distance > target.Distance)
                    {
                        LeftTarget.isTarget = false;
                        LeftTarget = target;
                        LeftTarget.isTarget = true;
                    }
                }
                else
                {
                    LeftTarget = target;
                    LeftTarget.isTarget = true;
                }
            }

            if ((targetTragectory > (rotation + (float)MathHelper.PiOver4)) && ((targetTragectory < (rotation + (float)MathHelper.Pi - (float)MathHelper.PiOver4))))
            {
                target.Distance = Vector2.Distance(Position, target.Position);
                if (RightTarget != null)
                {
                    if (RightTarget.Distance > target.Distance)
                    {
                        RightTarget.isTarget = false;
                        RightTarget = target;
                        RightTarget.isTarget = true;
                    }
                }
                else
                {
                    RightTarget = target;
                    RightTarget.isTarget = true;
                }
            }
        }
    }
}

任何想法都出错了?欢呼声

1 个答案:

答案 0 :(得分:2)

public static void DrawLine(SpriteBatch spriteBatch, Vector2 begin, Vector2 end, Color color, int width = 1)
    {
        Rectangle r = new Rectangle((int)begin.X, (int)begin.Y, (int)(end - begin).Length()+width, width);
        Vector2 v = Vector2.Normalize(begin - end);
        float angle = (float)Math.Acos(Vector2.Dot(v, -Vector2.UnitX));
        if (begin.Y > end.Y) angle = MathHelper.TwoPi - angle;
        spriteBatch.Draw(Pixel, r, null, color, angle, Vector2.Zero, SpriteEffects.None, 0);
    }

Pixel只是1x1精灵

您还可以使用this关键字制作便捷的扩展程序。

相关问题