您的位置:首页 > 其它

[翻译]XNA 3.0 Game Programming Recipes之three

2009-07-15 12:52 591 查看
PS:自己翻译的,转载请著明出处

2-3创建一个第一人称射击游戏照相机: 颤抖式摄像机

问题
你想创建一个行动就象是第一人称的射击模式。用鼠标来旋转摄象机,用键盘来移动摄象机。
解决方案
章节2-2介绍摄像机的方法,只要检测到用户的输入就将更新摄象机的位置和旋转。您的摄象机的轮换矩阵 将改为根据鼠标的移动。上下按键将导致摄象机的位置前后移动,左右按键也会使摄象机左右移动。
如何实现
一般来讲,在第一人称游戏中,玩家可以自由左右旋转和无约束的上下看。这些移动是靠围绕上和右向量旋转响应的,甚至更详细点就是围绕(0,1,0)和(1,0,0)的方向旋转。

移动之前,阅读第4章的4-2的"乘法矩阵顺序"是非常有用的。本次讨论的底线是顺序乘法没有问题,当你想整合2次旋转第2次旋转的坐标是被第一的旋转改变的。
第一次的旋转影响到第2次的坐标系被称为方向锁;它有时候使你很痛苦,但是有时候这又是你需要的。这种情况下的第一人称相机,您首先使你的相机沿着垂直向上的坐标轴旋转和沿着向右的向量旋转。第一轮很好的转动你的Right vector,您可以直观的站立和伸展你的右手.如果你右转,手臂也会随你旋转,而现在,您可以很好周围旋转的方向您的手臂上下看。
简而言之,需要存储两个变量:向上方向和向右方向的旋转。当你需要计算总的旋转,使用“想上旋转后再向右旋转”的原则来整合。一旦你知道总轮换,可以简单地插入到这一点到前面章节的代码中。
现在,您已经知道第一人称相机旋转背后的概念,你仍然需要与用户输入的两个变量控制的amount of轮换。在这方面,例如鼠标输入的方法。你将决定改变鼠标位置两个更新周期和相应的变量的变化.所以,你需要这些变量:

1 float leftrightRot;
2 float updownRot;
3 Vector3 cameraPosition;
4 Matrix viewMatrix;
5 MouseState originalMouseState;
MouseState包含鼠标指针的位置,以及一些bit表明鼠标按键在上次调用Mouse.GetState()后是否被按下。给2个变量在初始化情况下赋值:

Code
1 protected override void Initialize()
2 {
3 base.Initialize();
4 float viewAngle=MathHelper.PiOver4;
5 float aspectRatio=(float)this.Window.ClientBounds.With/(float)this.Window.ClientBounds.Height;
6 float nearPlane=0.5f;
7 float farPlane=100.0f;
8 projectMatrix=Matrix.CreatePerspectiveFieldOfView(viewAngle,aspectRatio,nearPlane,farPlane);
9 leftrightRot=0.0f;
10 updownRot=0.0f;
11 cameraPosition=new Vector3(1,1,10);
12 UpdateViewMatrix();
13 Mouse.SetPosition(Window.ClientBounds.Width/2,Window.ClientBounds.Height/2);
14 originalMouseState=Mouse.GetState();
15 }
16 protected override void Update(GameTime gameTime)
17 {
18 if(GamePad.GetState(PlayerIndex.One).Buttons.Back==ButtonState.Pressed)
19 this.Exit();
20 float rotationSpeed=0.005f;
21 MouseState currentMouseState=Mouse.GetState();
22 if(currentMouseState!=originalMouseState)
23 {
24 float xDifference=currentMouseState.X-originalMouseState.X;
25 float yDifference=currentMouseState.Y-originalMouseState.Y;
26 leftrightRot-=rotationSpeed*xDifference;
27 updownRot-=rotationSpeed*yDifference;
28 Mouse.SetPosition(Window.ClientBounds.Width/2,Window.ClientBounds.Height/2);
29 UpdateViewMatrix();
30 }
31 keyboardState keyState=keyboard.GetState();
32 if(keyState.IsKeyDown(keys.Up))
33 AddToCameraPosition(new Vector3(0,0,-1));
34 if(keyState.IsKeyDown(keys.Down))
35 AddToCameraPosition(new Vector3(0,0,1));
36 if(keyState.IsKeyDown(keys.Right))
37 AddToCameraPosition(new Vector3(1,0,0));
38 if(keyState.IsKeyDown(keys.Left))
39 AddToCameraPosition(new Vector3(-1,0,0));
40 base.Update(gameTime);
41 }
42 private void AddToCameraPosition(Vector3 vectorToAdd)
43 {
44 float moveSpeed=0.5f;
45 Matrix cameraRotation=Matrix.CreateRotationX(updownRot)*Matrix.CreateRotationY(leftrightRot);
46 Vector3 rotatedVector=Vector3.Transform(vectorToAdd,cameraRotation);
47 cameraPosition+=moveSpeed*rotatedVector;
48 UpdateViewMatrix():
49 }
50 private void UpdateViewMatrix()
51 {
52 Matrix cameraRotation=Matrix.CreateRotationX(updownRot)*Matrix.CreateRotationY(leftrightRot);
53 Vector3 cameraOriginalTarget=new Vector3(0,0,-1);
54 Vector3 cameraOriginalUpVector=new Vector3(0,1,0);
55 Vector3 cameraRotatedTarget=Vector3.Transform(cameraOriginalTarget,cameraRotation);
56 Vector3 cameraFinalTarget=cameraPosition+cameraRotatedTarget;
57 Vector3 cameraRotatedUpVector=Vector3.Transform(cameraOriginalUpVector,cameraRotation);
58 Vector3 cameraFinalUpVector=cameraPosition+cameraRotatedUpVector;
59 viewMatrix=Matrix.CreateLookAt(cameraPosition,cameraFinalTarget,cameraRotatedUpVector);
60 }
晃动的相机类

因为它往往是非常有用的现成第一人称相机模式,把它单独分开独成1份。这个类经常被用在许多3D例子这本书也用,很容易融入一个自己的项目
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: