/*
Copyright (C) 2010 Bepu Entertainment LLC.
This software source code is provided 'as-is', without
any express or implied warranty. In no event will the authors be held
liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
Contact us at:
contact@bepu-games.com
*/
using BEPUphysics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
namespace BEPUphysicsDemos
{
///
/// Handles input and movement of a character in the game.
/// Acts as a simple 'front end' for the bookkeeping and math of the character controller.
///
public class SimpleCharacterControllerInput
{
///
/// Camera to use for input.
///
public Camera Camera;
///
/// Current offset from the position of the character to the 'eyes.'
///
public Vector3 CameraOffset = new Vector3(0, .7f, 0);
///
/// Physics representation of the character.
///
public SimpleCharacterController CharacterController;
///
/// Whether or not to use the character controller's input.
///
public bool IsActive = true;
///
/// Owning space of the character.
///
public Space Space;
///
/// Constructs the character and internal physics character controller.
///
/// Space to add the character to.
/// Camera to attach to the character.
public SimpleCharacterControllerInput(Space owningSpace, Camera CameraToUse)
{
CharacterController = new SimpleCharacterController(Vector3.Zero, 2, .8f, 1f, 20);
Space = owningSpace;
Space.Add(CharacterController);
Camera = CameraToUse;
Deactivate();
}
///
/// Gives the character control over the Camera and movement input.
///
public void Activate()
{
if (!IsActive)
{
IsActive = true;
Camera.UseMovementControls = false;
CharacterController.Activate();
CharacterController.Body.Position = (Camera.Position);
}
}
///
/// Returns input control to the Camera.
///
public void Deactivate()
{
if (IsActive)
{
IsActive = false;
Camera.UseMovementControls = true;
CharacterController.Deactivate();
}
}
///
/// Handles the input and movement of the character.
///
/// Time since last frame in simulation seconds.
/// The last frame's keyboard state.
/// The current frame's keyboard state.
/// The last frame's gamepad state.
/// The current frame's keyboard state.
public void Update(float dt, KeyboardState previousKeyboardInput, KeyboardState keyboardInput, GamePadState previousGamePadInput, GamePadState gamePadInput)
{
if (IsActive)
{
//Note that the character controller's update method is not called here; this is because it is handled within its owning space.
//This method's job is simply to tell the character to move around based on the Camera and input.
//Puts the Camera at eye level.
Camera.Position = CharacterController.Body.Position + CameraOffset;
Vector2 totalMovement = Vector2.Zero;
#if !WINDOWS
Vector3 forward = Camera.WorldMatrix.Forward;
forward.Y = 0;
forward.Normalize();
Vector3 right = Camera.WorldMatrix.Right;
totalMovement += gamePadInput.ThumbSticks.Left.Y * new Vector2(forward.X, forward.Z);
totalMovement += gamePadInput.ThumbSticks.Left.X * new Vector2(right.X, right.Z);
CharacterController.MovementDirection = totalMovement;
//Jumping
if (previousGamePadInput.IsButtonUp(Buttons.LeftStick) && gamePadInput.IsButtonDown(Buttons.LeftStick))
{
CharacterController.Jump();
}
#else
//Collect the movement impulses.
Vector3 movementDir;
if (keyboardInput.IsKeyDown(Keys.E))
{
movementDir = Camera.WorldMatrix.Forward;
totalMovement += Vector2.Normalize(new Vector2(movementDir.X, movementDir.Z));
}
if (keyboardInput.IsKeyDown(Keys.D))
{
movementDir = Camera.WorldMatrix.Forward;
totalMovement -= Vector2.Normalize(new Vector2(movementDir.X, movementDir.Z));
}
if (keyboardInput.IsKeyDown(Keys.S))
{
movementDir = Camera.WorldMatrix.Left;
totalMovement += Vector2.Normalize(new Vector2(movementDir.X, movementDir.Z));
}
if (keyboardInput.IsKeyDown(Keys.F))
{
movementDir = Camera.WorldMatrix.Right;
totalMovement += Vector2.Normalize(new Vector2(movementDir.X, movementDir.Z));
}
if (totalMovement == Vector2.Zero)
CharacterController.MovementDirection = Vector2.Zero;
else
CharacterController.MovementDirection = Vector2.Normalize(totalMovement);
//Jumping
if (previousKeyboardInput.IsKeyUp(Keys.A) && keyboardInput.IsKeyDown(Keys.A))
{
CharacterController.Jump();
}
#endif
}
}
}
}