small refactoring

master
Vectozavr 2022-02-23 21:29:42 +07:00
parent 43de35309b
commit b4d7373461
16 changed files with 124 additions and 92 deletions

View File

@ -60,7 +60,7 @@ void Player::collisionWithObject(const ObjectNameTag &tag, std::shared_ptr<Rigid
}
void Player::addWeapon(std::shared_ptr<Weapon> weapon) {
SoundController::playSound(SoundTag("changeWeapon"), ShooterConsts::CHANGE_WEAPON_SOUND);
SoundController::loadAndPlay(SoundTag("changeWeapon"), ShooterConsts::CHANGE_WEAPON_SOUND);
for (auto &w : _weapons) {
if (w->name() == weapon->name()) {
@ -125,7 +125,7 @@ void Player::selectNextWeapon() {
_addWeaponCallBack(_weapons[_selectedWeapon]);
}
Log::log("selectedWeapon " + std::to_string(_selectedWeapon));
SoundController::playSound(SoundTag("changeWeapon"), ShooterConsts::CHANGE_WEAPON_SOUND);
SoundController::loadAndPlay(SoundTag("changeWeapon"), ShooterConsts::CHANGE_WEAPON_SOUND);
}
}
@ -144,7 +144,7 @@ void Player::selectPreviousWeapon() {
_addWeaponCallBack(_weapons[_selectedWeapon]);
}
Log::log("selectedWeapon " + std::to_string(_selectedWeapon));
SoundController::playSound(SoundTag("changeWeapon"), ShooterConsts::CHANGE_WEAPON_SOUND);
SoundController::loadAndPlay(SoundTag("changeWeapon"), ShooterConsts::CHANGE_WEAPON_SOUND);
}
}
@ -169,10 +169,10 @@ void Player::reload() {
void Player::setFullHealth() {
_health = ShooterConsts::HEALTH_MAX;
SoundController::playSound(SoundTag("addHealth"), ShooterConsts::RESTORE_HEALTH_SOUND);
SoundController::loadAndPlay(SoundTag("addHealth"), ShooterConsts::RESTORE_HEALTH_SOUND);
}
void Player::setFullAbility() {
_ability = ShooterConsts::ABILITY_MAX;
SoundController::playSound(SoundTag("addAbility"), ShooterConsts::RESTORE_ABILITY_SOUND);
SoundController::loadAndPlay(SoundTag("addAbility"), ShooterConsts::RESTORE_ABILITY_SOUND);
}

View File

@ -28,7 +28,7 @@ void PlayerController::update() {
_player->setAcceleration(
_player->acceleration() * ShooterConsts::SLOW_MO_COEFFICIENT * ShooterConsts::SLOW_MO_COEFFICIENT);
SoundController::stopSound(SoundTag("slowMo"));
SoundController::playSound(SoundTag("unSlowMo"), ShooterConsts::UN_SLOW_MO_SOUND);
SoundController::loadAndPlay(SoundTag("unSlowMo"), ShooterConsts::UN_SLOW_MO_SOUND);
}
}
@ -128,13 +128,13 @@ void PlayerController::update() {
(ShooterConsts::SLOW_MO_COEFFICIENT * ShooterConsts::SLOW_MO_COEFFICIENT),
0));
SoundController::stopSound(SoundTag("unSlowMo"));
SoundController::playSound(SoundTag("slowMo"), ShooterConsts::SLOW_MO_SOUND);
SoundController::loadAndPlay(SoundTag("slowMo"), ShooterConsts::SLOW_MO_SOUND);
} else if (_isInSlowMo && !Keyboard::isKeyPressed(sf::Keyboard::LShift)) {
_isInSlowMo = false;
_player->setVelocity(_player->velocity() * ShooterConsts::SLOW_MO_COEFFICIENT);
_player->setAcceleration(Vec3D(0, -ShooterConsts::GRAVITY, 0));
SoundController::stopSound(SoundTag("slowMo"));
SoundController::playSound(SoundTag("unSlowMo"), ShooterConsts::UN_SLOW_MO_SOUND);
SoundController::loadAndPlay(SoundTag("unSlowMo"), ShooterConsts::UN_SLOW_MO_SOUND);
}
if (Mouse::isButtonPressed(sf::Mouse::Button::Left)) {
@ -209,7 +209,7 @@ void PlayerController::update() {
}
if ((_inRunning || _player->velocity().sqrAbs() > 3) && _player->inCollision() && !walkSoundPlayed) {
int soundNum = (int) ((double) rand() / RAND_MAX * 6) + 1;
SoundController::playSound(SoundTag("walkSound_" + std::to_string(soundNum)),
SoundController::loadAndPlay(SoundTag("walkSound_" + std::to_string(soundNum)),
"sound/stonestep" + std::to_string(soundNum) + ".ogg");
}
}

View File

@ -29,19 +29,20 @@ Source code of simple shooter on [3Dzavr game engine](https://github.com/vectoza
<h4>Control:</h4>
<b>SHIFT</b> - slow motion (this ability is not infinite: its bar is next to hp)
<b>Mouse</b>, <b>Space</b>, <b>A</b>, <b>S</b>, <b>W</b>, <b>D</b> player control.
<b>E & Q </b> or keys <b> <- -> </b> - change weapon
<b>SHIFT</b> slow motion (this ability is not infinite: its bar is next to hp)
<b>R</b> - recharge
<b>E & Q </b> or keys <b> <- -> </b> change weapon
Player control is standard.
<b>R</b> recharge
<b>O</b> turn OpenGL on/off
<b>Tab</b> turn debug mode on/off
<h4>Playing with a source code:</h4>
Structure:
![Project demonstration](img/structure.png)
1) [Download and install OpenAL library](https://openal.org/downloads/) for SFML sound support (in current version you can't setup this engine without OpenAL)
2) Clone this repository
@ -56,7 +57,8 @@ Structure:
P/S: <b>SFML for 32-bit OS Windows is already included into this repository.</b> So, you don't need to manually install it to your computer. If you have any problems with SFML, you can try to [download another version or build SFML by yourself.](https://www.sfml-dev.org/download.php)
Demos:
Structure:
![Project demonstration](img/structure.png)
Online:
![Project demonstration](img/gamePlay4.png)

View File

@ -113,14 +113,14 @@ void Shooter::start() {
mainMenu.addButton(screen->width() / 2, 200, 200, 20, [this]() {
this->play();
SoundController::playSound(SoundTag("click"), ShooterConsts::CLICK_SOUND);
SoundController::loadAndPlay(SoundTag("click"), ShooterConsts::CLICK_SOUND);
}, "Server: " + client->serverIp().toString(), 5, 5, ShooterConsts::MAIN_MENU_GUI, {0, 66}, {0, 86}, {0, 46},
Consts::MEDIUM_FONT, {255, 255, 255});
mainMenu.addButton(screen->width() / 2, 350, 200, 20, [this]() {
this->player->translateToPoint(Vec3D{0, 0, 0});
this->player->setVelocity({});
this->play();
SoundController::playSound(SoundTag("click"), ShooterConsts::CLICK_SOUND);
SoundController::loadAndPlay(SoundTag("click"), ShooterConsts::CLICK_SOUND);
}, "Respawn", 5, 5, ShooterConsts::MAIN_MENU_GUI, {0, 66}, {0, 86}, {0, 46}, Consts::MEDIUM_FONT, {255, 255, 255});
mainMenu.addButton(screen->width() / 2, 500, 200, 20, [this]() {
@ -173,7 +173,7 @@ void Shooter::update() {
// background sounds and music control
if (SoundController::getStatus(SoundTag("background")) != sf::Sound::Status::Playing) {
SoundController::playSound(SoundTag("background"), ShooterConsts::BACK_NOISE);
SoundController::loadAndPlay(SoundTag("background"), ShooterConsts::BACK_NOISE);
}
}
@ -280,9 +280,9 @@ void Shooter::spawnPlayer(sf::Uint16 id) {
int colorBodyNum = static_cast<int> (static_cast<double>((rand() - 1)) / RAND_MAX * 5.0);
int colorFootNum = static_cast<int> (static_cast<double>((rand() - 1)) / RAND_MAX * 5.0);
newPlayer->setColor(ShooterConsts::WHITE_COLORS[colorBodyNum]);
world->body(ObjectNameTag(name + "_foot_1"))->setColor(ShooterConsts::DARK_COLORS[colorFootNum]);
world->body(ObjectNameTag(name + "_foot_2"))->setColor(ShooterConsts::DARK_COLORS[colorFootNum]);
newPlayer->setColor(Consts::WHITE_COLORS[colorBodyNum]);
world->body(ObjectNameTag(name + "_foot_1"))->setColor(Consts::DARK_COLORS[colorFootNum]);
world->body(ObjectNameTag(name + "_foot_2"))->setColor(Consts::DARK_COLORS[colorFootNum]);
changeEnemyWeapon("gun", id);
}

View File

@ -19,17 +19,17 @@ void ShooterClient::updatePacket() {
void ShooterClient::processInit(sf::Packet &packet) {
sf::Uint16 targetId;
double buf[4];
double x, y, z, health;
int kills, deaths;
while (packet >> targetId >> buf[0] >> buf[1] >> buf[2] >> buf[3] >> kills >> deaths) {
while (packet >> targetId >> x >> y >> z >> health >> kills >> deaths) {
if (targetId != _socket.ownId()) {
if (_spawnPlayerCallBack != nullptr) {
_spawnPlayerCallBack(targetId);
}
_players[targetId]->translateToPoint(Vec3D{buf[0], buf[1], buf[2]});
_players[targetId]->setHealth(buf[3]);
_players[targetId]->translateToPoint(Vec3D{x, y, z});
_players[targetId]->setHealth(health);
_players[targetId]->setKills(kills);
_players[targetId]->setDeaths(deaths);
}
@ -38,21 +38,21 @@ void ShooterClient::processInit(sf::Packet &packet) {
void ShooterClient::processUpdate(sf::Packet &packet) {
sf::Uint16 targetId;
double buf[6];
double x, y, z, health, bodyAngle, headAngle;
std::string playerName;
while (packet >> targetId >> buf[0] >> buf[1] >> buf[2] >> buf[3] >> buf[4] >> buf[5] >> playerName) {
while (packet >> targetId >> x >> y >> z >> health >> bodyAngle >> headAngle >> playerName) {
if (_players.count(targetId)) {
std::string name = "Enemy_" + std::to_string(targetId);
Vec3D newPosition = Vec3D{buf[0], buf[1], buf[2]};
Vec3D newPosition = Vec3D{x, y, z};
bool isAnimate = (_players[targetId]->position() - newPosition).sqrAbs() > 0.2;
_players[targetId]->translateToPoint(newPosition);
_players[targetId]->setHealth(buf[3]);
_players[targetId]->rotateToAngle(Vec3D{0, buf[4], 0});
_players[targetId]->setHealth(health);
_players[targetId]->rotateToAngle(Vec3D{0, bodyAngle, 0});
_players[targetId]->setPlayerNickName(playerName);
auto head = _players[targetId]->attached(ObjectNameTag(name + "_head"));
@ -62,10 +62,10 @@ void ShooterClient::processUpdate(sf::Packet &packet) {
auto foot2 = _players[targetId]->attached(ObjectNameTag(name + "_foot_2"));
if (head != nullptr) {
head->rotateLeft(buf[5] - _players[targetId]->headAngle());
head->rotateLeft(headAngle - _players[targetId]->headAngle());
}
if (weapon != nullptr) {
weapon->rotateLeft(buf[5] - _players[targetId]->headAngle());
weapon->rotateLeft(headAngle - _players[targetId]->headAngle());
}
if (isAnimate) {
@ -97,9 +97,9 @@ void ShooterClient::processUpdate(sf::Packet &packet) {
}
}
_players[targetId]->setHeadAngle(buf[5]);
_players[targetId]->setHeadAngle(headAngle);
} else if (targetId == _socket.ownId()) {
_player->setHealth(buf[3]);
_player->setHealth(health);
}
}
}
@ -136,7 +136,7 @@ void ShooterClient::processCustomPacket(sf::Packet &packet) {
_lastEvent = "";
if (buffId[1] == _socket.ownId()) {
_player->addKill();
SoundController::playSound(SoundTag("kill"), ShooterConsts::KILL_SOUND);
SoundController::loadAndPlay(SoundTag("kill"), ShooterConsts::KILL_SOUND);
_lastEvent += _player->playerNickName();
} else {
_players[buffId[1]]->addKill();
@ -182,7 +182,7 @@ void ShooterClient::processCustomPacket(sf::Packet &packet) {
}, 1, 0.1);
SoundController::playSound(SoundTag("death"), ShooterConsts::DEATH_SOUND);
SoundController::loadAndPlay(SoundTag("death"), ShooterConsts::DEATH_SOUND);
_lastEvent += _player->playerNickName();
} else {
_players[buffId[0]]->addDeath();

View File

@ -60,22 +60,6 @@ namespace ShooterConsts {
const std::string SLOW_MO_SOUND = "sound/slow_mo.ogg";
const std::string UN_SLOW_MO_SOUND = "sound/unslow_mo.ogg";
const std::string NO_AMMO_SOUND = "sound/weapons/no_ammo.ogg";
const sf::Color WHITE_COLORS[] = {
sf::Color(137, 135, 222), // blue
sf::Color(195, 155, 209), // pink
sf::Color(201, 137, 137), // red
sf::Color(116, 204, 135), // green
sf::Color(201, 171, 137), // orange
};
const sf::Color DARK_COLORS[] = {
sf::Color(16, 18, 69), // blue
sf::Color(77, 0, 62), // pink
sf::Color(99, 20, 20), // red
sf::Color(12, 46, 9), // green
sf::Color(97, 70, 51), // orange
};
}
#endif //SHOOTER_SHOOTERCONSTS_H

View File

@ -49,13 +49,15 @@ void ShooterServer::processConnect(sf::Uint16 targetId) {
}
void ShooterServer::processClientUpdate(sf::Uint16 senderId, sf::Packet &packet) {
double buf[5];
double x, y, z, angleBody, headAngle;
std::string playerName;
packet >> buf[0] >> buf[1] >> buf[2] >> buf[3] >> buf[4] >> playerName;
_players.at(senderId)->translateToPoint(Vec3D{buf[0], buf[1], buf[2]});
_players.at(senderId)->rotateToAngle(Vec3D{0, buf[3], 0});
_players.at(senderId)->setHeadAngle(buf[4]);
packet >> x >> y >> z >> angleBody >> headAngle >> playerName;
_players.at(senderId)->translateToPoint(Vec3D{x, y, z});
_players.at(senderId)->rotateToAngle(Vec3D{0, angleBody, 0});
_players.at(senderId)->setHeadAngle(headAngle);
_players.at(senderId)->setPlayerNickName(playerName);
}

View File

@ -39,6 +39,22 @@ namespace Consts {
const int NETWORK_WORLD_UPDATE_RATE = 30;
const double NETWORK_RELIABLE_RETRY_TIME = 1.0 / 20;
const uint16_t NETWORK_MAX_CLIENTS = 64;
const sf::Color WHITE_COLORS[] = {
sf::Color(137, 135, 222), // blue
sf::Color(195, 155, 209), // pink
sf::Color(201, 137, 137), // red
sf::Color(116, 204, 135), // green
sf::Color(201, 171, 137), // orange
};
const sf::Color DARK_COLORS[] = {
sf::Color(16, 18, 69), // blue
sf::Color(77, 0, 62), // pink
sf::Color(99, 20, 20), // red
sf::Color(12, 46, 9), // green
sf::Color(97, 70, 51), // orange
};
}
#endif //SHOOTER_CONSTS_H

View File

@ -149,20 +149,24 @@ void Object::unattach(const ObjectNameTag &tag) {
GLfloat *Object::glInvModel() const {
auto *v = new GLfloat[4 * 4];
v[0] = -static_cast<GLfloat>(left().x());
v[4] = -static_cast<GLfloat>(left().y());
v[8] = -static_cast<GLfloat>(left().z());
v[12] = static_cast<GLfloat>(position().dot(left()));
Vec3D _left = _transformMatrix.x();
Vec3D _up = _transformMatrix.y();
Vec3D _lookAt = _transformMatrix.z();
v[1] = static_cast<GLfloat>(up().x());
v[5] = static_cast<GLfloat>(up().y());
v[9] = static_cast<GLfloat>(up().z());
v[13] = -static_cast<GLfloat>(position().dot(up()));
v[0] = -static_cast<GLfloat>(_left.x());
v[4] = -static_cast<GLfloat>(_left.y());
v[8] = -static_cast<GLfloat>(_left.z());
v[12] = static_cast<GLfloat>(position().dot(_left));
v[2] = -static_cast<GLfloat>(lookAt().x());
v[6] = -static_cast<GLfloat>(lookAt().y());
v[10] = -static_cast<GLfloat>(lookAt().z());
v[14] = static_cast<GLfloat>(position().dot(lookAt()));
v[1] = static_cast<GLfloat>(_up.x());
v[5] = static_cast<GLfloat>(_up.y());
v[9] = static_cast<GLfloat>(_up.z());
v[13] = -static_cast<GLfloat>(position().dot(_up));
v[2] = -static_cast<GLfloat>(_lookAt.x());
v[6] = -static_cast<GLfloat>(_lookAt.y());
v[10] = -static_cast<GLfloat>(_lookAt.z());
v[14] = static_cast<GLfloat>(position().dot(_lookAt));
v[3] = static_cast<GLfloat>(0.0f);
v[7] = static_cast<GLfloat>(0.0f);
@ -175,19 +179,23 @@ GLfloat *Object::glInvModel() const {
GLfloat *Object::glModel() const {
auto *m = new GLfloat[4 * 4];
m[0] = static_cast<GLfloat>(left().x());
m[4] = static_cast<GLfloat>(up().x());
m[8] = static_cast<GLfloat>(lookAt().x());
Vec3D _left = _transformMatrix.x();
Vec3D _up = _transformMatrix.y();
Vec3D _lookAt = _transformMatrix.z();
m[0] = static_cast<GLfloat>(_left.x());
m[4] = static_cast<GLfloat>(_up.x());
m[8] = static_cast<GLfloat>(_lookAt.x());
m[12] = static_cast<GLfloat>(position().x());
m[1] = static_cast<GLfloat>(left().y());
m[5] = static_cast<GLfloat>(up().y());
m[9] = static_cast<GLfloat>(lookAt().y());
m[1] = static_cast<GLfloat>(_left.y());
m[5] = static_cast<GLfloat>(_up.y());
m[9] = static_cast<GLfloat>(_lookAt.y());
m[13] = static_cast<GLfloat>(position().y());
m[2] = static_cast<GLfloat>(left().z());
m[6] = static_cast<GLfloat>(up().z());
m[10] = static_cast<GLfloat>(lookAt().z());
m[2] = static_cast<GLfloat>(_left.z());
m[6] = static_cast<GLfloat>(_up.z());
m[10] = static_cast<GLfloat>(_lookAt.z());
m[14] = static_cast<GLfloat>(position().z());
m[3] = static_cast<GLfloat>(0.0f);

View File

@ -73,9 +73,9 @@ public:
void rotateUp(double ru);
void rotateLookAt(double rlAt);
[[nodiscard]] Vec3D left() const { return _transformMatrix.x(); }
[[nodiscard]] Vec3D up() const { return _transformMatrix.y(); }
[[nodiscard]] Vec3D lookAt() const { return _transformMatrix.z(); }
[[nodiscard]] Vec3D left() const { return _transformMatrix.x().normalized(); }
[[nodiscard]] Vec3D up() const { return _transformMatrix.y().normalized(); }
[[nodiscard]] Vec3D lookAt() const { return _transformMatrix.z().normalized(); }
[[nodiscard]] Vec3D position() const { return _position; }
[[nodiscard]] Vec3D angle() const { return _angle; }
[[nodiscard]] Vec3D angleLeftUpLookAt() const { return _angleLeftUpLookAt; }

View File

@ -16,15 +16,27 @@ void SoundController::init() {
Log::log("SoundController::init(): sound controller was initialized");
}
void SoundController::playSound(const SoundTag &soundTag, const std::string &filename) {
void SoundController::loadAndPlay(const SoundTag &soundTag, const std::string& filename) {
if (_instance == nullptr) {
return;
}
if (_instance->_sounds.count(soundTag) != 0) {
_instance->_sounds[soundTag] = sf::Sound(*ResourceManager::loadSoundBuffer(filename));
} else {
_instance->_sounds.emplace(soundTag, sf::Sound(*ResourceManager::loadSoundBuffer(filename)));
}
_instance->_sounds[soundTag].play();
}
void SoundController::playSound(const SoundTag &soundTag) {
if (_instance == nullptr) {
return;
}
if (_instance->_sounds.count(soundTag) == 0) {
_instance->_sounds.emplace(soundTag, sf::Sound(*ResourceManager::loadSoundBuffer(filename)));
}
if (_instance->_sounds.count(soundTag) != 0) {
_instance->_sounds[soundTag].play();
}
}
void SoundController::pauseSound(const SoundTag &soundTag) {

View File

@ -38,10 +38,10 @@ public:
SoundController &operator=(SoundController &) = delete;
static void playSound(const SoundTag &soundTag, const std::string &filename);
static void loadAndPlay(const SoundTag &soundTag, const std::string& filename);
static void playSound(const SoundTag &soundTag);
static void pauseSound(const SoundTag &soundTag);
static void stopSound(const SoundTag &soundTag);
static sf::Sound::Status getStatus(const SoundTag &soundTag);

View File

@ -29,6 +29,8 @@ public:
[[nodiscard]] const Vec4D& operator[](int i) const;
[[nodiscard]] Vec3D position() const { return Vec3D(_points[0] + _points[1] + _points[2])/3; }
[[nodiscard]] Vec3D norm() const;
// Operations with Matrix4x4

View File

@ -18,6 +18,10 @@ RigidBody::RigidBody(ObjectNameTag nameTag, const std::string &filename, const V
RigidBody::RigidBody(const Mesh &mesh, bool useSimpleBox) : Mesh(mesh), _hitBox(mesh, useSimpleBox) {
}
void RigidBody::regenerateHitBox(bool useSimpleBox) {
_hitBox = HitBox(*this, useSimpleBox);
}
Vec3D RigidBody::_findFurthestPoint(const Vec3D &direction) {
Vec3D maxPoint{0, 0, 0};

View File

@ -70,6 +70,8 @@ public:
[[nodiscard]] CollisionPoint EPA(const Simplex &simplex, std::shared_ptr<RigidBody> obj);
void solveCollision(const CollisionPoint &collision);
void regenerateHitBox(bool useSimpleBox = true);
[[nodiscard]] Vec3D collisionNormal() const { return _collisionNormal; }
[[nodiscard]] bool hasCollision() const { return _hasCollision; }
[[nodiscard]] bool inCollision() const { return _inCollision; }

View File

@ -31,7 +31,7 @@ FireInformation Weapon::fire(std::function<IntersectionInformation(const Vec3D &
if (_clipAmmo == 0) {
reload();
if (_clipAmmo == 0 && SoundController::getStatus(SoundTag("noAmmo")) != sf::Sound::Status::Playing) {
SoundController::playSound(SoundTag("noAmmo"), ShooterConsts::NO_AMMO_SOUND);
SoundController::loadAndPlay(SoundTag("noAmmo"), ShooterConsts::NO_AMMO_SOUND);
}
}
@ -47,7 +47,7 @@ FireInformation Weapon::fire(std::function<IntersectionInformation(const Vec3D &
reload();
}
SoundController::playSound(SoundTag("fireSound_" + name().str()), _fireSound);
SoundController::loadAndPlay(SoundTag("fireSound_" + name().str()), _fireSound);
Log::log("Weapon::fire (" + std::to_string(_stockAmmo) + " : " + std::to_string(_clipAmmo) + ")");
return FireInformation{processFire(std::move(rayCastFunction), position, direction), true};
@ -65,7 +65,7 @@ void Weapon::reload() {
_stockAmmo = 0;
}
SoundController::playSound(SoundTag("reloadSound_" + name().str()), _reloadSound);
SoundController::loadAndPlay(SoundTag("reloadSound_" + name().str()), _reloadSound);
Log::log("Weapon::reload (" + std::to_string(_stockAmmo) + " : " + std::to_string(_clipAmmo) + ")");
_lastReloadTime = Time::time();