0

「グラップル」フックとしてプレイヤーからターゲットの小惑星まで線を引き込もうとしています.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;
                }
            }
        }
    }
}

何がうまくいかないのですか?乾杯

4

1 に答える 1

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);
    }

ピクセルは単なる 1x1 スプライトです

thisキーワードを使用して便利な拡張メソッドを作成することもできます。

于 2013-01-26T21:09:49.087 に答える