Skip to content

Commit

Permalink
Add walking, shooting sounds and gun recoil feeling
Browse files Browse the repository at this point in the history
The gun makes sounds when firing, moves and the camera also shakes.
There are also sounds of walking on the ground.
  • Loading branch information
Notiooo committed Dec 1, 2023
1 parent ff216a9 commit 0a8f72b
Show file tree
Hide file tree
Showing 12 changed files with 300 additions and 41 deletions.
Binary file added AimGL/resources/Sounds/footsteps.wav
Binary file not shown.
Binary file added AimGL/resources/Sounds/gunshot.wav
Binary file not shown.
1 change: 1 addition & 0 deletions AimGL/src/CMakeLists_Sources.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,6 @@ set(PROJECT_SOURCES
Player/Player.cpp
World/Camera.cpp
World/InfiniteGridFloor.cpp
World/GameObjects/Rifle.cpp
Utils/Mouse.cpp
)
54 changes: 30 additions & 24 deletions AimGL/src/Player/Player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,51 +4,34 @@

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)
, mRifle(mCamera)
{
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);
mSoundBuffer.loadFromFile("resources/Sounds/footsteps.wav");
mWalkingSound.setBuffer(mSoundBuffer);
mWalkingSound.setVolume(50);
mRifle.update(1);
}

void Player::draw(const Renderer& target) const
{
glDepthRange(0.0, 0.01);
mGun.draw(target, mCamera);
mRifle.draw(target);
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);
mRifle.update(deltaTime);
}

void Player::updatePhysics(float deltaTime)
Expand Down Expand Up @@ -108,6 +91,27 @@ void Player::fixedUpdate(const float& deltaTime)
updatePhysics(deltaTime);
}

void Player::manageWalkingSounds(const glm::vec3& playerWalkingVector)
{
constexpr auto noDirection = glm::vec3(0.0f, 0.0f, 0.0f);
switch (mWalkingSound.getStatus())
{
case sf::Sound::Status::Playing:
if (playerWalkingVector == noDirection or not isOnGround())
{
mWalkingSound.stop();
}
break;
case sf::Sound::Status::Paused:
case sf::Sound::Status::Stopped:
if (playerWalkingVector != noDirection and isOnGround())
{
mWalkingSound.play();
}
break;
}
}

void Player::handleMovementKeyboardInputs(const float& deltaTime)
{
auto ACCELERATION_RATIO = 0.1f;
Expand All @@ -129,6 +133,7 @@ void Player::handleMovementKeyboardInputs(const float& deltaTime)
{
direction -= mCamera.rightDirectionWithoutPitch();
}
manageWalkingSounds(direction);

if (glm::length(direction) > 0.0f)
{
Expand All @@ -152,6 +157,7 @@ void Player::handleEvent(const sf::Event& event)
{
case sf::Keyboard::Space: tryJump(); break;
}
mRifle.handleEvent(event);
}

Camera& Player::camera()
Expand Down
13 changes: 8 additions & 5 deletions AimGL/src/Player/Player.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#pragma once
#include <Renderer/Graphics/2D/Sprite2D.h>
#include <Renderer/Graphics/3D/Model.h>
#include <World/Camera.h>
#include <World/GameObjects/Rifle.h>

class Renderer;
class Camera;
Expand Down Expand Up @@ -114,16 +114,19 @@ class Player
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.
* \brief Manages walking sound effects based on the player's movement.
* \param playerWalkingVector glm::vec3 indicating the direction of player movement.
* A zero vector suggests no movement, while a non-zero vector indicates movement.
*/
void updateGunPosition(const float& deltaTime);
void manageWalkingSounds(const glm::vec3& playerWalkingVector);

private:
Camera mCamera;
glm::vec3 mPosition{0, 0, 0};
glm::vec3 mVelocity{0, 0, 0};
Model mGun;
Rifle mRifle;
Texture mCrosshairTexture;
Sprite2D mCrosshair;
sf::SoundBuffer mSoundBuffer;
sf::Sound mWalkingSound;
};
69 changes: 69 additions & 0 deletions AimGL/src/Renderer/Graphics/3D/Utils/Rotation3D.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,27 @@
#include "Rotation3D.h"
#include "pch.h"

Rotation3D::Rotation3D()
: mRotation(0, 0, 0)
{
}

Rotation3D::Rotation3D(float yaw, float pitch, float roll)
: mRotation(yaw, pitch, roll)
{
}

Rotation3D::Rotation3D(const Rotation3D& rotation)
: mRotation(rotation.mRotation)
{
}

Rotation3D& Rotation3D::operator=(const Rotation3D& rotation)
{
mRotation = rotation.mRotation;
return *this;
}

glm::mat4 Rotation3D::rotate(glm::mat4 model, std::initializer_list<EulerAngle> ordering) const
{
for (const auto axisRotation: ordering)
Expand All @@ -27,3 +48,51 @@ void Rotation3D::imGuiRotationSlider()
ImGui::SliderFloat("Pitch", &pitch, -360, 360.0f);
ImGui::SliderFloat("Yaw", &yaw, -360, 360.0f);
}

bool Rotation3D::operator==(const Rotation3D& rhs) const
{
return mRotation == rhs.mRotation;
}

Rotation3D Rotation3D::operator+(const Rotation3D& rhs) const
{
return Rotation3D(mRotation + rhs.mRotation);
}

Rotation3D Rotation3D::operator-(const Rotation3D& rhs) const
{
return Rotation3D(mRotation - rhs.mRotation);
}

Rotation3D Rotation3D::operator*(const Rotation3D& rhs) const
{
return Rotation3D(mRotation * rhs.mRotation);
}

Rotation3D& Rotation3D::operator+=(const Rotation3D& rhs)
{
mRotation += rhs.mRotation;
return *this;
}

Rotation3D& Rotation3D::operator-=(const Rotation3D& rhs)
{
mRotation -= rhs.mRotation;
return *this;
}

Rotation3D& Rotation3D::operator*=(const Rotation3D& rhs)
{
mRotation *= rhs.mRotation;
return *this;
}

Rotation3D::operator glm::vec<3, float>()
{
return mRotation;
}

Rotation3D::Rotation3D(const glm::vec3& rotation)
: mRotation(rotation)
{
}
39 changes: 35 additions & 4 deletions AimGL/src/Renderer/Graphics/3D/Utils/Rotation3D.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,25 @@
/**
* \brief Represents a 3D rotation using Euler angles.
*/
struct Rotation3D
class Rotation3D
{
glm::vec3 mRotation{0, 0, 0};

public:
Rotation3D();
Rotation3D(float yaw, float pitch, float roll);
Rotation3D(const Rotation3D& rotation);
Rotation3D& operator=(const Rotation3D& rotation);
bool operator==(const Rotation3D&) const;
Rotation3D operator+(const Rotation3D&) const;
Rotation3D operator-(const Rotation3D&) const;
Rotation3D operator*(const Rotation3D&) const;
Rotation3D& operator+=(const Rotation3D&);
Rotation3D& operator-=(const Rotation3D&);
Rotation3D& operator*=(const Rotation3D&);
friend Rotation3D operator*(const Rotation3D& lhs, float rhs);
explicit operator glm::vec3();

/**
* \brief Angles of Euler rotation.
*/
Expand All @@ -15,9 +32,9 @@ struct Rotation3D
YAW
};

float yaw{0};
float pitch{0};
float roll{0};
float& yaw = mRotation.x;
float& pitch = mRotation.y;
float& roll = mRotation.z;

/**
* \brief Applies rotation to a 3D model matrix in a specified order.
Expand All @@ -33,4 +50,18 @@ struct Rotation3D
* \brief Renders an ImGui slider interface for adjusting the rotation.
*/
void imGuiRotationSlider();

private:
explicit Rotation3D(const glm::vec3& rotation);
};


inline Rotation3D operator*(const Rotation3D& lhs, float rhs)
{
return Rotation3D(lhs.mRotation * rhs);
}

inline Rotation3D operator*(float lhs, const Rotation3D& rhs)
{
return rhs * lhs;
}
2 changes: 1 addition & 1 deletion AimGL/src/States/CustomStates/GameState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ bool GameState::update(const float& deltaTime)
{
mPhaseInLogoColor.setOpacity(mPhaseInLogoColor.opacity() - deltaTime / 4.f);
}
mTree.showDebugImGui("Tree");
return true;
}

Expand All @@ -82,5 +81,6 @@ bool GameState::updateImGui(const float& deltaTime)
MTR_SCOPE("GameState", "GameState::updateImGui");
mInfiniteGridFloor.showDebugImGui();
mLogo.showDebugImGui("Logo");
mTree.showDebugImGui("Tree");
return true;
}
29 changes: 24 additions & 5 deletions AimGL/src/World/Camera.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include "Utils/Mouse.h"
#include <SFML/Window/Keyboard.hpp>
#include <Utils/Lerp.h>

Camera::Camera(const WindowToRender& target)
: mRenderTarget(target)
Expand All @@ -14,8 +15,20 @@ Camera::Camera(const WindowToRender& target)
glm::radians(0.0f), static_cast<float>(targetSize.x / targetSize.y), 1.f, 100.f);
}

void Camera::updateShakeValues(const float& deltaTime)
{
constexpr auto tolerance = 2.f;
mCurrentShakeValues = lerp(mCurrentShakeValues, mTargetShakeValues, deltaTime * 6.f);
auto difference = glm::abs(static_cast<glm::vec3>(mCurrentShakeValues - mTargetShakeValues));
if (difference.x <= tolerance && difference.y <= tolerance && difference.z <= tolerance)
{
mTargetShakeValues = {0, 0, 0};
}
}

void Camera::update(const float& deltaTime)
{
updateShakeValues(deltaTime);
handleMouseInputs(deltaTime);

auto width = static_cast<float>(mRenderTarget.getSize().x);
Expand All @@ -41,15 +54,16 @@ void Camera::handleMouseInputs(const float& deltaTime)

void Camera::calculateCameraDirectionVector()
{
auto rotation = mRotation + mCurrentShakeValues;
glm::vec3 direction;
direction.x = cos(glm::radians(mRotation.yaw)) * cos(glm::radians(mRotation.pitch));
direction.y = sin(glm::radians(mRotation.pitch));
direction.z = sin(glm::radians(mRotation.yaw)) * cos(glm::radians(mRotation.pitch));
direction.x = cos(glm::radians(rotation.yaw)) * cos(glm::radians(rotation.pitch));
direction.y = sin(glm::radians(rotation.pitch));
direction.z = sin(glm::radians(rotation.yaw)) * cos(glm::radians(rotation.pitch));
mCameraFront = glm::normalize(direction);

direction.x = cos(glm::radians(mRotation.yaw));
direction.x = cos(glm::radians(rotation.yaw));
direction.y = 0;
direction.z = sin(glm::radians(mRotation.yaw));
direction.z = sin(glm::radians(rotation.yaw));
mCameraFrontWithoutPitch = glm::normalize(direction);
}

Expand Down Expand Up @@ -157,6 +171,11 @@ Rotation3D Camera::rotation() const
return mRotation;
}

void Camera::shake()
{
mTargetShakeValues = {0.f, 4.f, 0.f};
}

glm::vec3 Camera::direction() const
{
return mCameraFront;
Expand Down
Loading

0 comments on commit 0a8f72b

Please sign in to comment.