quarta-feira, 27 de julho de 2011

XNA 4.0 - Parte 5 Integrando tudo

Vamos agora integrar tudo, fazer com que nossa câmera ganhe vida, para isso vamos configurar nossos objetos. Abra o arquivo "Game1.cs", adicione duas novas variáveis como a seguir: Será preciso adicionar a seguinte using

using Tutorial1.GameBase.Cameras;

CameraManager cameraManager;
MouseCamera camera1;

No método LoadContent() adicione

cameraManager = new CameraManager();
camera1 = new MouseCamera(aspectRatio);

Continuando em loadContent(), agora vamos aprender uma coisa nova, os componentes e os serviços do XNA. Um serviço é uma aréa especial onde tudo o que é adicionado pode ser recuperado por uma outra classe. Vamos ao exemplo para melhor entendimento, adicione a seguinte linhas:

Services.AddService(typeof(CameraManager), cameraManager);

Adicionamos um serviço do tipo CameraManager e adicionamos um onjeto a esse serviço, que é nossa cameraManager. Então a partir de agora uma outra classe pode requisitar esse serviço, e tudo que adicionarmos no nosso cameraManager estará visível para essa classe, inclusive posteriores alterações. Após isso adicione o seguinte código:

camera1.SetLookAt(new Vector3(5.0f, 5.0f, 5.0f), Vector3.Zero, Vector3.Up);
camera1.NearPlane = 1.0f;
camera1.FarPlane = 100.0f;
camera1.Fovy = MathHelper.ToRadians(45.0f);

cameraManager.Add("Camera1", camera1);

Então configuramos e adicionamos uma câmera ao nosso cameraManager, então todas as outras classes podem acessar essa camera se ela quiser.

No método Update() apague os imputs que tinhamos feito anteriormente e adicione o seguinte:

Vector3 moveVector = new Vector3(0, 0, 0);
float timeDifference = (float)gameTime.ElapsedGameTime.TotalMilliseconds / 1000.0f;

A variável moveVector é o que vai nos dizer a direção que nossa câmera vai se mover. e a timeDifference é uma variável que será usada pelo mouse. Adicione os seguites métodos de imput mais a atualização e inserção do addToCameraPosition seguida do Update:

KeyboardState keyState = Keyboard.GetState();
GamePadState padState = GamePad.GetState(PlayerIndex.One);

if (keyState.IsKeyDown(Keys.W))
moveVector += new Vector3(0, 0, -1);
if (keyState.IsKeyDown(Keys.S))
moveVector += new Vector3(0, 0, 1);
if (keyState.IsKeyDown(Keys.D))
moveVector += new Vector3(1, 0, 0);
if (keyState.IsKeyDown(Keys.A))
moveVector += new Vector3(-1, 0, 0);
if (keyState.IsKeyDown(Keys.Q))
moveVector += new Vector3(0, 1, 0);
if (keyState.IsKeyDown(Keys.Z))
moveVector += new Vector3(0, -1, 0);
if (keyState.IsKeyDown(Keys.Enter))
camera1.Shake(0.2f, 1.0f);

moveVector += new Vector3(0, padState.ThumbSticks.Left.Y, padState.ThumbSticks.Left.X);

cameraManager.ActiveCamera.addToCameraPosition(moveVector * timeDifference);

cameraManager.ActiveCamera.Update(gameTime);

Se você já pegou os macetes de programar em XNA vai saber que usaremos aas teclas W e S para nos movermos no eixo Z, as teclas A e D para nos movermos no eixo X, Q e Z no eixo Y e por fim que a tecla ENTER tremerá a tela.

Se o Mouse guiará nossa câmera então ele não pode deixar a posição central da tela, então para sabermos se ele se mecheu precisamos pegar onde ele estava e comparar com onde ele deveria estar. Adicione a seguinte variavel, lá em cimão, embaixo de MouseCamera camera1;

MouseState originalMouseState;

No método LoadContent(), denovo onde tem uma referência ao camera1 adicione

Mouse.SetPosition(GraphicsDevice.Viewport.Width / 2, GraphicsDevice.Viewport.Height / 2);
originalMouseState = Mouse.GetState();

Na primeira linha travamos o mouse na posição central da tela e na segunda pegamos o atual estado do mouse. Atenção, como o mouse está travado teremos que usar ALT+F4 para fechar a janela do jogo. Agora no método Update() cole o seguinte código abaico de float timedifference...

MouseState currentMouseState = Mouse.GetState();
if (currentMouseState != originalMouseState)
{
float xDifference = currentMouseState.X - originalMouseState.X;
float yDifference = currentMouseState.Y - originalMouseState.Y;
camera1.LeftrightRot -= camera1.RotationSpeed * xDifference * timeDifference;
camera1.UpdownRot -= camera1.RotationSpeed * yDifference * timeDifference;
Mouse.SetPosition(GraphicsDevice.Viewport.Width / 2, GraphicsDevice.Viewport.Height / 2);
}

O que esse pedaço de código faz, é pegar a diferença de onde o mouse está, onde deferia estar e depois recoloca o mouse no centro da tela, aqui temos que tomar cuidado, pois esse pedaço de código só funciona se a camera for do tipo MouseCamera, senão não deve executar mas não vamos nos preocupar com isso agora. Terminamos o arquivo "Game1.cs". Agora vamos para o arquivo "Terrain.cs".

Adicione uma variável global para cameraManager

CameraManager cameraManager;

Agora vamos resgatar esse componemte, no método Load() digite:

cameraManager = Game.Services.GetService(typeof(CameraManager)) as CameraManager;

Resgatamos nosso Componente, agora no método Update() coloque

effect.View = cameraManager.ActiveCamera.View;
effect.Projection = cameraManager.ActiveCamera.Projection;

Rode o programa e teste o teclado e o Mouse.

Nenhum comentário:

Postar um comentário