shooter/player/PlayerController.cpp

242 lines
12 KiB
C++
Raw Normal View History

//
// Created by Иван Ильин on 19.09.2021.
//
#include "PlayerController.h"
#include "../3dzavr/engine/utils/Log.h"
#include "../3dzavr/engine/animation/Animations.h"
PlayerController::PlayerController(std::shared_ptr<Player> player,
std::shared_ptr<Keyboard> keyboard,
2021-10-31 11:39:08 +03:00
std::shared_ptr<Mouse> mouse) : _player(player), _keyboard(keyboard),
_mouse(mouse) {}
void PlayerController::update() {
// friction
2021-10-31 11:39:08 +03:00
if (_player->inCollision()) {
2021-10-28 16:58:02 +03:00
_player->setVelocity(_player->velocity() * (1.0 - Time::deltaTime() * 2));
}
2021-10-31 11:39:08 +03:00
if (_isInSlowMo) {
if (_player->ability() > 0) {
_player->setAbility(_player->ability() - Time::deltaTime());
2021-10-28 16:58:02 +03:00
} else {
_player->setAbility(0);
_isInSlowMo = false;
2021-10-16 20:22:55 +03:00
_player->setVelocity(_player->velocity() * ShooterConsts::SLOW_MO_COEFFICIENT);
2021-10-31 11:39:08 +03:00
_player->setAcceleration(
_player->acceleration() * ShooterConsts::SLOW_MO_COEFFICIENT * ShooterConsts::SLOW_MO_COEFFICIENT);
2021-10-17 19:38:16 +03:00
SoundController::stopSound(SoundTag("slowMo"));
2022-02-23 17:29:42 +03:00
SoundController::loadAndPlay(SoundTag("unSlowMo"), ShooterConsts::UN_SLOW_MO_SOUND);
}
}
2021-10-16 20:22:55 +03:00
double coeff = _isInSlowMo ? 1.0 / ShooterConsts::SLOW_MO_COEFFICIENT : 1.0;
bool inRunning_old = _inRunning;
2021-10-31 11:39:08 +03:00
_inRunning = (Keyboard::isKeyPressed(sf::Keyboard::A) ||
Keyboard::isKeyPressed(sf::Keyboard::D) ||
Keyboard::isKeyPressed(sf::Keyboard::W) ||
Keyboard::isKeyPressed(sf::Keyboard::S));
std::shared_ptr<Object> camera = _player->attached(ObjectNameTag("Camera"));
2022-07-07 13:14:00 +03:00
if(camera != nullptr) {
// random motion during high speed
if (!Timeline::isInAnimList(AnimationListTag("high_speed_motion"))) {
2022-07-11 16:58:05 +03:00
double d_alpha = _player->velocity().abs()/2000*rand()/RAND_MAX;
double dt = 0.12;
2022-07-07 13:14:00 +03:00
Timeline::addAnimation<ARotateLeftUpLookAt>(AnimationListTag("high_speed_motion"),
camera, Vec3D(0, 0, d_alpha), dt,
Animation::LoopOut::None,
Animation::InterpolationType::Cos);
Timeline::addAnimation<AWait>(AnimationListTag("high_speed_motion"), 0);
Timeline::addAnimation<ARotateLeftUpLookAt>(AnimationListTag("high_speed_motion"),
camera, Vec3D(0, 0, -d_alpha), dt,
Animation::LoopOut::None,
Animation::InterpolationType::Cos);
Timeline::addAnimation<AWait>(AnimationListTag("high_speed_motion"), 0);
}
}
2021-10-31 11:39:08 +03:00
if (camera != nullptr && _inRunning && _player->inCollision()) {
2021-10-17 10:21:10 +03:00
if (!Timeline::isInAnimList(AnimationListTag("camera_hor_oscil"))) {
2021-11-09 22:54:20 +03:00
Timeline::addAnimation<ATranslate>(AnimationListTag("camera_hor_oscil"),
camera, -camera->left() / 6, 0.3,
Animation::LoopOut::None,
Animation::InterpolationType::Cos);
Timeline::addAnimation<AWait>(AnimationListTag("camera_hor_oscil"), 0);
Timeline::addAnimation<ATranslate>(AnimationListTag("camera_hor_oscil"),
camera, camera->left() / 6, 0.3,
Animation::LoopOut::None,
Animation::InterpolationType::Cos);
2021-10-02 20:36:07 +03:00
2021-11-09 22:54:20 +03:00
Timeline::addAnimation<ATranslate>(AnimationListTag("camera_vert_oscil"),
camera, -Vec3D{0, 1, 0} / 12, 0.15,
Animation::LoopOut::None,
Animation::InterpolationType::Cos);
Timeline::addAnimation<AWait>(AnimationListTag("camera_vert_oscil"), 0);
Timeline::addAnimation<ATranslate>(AnimationListTag("camera_vert_oscil"),
camera, Vec3D{0, 1, 0} / 12, 0.15,
Animation::LoopOut::None,
Animation::InterpolationType::Cos);
Timeline::addAnimation<AWait>(AnimationListTag("camera_vert_oscil"), 0);
Timeline::addAnimation<ATranslate>(AnimationListTag("camera_vert_oscil"),
camera, -Vec3D{0, 1, 0} / 12, 0.15,
Animation::LoopOut::None,
Animation::InterpolationType::Cos);
Timeline::addAnimation<AWait>(AnimationListTag("camera_vert_oscil"), 0);
Timeline::addAnimation<ATranslate>(AnimationListTag("camera_vert_oscil"),
camera, Vec3D{0, 1, 0} / 12, 0.15,
Animation::LoopOut::None,
Animation::InterpolationType::Cos);
2021-10-31 11:39:08 +03:00
2021-11-09 22:54:20 +03:00
Timeline::addAnimation<ATranslateToPoint>(AnimationListTag("camera_init"),
camera, _player->position() + Vec3D{0, 1.8, 0},
0.3,
Animation::LoopOut::None,
Animation::InterpolationType::Cos);
2021-10-02 20:36:07 +03:00
}
2021-10-31 11:39:08 +03:00
} else if (camera != nullptr && inRunning_old && !_inRunning) {
2021-10-17 10:21:10 +03:00
Timeline::deleteAnimationList(AnimationListTag("camera_hor_oscil"));
Timeline::deleteAnimationList(AnimationListTag("camera_vert_oscil"));
Timeline::deleteAnimationList(AnimationListTag("camera_init"));
2021-11-09 22:54:20 +03:00
Timeline::addAnimation<ATranslateToPoint>(AnimationListTag("camera_init"),
camera, _player->position() + Vec3D{0, 1.8, 0}, 0.15,
Animation::LoopOut::None,
Animation::InterpolationType::Cos);
}
// Left and right
2021-10-02 20:36:07 +03:00
if (Keyboard::isKeyPressed(sf::Keyboard::A)) {
2021-10-16 20:22:55 +03:00
_player->translate(_player->left() * Time::deltaTime() * ShooterConsts::WALK_SPEED * coeff);
2021-10-31 11:39:08 +03:00
if (_player->inCollision()) {
2021-10-28 16:58:02 +03:00
_player->setVelocity(Vec3D{0, 0, 0});
}
}
if (Keyboard::isKeyPressed(sf::Keyboard::D)) {
2021-10-16 20:22:55 +03:00
_player->translate(-_player->left() * Time::deltaTime() * ShooterConsts::WALK_SPEED * coeff);
2021-10-31 11:39:08 +03:00
if (_player->inCollision()) {
2021-10-28 16:58:02 +03:00
_player->setVelocity(Vec3D{0, 0, 0});
}
}
// Forward and backward
if (Keyboard::isKeyPressed(sf::Keyboard::W)) {
2021-10-16 20:22:55 +03:00
_player->translate(_player->lookAt() * Time::deltaTime() * ShooterConsts::WALK_SPEED * coeff);
2021-10-31 11:39:08 +03:00
if (_player->inCollision()) {
2021-10-28 16:58:02 +03:00
_player->setVelocity(Vec3D{0, 0, 0});
}
}
if (Keyboard::isKeyPressed(sf::Keyboard::S)) {
2021-10-16 20:22:55 +03:00
_player->translate(-_player->lookAt() * Time::deltaTime() * ShooterConsts::WALK_SPEED * coeff);
2021-10-31 11:39:08 +03:00
if (_player->inCollision()) {
2021-10-28 16:58:02 +03:00
_player->setVelocity(Vec3D{0, 0, 0});
}
}
if (_player->ability() > 0 && !_isInSlowMo && Keyboard::isKeyPressed(sf::Keyboard::LShift)) {
// slow mo
_isInSlowMo = true;
2021-10-16 20:22:55 +03:00
_player->setVelocity(_player->velocity() / ShooterConsts::SLOW_MO_COEFFICIENT);
2021-10-31 11:39:08 +03:00
_player->setAcceleration(Vec3D(0, -ShooterConsts::GRAVITY /
(ShooterConsts::SLOW_MO_COEFFICIENT * ShooterConsts::SLOW_MO_COEFFICIENT),
0));
2021-10-17 19:38:16 +03:00
SoundController::stopSound(SoundTag("unSlowMo"));
2022-02-23 17:29:42 +03:00
SoundController::loadAndPlay(SoundTag("slowMo"), ShooterConsts::SLOW_MO_SOUND);
} else if (_isInSlowMo && !Keyboard::isKeyPressed(sf::Keyboard::LShift)) {
_isInSlowMo = false;
2021-10-16 20:22:55 +03:00
_player->setVelocity(_player->velocity() * ShooterConsts::SLOW_MO_COEFFICIENT);
2021-10-17 10:25:09 +03:00
_player->setAcceleration(Vec3D(0, -ShooterConsts::GRAVITY, 0));
2021-10-17 19:38:16 +03:00
SoundController::stopSound(SoundTag("slowMo"));
2022-02-23 17:29:42 +03:00
SoundController::loadAndPlay(SoundTag("unSlowMo"), ShooterConsts::UN_SLOW_MO_SOUND);
}
2021-10-22 19:42:32 +03:00
if (Mouse::isButtonPressed(sf::Mouse::Button::Left)) {
bool shot = _player->fire();
2021-10-31 11:39:08 +03:00
if (shot) {
2021-10-31 19:01:06 +03:00
if (_player->weapon()->name() == ObjectNameTag("shotgun")) {
2021-10-22 19:42:32 +03:00
_player->addVelocity(-camera->lookAt() * 30 * coeff);
2021-10-28 16:58:02 +03:00
}
2021-10-22 19:42:32 +03:00
}
}
if (Keyboard::isKeyPressed(sf::Keyboard::Space) && _player->inCollision()) {
2021-10-09 13:41:12 +03:00
// if we just want to jump, we have to add particular speed
2022-07-07 13:14:00 +03:00
2021-10-28 16:58:02 +03:00
if (!_isSliding) {
_player->addVelocity(Vec3D{0, std::abs(_player->collisionNormal().y()) *
sqrt(2 * -_player->acceleration().y() * ShooterConsts::JUMP_HEIGHT) * coeff,
0});
// if we want to slide, we have to add speed * 60/fps to make it independent on frame rate
} else {
_player->addVelocity(Vec3D{0, std::abs(_player->collisionNormal().y()) *
sqrt(2 * -_player->acceleration().y() * ShooterConsts::JUMP_HEIGHT) * coeff *
Time::deltaTime() * 60, 0});
}
2021-10-31 11:39:08 +03:00
_player->translate(Vec3D{0, Time::deltaTime() * ShooterConsts::WALK_SPEED * 2 * coeff, 0});
2022-07-07 13:14:00 +03:00
//_player->setVelocity(Vec3D{_player->velocity().x(), sqrt(2 * -_player->acceleration().y() * ShooterConsts::JUMP_HEIGHT) * coeff,_player->velocity().z()});
2021-10-09 13:41:12 +03:00
_isSliding = true;
} else {
_isSliding = false;
}
// Mouse movement
Vec2D displacement = _mouse->getMouseDisplacement();
2021-10-16 20:22:55 +03:00
_player->rotate(Vec3D{0, -displacement.x() * ShooterConsts::MOUSE_SENSITIVITY, 0});
2022-07-07 13:14:00 +03:00
_player->setVelocity(Matrix4x4::RotationY(-displacement.x() * ShooterConsts::MOUSE_SENSITIVITY) * _player->velocity());
2021-10-16 20:22:55 +03:00
double rotationLeft = displacement.y() * ShooterConsts::MOUSE_SENSITIVITY;
// You can only see in range [-90 : 90] grad
2021-10-28 16:58:02 +03:00
if (_player->headAngle() + rotationLeft > Consts::PI / 2) {
2021-10-09 13:41:12 +03:00
rotationLeft = Consts::PI / 2 - _player->headAngle();
2021-10-28 16:58:02 +03:00
}
if (_player->headAngle() + rotationLeft < -Consts::PI / 2) {
2021-10-09 13:41:12 +03:00
rotationLeft = -Consts::PI / 2 - _player->headAngle();
2021-10-28 16:58:02 +03:00
}
2021-10-02 20:36:07 +03:00
_player->setHeadAngle(_player->headAngle() + rotationLeft);
_player->rotateWeaponsRelativePoint(_player->position() + Vec3D{0, 1.8, 0}, _player->left(), rotationLeft);
2021-10-31 11:39:08 +03:00
if (camera != nullptr) {
2022-07-07 13:14:00 +03:00
double lookAtAngle = camera->angleLeftUpLookAt().z();
camera->rotateLookAt(-lookAtAngle);
camera->rotateLeft(_player->headAngle() - camera->angleLeftUpLookAt().x());
2022-07-07 13:14:00 +03:00
camera->rotateLookAt(lookAtAngle);
2021-10-28 16:58:02 +03:00
}
if (_keyboard->isKeyTapped(sf::Keyboard::Right) || _keyboard->isKeyTapped(sf::Keyboard::E)) {
2021-10-31 19:01:06 +03:00
_player->selectNextWeapon();
}
if (_keyboard->isKeyTapped(sf::Keyboard::Left) || _keyboard->isKeyTapped(sf::Keyboard::Q)) {
2021-10-31 19:01:06 +03:00
_player->selectPreviousWeapon();
}
2021-10-31 11:39:08 +03:00
if (Keyboard::isKeyPressed(sf::Keyboard::R)) {
_player->reload();
}
bool walkSoundPlayed = false;
2021-10-31 11:39:08 +03:00
for (int k = 1; k < 7; k++) {
if (SoundController::getStatus(SoundTag("walkSound_" + std::to_string(k))) == sf::Sound::Status::Playing) {
walkSoundPlayed = true;
}
}
if ((_inRunning || _player->velocity().sqrAbs() > 3) && _player->inCollision() && !walkSoundPlayed) {
2021-10-31 11:39:08 +03:00
int soundNum = (int) ((double) rand() / RAND_MAX * 6) + 1;
2022-02-23 17:29:42 +03:00
SoundController::loadAndPlay(SoundTag("walkSound_" + std::to_string(soundNum)),
2021-10-31 11:39:08 +03:00
"sound/stonestep" + std::to_string(soundNum) + ".ogg");
}
}