Jump to content

  • Log In with Google      Sign In   
  • Create Account

Like
6Likes
Dislike

Building a First-Person Shooter: Part 1.4 Mouse Inputs

By Christopher Vossen | Published Aug 19 2013 08:17 AM in Game Programming
Peer Reviewed by (jbadams, Aldacron, ivan.spasov)

leadwerks c++ fps tutorial

Now it’s time to let the player look around using mouse movements. We start again by adding variables for mouse controls into the constructor:

sensitivity=1.0;
cameralooksmoothing = 2.0;
cameraypositionsmoothing = 3.0;
smoothedcamerapositiony = 0;

In UpdateControls we will need access to the games context which is the renderable area of the window, which is essentially the area of the game window inside the windows border. We use this context to find the center of the screen and store the coordinates as sx and sy.

Context* context = Context::GetCurrent();
//Get the mouse movement
float sx = context->GetWidth()/2;
float sy = context->GetHeight()/2;

Next we save the current mouse position and then return the mouse to the center of the screen:

//Get the mouse position
Vec3 mouseposition = window->GetMousePosition();
//Move the mouse to the center of the screen
window->SetMousePosition(sx,sy);

Now that we know where the center of the screen is and the current mouse position we can figure out the difference between the two which tells us which direction to look:

//Get change in mouse position
float dx = mouseposition.x - sx;
float dy = mouseposition.y - sy;

We want to set the mouse speed by smoothing between the previous mouse speed and the distance from the center of the screen.

//Mouse smoothing
mousespeed.x = Math::Curve(dx,mousespeed.x,cameralooksmoothing/Time::GetSpeed());
mousespeed.y = Math::Curve(dy,mousespeed.y,cameralooksmoothing/Time::GetSpeed());

Using the mouse speed we increment the player’s rotation and scale it by sensitivity, thus the higher the sensitivity the quicker the mouse movements:

//Adjust and set the camera rotation
playerrotation.x += mousespeed.y*sensitivity / 10.0;
playerrotation.y += mousespeed.x*sensitivity / 10.0;

To prevent the player from inhuman neck movements we clamp the y rotation values at -90 and 90:

//Prevent inhuman looking angles
playerrotation.x = Math::Clamp(playerrotation.x,-90,90);

In the player Update function we rotate the camera by the playerrotation value finally allowing for our character to look around:

//Set camera rotation
camera->SetRotation(playerrotation,true);

At this point the player character can move around with keyboard inputs and look around using the mouse:

#include "MyGame.h"
using namespace Leadwerks;
Player::Player()
{
//Create the entity
entity = Pivot::Create();
entity->SetUserData(this);

//Initialize values
sensitivity=1.0;
cameralooksmoothing = 2.0;
move = 0.0;
strafe = 0.0;
cameraypositionsmoothing = 3.0;
maxacceleleration = 0.5;
movementspeed = 3.0;
standheight=1.7;
crouchheight=1.2;
cameraheight = standheight;
smoothedcamerapositiony = 0;

//Create the player camera
camera = Camera::Create();
camera->SetPosition(0,entity->GetPosition().y + cameraheight,0,true);

//Set up player physics
entity->SetPhysicsMode(Entity::CharacterPhysics);
entity->SetCollisionType(Collision::Character);
entity->SetMass(10.0);

//Player position
entity->SetPosition(0,0,0,true);
}

Player::~Player()
{
if (camera)
{
camera->Release();
camera = NULL;
}
}

void Player::UpdateControls()
{
Window* window = Window::GetCurrent();
Context* context = Context::GetCurrent();

//Get inputs from the controller class
move = window->KeyDown(Key::W) - window->KeyDown(Key::S);
strafe = window->KeyDown(Key::D) - window->KeyDown(Key::A);

//Get the mouse movement
float sx = context->GetWidth()/2;
float sy = context->GetHeight()/2;

//Get the mouse position
Vec3 mouseposition = window->GetMousePosition();

//Move the mouse to the center of the screen
window->SetMousePosition(sx,sy);

//Get change in mouse position
float dx = mouseposition.x - sx;
float dy = mouseposition.y - sy;

//Mouse smoothing
mousespeed.x = Math::Curve(dx,mousespeed.x,cameralooksmoothing/Time::GetSpeed());
mousespeed.y = Math::Curve(dy,mousespeed.y,cameralooksmoothing/Time::GetSpeed());

//Adjust and set the camera rotation
playerrotation.x += mousespeed.y*sensitivity / 10.0;
playerrotation.y += mousespeed.x*sensitivity / 10.0;

//Prevent inhuman looking angles
playerrotation.x = Math::Clamp(playerrotation.x,-90,90);
}

//Update function
void Player::Update()
{
UpdateControls();

float maxaccel = this->maxacceleleration;
float movespeed = this->movementspeed;

//Make sure movements are normalized so that moving forward at the same time as strafing doesn't move your character faster
normalizedmovement.z = move;
normalizedmovement.x = strafe;
normalizedmovement = normalizedmovement.Normalize() * movespeed;

//Set camera rotation
camera->SetRotation(playerrotation,true);
entity->SetInput(playerrotation.y,normalizedmovement.z,normalizedmovement.x,0,false,maxaccel);

//Set the camera position
cameraposition = entity->GetPosition();

camera->SetPosition(cameraposition.x, cameraposition.y + cameraheight, cameraposition.z );
}



License


GDOL (Gamedev.net Open License)




Comments

Note: Please offer only positive, constructive comments - we are looking to promote a positive atmosphere where collaboration is valued above all else.




PARTNERS