【发布时间】:2018-09-27 21:36:27
【问题描述】:
开始之前:我尝试了 gamedev.stackexchange,但没有人回复,所以我想我会在这里测试一下我的运气:)
我对 3D 编程比较陌生,我正在尝试制作一款玩家可以在迷宫中控制角色的游戏。
我目前的问题并不是真正让鼠标居中并读取它来旋转相机 - 虽然我希望将来这样做,但现在它正在让 WASD 运动也旋转,我认为这意味着我'd 需要旋转轴。我已经尝试了大约 1-2 小时环顾四周,有人说使用四元数和其他矩阵,但到目前为止我还没有任何工作。澄清一下,当我按住 W 时,它会向前移动。但是,如果我随后将相机旋转到右侧并按住 W,它会向相机左侧移动
我不知道该做什么或如何最好地做到这一点,我会提供我的 Camera 类和 Game1 类,尽管我会警告你 - 我不太擅长很好地安排事情。我不是一个经验丰富的程序员,所以要求我将知识应用到我的项目中可能需要我一段时间才能正确,谢谢:D
public class Camera
{
float angle = 1f;
float currentAngle;
public Vector3 cameraPosition;
public Vector3 cameraTarget;
public Matrix worldMatrix { get; set; }
public Matrix viewMatrix { get; set; }
public Matrix projectionMatrix { get; set; }
public Matrix rotationMatrix;
Matrix playerPos;
Matrix movement;
Vector3 position;
public void SetMovement(Matrix inMovement)
{
movement = inMovement;
}
public void SetPosition(Vector3 inPosition)
{
position = inPosition;
}
public Camera(GraphicsDevice graphics, Vector3 inTarget)
{
rotationMatrix = Matrix.CreateRotationY(MathHelper.ToRadians(0f));
cameraTarget = new Vector3(0f, 0f, 0f);
cameraPosition = new Vector3(0f, -1f, 3.5f);
playerPos = Matrix.CreateScale(0.01f) *
Matrix.CreateTranslation(position);
projectionMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45f),
graphics.DisplayMode.AspectRatio,
0.03f, 100f);
worldMatrix = Matrix.CreateWorld(inTarget, Vector3.Forward, Vector3.Up);
viewMatrix = Matrix.CreateLookAt(position, inTarget, Vector3.Up);
}
public virtual void Update()
{
if(Keyboard.GetState().IsKeyDown(Keys.Right))
{
currentAngle += angle;
rotationMatrix = Matrix.CreateRotationY(MathHelper.ToRadians(currentAngle)) * rotationMatrix;
currentAngle = 0;
}
if (Keyboard.GetState().IsKeyDown(Keys.Left))
{
currentAngle += angle * -1;
rotationMatrix = rotationMatrix * Matrix.CreateRotationY(MathHelper.ToRadians(currentAngle));
currentAngle = 0;
}
viewMatrix = Matrix.CreateLookAt(new Vector3(cameraPosition.X + position.X, cameraPosition.Y + position.Y + 1.02f, //FIRST PERSON CAMERA
position.Z + 0.013f), cameraTarget + position + new Vector3(0f,1f,0f), Vector3.Up) * rotationMatrix;
//viewMatrix = Matrix.CreateLookAt(cameraPosition, cameraTarget, Vector3.Up); //MAP VIEW CAMERA
}
}
这是游戏 1
public class Game1 : Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Model map, player;
Camera playerCamera;
Vector3 playerPosition;
Matrix playerCurrentPosition, cameraCurrentPosition;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
graphics.PreferredBackBufferHeight = 1080;
graphics.PreferredBackBufferWidth = 1920;
}
protected override void Initialize()
{
player = Content.Load<Model>("ball2");
playerPosition = new Vector3(-0.84f, 0.86f, 0.02f);
playerCamera = new Camera(GraphicsDevice, new Vector3(0f, 0f, 0f));
base.Initialize();
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
map = Content.Load<Model>("newMap");
}
protected override void UnloadContent()
{
}
protected override void Update(GameTime gameTime)
{
playerCamera.SetMovement(playerCurrentPosition);
playerCamera.SetPosition(playerPosition);
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
Exit();
if (Keyboard.GetState().IsKeyDown(Keys.W))
playerPosition.Y += 0.01f;
if (Keyboard.GetState().IsKeyDown(Keys.A))
playerPosition.X -= 0.003f;
if (Keyboard.GetState().IsKeyDown(Keys.S))
playerPosition.Y -= 0.003f;
if (Keyboard.GetState().IsKeyDown(Keys.D))
playerPosition.X += 0.003f;
playerCurrentPosition =
Matrix.CreateScale(0.01f) *
Matrix.CreateTranslation(playerPosition);
cameraCurrentPosition = Matrix.CreateTranslation(playerPosition - new Vector3(0f, 0.1f, 0f));
playerCamera.Update();
base.Update(gameTime);
}
public void DrawModel(Model model, Matrix world, Matrix view, Matrix projection)
{
foreach (ModelMesh mesh in model.Meshes)
{
foreach (BasicEffect effect in mesh.Effects)
{
effect.View = view;
effect.Projection = projection;
effect.World = world;
effect.EnableDefaultLighting();
}
mesh.Draw();
}
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.Crimson);
DrawModel(map, playerCamera.worldMatrix, playerCamera.viewMatrix, playerCamera.projectionMatrix);
DrawModel(player, playerCamera.worldMatrix * playerCurrentPosition, playerCamera.viewMatrix, playerCamera.projectionMatrix);
base.Draw(gameTime);
}
}
【问题讨论】:
-
这里有一个很好的提示:改用 Unity。
-
@Aybe 我愿意,但它是针对一个我们被标记为项目复杂性的项目。因此,XNA 总体上会给我带来更好的分数,因为实现功能比统一更复杂:)
-
这是一个不太新的示例(未经测试):github.com/patteri/XNA-FPS,即使您不会使用 Unity,但这并不意味着您不能从中汲取灵感,例如 docs.unity3d.com/ScriptReference/Transform.html。
标签: c# rotation controls xna monogame