Skip to content

Commit

Permalink
Add Player class with rifle model
Browse files Browse the repository at this point in the history
Adds a basic player class to move around the map.
A rifle is attached to the player. It uses a lerp
to follow the player's camera in a nice-to-have way.
  • Loading branch information
Notiooo committed Nov 30, 2023
1 parent 756e56c commit b6e7aec
Show file tree
Hide file tree
Showing 15 changed files with 11,339 additions and 32 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added AimGL/resources/Models/ak47/ak47-alternative.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10,967 changes: 10,967 additions & 0 deletions AimGL/resources/Models/ak47/ak47.obj

Large diffs are not rendered by default.

Binary file added AimGL/resources/Models/ak47/ak47.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions AimGL/resources/Models/ak47/credits.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
https://sketchfab.com/3d-models/lowpoly-ak47-9d2d20e53cf7428c8c993f6aee04dc88
Model made by Firewarden
44 changes: 29 additions & 15 deletions AimGL/resources/Shaders/Graphics/Model/ModelTextured.fs
Original file line number Diff line number Diff line change
Expand Up @@ -7,44 +7,58 @@ in vec3 FragPos;
in vec2 TexCoords;

uniform vec3 lightPos = vec3(3, 3, 3);
uniform vec3 cameraPosition;
vec3 lightAmbient = vec3(0.3f, 0.3f, 0.3f);
vec3 lightDiffuse = vec3(0.6f, 0.6f, 0.6f);
vec3 lightSpecular = vec3(1.0f, 1.0f, 1.0f);
uniform vec3 lightColor = vec3(1,1,1);
uniform vec3 cameraPosition;

struct Light {
vec3 position;

vec3 ambient;
vec3 diffuse;
vec3 specular;
};

struct Material {
bool isDiffusePresent;
bool isSpecularPresent;
sampler2D diffuse;
sampler2D specular; // not used yet
sampler2D specular;
};

uniform Material material;

void main()
{
// ambient
float ambientStrength = 0.1;
vec3 ambientColor = vec3(1.0, 1.0, 1.0);
vec3 ambient = ambientStrength * ambientColor;
vec3 ambient = lightAmbient;
if(material.isDiffusePresent)
{
ambient = ambient * texture(material.diffuse, TexCoords).rgb;
}

// diffuse
vec3 norm = normalize(FragmentNormal);
vec3 lightDir = normalize(lightPos - FragPos);
float diff = max(dot(norm, lightDir), 0.0);
vec3 diffuseLight = diff * lightColor;
vec3 diffuse = lightDiffuse * diff;
if(material.isDiffusePresent)
{
diffuse = diffuse * texture(material.diffuse, TexCoords).rgb;
}

// specular
float specularStrength = 0.5;
vec3 viewDir = normalize(cameraPosition - FragPos);
vec3 reflectDir = reflect(-lightDir, norm);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), 16);
vec3 specular = specularStrength * spec * lightColor;

// Combine texture color with lighting
vec3 textureColor = vec3(1,1,1);
if(material.isDiffusePresent)
float spec = pow(max(dot(viewDir, reflectDir), 0.0), 64.f);
vec3 specular = lightSpecular * spec;
if(material.isSpecularPresent)
{
textureColor = vec3(texture(material.diffuse, TexCoords));
specular = specular * texture(material.specular, TexCoords).rgb;
}
vec3 result = textureColor * (ambient + diffuseLight) + specular;

vec3 result = ambient + diffuse + specular;
FragColor = vec4(result, 1.0);
}
Binary file added AimGL/resources/Textures/crosshair.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions AimGL/src/CMakeLists_Sources.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ set(PROJECT_SOURCES
States/CustomStates/LogoState.cpp
States/CustomStates/ExitGameState.cpp
States/CustomStates/GameState.cpp
Player/Player.cpp
World/Camera.cpp
World/InfiniteGridFloor.cpp
Utils/Mouse.cpp
Expand Down
170 changes: 170 additions & 0 deletions AimGL/src/Player/Player.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
#include "Player.h"
#include "Utils/Lerp.h"
#include "pch.h"

Player::Player(WindowToRender& window)
: mCamera(window)
, mGun("resources/Models/ak47/ak47.obj",
{{"resources/Models/ak47/ak47-alternative.png", Texture::Type::Diffuse},
{"resources/Models/ak47/ak47-alternative-specular.png", Texture::Type::Specular}})
, mCrosshairTexture("resources/Textures/crosshair.png")
, mCrosshair(mCrosshairTexture)
{
mCrosshair.setPosition({window.getSize().x / 2.f, window.getSize().y / 2.f},
Sprite2D::Origin::Center);
mCrosshair.setOpacity(0.8f);
mCamera.cameraPosition({mPosition.x, mPosition.y + PLAYER_HEGIHT, mPosition.z});
mGun.setPosition(mCamera.cameraPosition(), Model::Origin::Center);
}

void Player::draw(const Renderer& target) const
{
glDepthRange(0.0, 0.01);
mGun.draw(target, mCamera);
glDepthRange(0.0, 1.0);

mCrosshair.draw(target);
}

void Player::updateGunPosition(const float& deltaTime)
{
const glm::vec3 rotationOrigin = {0.3f, -0.2f, -0.35f};
const glm::vec3 targetPosition = {mPosition.x + rotationOrigin.x,
mPosition.y + PLAYER_HEGIHT * 5 / 8,
mPosition.z + rotationOrigin.z};

const auto gunPosition = lerp(mGun.position(), targetPosition, deltaTime * 30.f);
mGun.setPosition(gunPosition, Model::Origin::Center);
mGun.setRotationOrigin(rotationOrigin);

const auto gunTargetPitch =
lerp(mGun.rotation().pitch, mCamera.rotation().pitch, deltaTime * 20.f);
const auto gunTargetYaw =
lerp(mGun.rotation().yaw, -(mCamera.rotation().yaw + 90), deltaTime * 20.f);
mGun.setRotation({gunTargetYaw, gunTargetPitch, 0});
}

void Player::update(const float& deltaTime)
{
mCamera.cameraPosition({mPosition.x, mPosition.y + PLAYER_HEGIHT, mPosition.z});
mCamera.update(deltaTime);
updateGunPosition(deltaTime);
}

void Player::updatePhysics(float deltaTime)
{
handleMovementKeyboardInputs(deltaTime);
decelerateVelocity(deltaTime);
manageVerticalVelocity(deltaTime);
limitVelocity(deltaTime);

mPosition += mVelocity;
if (mPosition.y < 0)
{
mPosition.y = 0;
}
}

void Player::decelerateVelocity(const float& deltaTime)
{
float decayFactor = exp(-PLAYER_WALKING_DECELERATE_RATIO * deltaTime);
mVelocity.x *= decayFactor;
mVelocity.z *= decayFactor;
}

void Player::manageVerticalVelocity(const float& deltaTime)
{
constexpr auto G = -9.81f * 0.01f;
mVelocity.y += G * deltaTime;
}

void Player::limitVelocity(const float& deltaTime)
{
static auto limitVelocitySpeed = [](auto& velocity, const auto& maxVelocity)
{
if (velocity > maxVelocity)
{
velocity = maxVelocity;
}
else if (-velocity > maxVelocity)
{
velocity = -maxVelocity;
}
};

auto playerVelocity = PLAYER_MAX_HORIZONTAL_SPEED * deltaTime;
limitVelocitySpeed(mVelocity.x, playerVelocity);
limitVelocitySpeed(mVelocity.z, playerVelocity);


if (-mVelocity.y > PLAYER_MAX_FALLING_SPEED)
{
mVelocity.y = -PLAYER_MAX_FALLING_SPEED;
}
}

void Player::fixedUpdate(const float& deltaTime)
{
updatePhysics(deltaTime);
}

void Player::handleMovementKeyboardInputs(const float& deltaTime)
{
auto ACCELERATION_RATIO = 0.1f;
glm::vec3 direction = glm::vec3(0.0f, 0.0f, 0.0f);

if (sf::Keyboard::isKeyPressed(sf::Keyboard::W))
{
direction += mCamera.directionWithoutPitch();
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::S))
{
direction -= mCamera.directionWithoutPitch();
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::D))
{
direction += mCamera.rightDirectionWithoutPitch();
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::A))
{
direction -= mCamera.rightDirectionWithoutPitch();
}

if (glm::length(direction) > 0.0f)
{
direction = glm::normalize(direction);// Normalize the combined direction
const auto finalSpeed = PLAYER_WALKING_SPEED * ACCELERATION_RATIO * deltaTime;
mVelocity += finalSpeed * direction;
}
}

void Player::tryJump()
{
if (isOnGround())
{
mVelocity.y = PLAYER_JUMP_FORCE;
}
}

void Player::handleEvent(const sf::Event& event)
{
switch (event.key.code)
{
case sf::Keyboard::Space: tryJump(); break;
}
}

Camera& Player::camera()
{
return mCamera;
}

const Camera& Player::camera() const
{
return mCamera;
}

bool Player::isOnGround() const
{
return mPosition.y <= 0;
}
129 changes: 129 additions & 0 deletions AimGL/src/Player/Player.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
#pragma once
#include <Renderer/Graphics/2D/Sprite2D.h>
#include <Renderer/Graphics/3D/Model.h>
#include <World/Camera.h>

class Renderer;
class Camera;

namespace sf
{
class Event;
}

/**
* \brief The class that defines the player (physics, camera and all things related to the player)
*/
class Player
{
public:
/**
* \brief Player class constructor
* \param window The window into which the player's eye view is rendered
*/
explicit Player(WindowToRender& window);

static constexpr auto PLAYER_HEGIHT = 0.8f;
static constexpr auto PLAYER_MAX_HORIZONTAL_SPEED = 5.f;
static constexpr auto PLAYER_WALKING_DECELERATE_RATIO = 10.f;
static constexpr auto PLAYER_JUMP_FORCE = 0.04f;
static constexpr auto PLAYER_WALKING_SPEED = 2.5f;
static constexpr auto PLAYER_MAX_FALLING_SPEED = 8.f;

/**
* \brief Draws all player components to a given target
* \param target The target to which the model is drawn
*/
void draw(const Renderer& target) const;

/**
* Updates the Player logic dependent, or independent of time, every rendered frame.
* \param deltaTime the time that has passed since the game was last updated.
*/
void update(const float& deltaTime);

/**
* \brief Updates the Player logic at equal intervals independent of the frame rate.
* \param deltaTime Time interval
*/
void fixedUpdate(const float& deltaTime);

/**
* @brief Handles keyboard states such as button presses and responds accordingly
* @param deltaTime the time that has passed since the game was last updated.
*/
void handleMovementKeyboardInputs(const float& deltaTime);

/**
* \brief The player will try to jump if the player is on the ground
*/
void tryJump();

/**
* \brief It takes input (event) from the user and interprets it
* \param event user input
*/
void handleEvent(const sf::Event& event);

/**
* @brief Enables/disables player controls.
*/
void toggleControls();

/**
* \brief Returns the player's camera
* \return Player's camera
*/
Camera& camera();

/**
* \brief Returns the player's camera
* \return Player's camera
*/
const Camera& camera() const;

private:
/**
* \brief Updates the player's physics
* \param deltaTime the time that has passed since the game was last updated.
*/
void updatePhysics(float deltaTime);

/**
* \brief Reduces the player's velocity by gradually decelerating it
* \param deltaTime the time that has passed since the game was last updated.
*/
void decelerateVelocity(const float& deltaTime);

/**
* \brief Controls the player's vertical position by applying gravity, for example
* \param deltaTime the time that has passed since the game was last updated.
*/
void manageVerticalVelocity(const float& deltaTime);

/**
* \brief Limits player's speed to maximum level
* \param deltaTime the time that has passed since the game was last updated.
*/
void limitVelocity(const float& deltaTime);

/**
* \brief Checks if the player is on the ground
* \return True if the player is on the ground, false otherwise
*/
bool isOnGround() const;

/**
* \brief Updates the position of the player's weapon
* \param deltaTime the time that has passed since the game was last updated.
*/
void updateGunPosition(const float& deltaTime);

private:
Camera mCamera;
glm::vec3 mPosition{0, 0, 0};
glm::vec3 mVelocity{0, 0, 0};
Model mGun;
Texture mCrosshairTexture;
Sprite2D mCrosshair;
};
Loading

0 comments on commit b6e7aec

Please sign in to comment.