3

我正在尝试制作一个 2D 相机,它可以垂直和水平地跟随我的玩家。相机仅在水平 atm 后跟随我的播放器。我被告知要在我的方法中更新 Y 部分和 X 部分ScrollCamera(),但我不知道该怎么做(最终弄得一团糟)。

继承人的代码:

private void ScrollCamera(Viewport viewport)
        {
#if ZUNE
const float ViewMargin = 0.45f;
#else
            const float ViewMargin = 0.5f;
#endif

            // Calculate the edges of the screen.
            float marginWidth = viewport.Width * ViewMargin;
            float marginLeft = cameraPosition + marginWidth;
            float marginRight = cameraPosition + viewport.Width - marginWidth;



            // Calculate how far to scroll when the player is near the edges of the screen.
            float cameraMovement = 0.0f;
            if (Player.Position.X < marginLeft)
                cameraMovement = Player.Position.X - marginLeft;
            else if (Player.Position.X > marginRight)
                cameraMovement = Player.Position.X - marginRight;

            // Update the camera position, but prevent scrolling off the ends of the level.
            float maxCameraPositionWidth = Tile.Width * Width - viewport.Width;
            cameraPosition = MathHelper.Clamp(cameraPosition + cameraMovement, 0.0f, maxCameraPositionWidth);


        }

这是我的关卡类中的绘制方法:

public void Draw(GameTime gameTime, SpriteBatch spriteBatch)
        {
            spriteBatch.Begin();
            for (int i = 0; i <= EntityLayer; ++i)
                layers[i].Draw(spriteBatch, cameraPosition);
            spriteBatch.End();

            ScrollCamera(spriteBatch.GraphicsDevice.Viewport);
            Matrix cameraTransform = Matrix.CreateTranslation(-cameraPosition, 0.0f, 0.0f);
            spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend, SamplerState.LinearClamp, DepthStencilState.Default,
                RasterizerState.CullCounterClockwise, null, cameraTransform);

            DrawTiles(spriteBatch);

            Player.Draw(gameTime, spriteBatch);

            foreach (Enemy enemy in enemies)
                enemy.Draw(gameTime, spriteBatch);

            spriteBatch.End();

            spriteBatch.Begin();
            for (int i = EntityLayer + 1; i < layers.Length; ++i)
                layers[i].Draw(spriteBatch, cameraPosition);
            spriteBatch.End();
        }

我对 Xna 和 C# 很陌生,我这样做只是为了好玩,但如果有人能告诉我怎么做就太好了:)

我努力了:

private void ScrollCamera(Viewport viewport)
        {
#if ZUNE
const float ViewMargin = 0.45f;
#else
            const float ViewMargin = 0.5f;
            const float ViewHeight = 0.3f;
#endif

            // Calculate the edges of the screen.
            float marginHeight = viewport.Height * ViewHeight;
            float marginTop = cameraPosition + marginHeight;
            float marginBottom = cameraPosition + marginHeight;

            float marginWidth = viewport.Width * ViewMargin;
            float marginLeft = cameraPosition + marginWidth;
            float marginRight = cameraPosition + viewport.Width - marginWidth;


            // Calculate how far to scroll when the player is near the edges of the screen.
            float cameraMovement = 0.0f;
            if (Player.Position.X < marginLeft)
                cameraMovement = Player.Position.X - marginLeft;
            else if (Player.Position.X > marginRight)
                cameraMovement = Player.Position.X - marginRight;

            if (Player.Position.Y < marginTop)
                cameraMovement = Player.Position.Y - marginTop;
            else if (Player.Position.Y > marginBottom)
                cameraMovement = Player.Position.X - marginBottom;



            // Update the camera position, but prevent scrolling off the ends of the level.
            float maxCameraPositionWidth = Tile.Width * Width - viewport.Width;
            cameraPosition = MathHelper.Clamp(cameraPosition + cameraMovement, 0.0f, maxCameraPositionWidth);

        }

这根本不对。

4

1 回答 1

2

从您提供的代码中,我得出结论“cameraPosition”是一个浮点数,您只能使用它来跟踪 X 位置。我建议为此使用 Vector2。这在技术上是两个花车合二为一。一个用于 X 位置,一个用于 Y。如果这样做,您将不得不重复计算 Y 值。如果您不想使用 Vector2,则可以为 Y 位置创建第二个变量。

我看不到你对 cameraPosition 做了什么,所以我无法帮助你处理 Y 的那部分。

编辑 您所做的绘图功能不正确,因为您只有一个用于相机位置的变量。X 位置需要一个变量,Y 位置需要另一个变量。如上所述,在 XNA 中执行此操作的典型方法是通过 Vector2 结构。如果您不熟悉结构(或类),我建议您尽快阅读相关内容,因为它们在面向对象编程中非常重要。微软 Vector2 文档的链接:http: //msdn.microsoft.com/en-us/library/microsoft.xna.framework.vector2.aspx

你基本上会做的是首先计算你的计算。

float cameraMovement = 0.0f;
if (Player.Position.X < marginLeft)
    cameraMovement = Player.Position.X - marginLeft;
else if (Player.Position.X > marginRight)
    cameraMovement = Player.Position.X - marginRight;

// Update the camera position, but prevent scrolling off the ends of the level.
float maxCameraPositionWidth = Tile.Width * Width - viewport.Width;
cameraPosition = MathHelper.Clamp(cameraPosition + cameraMovement, 0.0f, maxCameraPositionWidth);

这是相机 X 位置的计算。您使用 Vector2 的代码将是:

// Declare a Vector2 cameraPosition where you are now declaring a float cameraPosition right now.

Vector2 cameraMovement = new Vector2(0,0);
if (Player.Position.X < marginLeft)
    cameraMovement.X = Player.Position.X - marginLeft;
else if (Player.Position.X > marginRight)
    cameraMovement.X = Player.Position.X - marginRight;

float maxCameraPositionWidth = Tile.Width * Width - viewport.Width;
cameraPosition.X = MathHelper.Clamp(cameraPosition.X + cameraMovement.X, 0.0f, maxCameraPositionWidth);

您必须对 cameraMovement.Y 和 cameraPosition.Y 进行类似的计算。

当你有了这些,你唯一需要在你的绘图函数中改变的就是 Y 平移。目前您有:

Matrix cameraTransform = Matrix.CreateTranslation(-cameraPosition, 0.0f, 0.0f);

如您所见,您只是在 X 轴上平移。添加 Y 轴后,它看起来像这样:

Matrix cameraTransform = Matrix.CreateTranslation(-cameraPosition.X, -cameraPosition.Y, 0.0f);

我希望你现在弄清楚。祝你好运!

于 2013-07-01T14:57:56.137 回答