super huge code refactoring
parent
b0a457ce47
commit
8a0221ed77
|
@ -8,6 +8,4 @@ Bonus::Bonus(const std::string &bonusName, const std::string &filename, const st
|
||||||
_name = bonusName;
|
_name = bonusName;
|
||||||
loadObj(filename, materials, scale);
|
loadObj(filename, materials, scale);
|
||||||
setCollider(false);
|
setCollider(false);
|
||||||
|
|
||||||
a_rotate("a_rotation", Point4D{0, 2*M_PI, 0}, 4, Animation::Continue, Animation::linear);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,6 +66,7 @@ add_executable(shooter
|
||||||
engine/physics/Simplex.h
|
engine/physics/Simplex.h
|
||||||
engine/physics/Solver.cpp
|
engine/physics/Solver.cpp
|
||||||
engine/physics/Solver.h
|
engine/physics/Solver.h
|
||||||
|
engine/Object.cpp
|
||||||
engine/Object.h
|
engine/Object.h
|
||||||
engine/gui/Button.cpp
|
engine/gui/Button.cpp
|
||||||
engine/gui/Button.h
|
engine/gui/Button.h
|
||||||
|
@ -85,7 +86,7 @@ add_executable(shooter
|
||||||
engine/network/UDPSocket.h
|
engine/network/UDPSocket.h
|
||||||
engine/network/config.h
|
engine/network/config.h
|
||||||
engine/animation/AFunction.h
|
engine/animation/AFunction.h
|
||||||
PlayerController.cpp PlayerController.h engine/Keyboard.cpp engine/Keyboard.h engine/Mouse.cpp engine/Mouse.h)
|
PlayerController.cpp PlayerController.h engine/Keyboard.cpp engine/Keyboard.h engine/Mouse.cpp engine/Mouse.h Shooter.cpp Shooter.h)
|
||||||
|
|
||||||
if(APPLE OR UNIX)
|
if(APPLE OR UNIX)
|
||||||
include_directories(/usr/local/include)
|
include_directories(/usr/local/include)
|
||||||
|
|
104
Client.cpp
104
Client.cpp
|
@ -3,39 +3,20 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "Client.h"
|
#include "Client.h"
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
#include "utils/Log.h"
|
#include "utils/Log.h"
|
||||||
#include "Bonus.h"
|
#include "Bonus.h"
|
||||||
|
|
||||||
void Client::updatePacket() {
|
void Client::updatePacket() {
|
||||||
sf::Packet packet;
|
sf::Packet packet;
|
||||||
packet << MsgType::ClientUpdate << _player->position().x() << _player->position().y() << _player->position().z() << _player->angle().y() << _player->camera()->angleLeftUpLookAt().x();
|
packet << MsgType::ClientUpdate << _player->position().x() << _player->position().y() << _player->position().z() << _player->angle().y() << _player->headAngle();
|
||||||
_socket.send(packet, _socket.serverId());
|
_socket.send(packet, _socket.serverId());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::spawnPlayer(sf::Uint16 id) {
|
void Client::spawnPlayer(sf::Uint16 id) {
|
||||||
std::string name = "Player_" + std::to_string(id);
|
if(_spawnPlayerCallBack != nullptr)
|
||||||
_players.insert({ id, std::make_shared<Player>() });
|
_spawnPlayerCallBack(id);
|
||||||
(*_world).addBody(_players[id], name);
|
|
||||||
_players[id]->setVisible(true);
|
|
||||||
_players[id]->setAcceleration(Point4D{0, 0, 0});
|
|
||||||
|
|
||||||
// add head and other stuff:
|
|
||||||
_world->loadBody(name + "_head", "../obj/cube.obj", "", Point4D{0.7, 0.7, 0.7});
|
|
||||||
_world->body(name + "_head")->translate(Point4D{0, 2, 0});
|
|
||||||
_world->body(name + "_head")->setCollider(false);
|
|
||||||
_players[id]->attach(_world->body(name + "_head"));
|
|
||||||
|
|
||||||
_world->loadBody(name + "_eye1", "../obj/cube.obj", "", Point4D{0.2, 0.2, 0.05});
|
|
||||||
_world->body(name + "_eye1")->translate(Point4D{0.3, 2.1, 0.7});
|
|
||||||
_world->body(name + "_eye1")->setCollider(false);
|
|
||||||
_world->body(name + "_eye1")->setColor({147, 159, 255});
|
|
||||||
_world->body(name + "_head")->attach(_world->body(name + "_eye1"));
|
|
||||||
|
|
||||||
_world->loadBody(name + "_eye2", "../obj/cube.obj", "", Point4D{0.2, 0.2, 0.05});
|
|
||||||
_world->body(name + "_eye2")->translate(Point4D{-0.3, 2.1, 0.7});
|
|
||||||
_world->body(name + "_eye2")->setCollider(false);
|
|
||||||
_world->body(name + "_eye2")->setColor({147, 159, 255});
|
|
||||||
_world->body(name + "_head")->attach(_world->body(name + "_eye2"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::processInit(sf::Packet& packet) {
|
void Client::processInit(sf::Packet& packet) {
|
||||||
|
@ -64,8 +45,8 @@ void Client::processUpdate(sf::Packet& packet) {
|
||||||
_players[targetId]->setHealth(buf[3]);
|
_players[targetId]->setHealth(buf[3]);
|
||||||
_players[targetId]->rotateToAngle(Point4D{0, buf[4], 0});
|
_players[targetId]->rotateToAngle(Point4D{0, buf[4], 0});
|
||||||
|
|
||||||
_world->body(name + "_head")->rotate(Matrix4x4::RotationY(buf[4]) * Point4D{1, 0, 0},
|
_players[targetId]->attached("head")->rotate(Matrix4x4::RotationY(buf[4]) * Point4D{1, 0, 0}, buf[5] - _players[targetId]->headAngle());
|
||||||
buf[5] - _players[targetId]->headAngle());
|
|
||||||
_players[targetId]->setHeadAngle(buf[5]);
|
_players[targetId]->setHeadAngle(buf[5]);
|
||||||
} else if (targetId == _socket.ownId()) {
|
} else if (targetId == _socket.ownId()) {
|
||||||
_player->setHealth(buf[3]);
|
_player->setHealth(buf[3]);
|
||||||
|
@ -83,13 +64,8 @@ void Client::processNewClient(sf::Packet& packet) {
|
||||||
|
|
||||||
void Client::processDisconnect(sf::Uint16 targetId) {
|
void Client::processDisconnect(sf::Uint16 targetId) {
|
||||||
if (targetId != _socket.ownId() && _players.count(targetId)) {
|
if (targetId != _socket.ownId() && _players.count(targetId)) {
|
||||||
std::string name = "Player_" + std::to_string(targetId);
|
|
||||||
_world->removeBody(name);
|
|
||||||
_world->removeBody(name + "_head");
|
|
||||||
_world->removeBody(name + "_eye1");
|
|
||||||
_world->removeBody(name + "_eye2");
|
|
||||||
|
|
||||||
_players.erase(targetId);
|
_players.erase(targetId);
|
||||||
|
_removePlayerCallBack(targetId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,49 +102,34 @@ void Client::processCustomPacket(MsgType type, sf::Packet& packet) {
|
||||||
|
|
||||||
p1 = Point4D(dbuff[0], dbuff[1], dbuff[2]);
|
p1 = Point4D(dbuff[0], dbuff[1], dbuff[2]);
|
||||||
p2 = Point4D(dbuff[3], dbuff[4], dbuff[5]);
|
p2 = Point4D(dbuff[3], dbuff[4], dbuff[5]);
|
||||||
|
if(_addFireTraceCallBack != nullptr)
|
||||||
tmp = "Client_fireTraces_" + std::to_string(fireTraces++);
|
_addFireTraceCallBack(p1, p2);
|
||||||
_world->addBody(std::make_shared<RigidBody>(Mesh::LineTo(p1, p2, 0.05)), tmp);
|
|
||||||
_world->body(tmp)->setCollider(false);
|
|
||||||
|
|
||||||
_world->body(tmp)->a_color(tmp + "_fadeOut", {255, 255, 255, 0}, 1, Animation::None, Animation::linear);
|
|
||||||
_world->body("Player_im")->a_function(tmp + "delete", [this, tmp](){ deleteTrace(_world, tmp); }, 1, 2);
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case MsgType::InitBonuses:
|
case MsgType::InitBonuses:
|
||||||
while (packet >> tmp >> dbuff[0] >> dbuff[1] >> dbuff[2]) {
|
while (packet >> tmp >> dbuff[0] >> dbuff[1] >> dbuff[2]) {
|
||||||
tmp2 = tmp.substr(6, tmp.size()-3-5);
|
if(_addBonusCallBack != nullptr)
|
||||||
_world->addBody(std::make_shared<Bonus>(tmp, "../obj/" + tmp2 + ".obj", "../obj/" + tmp2 + "_mat.txt",
|
_addBonusCallBack(tmp, Point4D(dbuff[0], dbuff[1], dbuff[2]));
|
||||||
Point4D{3, 3, 3}), tmp);
|
|
||||||
_world->body(tmp)->translateToPoint(Point4D(dbuff[0], dbuff[1], dbuff[2]));
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MsgType::AddBonus:
|
case MsgType::AddBonus:
|
||||||
packet >> tmp >> dbuff[0] >> dbuff[1] >> dbuff[2];
|
packet >> tmp >> dbuff[0] >> dbuff[1] >> dbuff[2];
|
||||||
|
if(_addBonusCallBack != nullptr)
|
||||||
tmp2 = tmp.substr(6, tmp.size()-3-5);
|
_addBonusCallBack(tmp, Point4D(dbuff[0], dbuff[1], dbuff[2]));
|
||||||
_world->addBody(std::make_shared<Bonus>(tmp, "../obj/" + tmp2 + ".obj", "../obj/" + tmp2 + "_mat.txt",
|
|
||||||
Point4D{3, 3, 3}), tmp);
|
|
||||||
_world->body(tmp)->translateToPoint(Point4D(dbuff[0], dbuff[1], dbuff[2]));
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case MsgType::RemoveBonus:
|
case MsgType::RemoveBonus:
|
||||||
packet >> tmp;
|
packet >> tmp;
|
||||||
_world->removeBody(tmp);
|
if(_removeBonusCallBack != nullptr)
|
||||||
|
_removeBonusCallBack(tmp);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::processDisconnected() {
|
void Client::processDisconnected() {
|
||||||
for (auto it = _players.begin(); it != _players.end();) {
|
for (auto it = _players.begin(); it != _players.end();) {
|
||||||
std::string name = "Player_" + std::to_string(it->first);
|
processDisconnect(it++->first);
|
||||||
|
|
||||||
_world->removeBody(name);
|
|
||||||
_world->removeBody(name + "_head");
|
|
||||||
_world->removeBody(name + "_eye1");
|
|
||||||
_world->removeBody(name + "_eye2");
|
|
||||||
_players.erase(it++);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,13 +149,36 @@ void Client::addTrace(const Point4D& from, const Point4D& to) {
|
||||||
_socket.send(packet, _socket.serverId());
|
_socket.send(packet, _socket.serverId());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::deleteTrace(std::shared_ptr<World> world, const std::string &traceName) {
|
|
||||||
world->removeBody(traceName);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Client::takeBonus(const std::string& bonusName) {
|
void Client::takeBonus(const std::string& bonusName) {
|
||||||
sf::Packet packet;
|
sf::Packet packet;
|
||||||
|
|
||||||
packet << MsgType::RemoveBonus << bonusName;
|
packet << MsgType::RemoveBonus << bonusName;
|
||||||
_socket.send(packet, _socket.serverId());
|
_socket.send(packet, _socket.serverId());
|
||||||
|
|
||||||
|
if(_removeBonusCallBack != nullptr)
|
||||||
|
_removeBonusCallBack(bonusName);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Client::addPlayer(sf::Uint16 id, std::shared_ptr<Player> player) {
|
||||||
|
_players.insert({ id, player });
|
||||||
|
}
|
||||||
|
|
||||||
|
void Client::setSpawnPlayerCallBack(std::function<void(sf::Uint16)> spawn) {
|
||||||
|
_spawnPlayerCallBack = std::move(spawn);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Client::setRemovePlayerCallBack(std::function<void(sf::Uint16)> remove) {
|
||||||
|
_removePlayerCallBack = std::move(remove);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Client::setAddFireTraceCallBack(std::function<void(const Point4D &, const Point4D &)> addTrace) {
|
||||||
|
_addFireTraceCallBack = std::move(addTrace);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Client::setAddBonusCallBack(std::function<void(const std::string &, const Point4D &)> addBonus) {
|
||||||
|
_addBonusCallBack = std::move(addBonus);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Client::setRemoveBonusCallBack(std::function<void(const std::string &)> removeBonus) {
|
||||||
|
_removeBonusCallBack = std::move(removeBonus);
|
||||||
}
|
}
|
||||||
|
|
22
Client.h
22
Client.h
|
@ -12,19 +12,27 @@
|
||||||
|
|
||||||
class Client : public ClientUDP {
|
class Client : public ClientUDP {
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<Player> _player;
|
|
||||||
std::shared_ptr<World> _world;
|
|
||||||
|
|
||||||
std::map<sf::Uint16, std::shared_ptr<Player>> _players{};
|
std::map<sf::Uint16, std::shared_ptr<Player>> _players{};
|
||||||
|
std::shared_ptr<Player> _player;
|
||||||
int fireTraces = 0;
|
|
||||||
|
|
||||||
void spawnPlayer(sf::Uint16 id);
|
void spawnPlayer(sf::Uint16 id);
|
||||||
|
|
||||||
|
std::function<void(sf::Uint16)> _spawnPlayerCallBack;
|
||||||
|
std::function<void(sf::Uint16)> _removePlayerCallBack;
|
||||||
|
std::function<void(const Point4D&, const Point4D&)> _addFireTraceCallBack;
|
||||||
|
std::function<void(const std::string&, const Point4D&)> _addBonusCallBack;
|
||||||
|
std::function<void(const std::string&)> _removeBonusCallBack;
|
||||||
public:
|
public:
|
||||||
Client(std::shared_ptr<Player> player, std::shared_ptr<World> world) : _player(player), _world(world) {};
|
Client(std::shared_ptr<Player> player) : _player(player){};
|
||||||
|
|
||||||
void updatePacket() override;
|
void updatePacket() override;
|
||||||
|
|
||||||
|
void setSpawnPlayerCallBack(std::function<void(sf::Uint16)> spawn);
|
||||||
|
void setRemovePlayerCallBack(std::function<void(sf::Uint16)> remove);
|
||||||
|
void setAddFireTraceCallBack(std::function<void(const Point4D&, const Point4D&)> addTrace);
|
||||||
|
void setAddBonusCallBack(std::function<void(const std::string&, const Point4D&)> addBonus);
|
||||||
|
void setRemoveBonusCallBack(std::function<void(const std::string&)> removeBonus);
|
||||||
|
|
||||||
void processInit(sf::Packet& packet) override;
|
void processInit(sf::Packet& packet) override;
|
||||||
void processUpdate(sf::Packet& packet) override;
|
void processUpdate(sf::Packet& packet) override;
|
||||||
void processNewClient(sf::Packet& packet) override;
|
void processNewClient(sf::Packet& packet) override;
|
||||||
|
@ -40,7 +48,7 @@ public:
|
||||||
|
|
||||||
void addTrace(const Point4D& from, const Point4D& to);
|
void addTrace(const Point4D& from, const Point4D& to);
|
||||||
|
|
||||||
void deleteTrace(std::shared_ptr<World> world, const std::string& traceName);
|
void addPlayer(sf::Uint16 id, std::shared_ptr<Player> player);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
62
Player.cpp
62
Player.cpp
|
@ -7,47 +7,11 @@
|
||||||
#include "ResourceManager.h"
|
#include "ResourceManager.h"
|
||||||
#include "utils/Log.h"
|
#include "utils/Log.h"
|
||||||
|
|
||||||
void Player::update() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void Player::rotateWeaponsRelativePoint(const Point4D& point4D, const Point4D& v, double val) {
|
void Player::rotateWeaponsRelativePoint(const Point4D& point4D, const Point4D& v, double val) {
|
||||||
for(auto& weapon : _weapons)
|
for(auto& weapon : _weapons)
|
||||||
weapon->rotateRelativePoint(point4D, v, val);
|
weapon->rotateRelativePoint(point4D, v, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::drawStats() {
|
|
||||||
if(_screen == nullptr)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// health bar
|
|
||||||
double xPos = 10;
|
|
||||||
double yPos = _screen->height() - 10 - 10;
|
|
||||||
|
|
||||||
double width = _screen->width()/2 - 20;
|
|
||||||
double height = 10;
|
|
||||||
|
|
||||||
_screen->drawTetragon(Point4D{xPos, yPos},
|
|
||||||
Point4D{xPos + width, yPos},
|
|
||||||
Point4D{xPos + width, yPos + height},
|
|
||||||
Point4D{xPos, yPos + height},
|
|
||||||
{ static_cast<sf::Uint8>((_healthMax - _health)/_healthMax * 255), static_cast<sf::Uint8>(_health * 255 / _healthMax), 0, 100 });
|
|
||||||
|
|
||||||
_screen->drawTetragon(Point4D{xPos, yPos - 15},
|
|
||||||
Point4D{xPos + width * _ability / _abilityMax, yPos - 15},
|
|
||||||
Point4D{xPos + width * _ability / _abilityMax, yPos - 15 + height},
|
|
||||||
Point4D{xPos, yPos - 15 + height},
|
|
||||||
{ 255, 168, 168, 100 });
|
|
||||||
|
|
||||||
auto balance = _weapons[_selectedWeapon]->balance();
|
|
||||||
|
|
||||||
_screen->drawText(std::to_string((int)balance.first),Point4D{150, static_cast<double>(_screen->height() - 50 - 100)},100, sf::Color(0, 0, 0, 100));
|
|
||||||
_screen->drawText(std::to_string((int)balance.second),Point4D{50, static_cast<double>(_screen->height() - 50 - 50)},50, sf::Color(0, 0, 0, 70));
|
|
||||||
|
|
||||||
_screen->drawText("KILLS: " + std::to_string((int)_kills) + " | " + "DEATHS: " + std::to_string((int)_deaths),
|
|
||||||
Point4D{10, 10},25, sf::Color(0, 0, 0, 100));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Player::playDeath() {
|
void Player::playDeath() {
|
||||||
_deathSound.setBuffer(*ResourceManager::loadSoundBuffer("../sound/classic_hurt.ogg"));
|
_deathSound.setBuffer(*ResourceManager::loadSoundBuffer("../sound/classic_hurt.ogg"));
|
||||||
_deathSound.play();
|
_deathSound.play();
|
||||||
|
@ -81,7 +45,6 @@ void Player::collisionWithObject(const std::string &objName, std::shared_ptr<Rig
|
||||||
setFullAbility();
|
setFullAbility();
|
||||||
|
|
||||||
if(objName.find("Bonus") != std::string::npos) {
|
if(objName.find("Bonus") != std::string::npos) {
|
||||||
_world->removeBody(objName);
|
|
||||||
_takeBonusCallBack(objName);
|
_takeBonusCallBack(objName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -89,45 +52,44 @@ void Player::collisionWithObject(const std::string &objName, std::shared_ptr<Rig
|
||||||
void Player::addWeapon(std::shared_ptr<Weapon> weapon) {
|
void Player::addWeapon(std::shared_ptr<Weapon> weapon) {
|
||||||
_changeWeaponSound.play();
|
_changeWeaponSound.play();
|
||||||
|
|
||||||
if(!_weapons.empty()) {
|
|
||||||
for(auto& w : _weapons) {
|
for(auto& w : _weapons) {
|
||||||
if (w->name() == weapon->name()) {
|
if (w->name() == weapon->name()) {
|
||||||
w->addAmmo(w->initialPack());
|
w->addAmmo(w->initialPack());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
_weapons.push_back(weapon);
|
_weapons.push_back(weapon);
|
||||||
_weapons.back()->attachToPlayer(*this);
|
attach(weapon, weapon->name());
|
||||||
|
|
||||||
_weapons.back()->translate(position());
|
_weapons.back()->translate(position());
|
||||||
_weapons.back()->rotateRelativePoint(position() + Point4D{0, 1.8, 0}, Point4D{0, 1, 0}, _angle.y());
|
_weapons.back()->rotateRelativePoint(position() + Point4D{0, 1.8, 0}, Point4D{0, 1, 0}, _angle.y());
|
||||||
_weapons.back()->rotateRelativePoint(position() + Point4D{0, 1.8, 0}, _camera->left(), _camera->angleLeftUpLookAt().x());
|
_weapons.back()->rotateRelativePoint(position() + Point4D{0, 1.8, 0}, left(), headAngle());
|
||||||
|
|
||||||
_weapons.back()->setAddTraceCallBack(_addTraceCallBack);
|
_weapons.back()->setAddTraceCallBack(_addTraceCallBack);
|
||||||
_changeWeaponSound.play();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::initWeapons() {
|
void Player::initWeapons() {
|
||||||
|
|
||||||
if(!_weapons.empty()) {
|
if(!_weapons.empty()) {
|
||||||
_weapons[_selectedWeapon]->removeFromWorld(_world);
|
for(auto weapon : _weapons)
|
||||||
|
unattach(weapon->name());
|
||||||
|
|
||||||
|
_removeWeaponCallBack(_weapons[_selectedWeapon]);
|
||||||
_weapons.clear();
|
_weapons.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
_selectedWeapon = 0;
|
_selectedWeapon = 0;
|
||||||
addWeapon(std::make_shared<Gun>());
|
addWeapon(std::make_shared<Gun>());
|
||||||
|
_addWeaponCallBack(_weapons[_selectedWeapon]);
|
||||||
_weapons[_selectedWeapon]->addToWorld(_world);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::nextWeapon() {
|
void Player::nextWeapon() {
|
||||||
if(_weapons.size() > 1) {
|
if(_weapons.size() > 1) {
|
||||||
// change '_selectedWeapon'
|
// change '_selectedWeapon'
|
||||||
_weapons[_selectedWeapon]->removeFromWorld(_world);
|
_removeWeaponCallBack(_weapons[_selectedWeapon]);
|
||||||
_selectedWeapon = (_selectedWeapon + 1) % _weapons.size();
|
_selectedWeapon = (_selectedWeapon + 1) % _weapons.size();
|
||||||
_weapons[_selectedWeapon]->addToWorld(_world);
|
_addWeaponCallBack(_weapons[_selectedWeapon]);
|
||||||
Log::log("selected _selectedWeapon " + std::to_string(_selectedWeapon));
|
Log::log("selected _selectedWeapon " + std::to_string(_selectedWeapon));
|
||||||
_changeWeaponSound.play();
|
_changeWeaponSound.play();
|
||||||
}
|
}
|
||||||
|
@ -136,19 +98,19 @@ void Player::nextWeapon() {
|
||||||
void Player::previousWeapon() {
|
void Player::previousWeapon() {
|
||||||
if(_weapons.size() > 1) {
|
if(_weapons.size() > 1) {
|
||||||
// change '_selectedWeapon'
|
// change '_selectedWeapon'
|
||||||
_weapons[_selectedWeapon]->removeFromWorld(_world);
|
_removeWeaponCallBack(_weapons[_selectedWeapon]);
|
||||||
if (_selectedWeapon > 0)
|
if (_selectedWeapon > 0)
|
||||||
_selectedWeapon = (_selectedWeapon - 1) % _weapons.size();
|
_selectedWeapon = (_selectedWeapon - 1) % _weapons.size();
|
||||||
else
|
else
|
||||||
_selectedWeapon = _weapons.size() - 1;
|
_selectedWeapon = _weapons.size() - 1;
|
||||||
_weapons[_selectedWeapon]->addToWorld(_world);
|
_addWeaponCallBack(_weapons[_selectedWeapon]);
|
||||||
Log::log("selected _selectedWeapon " + std::to_string(_selectedWeapon));
|
Log::log("selected _selectedWeapon " + std::to_string(_selectedWeapon));
|
||||||
_changeWeaponSound.play();
|
_changeWeaponSound.play();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::fire() {
|
void Player::fire() {
|
||||||
auto damagedPlayers = _weapons[_selectedWeapon]->fire(_world, _camera);
|
auto damagedPlayers = _weapons[_selectedWeapon]->fire(_rayCastFunction, attached("camera")->position(), attached("camera")->lookAt());
|
||||||
for(auto& damagedPlayer : damagedPlayers) {
|
for(auto& damagedPlayer : damagedPlayers) {
|
||||||
sf::Uint16 targetId = std::stoi(damagedPlayer.first.substr(7));
|
sf::Uint16 targetId = std::stoi(damagedPlayer.first.substr(7));
|
||||||
_damagePlayerCallBack(targetId, damagedPlayer.second);
|
_damagePlayerCallBack(targetId, damagedPlayer.second);
|
||||||
|
|
99
Player.h
99
Player.h
|
@ -26,16 +26,11 @@ private:
|
||||||
|
|
||||||
double _headAngle = 0;
|
double _headAngle = 0;
|
||||||
|
|
||||||
unsigned _kills = 0;
|
int _kills = 0;
|
||||||
unsigned _deaths = 0;
|
int _deaths = 0;
|
||||||
|
|
||||||
double _g = 35;
|
double _g = 35;
|
||||||
|
|
||||||
std::shared_ptr<Camera> _camera;
|
|
||||||
std::shared_ptr<Screen> _screen;
|
|
||||||
|
|
||||||
std::shared_ptr<World> _world;
|
|
||||||
|
|
||||||
// sounds
|
// sounds
|
||||||
sf::Sound _killSound;
|
sf::Sound _killSound;
|
||||||
sf::Sound _deathSound;
|
sf::Sound _deathSound;
|
||||||
|
@ -51,7 +46,12 @@ private:
|
||||||
std::function<void(sf::Uint16 targetId, double)> _damagePlayerCallBack;
|
std::function<void(sf::Uint16 targetId, double)> _damagePlayerCallBack;
|
||||||
std::function<void(const Point4D&, const Point4D&)> _addTraceCallBack;
|
std::function<void(const Point4D&, const Point4D&)> _addTraceCallBack;
|
||||||
std::function<void(const std::string&)> _takeBonusCallBack;
|
std::function<void(const std::string&)> _takeBonusCallBack;
|
||||||
|
std::function<void(const std::string&)> _fireCallBack;
|
||||||
|
|
||||||
|
std::function<void(std::shared_ptr<Weapon>)> _addWeaponCallBack;
|
||||||
|
std::function<void(std::shared_ptr<Weapon>)> _removeWeaponCallBack;
|
||||||
|
|
||||||
|
std::function<std::pair<Point4D, std::string>(const Point4D&, const Point4D&)> _rayCastFunction;
|
||||||
public:
|
public:
|
||||||
Player() {
|
Player() {
|
||||||
loadObj("../obj/cube.obj", "", Point4D{0.5, 1.9, 0.5});
|
loadObj("../obj/cube.obj", "", Point4D{0.5, 1.9, 0.5});
|
||||||
|
@ -68,23 +68,7 @@ public:
|
||||||
setCollisionCallBack([this](const std::string& objName, std::shared_ptr<RigidBody> obj) {collisionWithObject(objName, obj);});
|
setCollisionCallBack([this](const std::string& objName, std::shared_ptr<RigidBody> obj) {collisionWithObject(objName, obj);});
|
||||||
};
|
};
|
||||||
|
|
||||||
void update();
|
[[nodiscard]] std::string name() const { return "Player_" + _name; }
|
||||||
|
|
||||||
void attachCamera(std::shared_ptr<Camera> camera, std::shared_ptr<Screen> screen) {
|
|
||||||
_camera = camera;
|
|
||||||
_screen = screen;
|
|
||||||
|
|
||||||
_camera->translateToPoint(position() + Point4D{0, 1.8, 0});
|
|
||||||
this->attach(_camera);
|
|
||||||
}
|
|
||||||
|
|
||||||
void attachWorld(std::shared_ptr<World> world, const Point4D& pos = Point4D{0, 30, 0}) {
|
|
||||||
_world = world;
|
|
||||||
|
|
||||||
translate(pos);
|
|
||||||
|
|
||||||
initWeapons();
|
|
||||||
}
|
|
||||||
|
|
||||||
void setHealth(double h) {
|
void setHealth(double h) {
|
||||||
_health = h;
|
_health = h;
|
||||||
|
@ -93,13 +77,12 @@ public:
|
||||||
_ability = a;
|
_ability = a;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nextWeapon();
|
[[nodiscard]] double health() const { return _health; }
|
||||||
void previousWeapon();
|
|
||||||
void fire();
|
|
||||||
void reload();
|
|
||||||
|
|
||||||
[[nodiscard]] double ability() const { return _ability; }
|
[[nodiscard]] double ability() const { return _ability; }
|
||||||
|
|
||||||
|
[[nodiscard]] double maxHealth() const { return _healthMax; }
|
||||||
|
[[nodiscard]] double maxAbility() const { return _abilityMax; }
|
||||||
|
|
||||||
void setFullHealth() {
|
void setFullHealth() {
|
||||||
_health = _healthMax;
|
_health = _healthMax;
|
||||||
_fullHealthSound.play();
|
_fullHealthSound.play();
|
||||||
|
@ -109,32 +92,19 @@ public:
|
||||||
_fullAbilitySound.play();
|
_fullAbilitySound.play();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void initWeapons();
|
||||||
|
void addWeapon(std::shared_ptr<Weapon> weapon);
|
||||||
|
[[nodiscard]] std::pair<double, double> balance() const{ return _weapons[_selectedWeapon]->balance();}
|
||||||
|
|
||||||
void setDamagePlayerCallBack(std::function<void(sf::Uint16 targetId, double)> hit) {
|
void nextWeapon();
|
||||||
_damagePlayerCallBack = std::move(hit);
|
void previousWeapon();
|
||||||
}
|
void fire();
|
||||||
|
void reload();
|
||||||
void setAddTraceCallBack(std::function<void(const Point4D&, const Point4D&)> add) {
|
|
||||||
_addTraceCallBack = std::move(add);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setTakeBonusCallBack(std::function<void(const std::string&)> take) {
|
|
||||||
_takeBonusCallBack = std::move(take);
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] double health() const { return _health; }
|
|
||||||
[[nodiscard]] std::string name() const { return "Player_" + _name; }
|
|
||||||
|
|
||||||
|
|
||||||
std::shared_ptr<Camera> camera() { return _camera; }
|
|
||||||
|
|
||||||
// This is for situation when you want to store the position of the head but you dont have attached camera
|
|
||||||
void setHeadAngle(double a) { _headAngle = a; }
|
|
||||||
[[nodiscard]] double headAngle() const { return _headAngle; };
|
|
||||||
|
|
||||||
void rotateWeaponsRelativePoint(const Point4D& point4D, const Point4D& v, double val);
|
void rotateWeaponsRelativePoint(const Point4D& point4D, const Point4D& v, double val);
|
||||||
|
|
||||||
void drawStats();
|
[[nodiscard]] int kills() const {return _kills;}
|
||||||
|
[[nodiscard]] int deaths() const {return _deaths;}
|
||||||
|
|
||||||
void addKill() { _kills++; }
|
void addKill() { _kills++; }
|
||||||
void addDeath() { _deaths++; }
|
void addDeath() { _deaths++; }
|
||||||
|
@ -142,11 +112,30 @@ public:
|
||||||
void playDeath();
|
void playDeath();
|
||||||
void playKill();
|
void playKill();
|
||||||
|
|
||||||
|
void setDamagePlayerCallBack(std::function<void(sf::Uint16 targetId, double)> hit) {
|
||||||
|
_damagePlayerCallBack = std::move(hit);
|
||||||
|
}
|
||||||
|
void setAddTraceCallBack(std::function<void(const Point4D&, const Point4D&)> add) {
|
||||||
|
_addTraceCallBack = std::move(add);
|
||||||
|
}
|
||||||
|
void setTakeBonusCallBack(std::function<void(const std::string&)> take) {
|
||||||
|
_takeBonusCallBack = std::move(take);
|
||||||
|
}
|
||||||
|
void setAddWeaponCallBack(std::function<void(std::shared_ptr<Weapon>)> addWeapon) {
|
||||||
|
_addWeaponCallBack = addWeapon;
|
||||||
|
}
|
||||||
|
void setRemoveWeaponCallBack(std::function<void(std::shared_ptr<Weapon>)> removeWeapon) {
|
||||||
|
_removeWeaponCallBack = std::move(removeWeapon);
|
||||||
|
}
|
||||||
|
void setRayCastFunction(std::function<std::pair<Point4D, std::string>(const Point4D&, const Point4D&)> rayCastFunction) {
|
||||||
|
_rayCastFunction = std::move(rayCastFunction);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is for situation when you want to store the position of the head but you dont have attached camera
|
||||||
|
void setHeadAngle(double a) { _headAngle = a; }
|
||||||
|
[[nodiscard]] double headAngle() const { return _headAngle; };
|
||||||
|
|
||||||
void collisionWithObject(const std::string& objName, std::shared_ptr<RigidBody> obj);
|
void collisionWithObject(const std::string& objName, std::shared_ptr<RigidBody> obj);
|
||||||
|
|
||||||
void addWeapon(std::shared_ptr<Weapon> weapon);
|
|
||||||
|
|
||||||
void initWeapons();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,11 +3,16 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "PlayerController.h"
|
#include "PlayerController.h"
|
||||||
|
#include "utils/Log.h"
|
||||||
|
#include "animation/AColor.h"
|
||||||
|
#include "animation/AFunction.h"
|
||||||
|
#include "animation/AWait.h"
|
||||||
|
#include "animation/ATranslate.h"
|
||||||
|
#include "animation/ATranslateToPoint.h"
|
||||||
|
|
||||||
PlayerController::PlayerController(std::shared_ptr<Player> player,
|
PlayerController::PlayerController(std::shared_ptr<Player> player,
|
||||||
std::shared_ptr<World> world,
|
|
||||||
std::shared_ptr<Keyboard> keyboard,
|
std::shared_ptr<Keyboard> keyboard,
|
||||||
std::shared_ptr<Mouse> mouse) : _player(player), _world(world), _keyboard(keyboard), _mouse(mouse) {
|
std::shared_ptr<Mouse> mouse) : _player(player), _keyboard(keyboard), _mouse(mouse) {
|
||||||
_slowMoSound.setBuffer(*ResourceManager::loadSoundBuffer("../sound/slow_mo.ogg"));
|
_slowMoSound.setBuffer(*ResourceManager::loadSoundBuffer("../sound/slow_mo.ogg"));
|
||||||
_unSlowMoSound.setBuffer(*ResourceManager::loadSoundBuffer("../sound/unslow_mo.ogg"));
|
_unSlowMoSound.setBuffer(*ResourceManager::loadSoundBuffer("../sound/unslow_mo.ogg"));
|
||||||
}
|
}
|
||||||
|
@ -38,51 +43,50 @@ void PlayerController::update() {
|
||||||
Keyboard::isKeyPressed(sf::Keyboard::W) ||
|
Keyboard::isKeyPressed(sf::Keyboard::W) ||
|
||||||
Keyboard::isKeyPressed(sf::Keyboard::S));
|
Keyboard::isKeyPressed(sf::Keyboard::S));
|
||||||
|
|
||||||
// in case when the camera is attached we make some animation during running
|
std::shared_ptr<Object> camera = _player->attached("camera");
|
||||||
if(_inRunning && !_player->camera()->isInAnim()) {
|
if(_inRunning) {
|
||||||
_player->camera()->a_translate("hor_oscil", -_player->camera()->left()/12, 0.3/coeff, Animation::LoopOut::None, Animation::cos);
|
if (!camera->isInAnim()) {
|
||||||
_player->camera()->a_wait("hor_oscil", 0);
|
camera->animate("hor_oscil", new ATranslate(camera, -camera->left() / 6, 0.3,Animation::LoopOut::None, Animation::cos));
|
||||||
_player->camera()->a_translate("hor_oscil", _player->camera()->left()/12, 0.3/coeff, Animation::LoopOut::None, Animation::cos);
|
camera->animate("hor_oscil", new AWait(0));
|
||||||
|
camera->animate("hor_oscil", new ATranslate(camera, camera->left() / 6, 0.3, Animation::LoopOut::None, Animation::cos));
|
||||||
|
|
||||||
_player->camera()->a_translate("vert_oscil", -Point4D{0, 1, 0}/24, 0.15/coeff, Animation::LoopOut::None, Animation::cos);
|
camera->animate("vert_oscil", new ATranslate(camera, -Point4D{0, 1, 0} / 12, 0.15, Animation::LoopOut::None, Animation::cos));
|
||||||
_player->camera()->a_wait("vert_oscil", 0);
|
camera->animate("vert_oscil", new AWait(0));
|
||||||
_player->camera()->a_translate("vert_oscil", Point4D{0, 1, 0}/24, 0.15/coeff, Animation::LoopOut::None, Animation::cos);
|
camera->animate("vert_oscil", new ATranslate(camera, Point4D{0, 1, 0} / 12, 0.15, Animation::LoopOut::None,Animation::cos));
|
||||||
_player->camera()->a_wait("vert_oscil", 0);
|
camera->animate("vert_oscil", new AWait(0));
|
||||||
_player->camera()->a_translate("vert_oscil", -Point4D{0, 1, 0}/24, 0.15/coeff, Animation::LoopOut::None, Animation::cos);
|
camera->animate("vert_oscil", new ATranslate(camera, -Point4D{0, 1, 0} / 12, 0.15, Animation::LoopOut::None, Animation::cos));
|
||||||
_player->camera()->a_wait("vert_oscil", 0);
|
camera->animate("vert_oscil", new AWait(0));
|
||||||
_player->camera()->a_translate("vert_oscil", Point4D{0, 1, 0}/24, 0.15/coeff, Animation::LoopOut::None, Animation::cos);
|
camera->animate("vert_oscil", new ATranslate(camera, Point4D{0, 1, 0} / 12, 0.15, Animation::LoopOut::None, Animation::cos));
|
||||||
|
|
||||||
_player->camera()->a_translateToPoint("init", _player->position() + Point4D{0, 1.8, 0}, 0.3/coeff, Animation::None, Animation::cos);
|
|
||||||
|
|
||||||
|
camera->animate("init", new ATranslateToPoint( camera, _player->position() + Point4D{0, 1.8, 0}, 0.3, Animation::None, Animation::cos));
|
||||||
|
}
|
||||||
} else if(inRunning_old && !_inRunning) {
|
} else if(inRunning_old && !_inRunning) {
|
||||||
_player->camera()->a_stopAllAnimations();
|
camera->stopAllAnimations();
|
||||||
|
camera->animate("init", new ATranslateToPoint( camera, _player->position() + Point4D{0, 1.8, 0}, 0.15, Animation::None, Animation::cos));
|
||||||
_player->camera()->a_translateToPoint("init", _player->position() + Point4D{0, 1.8, 0}, 0.15/coeff, Animation::None, Animation::cos);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto rayToFloor = (*_world).rayCast(_player->position(), _player->position() + Point4D{0, -5, 0});
|
|
||||||
|
|
||||||
// Left and right
|
// Left and right
|
||||||
|
|
||||||
if (Keyboard::isKeyPressed(sf::Keyboard::A)) {
|
if (Keyboard::isKeyPressed(sf::Keyboard::A)) {
|
||||||
_player->translate(_player->camera()->left() * Time::deltaTime() * _walkSpeed * coeff);
|
_player->translate(_player->left() * Time::deltaTime() * _walkSpeed * coeff);
|
||||||
if(_player->inCollision())
|
if(_player->inCollision())
|
||||||
_player->setVelocity(Point4D{0,0,0});
|
_player->setVelocity(Point4D{0,0,0});
|
||||||
}
|
}
|
||||||
if (Keyboard::isKeyPressed(sf::Keyboard::D)) {
|
if (Keyboard::isKeyPressed(sf::Keyboard::D)) {
|
||||||
_player->translate(-_player->camera()->left() * Time::deltaTime() * _walkSpeed * coeff);
|
_player->translate(-_player->left() * Time::deltaTime() * _walkSpeed * coeff);
|
||||||
if(_player->inCollision())
|
if(_player->inCollision())
|
||||||
_player->setVelocity(Point4D{0,0,0});
|
_player->setVelocity(Point4D{0,0,0});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Forward and backward
|
// Forward and backward
|
||||||
if (Keyboard::isKeyPressed(sf::Keyboard::W)) {
|
if (Keyboard::isKeyPressed(sf::Keyboard::W)) {
|
||||||
_player->translate(_player->camera()->left().cross3D(Point4D{0, 1, 0}) * Time::deltaTime() * _walkSpeed * coeff);
|
_player->translate(_player->lookAt() * Time::deltaTime() * _walkSpeed * coeff);
|
||||||
if(_player->inCollision())
|
if(_player->inCollision())
|
||||||
_player->setVelocity(Point4D{0,0,0});
|
_player->setVelocity(Point4D{0,0,0});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Keyboard::isKeyPressed(sf::Keyboard::S)) {
|
if (Keyboard::isKeyPressed(sf::Keyboard::S)) {
|
||||||
_player->translate(-_player->camera()->left().cross3D(Point4D{0, 1, 0}) * Time::deltaTime() * _walkSpeed * coeff);
|
_player->translate(-_player->lookAt() * Time::deltaTime() * _walkSpeed * coeff);
|
||||||
|
|
||||||
if(_player->inCollision())
|
if(_player->inCollision())
|
||||||
_player->setVelocity(Point4D{0,0,0});
|
_player->setVelocity(Point4D{0,0,0});
|
||||||
|
@ -109,21 +113,21 @@ void PlayerController::update() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mouse movement
|
// Mouse movement
|
||||||
Point4D disp = _mouse->getMouseDisplacement();
|
Point4D displacement = _mouse->getMouseDisplacement();
|
||||||
|
|
||||||
_player->rotate(Point4D{0, -disp.x() / 1000.0, 0});
|
_player->rotate(Point4D{0, -displacement.x() / 1000.0, 0});
|
||||||
_player->setVelocity(Matrix4x4::RotationY(-disp.x() / 1000.0) * _player->velocity());
|
_player->setVelocity(Matrix4x4::RotationY(-displacement.x() / 1000.0) * _player->velocity());
|
||||||
|
|
||||||
double rotationLeft = disp.y() / 1000.0;
|
double rotationLeft = displacement.y() / 1000.0;
|
||||||
|
|
||||||
// You can only see in range [-90 : 90] grad
|
// You can only see in range [-90 : 90] grad
|
||||||
if (_player->camera()->angleLeftUpLookAt().x() + rotationLeft > M_PI / 2)
|
if (_player->headAngle() + rotationLeft > M_PI / 2)
|
||||||
rotationLeft = M_PI / 2 - _player->camera()->angleLeftUpLookAt().x();
|
rotationLeft = M_PI / 2 - _player->headAngle();
|
||||||
if (_player->camera()->angleLeftUpLookAt().x() + rotationLeft < -M_PI / 2)
|
if (_player->headAngle() + rotationLeft < -M_PI / 2)
|
||||||
rotationLeft = -M_PI / 2 - _player->camera()->angleLeftUpLookAt().x();
|
rotationLeft = -M_PI / 2 - _player->headAngle();
|
||||||
|
|
||||||
_player->camera()->rotateLeft(rotationLeft);
|
_player->setHeadAngle(_player->headAngle() + rotationLeft);
|
||||||
_player->rotateWeaponsRelativePoint(_player->position() + Point4D{0, 1.8, 0}, _player->camera()->left(), rotationLeft);
|
_player->rotateWeaponsRelativePoint(_player->position() + Point4D{0, 1.8, 0}, _player->left(), rotationLeft);
|
||||||
|
|
||||||
if (_keyboard->isKeyTapped(sf::Keyboard::Right) || _keyboard->isKeyTapped(sf::Keyboard::E)) {
|
if (_keyboard->isKeyTapped(sf::Keyboard::Right) || _keyboard->isKeyTapped(sf::Keyboard::E)) {
|
||||||
_player->nextWeapon();
|
_player->nextWeapon();
|
||||||
|
@ -141,11 +145,9 @@ void PlayerController::update() {
|
||||||
_player->reload();
|
_player->reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_inRunning && _player->inCollision() && _walkSound.getStatus() != sf::Sound::Status::Playing) {
|
if ((_inRunning || _player->velocity().sqrAbs() > 3) && _player->inCollision() && _walkSound.getStatus() != sf::Sound::Status::Playing) {
|
||||||
if ((_player->position() - rayToFloor.first).abs() < 2) {
|
|
||||||
int soundNum = round((double) rand() / RAND_MAX * 5) + 1;
|
int soundNum = round((double) rand() / RAND_MAX * 5) + 1;
|
||||||
_walkSound.setBuffer(*ResourceManager::loadSoundBuffer("../sound/stonestep" + std::to_string(soundNum) + ".ogg"));
|
_walkSound.setBuffer(*ResourceManager::loadSoundBuffer("../sound/stonestep" + std::to_string(soundNum) + ".ogg"));
|
||||||
_walkSound.play();
|
_walkSound.play();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -12,8 +12,6 @@
|
||||||
class PlayerController {
|
class PlayerController {
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<Player> _player;
|
std::shared_ptr<Player> _player;
|
||||||
std::shared_ptr<World> _world;
|
|
||||||
|
|
||||||
std::shared_ptr<Keyboard> _keyboard;
|
std::shared_ptr<Keyboard> _keyboard;
|
||||||
std::shared_ptr<Mouse> _mouse;
|
std::shared_ptr<Mouse> _mouse;
|
||||||
|
|
||||||
|
@ -30,7 +28,7 @@ private:
|
||||||
double _jumpHeight = 3;
|
double _jumpHeight = 3;
|
||||||
double _walkSpeed = 10;
|
double _walkSpeed = 10;
|
||||||
public:
|
public:
|
||||||
PlayerController(std::shared_ptr<Player> player, std::shared_ptr<World> world, std::shared_ptr<Keyboard> keyboard, std::shared_ptr<Mouse> mouse);
|
PlayerController(std::shared_ptr<Player> player, std::shared_ptr<Keyboard> keyboard, std::shared_ptr<Mouse> mouse);
|
||||||
void update();
|
void update();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,269 @@
|
||||||
|
//
|
||||||
|
// Created by Иван Ильин on 22.09.2021.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "Shooter.h"
|
||||||
|
#include <fstream>
|
||||||
|
#include "animation/AColor.h"
|
||||||
|
#include "animation/AFunction.h"
|
||||||
|
#include "animation/ATranslate.h"
|
||||||
|
#include "animation/ARotate.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
// Read server/client settings and start both.
|
||||||
|
// If client doesn't connect to the localhost - server doesn't start.
|
||||||
|
void Shooter::InitNetwork()
|
||||||
|
{
|
||||||
|
std::string clientIp;
|
||||||
|
sf::Uint16 clientPort;
|
||||||
|
sf::Uint16 serverPort;
|
||||||
|
std::ifstream connectFile("connect.txt", std::ifstream::in);
|
||||||
|
|
||||||
|
// If failed to read client settings
|
||||||
|
if (!connectFile.is_open() || !(connectFile >> clientIp >> clientPort) || sf::IpAddress(clientIp) == sf::IpAddress::None)
|
||||||
|
{
|
||||||
|
connectFile.close();
|
||||||
|
// Create file and write default settings
|
||||||
|
clientIp = "127.0.0.1";
|
||||||
|
clientPort = 54000;
|
||||||
|
std::ofstream temp("connect.txt", std::ofstream::out);
|
||||||
|
temp << clientIp << std::endl << clientPort;
|
||||||
|
temp.close();
|
||||||
|
}
|
||||||
|
connectFile.close();
|
||||||
|
|
||||||
|
// If failed to read server settings
|
||||||
|
connectFile.open("server.txt", std::ifstream::in);
|
||||||
|
if (!connectFile.is_open() || !(connectFile >> serverPort))
|
||||||
|
{
|
||||||
|
connectFile.close();
|
||||||
|
// Create file and write default settings
|
||||||
|
serverPort = 54000;
|
||||||
|
std::ofstream temp("server.txt", std::ofstream::out);
|
||||||
|
temp << serverPort;
|
||||||
|
temp.close();
|
||||||
|
}
|
||||||
|
connectFile.close();
|
||||||
|
|
||||||
|
if (clientIp == sf::IpAddress::LocalHost) {
|
||||||
|
server->start(serverPort);
|
||||||
|
if(server->isWorking())
|
||||||
|
server->generateBonuses();
|
||||||
|
}
|
||||||
|
|
||||||
|
client->connect(clientIp, clientPort);
|
||||||
|
|
||||||
|
client->setSpawnPlayerCallBack([this](sf::Uint16 id){ spawnPlayer(id); });
|
||||||
|
client->setRemovePlayerCallBack([this](sf::Uint16 id){ removePlayer(id); });
|
||||||
|
client->setAddFireTraceCallBack([this](const Point4D& from, const Point4D& to){ addFireTrace(from, to); });
|
||||||
|
client->setAddBonusCallBack([this](const std::string& bonusName, const Point4D& position){ addBonus(bonusName, position); });
|
||||||
|
client->setRemoveBonusCallBack([this](const std::string& bonusName){ removeBonus(bonusName); });
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shooter::start() {
|
||||||
|
// This code executed once in the beginning:
|
||||||
|
setDebugText(false);
|
||||||
|
setUpdateWorld(false);
|
||||||
|
|
||||||
|
mouse->setMouseCursorVisible(true);
|
||||||
|
|
||||||
|
world->loadMap("../maps/map1.obj", "map", Point4D{5, 5, 5});
|
||||||
|
|
||||||
|
player = std::make_shared<Player>();
|
||||||
|
playerController = std::make_shared<PlayerController>(player, keyboard, mouse);
|
||||||
|
|
||||||
|
player->setAddTraceCallBack([this](const Point4D& from, const Point4D& to){ client->addTrace(from, to); addFireTrace(from, to); });
|
||||||
|
player->setDamagePlayerCallBack([this] (sf::Uint16 targetId, double damage) { client->damagePlayer(targetId, damage); });
|
||||||
|
player->setRayCastFunction([this](const Point4D& from, const Point4D& to) { return world->rayCast(from, to); });
|
||||||
|
player->setTakeBonusCallBack([this] (const string& bonusName) { client->takeBonus(bonusName); });
|
||||||
|
|
||||||
|
player->setAddWeaponCallBack([this](std::shared_ptr<Weapon> weapon){ addWeapon(weapon); });
|
||||||
|
player->setRemoveWeaponCallBack([this](std::shared_ptr<Weapon> weapon){ removeWeapon(weapon); });
|
||||||
|
player->initWeapons();
|
||||||
|
|
||||||
|
camera->translateToPoint(player->position() + Point4D{0, 1.8, 0});
|
||||||
|
player->attach(camera, "camera");
|
||||||
|
|
||||||
|
world->addBody(player, player->name());
|
||||||
|
player->translate(Point4D{0, 10, 0});
|
||||||
|
|
||||||
|
client = std::make_shared<Client>(player);
|
||||||
|
server = std::make_shared<Server>();
|
||||||
|
|
||||||
|
// windows init:
|
||||||
|
mainMenu.title("Main menu");
|
||||||
|
mainMenu.setBackgroundTexture("../textures/back.png", 1.1, 1.1, screen->width(), screen->height());
|
||||||
|
|
||||||
|
mainMenu.addButton(screen->width()/2, 200, 200, 20, [this] () { this->play(); }, "Play", 5, 5, "../textures/gui.png", {0, 66}, {0, 86}, {0, 46}, "../engine/fonts/Roboto-Medium.ttf", {255, 255, 255}, "../sound/click.ogg");
|
||||||
|
mainMenu.addButton(screen->width()/2, 350, 200, 20, [this] () { this->player->translateToPoint(Point4D{0, 0, 0}); this->player->setVelocity({}); this->play(); }, "Respawn", 5, 5, "../textures/gui.png", {0, 66}, {0, 86}, {0, 46}, "../engine/fonts/Roboto-Medium.ttf", {255, 255, 255}, "../sound/click.ogg");
|
||||||
|
|
||||||
|
mainMenu.addButton(screen->width()/2, 500, 200, 20, [this] () { client->disconnect(); server->stop(); this->exit();}, "Exit", 5, 5, "../textures/gui.png", {0, 66}, {0, 86}, {0, 46}, "../engine/fonts/Roboto-Medium.ttf", {255, 255, 255}, "../sound/click.ogg");
|
||||||
|
|
||||||
|
// connecting to the server
|
||||||
|
InitNetwork();
|
||||||
|
// Waiting for connect and updating server if it's same window
|
||||||
|
while (client->isWorking() && !client->connected())
|
||||||
|
{
|
||||||
|
client->update();
|
||||||
|
server->update();
|
||||||
|
Time::update();
|
||||||
|
}
|
||||||
|
// If connect fail - return to menu
|
||||||
|
if (!client->isWorking())
|
||||||
|
{
|
||||||
|
inGame = false;
|
||||||
|
server->stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shooter::update() {
|
||||||
|
// This code executed every time step:
|
||||||
|
|
||||||
|
server->update();
|
||||||
|
client->update();
|
||||||
|
|
||||||
|
// Check all input after this condition please
|
||||||
|
if (!screen->hasFocus())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(keyboard->isKeyTapped(sf::Keyboard::Escape)) {
|
||||||
|
inGame = !inGame;
|
||||||
|
mouse->setMouseCursorVisible(!inGame);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(inGame) {
|
||||||
|
screen->setTitle("Shooter");
|
||||||
|
playerController->update();
|
||||||
|
mouse->setMouseInCenter();
|
||||||
|
camera->rotateLeft(player->headAngle() - camera->angleLeftUpLookAt().x());
|
||||||
|
|
||||||
|
} else {
|
||||||
|
mainMenu.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
setUpdateWorld(inGame);
|
||||||
|
|
||||||
|
// background sounds and music control
|
||||||
|
if(backgroundNoise.getStatus() != sf::Sound::Status::Playing) {
|
||||||
|
backgroundNoise.setBuffer(*ResourceManager::loadSoundBuffer("../sound/backNoise.ogg"));
|
||||||
|
backgroundNoise.play();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shooter::gui() {
|
||||||
|
|
||||||
|
sf::Sprite sprite;
|
||||||
|
sprite.setTexture(*ResourceManager::loadTexture("../textures/gui.png"));
|
||||||
|
sprite.setTextureRect(sf::IntRect(243, 3, 9, 9));
|
||||||
|
sprite.scale(3, 3);
|
||||||
|
sprite.setPosition(screen->width() / 2.0 - 27.0/2.0, screen->height() / 2 - 27.0/2.0);
|
||||||
|
sprite.setColor(sf::Color(0,0,0, 200));
|
||||||
|
screen->drawSprite(sprite);
|
||||||
|
|
||||||
|
// health player stats
|
||||||
|
drawPlayerStats();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shooter::drawPlayerStats() {
|
||||||
|
// health bar
|
||||||
|
double xPos = 10;
|
||||||
|
double yPos = screen->height() - 10 - 10;
|
||||||
|
|
||||||
|
int width = screen->width()/2 - 20;
|
||||||
|
int height = 10;
|
||||||
|
|
||||||
|
screen->drawTetragon(Point4D{xPos, yPos},
|
||||||
|
Point4D{xPos + width * player->health() / player->maxHealth(), yPos},
|
||||||
|
Point4D{xPos + width * player->health() / player->maxHealth(), yPos + height},
|
||||||
|
Point4D{xPos, yPos + height},
|
||||||
|
{ static_cast<sf::Uint8>((player->maxHealth() - player->health())/player->maxHealth() * 255), static_cast<sf::Uint8>(player->health() * 255 / player->maxHealth()), 0, 100 });
|
||||||
|
|
||||||
|
screen->drawTetragon(Point4D{xPos, yPos - 15},
|
||||||
|
Point4D{xPos + width * player->ability() / player->maxAbility(), yPos - 15},
|
||||||
|
Point4D{xPos + width * player->ability() / player->maxAbility(), yPos - 15 + height},
|
||||||
|
Point4D{xPos, yPos - 15 + height},
|
||||||
|
{ 255, 168, 168, 100 });
|
||||||
|
|
||||||
|
auto balance = player->balance();
|
||||||
|
|
||||||
|
screen->drawText(std::to_string((int)balance.first),Point4D{150, static_cast<double>(screen->height() - 50 - 100)},100, sf::Color(0, 0, 0, 100));
|
||||||
|
screen->drawText(std::to_string((int)balance.second),Point4D{50, static_cast<double>(screen->height() - 50 - 50)},50, sf::Color(0, 0, 0, 70));
|
||||||
|
|
||||||
|
screen->drawText("KILLS: " + std::to_string(player->kills()) + " | " + "DEATHS: " + std::to_string(player->deaths()),
|
||||||
|
Point4D{10, 10},25, sf::Color(0, 0, 0, 100));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shooter::play() {
|
||||||
|
inGame = true;
|
||||||
|
mouse->setMouseCursorVisible(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shooter::spawnPlayer(sf::Uint16 id) {
|
||||||
|
std::string name = "Player_" + std::to_string(id);
|
||||||
|
std::shared_ptr<Player> newPlayer = std::make_shared<Player>();
|
||||||
|
newPlayer->setCollision(false);
|
||||||
|
|
||||||
|
client->addPlayer(id, newPlayer);
|
||||||
|
world->addBody(newPlayer, name);
|
||||||
|
newPlayer->setVisible(true);
|
||||||
|
newPlayer->setAcceleration(Point4D{0, 0, 0});
|
||||||
|
|
||||||
|
// add head and other stuff:
|
||||||
|
world->loadBody(name + "_head", "../obj/cube.obj", "", Point4D{0.7, 0.7, 0.7});
|
||||||
|
world->body(name + "_head")->translate(Point4D{0, 2, 0});
|
||||||
|
world->body(name + "_head")->setCollider(false);
|
||||||
|
newPlayer->attach(world->body(name + "_head"), "head");
|
||||||
|
|
||||||
|
world->loadBody(name + "_eye1", "../obj/cube.obj", "", Point4D{0.2, 0.2, 0.05});
|
||||||
|
world->body(name + "_eye1")->translate(Point4D{0.3, 2.1, 0.7});
|
||||||
|
world->body(name + "_eye1")->setCollider(false);
|
||||||
|
world->body(name + "_eye1")->setColor({147, 159, 255});
|
||||||
|
world->body(name + "_head")->attach(world->body(name + "_eye1"), "eye1");
|
||||||
|
|
||||||
|
world->loadBody(name + "_eye2", "../obj/cube.obj", "", Point4D{0.2, 0.2, 0.05});
|
||||||
|
world->body(name + "_eye2")->translate(Point4D{-0.3, 2.1, 0.7});
|
||||||
|
world->body(name + "_eye2")->setCollider(false);
|
||||||
|
world->body(name + "_eye2")->setColor({147, 159, 255});
|
||||||
|
world->body(name + "_head")->attach(world->body(name + "_eye2"), "eye2");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shooter::removePlayer(sf::Uint16 id) {
|
||||||
|
std::string name = "Player_" + std::to_string(id);
|
||||||
|
world->removeBody(name);
|
||||||
|
world->removeBody(name + "_head");
|
||||||
|
world->removeBody(name + "_eye1");
|
||||||
|
world->removeBody(name + "_eye2");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shooter::addFireTrace(const Point4D &from, const Point4D &to) {
|
||||||
|
std::string traceName = "Client_fireTraces_" + std::to_string(fireTraces++);
|
||||||
|
world->addBody(std::make_shared<RigidBody>(Mesh::LineTo(from, to, 0.05)), traceName);
|
||||||
|
world->body(traceName)->setCollider(false);
|
||||||
|
|
||||||
|
world->body(traceName)->animate(traceName + "_fadeOut", new AColor(world->body(traceName), {255, 255, 255, 0}));
|
||||||
|
world->body("Player_im")->animate(traceName + "delete", new AFunction([this, traceName](){ deleteFireTrace(traceName); }, 1, 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shooter::deleteFireTrace(const std::string& traceName) {
|
||||||
|
world->removeBody(traceName);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shooter::addBonus(const string &bonusName, const Point4D &position) {
|
||||||
|
std::string name = bonusName.substr(6, bonusName.size()-3-5);
|
||||||
|
world->addBody(std::make_shared<Bonus>(bonusName, "../obj/" + name + ".obj", "../obj/" + name + "_mat.txt", Point4D{3, 3, 3}), bonusName);
|
||||||
|
world->body(bonusName)->translateToPoint(position);
|
||||||
|
world->body(bonusName)->animate("a_rotation", new ARotate(world->body(bonusName), Point4D{0, 2*M_PI, 0}, 4, Animation::Continue, Animation::linear));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shooter::removeBonus(const string &bonusName) {
|
||||||
|
world->removeBody(bonusName);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shooter::addWeapon(std::shared_ptr<Weapon> weapon) {
|
||||||
|
world->addBody(weapon, weapon->name());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shooter::removeWeapon(std::shared_ptr<Weapon> weapon) {
|
||||||
|
world->removeBodyInstantly(weapon->name());
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
//
|
||||||
|
// Created by Иван Ильин on 22.09.2021.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef SHOOTER_SHOOTER_H
|
||||||
|
#define SHOOTER_SHOOTER_H
|
||||||
|
|
||||||
|
#include "Engine.h"
|
||||||
|
#include "Player.h"
|
||||||
|
#include "PlayerController.h"
|
||||||
|
#include "PlayerController.h"
|
||||||
|
#include "gui/Window.h"
|
||||||
|
|
||||||
|
#include "Client.h"
|
||||||
|
#include "Server.h"
|
||||||
|
|
||||||
|
|
||||||
|
class Shooter : public Engine {
|
||||||
|
private:
|
||||||
|
std::shared_ptr<Player> player;
|
||||||
|
std::shared_ptr<PlayerController> playerController;
|
||||||
|
|
||||||
|
sf::Sound backgroundNoise;
|
||||||
|
|
||||||
|
Window mainMenu;
|
||||||
|
|
||||||
|
std::shared_ptr<Server> server;
|
||||||
|
std::shared_ptr<Client> client;
|
||||||
|
|
||||||
|
bool inGame = false;
|
||||||
|
|
||||||
|
int fireTraces = 0;
|
||||||
|
|
||||||
|
void start() override;
|
||||||
|
void update() override;
|
||||||
|
|
||||||
|
void gui() override;
|
||||||
|
|
||||||
|
void play();
|
||||||
|
|
||||||
|
void drawPlayerStats();
|
||||||
|
void InitNetwork();
|
||||||
|
|
||||||
|
void spawnPlayer(sf::Uint16 id);
|
||||||
|
void removePlayer(sf::Uint16 id);
|
||||||
|
void addFireTrace(const Point4D& from, const Point4D& to);
|
||||||
|
void deleteFireTrace(const std::string& traceName);
|
||||||
|
void addBonus(const std::string& bonusName, const Point4D& position);
|
||||||
|
void removeBonus(const std::string& bonusName);
|
||||||
|
void addWeapon(std::shared_ptr<Weapon> weapon);
|
||||||
|
void removeWeapon(std::shared_ptr<Weapon> weapon);
|
||||||
|
public:
|
||||||
|
Shooter() : mainMenu(screen, mouse) {};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //SHOOTER_SHOOTER_H
|
|
@ -76,7 +76,6 @@ std::vector<Triangle> &Camera::project(std::shared_ptr<Mesh> mesh) {
|
||||||
void Camera::init(int width, int height, double fov, double ZNear, double ZFar) {
|
void Camera::init(int width, int height, double fov, double ZNear, double ZFar) {
|
||||||
// We need to init camera only after creation or changing width, height, fov, ZNear or ZFar.
|
// We need to init camera only after creation or changing width, height, fov, ZNear or ZFar.
|
||||||
// Because here we calculate matrix that does not change during the motion of _objects or camera
|
// Because here we calculate matrix that does not change during the motion of _objects or camera
|
||||||
_w = width; _h = height;
|
|
||||||
_aspect = (double)width / (double)height;
|
_aspect = (double)width / (double)height;
|
||||||
_P = Matrix4x4::Projection(fov, _aspect, ZNear, ZFar);
|
_P = Matrix4x4::Projection(fov, _aspect, ZNear, ZFar);
|
||||||
_S = Matrix4x4::ScreenSpace(width, height);
|
_S = Matrix4x4::ScreenSpace(width, height);
|
||||||
|
@ -127,108 +126,3 @@ void Camera::clear() {
|
||||||
_triangles.clear();
|
_triangles.clear();
|
||||||
_V = Matrix4x4::View(_left, _up, _lookAt, _position);
|
_V = Matrix4x4::View(_left, _up, _lookAt, _position);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Camera::rotateX(double rx) {
|
|
||||||
_angle = Point4D{_angle.x() + rx, _angle.y(), _angle.z()};
|
|
||||||
_left = Matrix4x4::RotationX(rx) * _left;
|
|
||||||
_up = Matrix4x4::RotationX(rx) * _up;
|
|
||||||
_lookAt = Matrix4x4::RotationX(rx) * _lookAt;
|
|
||||||
|
|
||||||
for(auto attached : _attachedObjects)
|
|
||||||
attached->rotateRelativePoint(position(), Point4D{rx, 0, 0});
|
|
||||||
}
|
|
||||||
|
|
||||||
void Camera::rotateY(double ry) {
|
|
||||||
_angle = Point4D{_angle.x(), _angle.y() + ry, _angle.z()};
|
|
||||||
_left = Matrix4x4::RotationY(ry) * _left;
|
|
||||||
_up = Matrix4x4::RotationY(ry) * _up;
|
|
||||||
_lookAt = Matrix4x4::RotationY(ry) * _lookAt;
|
|
||||||
|
|
||||||
for(auto attached : _attachedObjects)
|
|
||||||
attached->rotateRelativePoint(position(), Point4D{0, ry, 0});
|
|
||||||
}
|
|
||||||
|
|
||||||
void Camera::rotateZ(double rz) {
|
|
||||||
_angle = Point4D{_angle.x(), _angle.y(), _angle.z() + rz};
|
|
||||||
_left = Matrix4x4::RotationZ(rz) * _left;
|
|
||||||
_up = Matrix4x4::RotationZ(rz) * _up;
|
|
||||||
_lookAt = Matrix4x4::RotationZ(rz) * _lookAt;
|
|
||||||
|
|
||||||
for(auto attached : _attachedObjects)
|
|
||||||
attached->rotateRelativePoint(position(), Point4D{0, 0, rz});
|
|
||||||
}
|
|
||||||
|
|
||||||
void Camera::rotate(const Point4D& r) {
|
|
||||||
rotateX(r.x());
|
|
||||||
rotateY(r.y());
|
|
||||||
rotateZ(r.z());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Camera::rotate(const Point4D& v, double rv) {
|
|
||||||
_left = Matrix4x4::Rotation(v, rv) * _left;
|
|
||||||
_up = Matrix4x4::Rotation(v, rv) * _up;
|
|
||||||
_lookAt = Matrix4x4::Rotation(v, rv) * _lookAt;
|
|
||||||
|
|
||||||
for(auto attached : _attachedObjects)
|
|
||||||
attached->rotateRelativePoint(position(), v, rv);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Camera::rotateLeft(double rl) {
|
|
||||||
_angleLeftUpLookAt = Point4D{_angleLeftUpLookAt.x() + rl, _angleLeftUpLookAt.y(), _angleLeftUpLookAt.z()};
|
|
||||||
|
|
||||||
rotate(_left, rl);
|
|
||||||
|
|
||||||
for(auto attached : _attachedObjects)
|
|
||||||
attached->rotateRelativePoint(position(), _left, rl);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Camera::rotateUp(double ru) {
|
|
||||||
_angleLeftUpLookAt = Point4D{_angleLeftUpLookAt.x(), _angleLeftUpLookAt.y() + ru, _angleLeftUpLookAt.z()};
|
|
||||||
rotate(_up, ru);
|
|
||||||
|
|
||||||
for(auto attached : _attachedObjects)
|
|
||||||
attached->rotateRelativePoint(position(), _up, ru);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Camera::rotateLookAt(double rlAt) {
|
|
||||||
_angleLeftUpLookAt = Point4D{_angleLeftUpLookAt.x(), _angleLeftUpLookAt.y(), _angleLeftUpLookAt.z() + rlAt};
|
|
||||||
rotate(_lookAt, rlAt);
|
|
||||||
|
|
||||||
for(auto attached : _attachedObjects)
|
|
||||||
attached->rotateRelativePoint(position(), _lookAt, rlAt);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Camera::rotateRelativePoint(const Point4D &s, const Point4D &r) {
|
|
||||||
_angle = _angle + r;
|
|
||||||
|
|
||||||
// Translate XYZ by vector r1
|
|
||||||
Point4D r1 = _position - s;
|
|
||||||
// In translated coordinate system we rotate camera and position
|
|
||||||
Point4D r2 = Matrix4x4::Rotation(r)*r1;
|
|
||||||
rotate(r);
|
|
||||||
|
|
||||||
// After rotation we translate XYZ by vector -r2 and recalculate position
|
|
||||||
_position = s + r2;
|
|
||||||
|
|
||||||
for(auto attached : _attachedObjects)
|
|
||||||
attached->rotateRelativePoint(s, r);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Camera::rotateRelativePoint(const Point4D &s, const Point4D &v, double r) {
|
|
||||||
// Translate XYZ by vector r1
|
|
||||||
Point4D r1 = _position - s;
|
|
||||||
// In translated coordinate system we rotate camera and position
|
|
||||||
Point4D r2 = Matrix4x4::Rotation(v, r)*r1;
|
|
||||||
rotate(v, r);
|
|
||||||
|
|
||||||
// After rotation we translate XYZ by vector -r2 and recalculate position
|
|
||||||
_position = s + r2;
|
|
||||||
|
|
||||||
for(auto attached : _attachedObjects)
|
|
||||||
attached->rotateRelativePoint(s, v, r);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Camera::translateToPoint(const Point4D &point) {
|
|
||||||
translate(point - _position);
|
|
||||||
}
|
|
||||||
|
|
|
@ -10,30 +10,20 @@
|
||||||
#include "Plane.h"
|
#include "Plane.h"
|
||||||
#include "Mesh.h"
|
#include "Mesh.h"
|
||||||
|
|
||||||
class Camera : public Object, public Animatable{
|
class Camera : public Object{
|
||||||
private:
|
private:
|
||||||
Point4D _angleLeftUpLookAt;
|
|
||||||
|
|
||||||
Point4D _left = Point4D{1, 0, 0, 0}; // internal X
|
|
||||||
Point4D _up = Point4D{0, 1, 0, 0}; // internal Y
|
|
||||||
Point4D _lookAt = Point4D{0, 0, 1, 0}; // internal Z
|
|
||||||
|
|
||||||
Matrix4x4 _S; // screen space matrix
|
Matrix4x4 _S; // screen space matrix
|
||||||
Matrix4x4 _P; // projections matrix
|
Matrix4x4 _P; // projections matrix
|
||||||
Matrix4x4 _V; // camera matrix
|
Matrix4x4 _V; // camera matrix
|
||||||
|
|
||||||
double _aspect = 0;
|
|
||||||
|
|
||||||
// To accelerate calculations we can use precalculated matrix that does not chance
|
// To accelerate calculations we can use precalculated matrix that does not chance
|
||||||
Matrix4x4 _SP; // screen-space-projections matrix
|
Matrix4x4 _SP; // screen-space-projections matrix
|
||||||
|
|
||||||
std::vector<Triangle> _triangles;
|
std::vector<Triangle> _triangles{};
|
||||||
std::vector<Plane> _clipPlanes;
|
std::vector<Plane> _clipPlanes{};
|
||||||
|
|
||||||
bool _ready = false;
|
bool _ready = false;
|
||||||
|
double _aspect = 0;
|
||||||
double _w = 0;
|
|
||||||
double _h = 0;
|
|
||||||
public:
|
public:
|
||||||
Camera() = default;
|
Camera() = default;
|
||||||
Camera(const Camera& camera) = delete;
|
Camera(const Camera& camera) = delete;
|
||||||
|
@ -46,42 +36,6 @@ public:
|
||||||
|
|
||||||
[[nodiscard]] int buffSize() const { return _triangles.size(); }
|
[[nodiscard]] int buffSize() const { return _triangles.size(); }
|
||||||
std::vector<Triangle>& sorted();
|
std::vector<Triangle>& sorted();
|
||||||
|
|
||||||
[[nodiscard]] Point4D position() const override { return _position; }
|
|
||||||
[[nodiscard]] Point4D angle() const override { return _angle; }
|
|
||||||
[[nodiscard]] Point4D angleLeftUpLookAt() const { return _angleLeftUpLookAt; }
|
|
||||||
|
|
||||||
[[nodiscard]] Point4D eye() const { return _position; }
|
|
||||||
[[nodiscard]] Point4D left() const { return _left; }
|
|
||||||
[[nodiscard]] Point4D right() const { return -_left; }
|
|
||||||
[[nodiscard]] Point4D up() const { return _up; }
|
|
||||||
[[nodiscard]] Point4D down() const { return -_up; }
|
|
||||||
[[nodiscard]] Point4D lookAt() const { return _lookAt; }
|
|
||||||
|
|
||||||
void translate(const Point4D& dv) override {
|
|
||||||
_position = _position + dv;
|
|
||||||
|
|
||||||
for(auto attached : _attachedObjects)
|
|
||||||
attached->translate(dv);
|
|
||||||
}
|
|
||||||
|
|
||||||
void translateToPoint(const Point4D& point);
|
|
||||||
|
|
||||||
void rotateX(double rx);
|
|
||||||
void rotateY(double ry);
|
|
||||||
void rotateZ(double rz);
|
|
||||||
void rotate(const Point4D& r) override;
|
|
||||||
|
|
||||||
void rotate(const Point4D& v, double rv) override;
|
|
||||||
|
|
||||||
void rotateLeft(double rl);
|
|
||||||
void rotateUp(double ru);
|
|
||||||
void rotateLookAt(double rlAt);
|
|
||||||
|
|
||||||
// Rotate body around XYZ by (r.x, r.y, r.z) radians relative val 'point4D'
|
|
||||||
void rotateRelativePoint(const Point4D& s, const Point4D& r) override;
|
|
||||||
// Rotate body around normalised vector 'v' by 'r' radians relative val 'point4D'
|
|
||||||
void rotateRelativePoint(const Point4D& s, const Point4D& v, double r) override;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ void Engine::create(int screenWidth, int screenHeight, const std::string &name,
|
||||||
// hence we can set '_updateWorld' equal to false in setUpdateWorld(bool):
|
// hence we can set '_updateWorld' equal to false in setUpdateWorld(bool):
|
||||||
if(_updateWorld) {
|
if(_updateWorld) {
|
||||||
|
|
||||||
camera->a_update();
|
camera->update_animations();
|
||||||
camera->clear();
|
camera->clear();
|
||||||
|
|
||||||
world->update();
|
world->update();
|
||||||
|
@ -80,9 +80,9 @@ void Engine::exit() {
|
||||||
void Engine::printDebugText() const {
|
void Engine::printDebugText() const {
|
||||||
if (_debugText) {
|
if (_debugText) {
|
||||||
screen->debugText(_name + "\n\n X: " +
|
screen->debugText(_name + "\n\n X: " +
|
||||||
std::to_string((camera->eye().x())) + "\n Y: " +
|
std::to_string((camera->position().x())) + "\n Y: " +
|
||||||
std::to_string((camera->eye().y())) + "\n Z: " +
|
std::to_string((camera->position().y())) + "\n Z: " +
|
||||||
std::to_string((camera->eye().z())) + "\n\n" +
|
std::to_string((camera->position().z())) + "\n\n" +
|
||||||
std::to_string(screen->width()) + "x" +
|
std::to_string(screen->width()) + "x" +
|
||||||
std::to_string(screen->height()) + "\n" +
|
std::to_string(screen->height()) + "\n" +
|
||||||
std::to_string(Time::fps()) +
|
std::to_string(Time::fps()) +
|
||||||
|
|
|
@ -30,21 +30,20 @@ protected:
|
||||||
std::shared_ptr<World> world;
|
std::shared_ptr<World> world;
|
||||||
std::shared_ptr<Camera> camera;
|
std::shared_ptr<Camera> camera;
|
||||||
|
|
||||||
|
virtual void start() {};
|
||||||
|
virtual void update() {};
|
||||||
|
|
||||||
|
void setDebugText(bool value) { _debugText = value; }
|
||||||
|
void setUpdateWorld(bool value) { _updateWorld = value; }
|
||||||
|
|
||||||
|
virtual void gui(){}
|
||||||
public:
|
public:
|
||||||
Engine();
|
Engine();
|
||||||
|
|
||||||
virtual ~Engine() = default;
|
virtual ~Engine() = default;
|
||||||
|
|
||||||
void create(int screenWidth = 1920, int screenHeight = 1080, const std::string& name = "engine", bool verticalSync = true, sf::Color background = sf::Color(255, 255, 255), sf::Uint32 style = sf::Style::Default);
|
void create(int screenWidth = 1920, int screenHeight = 1080, const std::string& name = "engine", bool verticalSync = true, sf::Color background = sf::Color(255, 255, 255), sf::Uint32 style = sf::Style::Default);
|
||||||
|
|
||||||
virtual void start() {};
|
|
||||||
virtual void update() {};
|
|
||||||
void exit();
|
void exit();
|
||||||
|
|
||||||
void setDebugText(bool value) { _debugText = value; }
|
|
||||||
void setUpdateWorld(bool value) { _updateWorld = value; }
|
|
||||||
|
|
||||||
virtual void gui(){}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -46,31 +46,18 @@ Mesh Mesh::Obj(const std::string& filename) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mesh::rotate(const Point4D &r) {
|
void Mesh::rotate(const Point4D &r) {
|
||||||
_angle = _angle + r;
|
Object::rotate(r);
|
||||||
*this *= Matrix4x4::Rotation(r);
|
*this *= Matrix4x4::Rotation(r);
|
||||||
|
|
||||||
for(auto attached : _attachedObjects)
|
|
||||||
attached->rotateRelativePoint(position(), r);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mesh::rotate(const Point4D &v, double r) {
|
void Mesh::rotate(const Point4D &v, double r) {
|
||||||
|
Object::rotate(v, r);
|
||||||
*this *= Matrix4x4::Rotation(v, r);
|
*this *= Matrix4x4::Rotation(v, r);
|
||||||
|
|
||||||
for(auto attached : _attachedObjects)
|
|
||||||
attached->rotateRelativePoint(position(), v, r);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mesh::scale(const Point4D &s) {
|
void Mesh::scale(const Point4D &s) {
|
||||||
|
Object::scale(s);
|
||||||
*this *= Matrix4x4::Scale(s);
|
*this *= Matrix4x4::Scale(s);
|
||||||
|
|
||||||
// TODO: scale attached objects
|
|
||||||
}
|
|
||||||
|
|
||||||
void Mesh::translate(const Point4D &t) {
|
|
||||||
_position = _position + t;
|
|
||||||
|
|
||||||
for(auto attached : _attachedObjects)
|
|
||||||
attached->translate(t);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Mesh &Mesh::operator=(const Mesh &mesh) {
|
Mesh &Mesh::operator=(const Mesh &mesh) {
|
||||||
|
@ -81,48 +68,13 @@ Mesh &Mesh::operator=(const Mesh &mesh) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mesh::rotateRelativePoint(const Point4D &s, const Point4D &r) {
|
void Mesh::rotateRelativePoint(const Point4D &s, const Point4D &r) {
|
||||||
_angle = _angle + r;
|
Object::rotateRelativePoint(s, r);
|
||||||
|
*this *= Matrix4x4::Rotation(r);
|
||||||
// Translate XYZ by vector r1
|
|
||||||
Point4D r1 = _position - s;
|
|
||||||
*this *= Matrix4x4::Translation(r1);
|
|
||||||
|
|
||||||
// In translated coordinate system we rotate body and position
|
|
||||||
Matrix4x4 rotationMatrix = Matrix4x4::Rotation(r);
|
|
||||||
Point4D r2 = rotationMatrix*r1;
|
|
||||||
*this *= rotationMatrix;
|
|
||||||
|
|
||||||
// After rotation we translate XYZ by vector -r2 and recalculate position
|
|
||||||
*this *= Matrix4x4::Translation(-r2);
|
|
||||||
_position = s + r2;
|
|
||||||
|
|
||||||
if(_attachedObjects.empty())
|
|
||||||
return;
|
|
||||||
for(auto attached : _attachedObjects)
|
|
||||||
attached->rotateRelativePoint(s, r);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mesh::rotateRelativePoint(const Point4D &s, const Point4D &v, double r) {
|
void Mesh::rotateRelativePoint(const Point4D &s, const Point4D &v, double r) {
|
||||||
// Translate XYZ by vector r1
|
Object::rotateRelativePoint(s, v, r);
|
||||||
Point4D r1 = _position - s;
|
*this *= Matrix4x4::Rotation(v, r);
|
||||||
*this *= Matrix4x4::Translation(r1);
|
|
||||||
|
|
||||||
// In translated coordinate system we rotate body and position
|
|
||||||
Matrix4x4 rotationMatrix = Matrix4x4::Rotation(v, r);
|
|
||||||
Point4D r2 = rotationMatrix*r1;
|
|
||||||
*this *= rotationMatrix;
|
|
||||||
|
|
||||||
// After rotation we translate XYZ by vector -r2 and recalculate position
|
|
||||||
*this *= Matrix4x4::Translation(-r2);
|
|
||||||
_position = s + r2;
|
|
||||||
|
|
||||||
for(auto attached : _attachedObjects)
|
|
||||||
attached->rotateRelativePoint(s, v, r);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Mesh::translateToPoint(const Point4D &point) {
|
|
||||||
translate(point - _position);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mesh::setColor(sf::Color c) {
|
void Mesh::setColor(sf::Color c) {
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
#include <SFML/Graphics.hpp>
|
#include <SFML/Graphics.hpp>
|
||||||
#include "Object.h"
|
#include "Object.h"
|
||||||
|
|
||||||
class Mesh : public Object, public Animatable {
|
class Mesh : public Object {
|
||||||
private:
|
private:
|
||||||
std::vector<Triangle> _tris;
|
std::vector<Triangle> _tris;
|
||||||
sf::Color _color = sf::Color(255, 245, 194);
|
sf::Color _color = sf::Color(255, 245, 194);
|
||||||
|
@ -29,12 +29,10 @@ public:
|
||||||
Mesh& loadObj(const std::string& filename, const std::string &materials = "", const Point4D& scale = Point4D{1, 1, 1});
|
Mesh& loadObj(const std::string& filename, const std::string &materials = "", const Point4D& scale = Point4D{1, 1, 1});
|
||||||
|
|
||||||
[[nodiscard]] std::vector<Triangle>const &triangles() const { return _tris; }
|
[[nodiscard]] std::vector<Triangle>const &triangles() const { return _tris; }
|
||||||
[[nodiscard]] std::vector<Triangle>& triangles() override { return _tris; }
|
[[nodiscard]] std::vector<Triangle>& triangles() { return _tris; }
|
||||||
void setTriangles(const std::vector<Triangle>& t) override { _tris = t; }
|
void setTriangles(const std::vector<Triangle>& t) { _tris = t; }
|
||||||
|
|
||||||
// Translate body
|
// Translate body
|
||||||
void translate(const Point4D& t) override;
|
|
||||||
void translateToPoint(const Point4D& point);
|
|
||||||
// Rotate body around XYZ axes
|
// Rotate body around XYZ axes
|
||||||
void rotate(const Point4D& r) override;
|
void rotate(const Point4D& r) override;
|
||||||
// Rotate body around normalised vector 'v' by 'r' radians
|
// Rotate body around normalised vector 'v' by 'r' radians
|
||||||
|
@ -43,15 +41,10 @@ public:
|
||||||
void rotateRelativePoint(const Point4D& point4D, const Point4D& r) override;
|
void rotateRelativePoint(const Point4D& point4D, const Point4D& r) override;
|
||||||
// Rotate body around normalised vector 'v' by 'r' radians relative val 'point4D'
|
// Rotate body around normalised vector 'v' by 'r' radians relative val 'point4D'
|
||||||
void rotateRelativePoint(const Point4D& point4D, const Point4D& v, double r) override;
|
void rotateRelativePoint(const Point4D& point4D, const Point4D& v, double r) override;
|
||||||
void scale(const Point4D& s);
|
void scale(const Point4D& s) override;
|
||||||
|
|
||||||
void rotateToAngle(const Point4D& v) { rotate(v - _angle); }
|
[[nodiscard]] sf::Color color() const { return _color; }
|
||||||
|
void setColor(sf::Color c);
|
||||||
[[nodiscard]] Point4D position() const override { return _position; }
|
|
||||||
[[nodiscard]] Point4D angle() const override { return _angle; }
|
|
||||||
|
|
||||||
[[nodiscard]] sf::Color color() const override { return _color; }
|
|
||||||
void setColor(sf::Color c) override;
|
|
||||||
|
|
||||||
Mesh static Obj(const std::string& filename);
|
Mesh static Obj(const std::string& filename);
|
||||||
Mesh static LineTo(const Point4D& from, const Point4D& to, double line_width = 0.1, sf::Color color = {150, 150, 150, 255});
|
Mesh static LineTo(const Point4D& from, const Point4D& to, double line_width = 0.1, sf::Color color = {150, 150, 150, 255});
|
||||||
|
|
|
@ -14,9 +14,9 @@ Point4D Mouse::getMouseDisplacement() const {
|
||||||
sf::Vector2<int> mousePos = sf::Mouse::getPosition(*_window);
|
sf::Vector2<int> mousePos = sf::Mouse::getPosition(*_window);
|
||||||
sf::Vector2<int> center = sf::Vector2<int>(_window->getSize().x/2, _window->getSize().y/2);
|
sf::Vector2<int> center = sf::Vector2<int>(_window->getSize().x/2, _window->getSize().y/2);
|
||||||
|
|
||||||
sf::Vector2<int> disp = mousePos - center;
|
sf::Vector2<int> displacement = mousePos - center;
|
||||||
//setMouseInCenter();
|
//setMouseInCenter();
|
||||||
return Point4D(disp.x, disp.y, 0, 0);
|
return Point4D(displacement.x, displacement.y, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mouse::setMouseInCenter() const {
|
void Mouse::setMouseInCenter() const {
|
||||||
|
|
|
@ -0,0 +1,128 @@
|
||||||
|
//
|
||||||
|
// Created by Иван Ильин on 15.03.2021.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "Object.h"
|
||||||
|
#include "utils/Matrix4x4.h"
|
||||||
|
#include "utils/Log.h"
|
||||||
|
|
||||||
|
void Object::translate(const Point4D &dv) {
|
||||||
|
_position = _position + dv;
|
||||||
|
|
||||||
|
for(auto attached : _attachedObjects)
|
||||||
|
attached.second->translate(dv);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Object::scale(const Point4D &s) {
|
||||||
|
for(auto attached : _attachedObjects)
|
||||||
|
attached.second->scale(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Object::rotate(const Point4D &r) {
|
||||||
|
_angle = _angle + r;
|
||||||
|
|
||||||
|
Matrix4x4 rotationMatrix = Matrix4x4::RotationZ(r.z())*Matrix4x4::RotationY(r.y())*Matrix4x4::RotationX(r.z());
|
||||||
|
|
||||||
|
_left = rotationMatrix * _left;
|
||||||
|
_up = rotationMatrix * _up;
|
||||||
|
_lookAt = rotationMatrix * _lookAt;
|
||||||
|
|
||||||
|
for(auto attached : _attachedObjects)
|
||||||
|
attached.second->rotateRelativePoint(position(), r);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Object::rotate(const Point4D &v, double rv) {
|
||||||
|
Matrix4x4 rotationMatrix = Matrix4x4::Rotation(v, rv);
|
||||||
|
_left = rotationMatrix * _left;
|
||||||
|
_up = rotationMatrix * _up;
|
||||||
|
_lookAt = rotationMatrix * _lookAt;
|
||||||
|
|
||||||
|
for(auto attached : _attachedObjects)
|
||||||
|
attached.second->rotateRelativePoint(position(), v, rv);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Object::rotateRelativePoint(const Point4D &s, const Point4D &r) {
|
||||||
|
_angle = _angle + r;
|
||||||
|
|
||||||
|
// Translate XYZ by vector r1
|
||||||
|
Point4D r1 = _position - s;
|
||||||
|
|
||||||
|
// In translated coordinate system we rotate body and position
|
||||||
|
Matrix4x4 rotationMatrix = Matrix4x4::Rotation(r);
|
||||||
|
Point4D r2 = rotationMatrix*r1;
|
||||||
|
|
||||||
|
_left = rotationMatrix * _left;
|
||||||
|
_up = rotationMatrix * _up;
|
||||||
|
_lookAt = rotationMatrix * _lookAt;
|
||||||
|
|
||||||
|
// After rotation we translate XYZ by vector -r2 and recalculate position
|
||||||
|
_position = s + r2;
|
||||||
|
|
||||||
|
for(auto attached : _attachedObjects)
|
||||||
|
attached.second->rotateRelativePoint(s, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Object::rotateRelativePoint(const Point4D &s, const Point4D &v, double r) {
|
||||||
|
// Translate XYZ by vector r1
|
||||||
|
Point4D r1 = _position - s;
|
||||||
|
// In translated coordinate system we rotate body and position
|
||||||
|
Matrix4x4 rotationMatrix = Matrix4x4::Rotation(v, r);
|
||||||
|
Point4D r2 = rotationMatrix*r1;
|
||||||
|
|
||||||
|
_left = rotationMatrix * _left;
|
||||||
|
_up = rotationMatrix * _up;
|
||||||
|
_lookAt = rotationMatrix * _lookAt;
|
||||||
|
|
||||||
|
// After rotation we translate XYZ by vector -r2 and recalculate position
|
||||||
|
_position = s + r2;
|
||||||
|
|
||||||
|
for(auto attached : _attachedObjects)
|
||||||
|
attached.second->rotateRelativePoint(s, v, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Object::rotateLeft(double rl) {
|
||||||
|
_angleLeftUpLookAt = Point4D{_angleLeftUpLookAt.x() + rl, _angleLeftUpLookAt.y(), _angleLeftUpLookAt.z()};
|
||||||
|
|
||||||
|
rotate(_left, rl);
|
||||||
|
|
||||||
|
for(auto attached : _attachedObjects)
|
||||||
|
attached.second->rotateRelativePoint(position(), _left, rl);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Object::rotateUp(double ru) {
|
||||||
|
_angleLeftUpLookAt = Point4D{_angleLeftUpLookAt.x(), _angleLeftUpLookAt.y() + ru, _angleLeftUpLookAt.z()};
|
||||||
|
rotate(_up, ru);
|
||||||
|
|
||||||
|
for(auto attached : _attachedObjects)
|
||||||
|
attached.second->rotateRelativePoint(position(), _up, ru);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Object::rotateLookAt(double rlAt) {
|
||||||
|
_angleLeftUpLookAt = Point4D{_angleLeftUpLookAt.x(), _angleLeftUpLookAt.y(), _angleLeftUpLookAt.z() + rlAt};
|
||||||
|
rotate(_lookAt, rlAt);
|
||||||
|
|
||||||
|
for(auto attached : _attachedObjects)
|
||||||
|
attached.second->rotateRelativePoint(position(), _lookAt, rlAt);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Object::translateToPoint(const Point4D &point) {
|
||||||
|
translate(point - _position);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Object::rotateToAngle(const Point4D &v) {
|
||||||
|
rotate(v - _angle);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<Object> Object::attached(const std::string &name) {
|
||||||
|
if(_attachedObjects.count(name) == 0)
|
||||||
|
Log::log("Object::attached: object '" + name + "' does not exist.");
|
||||||
|
return _attachedObjects.find(name)->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Object::attach(std::shared_ptr<Object> object, const std::string &name) {
|
||||||
|
_attachedObjects.emplace(name, object);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Object::unattach(const std::string &name) {
|
||||||
|
_attachedObjects.erase(name);
|
||||||
|
}
|
|
@ -5,32 +5,49 @@
|
||||||
#ifndef ENGINE_OBJECT_H
|
#ifndef ENGINE_OBJECT_H
|
||||||
#define ENGINE_OBJECT_H
|
#define ENGINE_OBJECT_H
|
||||||
|
|
||||||
#include <vector>
|
#include <map>
|
||||||
#include "utils/Point4D.h"
|
#include "utils/Point4D.h"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include "animation/Animatable.h"
|
||||||
|
|
||||||
class Object {
|
class Object : public Animatable {
|
||||||
protected:
|
protected:
|
||||||
std::vector<std::shared_ptr<Object>> _attachedObjects;
|
Point4D _left = Point4D{1, 0, 0, 0}; // internal X
|
||||||
|
Point4D _up = Point4D{0, 1, 0, 0}; // internal Y
|
||||||
|
Point4D _lookAt = Point4D{0, 0, 1, 0}; // internal Z
|
||||||
|
|
||||||
|
std::map<std::string, std::shared_ptr<Object>> _attachedObjects;
|
||||||
|
|
||||||
Point4D _position;
|
Point4D _position;
|
||||||
Point4D _angle;
|
Point4D _angle;
|
||||||
|
Point4D _angleLeftUpLookAt;
|
||||||
public:
|
public:
|
||||||
Object() = default;
|
Object() = default;
|
||||||
|
|
||||||
virtual void translate(const Point4D& dv) {}
|
virtual void translate(const Point4D& dv);
|
||||||
virtual void rotate(const Point4D& r) {}
|
virtual void translateToPoint(const Point4D& point);
|
||||||
virtual void rotateRelativePoint(const Point4D& point4D, const Point4D& r) {}
|
virtual void scale(const Point4D& s);
|
||||||
virtual void rotate(const Point4D& v, double rv) {}
|
virtual void rotate(const Point4D& r);
|
||||||
virtual void rotateRelativePoint(const Point4D& s, const Point4D& v, double r) {}
|
virtual void rotate(const Point4D& v, double rv);
|
||||||
|
virtual void rotateToAngle(const Point4D& v);
|
||||||
|
virtual void rotateRelativePoint(const Point4D& s, const Point4D& r);
|
||||||
|
virtual void rotateRelativePoint(const Point4D& s, const Point4D& v, double r);
|
||||||
|
|
||||||
[[nodiscard]] Point4D position() const { return _position; }
|
[[nodiscard]] Point4D position() const { return _position; }
|
||||||
[[nodiscard]] Point4D angle() const { return _angle; }
|
[[nodiscard]] Point4D angle() const { return _angle; }
|
||||||
|
[[nodiscard]] Point4D angleLeftUpLookAt() const { return _angleLeftUpLookAt; }
|
||||||
|
|
||||||
void attach(std::shared_ptr<Object> object) {
|
[[nodiscard]] Point4D left() const { return _left; }
|
||||||
_attachedObjects.push_back(object);
|
[[nodiscard]] Point4D up() const { return _up; }
|
||||||
}
|
[[nodiscard]] Point4D lookAt() const { return _lookAt; }
|
||||||
|
|
||||||
|
void rotateLeft(double rl);
|
||||||
|
void rotateUp(double ru);
|
||||||
|
void rotateLookAt(double rlAt);
|
||||||
|
|
||||||
|
void attach(std::shared_ptr<Object> object, const std::string& name);
|
||||||
|
void unattach(const std::string& name);
|
||||||
|
std::shared_ptr<Object> attached(const std::string& name);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif //MINECRAFT_3DZAVR_OBJECT_H
|
#endif //MINECRAFT_3DZAVR_OBJECT_H
|
||||||
|
|
|
@ -95,7 +95,7 @@ void World::checkCollision(const std::string& body) {
|
||||||
|
|
||||||
void World::update() {
|
void World::update() {
|
||||||
for (auto &m : _objects) {
|
for (auto &m : _objects) {
|
||||||
m.second->a_update();
|
m.second->update_animations();
|
||||||
m.second->updatePhysicsState();
|
m.second->updatePhysicsState();
|
||||||
checkCollision(m.first);
|
checkCollision(m.first);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,14 +7,18 @@
|
||||||
|
|
||||||
#include "Animatable.h"
|
#include "Animatable.h"
|
||||||
#include "Animation.h"
|
#include "Animation.h"
|
||||||
|
#include "Mesh.h"
|
||||||
|
|
||||||
class AColor : public Animation {
|
class AColor : public Animation {
|
||||||
private:
|
private:
|
||||||
|
std::shared_ptr<Mesh> _mesh;
|
||||||
|
|
||||||
sf::Color newColor;
|
sf::Color newColor;
|
||||||
sf::Color startColor;
|
sf::Color startColor;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AColor(const sf::Color &color, double duration, LoopOut looped, InterpolationType interpolationType) {
|
AColor(std::shared_ptr<Mesh> mesh, const sf::Color &color, double duration = 1, LoopOut looped = LoopOut::None, InterpolationType interpolationType = InterpolationType::linear) {
|
||||||
|
_mesh = mesh;
|
||||||
_duration = duration;
|
_duration = duration;
|
||||||
_looped = looped;
|
_looped = looped;
|
||||||
_intType = interpolationType;
|
_intType = interpolationType;
|
||||||
|
@ -23,15 +27,15 @@ public:
|
||||||
newColor = color;
|
newColor = color;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool update(Animatable& obj) override {
|
bool update() override {
|
||||||
if(!_started)
|
if(!_started)
|
||||||
startColor = obj.color();
|
startColor = _mesh->color();
|
||||||
|
|
||||||
Point4D start(startColor.r, startColor.g, startColor.b, startColor.a);
|
Point4D start(startColor.r, startColor.g, startColor.b, startColor.a);
|
||||||
Point4D end(newColor.r, newColor.g, newColor.b, newColor.a);
|
Point4D end(newColor.r, newColor.g, newColor.b, newColor.a);
|
||||||
Point4D mid = start + (end - start)*_p;
|
Point4D mid = start + (end - start)*_p;
|
||||||
|
|
||||||
obj.setColor(sf::Color(static_cast<sf::Uint8>(mid.x()), static_cast<sf::Uint8>(mid.y()), static_cast<sf::Uint8>(mid.z()), static_cast<sf::Uint8>(mid.w())));
|
_mesh->setColor(sf::Color(static_cast<sf::Uint8>(mid.x()), static_cast<sf::Uint8>(mid.y()), static_cast<sf::Uint8>(mid.z()), static_cast<sf::Uint8>(mid.w())));
|
||||||
|
|
||||||
return updateState();
|
return updateState();
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ private:
|
||||||
std::function<void()> _callBack;
|
std::function<void()> _callBack;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AFunction(std::function<void()> function, int calls, double duration, LoopOut looped, InterpolationType interpolationType) {
|
explicit AFunction(std::function<void()> function, int calls = 1, double duration = 1, LoopOut looped = LoopOut::None, InterpolationType interpolationType = InterpolationType::linear) {
|
||||||
_callBack = std::move(function);
|
_callBack = std::move(function);
|
||||||
_allCalls = calls;
|
_allCalls = calls;
|
||||||
_duration = duration;
|
_duration = duration;
|
||||||
|
@ -24,7 +24,7 @@ public:
|
||||||
_intType = interpolationType;
|
_intType = interpolationType;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool update(Animatable& obj) override {
|
bool update() override {
|
||||||
if(_allCalls != 0 && _p >= (double)(_calls+1) / (_allCalls+1)) {
|
if(_allCalls != 0 && _p >= (double)(_calls+1) / (_allCalls+1)) {
|
||||||
_calls++;
|
_calls++;
|
||||||
_callBack();
|
_callBack();
|
||||||
|
|
|
@ -7,12 +7,16 @@
|
||||||
|
|
||||||
#include "Animatable.h"
|
#include "Animatable.h"
|
||||||
#include "Animation.h"
|
#include "Animation.h"
|
||||||
|
#include "Object.h"
|
||||||
|
|
||||||
class ARotate : public Animation {
|
class ARotate : public Animation {
|
||||||
private:
|
private:
|
||||||
|
std::shared_ptr<Object> _object;
|
||||||
|
|
||||||
Point4D value;
|
Point4D value;
|
||||||
public:
|
public:
|
||||||
ARotate(const Point4D& r, double duration, LoopOut looped, InterpolationType interpolationType) {
|
ARotate(std::shared_ptr<Object> object, const Point4D& r, double duration = 1, LoopOut looped = LoopOut::None, InterpolationType interpolationType = InterpolationType::bezier) {
|
||||||
|
_object = object;
|
||||||
_duration = duration;
|
_duration = duration;
|
||||||
_looped = looped;
|
_looped = looped;
|
||||||
_intType = interpolationType;
|
_intType = interpolationType;
|
||||||
|
@ -20,8 +24,8 @@ public:
|
||||||
value = r;
|
value = r;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool update(Animatable& obj) override {
|
bool update() override {
|
||||||
obj.rotate(value * _dp);
|
_object->rotate(value * _dp);
|
||||||
return updateState();
|
return updateState();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -7,14 +7,17 @@
|
||||||
|
|
||||||
#include "Animatable.h"
|
#include "Animatable.h"
|
||||||
#include "Animation.h"
|
#include "Animation.h"
|
||||||
|
#include "Mesh.h"
|
||||||
|
|
||||||
class AScale : public Animation {
|
class AScale : public Animation {
|
||||||
private:
|
private:
|
||||||
Point4D value;
|
std::shared_ptr<Mesh> _mesh;
|
||||||
|
|
||||||
std::vector<Triangle> triangles;
|
Point4D value;
|
||||||
|
std::vector<Triangle> triangles{};
|
||||||
public:
|
public:
|
||||||
AScale(const Point4D &s, double duration, LoopOut looped, InterpolationType interpolationType) {
|
AScale(std::shared_ptr<Mesh> mesh, const Point4D &s, double duration = 1, LoopOut looped = LoopOut::None, InterpolationType interpolationType = InterpolationType::bezier) {
|
||||||
|
_mesh = mesh;
|
||||||
_duration = duration;
|
_duration = duration;
|
||||||
_looped = looped;
|
_looped = looped;
|
||||||
_intType = interpolationType;
|
_intType = interpolationType;
|
||||||
|
@ -23,15 +26,15 @@ public:
|
||||||
value = s;
|
value = s;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool update(Animatable& obj) override {
|
bool update() override {
|
||||||
if(!_started)
|
if(!_started)
|
||||||
triangles = obj.triangles();
|
triangles = _mesh->triangles();
|
||||||
|
|
||||||
std::vector<Triangle> newTriangles;
|
std::vector<Triangle> newTriangles;
|
||||||
for(auto &t : triangles) {
|
for(auto &t : triangles) {
|
||||||
newTriangles.emplace_back(t * Matrix4x4::Scale(Point4D{1, 1, 1} + (value - Point4D{1, 1, 1}) * _p));
|
newTriangles.emplace_back(t * Matrix4x4::Scale(Point4D{1, 1, 1} + (value - Point4D{1, 1, 1}) * _p));
|
||||||
}
|
}
|
||||||
obj.setTriangles(newTriangles);
|
_mesh->setTriangles(newTriangles);
|
||||||
return updateState();
|
return updateState();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -7,12 +7,16 @@
|
||||||
|
|
||||||
#include "Animatable.h"
|
#include "Animatable.h"
|
||||||
#include "Animation.h"
|
#include "Animation.h"
|
||||||
|
#include "Object.h"
|
||||||
|
|
||||||
class ATranslate : public Animation {
|
class ATranslate : public Animation {
|
||||||
private:
|
private:
|
||||||
|
std::shared_ptr<Object> _object;
|
||||||
|
|
||||||
Point4D value;
|
Point4D value;
|
||||||
public:
|
public:
|
||||||
ATranslate(const Point4D& t, double duration, LoopOut looped, InterpolationType interpolationType) {
|
ATranslate(std::shared_ptr<Object> object, const Point4D& t, double duration = 1, LoopOut looped = LoopOut::None, InterpolationType interpolationType = InterpolationType::bezier) {
|
||||||
|
_object = object;
|
||||||
_duration = duration;
|
_duration = duration;
|
||||||
_looped = looped;
|
_looped = looped;
|
||||||
_intType = interpolationType;
|
_intType = interpolationType;
|
||||||
|
@ -20,14 +24,10 @@ public:
|
||||||
value = t;
|
value = t;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool update(Animatable& obj) override {
|
bool update() override {
|
||||||
obj.translate(value * _dp);
|
_object->translate(value * _dp);
|
||||||
return updateState();
|
return updateState();
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] int type() const override {
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //INC_3DZAVR_ATRANSLATE_H
|
#endif //INC_3DZAVR_ATRANSLATE_H
|
||||||
|
|
|
@ -7,13 +7,17 @@
|
||||||
|
|
||||||
#include "Animatable.h"
|
#include "Animatable.h"
|
||||||
#include "Animation.h"
|
#include "Animation.h"
|
||||||
|
#include "Object.h"
|
||||||
|
|
||||||
class ATranslateToPoint : public Animation {
|
class ATranslateToPoint : public Animation {
|
||||||
private:
|
private:
|
||||||
|
std::shared_ptr<Object> _object;
|
||||||
|
|
||||||
Point4D point;
|
Point4D point;
|
||||||
Point4D value;
|
Point4D value;
|
||||||
public:
|
public:
|
||||||
ATranslateToPoint(const Point4D& p, double duration, LoopOut looped, InterpolationType interpolationType) {
|
ATranslateToPoint(std::shared_ptr<Object> object, const Point4D& p, double duration = 1, LoopOut looped = LoopOut::None, InterpolationType interpolationType = InterpolationType::bezier) {
|
||||||
|
_object = object;
|
||||||
_duration = duration;
|
_duration = duration;
|
||||||
_looped = looped;
|
_looped = looped;
|
||||||
_intType = interpolationType;
|
_intType = interpolationType;
|
||||||
|
@ -21,11 +25,11 @@ public:
|
||||||
point = p;
|
point = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool update(Animatable& obj) override {
|
bool update() override {
|
||||||
if(!_started) {
|
if(!_started) {
|
||||||
value = point - obj.position();
|
value = point - _object->position();
|
||||||
}
|
}
|
||||||
obj.translate(value * _dp);
|
_object->translate(value * _dp);
|
||||||
|
|
||||||
return updateState();
|
return updateState();
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,22 +9,16 @@
|
||||||
#include "Animation.h"
|
#include "Animation.h"
|
||||||
|
|
||||||
class AWait : public Animation {
|
class AWait : public Animation {
|
||||||
private:
|
|
||||||
Point4D value;
|
|
||||||
public:
|
public:
|
||||||
explicit AWait(double duration) {
|
explicit AWait(double duration = 1) {
|
||||||
_duration = duration;
|
_duration = duration;
|
||||||
_intType = linear;
|
_intType = linear;
|
||||||
_waitFor = true;
|
_waitFor = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool update(Animatable& obj) override {
|
bool update() override {
|
||||||
return updateState();
|
return updateState();
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] int type() const override {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //INC_3DZAVR_AWAIT_H
|
#endif //INC_3DZAVR_AWAIT_H
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include "AFunction.h"
|
#include "AFunction.h"
|
||||||
#include "AColor.h"
|
#include "AColor.h"
|
||||||
|
|
||||||
|
/*
|
||||||
void Animatable::a_translate(const std::string& listName,
|
void Animatable::a_translate(const std::string& listName,
|
||||||
const Point4D &t,
|
const Point4D &t,
|
||||||
double duration,
|
double duration,
|
||||||
|
@ -30,7 +31,7 @@ void Animatable::a_translateToPoint(const std::string& listName,
|
||||||
animations[listName].emplace_back(new ATranslateToPoint(point, duration, looped, interpolationType));
|
animations[listName].emplace_back(new ATranslateToPoint(point, duration, looped, interpolationType));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Animatable::a_rotate(const std::string& listName,
|
void Animatable::a_rotate(c
|
||||||
const Point4D &r,
|
const Point4D &r,
|
||||||
double duration,
|
double duration,
|
||||||
Animation::LoopOut looped,
|
Animation::LoopOut looped,
|
||||||
|
@ -63,8 +64,9 @@ void Animatable::a_function(const std::string &listName,
|
||||||
Animation::InterpolationType interpolationType) {
|
Animation::InterpolationType interpolationType) {
|
||||||
animations[listName].emplace_back(new AFunction(std::move(function), calls, duration, looped, interpolationType));
|
animations[listName].emplace_back(new AFunction(std::move(function), calls, duration, looped, interpolationType));
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
void Animatable::a_update() {
|
void Animatable::update_animations() {
|
||||||
|
|
||||||
for (auto& [listName, animationList] : animations) {
|
for (auto& [listName, animationList] : animations) {
|
||||||
|
|
||||||
|
@ -74,18 +76,21 @@ void Animatable::a_update() {
|
||||||
// If it the front animation is 'a_wait()' we should wait until waiting time is over
|
// If it the front animation is 'a_wait()' we should wait until waiting time is over
|
||||||
|
|
||||||
if (it.operator*()->waitFor()) {
|
if (it.operator*()->waitFor()) {
|
||||||
if (!it.operator*()->update(*this))
|
if (!it.operator*()->update())
|
||||||
animationList.erase(it);
|
animationList.erase(it);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Otherwise we iterate over all animation until we meet animations.end() or wait animation
|
// Otherwise we iterate over all animation until we meet animations.end() or wait animation
|
||||||
while (!animationList.empty() && (it != animationList.end()) && (!it.operator*()->waitFor())) {
|
while (!animationList.empty() && (it != animationList.end()) && (!it.operator*()->waitFor())) {
|
||||||
if (!it.operator*()->update(*this))
|
if (!it.operator*()->update())
|
||||||
animationList.erase(it++);
|
animationList.erase(it++);
|
||||||
else
|
else
|
||||||
it++;
|
it++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Animatable::animate(const std::string &listName, Animation* anim) {
|
||||||
|
animations[listName].emplace_back(anim);
|
||||||
|
}
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
#include <list>
|
#include <list>
|
||||||
#include "../Triangle.h"
|
#include "../Triangle.h"
|
||||||
|
|
||||||
//class Animation;
|
|
||||||
#include "Animation.h"
|
#include "Animation.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
@ -21,50 +20,13 @@ protected:
|
||||||
public:
|
public:
|
||||||
Animatable() = default;
|
Animatable() = default;
|
||||||
virtual ~Animatable() = default;
|
virtual ~Animatable() = default;
|
||||||
// All methods about animation begins with 'a_'
|
|
||||||
void a_translate(const std::string& listName,
|
|
||||||
const Point4D& t,
|
|
||||||
double duration = 1,
|
|
||||||
Animation::LoopOut looped = Animation::None,
|
|
||||||
Animation::InterpolationType interpolationType = Animation::bezier);
|
|
||||||
void a_translateToPoint(const std::string& listName,
|
|
||||||
const Point4D& point,
|
|
||||||
double duration = 1,
|
|
||||||
Animation::LoopOut looped = Animation::None,
|
|
||||||
Animation::InterpolationType interpolationType = Animation::bezier);
|
|
||||||
|
|
||||||
void a_rotate(const std::string& listName,
|
void animate(const std::string& listName, Animation* anim);
|
||||||
const Point4D& r,
|
|
||||||
double duration = 1,
|
|
||||||
Animation::LoopOut looped = Animation::None,
|
|
||||||
Animation::InterpolationType interpolationType = Animation::bezier);
|
|
||||||
|
|
||||||
void a_scale(const std::string& listName,
|
void update_animations();
|
||||||
const Point4D& s,
|
|
||||||
double duration = 1,
|
|
||||||
Animation::LoopOut looped = Animation::None,
|
|
||||||
Animation::InterpolationType interpolationType = Animation::bezier);
|
|
||||||
|
|
||||||
void a_wait(const std::string& listName, double duration = 1);
|
void stopAllAnimations() { animations.clear(); }
|
||||||
|
void stopAnimationList(const std::string& name) { animations[name].clear(); }
|
||||||
void a_function(const std::string& listName,
|
|
||||||
std::function<void()> function,
|
|
||||||
int calls = 1,
|
|
||||||
double duration = 1,
|
|
||||||
Animation::LoopOut looped = Animation::None,
|
|
||||||
Animation::InterpolationType interpolationType = Animation::bezier);
|
|
||||||
|
|
||||||
void a_color(const std::string& listName,
|
|
||||||
const sf::Color& color,
|
|
||||||
double duration = 1,
|
|
||||||
Animation::LoopOut looped = Animation::None,
|
|
||||||
Animation::InterpolationType interpolationType = Animation::bezier);
|
|
||||||
|
|
||||||
|
|
||||||
void a_update();
|
|
||||||
|
|
||||||
void a_stopAllAnimations() { animations.clear(); }
|
|
||||||
void a_stopAnimationList(const std::string& name) { animations[name].clear(); }
|
|
||||||
|
|
||||||
[[nodiscard]] bool isInAnim() const {
|
[[nodiscard]] bool isInAnim() const {
|
||||||
for(auto& animList : animations)
|
for(auto& animList : animations)
|
||||||
|
@ -74,19 +36,6 @@ public:
|
||||||
|
|
||||||
}
|
}
|
||||||
[[nodiscard]] bool isInAnimList(const std::string& name) { return !animations[name].empty(); }
|
[[nodiscard]] bool isInAnimList(const std::string& name) { return !animations[name].empty(); }
|
||||||
|
|
||||||
// methods to override:
|
|
||||||
// If you want to create new animation you can either add new virtual function here
|
|
||||||
// or override one of the following function:
|
|
||||||
[[nodiscard]] virtual Point4D position() const { return Point4D{}; }
|
|
||||||
[[nodiscard]] virtual Point4D angle() const { return Point4D{}; }
|
|
||||||
virtual void translate(const Point4D& dv) {}
|
|
||||||
virtual void rotate(const Point4D& r) {}
|
|
||||||
[[nodiscard]] virtual std::vector<Triangle>& triangles() { return *(std::vector<Triangle>*)(new std::vector<Triangle>()); }
|
|
||||||
virtual void setTriangles(const std::vector<Triangle>& tris) {}
|
|
||||||
|
|
||||||
[[nodiscard]] virtual sf::Color color() const {return sf::Color(); }
|
|
||||||
virtual void setColor(sf::Color c) { }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //INC_3DZAVR_ANIMATABLE_H
|
#endif //INC_3DZAVR_ANIMATABLE_H
|
||||||
|
|
|
@ -54,9 +54,7 @@ public:
|
||||||
|
|
||||||
|
|
||||||
// You should override this method for your particular animation
|
// You should override this method for your particular animation
|
||||||
virtual bool update(Animatable& obj) = 0;
|
virtual bool update() = 0;
|
||||||
|
|
||||||
[[nodiscard]] virtual int type() const{return 0;}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //INC_3DZAVR_ANIMATION_H
|
#endif //INC_3DZAVR_ANIMATION_H
|
||||||
|
|
185
main.cpp
185
main.cpp
|
@ -2,193 +2,10 @@
|
||||||
// Created by Иван Ильин on 06.02.2021.
|
// Created by Иван Ильин on 06.02.2021.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "Engine.h"
|
#include "Shooter.h"
|
||||||
#include <iostream>
|
|
||||||
#include "Player.h"
|
|
||||||
#include "ResourceManager.h"
|
|
||||||
#include "gui/Window.h"
|
|
||||||
#include "PlayerController.h"
|
|
||||||
|
|
||||||
#include "Client.h"
|
|
||||||
#include "Server.h"
|
|
||||||
#include <fstream>
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
// Read server/client settings and start both.
|
|
||||||
// If client doesn't connect to the localhost - server doesn't start.
|
|
||||||
void InitNetwork(shared_ptr<Server> server, shared_ptr<Client> client)
|
|
||||||
{
|
|
||||||
std::string clientIp;
|
|
||||||
sf::Uint16 clientPort;
|
|
||||||
sf::Uint16 serverPort;
|
|
||||||
std::ifstream connectfile("connect.txt", std::ifstream::in);
|
|
||||||
|
|
||||||
// If failed to read client settings
|
|
||||||
if (!connectfile.is_open() || !(connectfile >> clientIp >> clientPort) || sf::IpAddress(clientIp) == sf::IpAddress::None)
|
|
||||||
{
|
|
||||||
connectfile.close();
|
|
||||||
// Create file and write default settings
|
|
||||||
clientIp = "127.0.0.1";
|
|
||||||
clientPort = 54000;
|
|
||||||
std::ofstream temp("connect.txt", std::ofstream::out);
|
|
||||||
temp << clientIp << std::endl << clientPort;
|
|
||||||
temp.close();
|
|
||||||
}
|
|
||||||
connectfile.close();
|
|
||||||
|
|
||||||
// If failed to read server settings
|
|
||||||
connectfile.open("server.txt", std::ifstream::in);
|
|
||||||
if (!connectfile.is_open() || !(connectfile >> serverPort))
|
|
||||||
{
|
|
||||||
connectfile.close();
|
|
||||||
// Create file and write default settings
|
|
||||||
serverPort = 54000;
|
|
||||||
std::ofstream temp("server.txt", std::ofstream::out);
|
|
||||||
temp << serverPort;
|
|
||||||
temp.close();
|
|
||||||
}
|
|
||||||
connectfile.close();
|
|
||||||
|
|
||||||
if (clientIp == sf::IpAddress::LocalHost) {
|
|
||||||
server->start(serverPort);
|
|
||||||
if(server->isWorking())
|
|
||||||
server->generateBonuses();
|
|
||||||
}
|
|
||||||
|
|
||||||
client->connect(clientIp, clientPort);
|
|
||||||
}
|
|
||||||
|
|
||||||
class Shooter : public Engine {
|
|
||||||
private:
|
|
||||||
shared_ptr<Player> player;
|
|
||||||
shared_ptr<PlayerController> playerController;
|
|
||||||
|
|
||||||
sf::Sound backgroundNoise;
|
|
||||||
|
|
||||||
Window mainMenu;
|
|
||||||
|
|
||||||
shared_ptr<Server> server;
|
|
||||||
shared_ptr<Client> client;
|
|
||||||
|
|
||||||
bool inGame = false;
|
|
||||||
|
|
||||||
public:
|
|
||||||
Shooter() : mainMenu(screen, mouse) {};
|
|
||||||
|
|
||||||
void start() override;
|
|
||||||
void update() override;
|
|
||||||
|
|
||||||
void gui() override;
|
|
||||||
|
|
||||||
void play();
|
|
||||||
};
|
|
||||||
|
|
||||||
void Shooter::start() {
|
|
||||||
// This code executed once in the beginning:
|
|
||||||
setDebugText(false);
|
|
||||||
|
|
||||||
mouse->setMouseCursorVisible(true);
|
|
||||||
|
|
||||||
world->loadMap("../maps/map1.obj", "map", Point4D{5, 5, 5});
|
|
||||||
|
|
||||||
player = std::make_shared<Player>();
|
|
||||||
playerController = std::make_shared<PlayerController>(player, world, keyboard, mouse);
|
|
||||||
|
|
||||||
client = std::make_shared<Client>(player, world);
|
|
||||||
server = std::make_shared<Server>();
|
|
||||||
|
|
||||||
player->setAddTraceCallBack([this](const Point4D& from, const Point4D& to){ client->addTrace(from, to); });
|
|
||||||
player->attachCamera(camera, screen);
|
|
||||||
player->attachWorld(world);
|
|
||||||
|
|
||||||
setUpdateWorld(false);
|
|
||||||
|
|
||||||
world->addBody(player, player->name());
|
|
||||||
|
|
||||||
player->setDamagePlayerCallBack([this] (sf::Uint16 targetId, double damage) { client->damagePlayer(targetId, damage); });
|
|
||||||
player->setTakeBonusCallBack([this] (const string& bonusName) { client->takeBonus(bonusName); });
|
|
||||||
|
|
||||||
|
|
||||||
// windows init:
|
|
||||||
mainMenu.title("Main menu");
|
|
||||||
mainMenu.setBackgroundTexture("../textures/back.png", 1.1, 1.1, screen->width(), screen->height());
|
|
||||||
|
|
||||||
mainMenu.addButton(screen->width()/2, 200, 200, 20, [this] () { this->play(); }, "Play", 5, 5, "../textures/gui.png", {0, 66}, {0, 86}, {0, 46}, "../engine/fonts/Roboto-Medium.ttf", {255, 255, 255}, "../sound/click.ogg");
|
|
||||||
mainMenu.addButton(screen->width()/2, 350, 200, 20, [this] () { this->player->translateToPoint(Point4D{0, 0, 0}); this->player->setVelocity({}); this->play(); }, "Respawn", 5, 5, "../textures/gui.png", {0, 66}, {0, 86}, {0, 46}, "../engine/fonts/Roboto-Medium.ttf", {255, 255, 255}, "../sound/click.ogg");
|
|
||||||
|
|
||||||
mainMenu.addButton(screen->width()/2, 500, 200, 20, [this] () { client->disconnect(); server->stop(); this->exit();}, "Exit", 5, 5, "../textures/gui.png", {0, 66}, {0, 86}, {0, 46}, "../engine/fonts/Roboto-Medium.ttf", {255, 255, 255}, "../sound/click.ogg");
|
|
||||||
|
|
||||||
// connecting to the server
|
|
||||||
InitNetwork(server, client);
|
|
||||||
// Waiting for connect and updating server if it's same window
|
|
||||||
while (client->isWorking() && !client->connected())
|
|
||||||
{
|
|
||||||
client->update();
|
|
||||||
server->update();
|
|
||||||
Time::update();
|
|
||||||
}
|
|
||||||
// If connect fail - return to menu
|
|
||||||
if (!client->isWorking())
|
|
||||||
{
|
|
||||||
inGame = false;
|
|
||||||
server->stop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Shooter::update() {
|
|
||||||
// This code executed every time step:
|
|
||||||
|
|
||||||
server->update();
|
|
||||||
client->update();
|
|
||||||
|
|
||||||
// Check all input after this condition please
|
|
||||||
if (!screen->hasFocus())
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(keyboard->isKeyTapped(sf::Keyboard::Escape)) {
|
|
||||||
inGame = !inGame;
|
|
||||||
mouse->setMouseCursorVisible(!inGame);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(inGame) {
|
|
||||||
screen->setTitle("Shooter");
|
|
||||||
player->update();
|
|
||||||
playerController->update();
|
|
||||||
mouse->setMouseInCenter();
|
|
||||||
} else {
|
|
||||||
mainMenu.update();
|
|
||||||
}
|
|
||||||
|
|
||||||
setUpdateWorld(inGame);
|
|
||||||
|
|
||||||
// background sounds and music control
|
|
||||||
if(backgroundNoise.getStatus() != sf::Sound::Status::Playing) {
|
|
||||||
backgroundNoise.setBuffer(*ResourceManager::loadSoundBuffer("../sound/backNoise.ogg"));
|
|
||||||
backgroundNoise.play();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Shooter::gui() {
|
|
||||||
|
|
||||||
sf::Sprite sprite;
|
|
||||||
sprite.setTexture(*ResourceManager::loadTexture("../textures/gui.png"));
|
|
||||||
sprite.setTextureRect(sf::IntRect(243, 3, 9, 9));
|
|
||||||
sprite.scale(3, 3);
|
|
||||||
sprite.setPosition(screen->width() / 2.0 - 27.0/2.0, screen->height() / 2 - 27.0/2.0);
|
|
||||||
sprite.setColor(sf::Color(0,0,0, 200));
|
|
||||||
screen->drawSprite(sprite);
|
|
||||||
|
|
||||||
// health player stats
|
|
||||||
player->drawStats();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Shooter::play() {
|
|
||||||
inGame = true;
|
|
||||||
|
|
||||||
mouse->setMouseCursorVisible(!inGame);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
Shooter game;
|
Shooter game;
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
|
|
||||||
#include <ResourceManager.h>
|
#include <ResourceManager.h>
|
||||||
#include "Shotgun.h"
|
#include "Shotgun.h"
|
||||||
|
#include "animation/AColor.h"
|
||||||
|
#include "animation/AFunction.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
@ -23,7 +25,7 @@ Shotgun::Shotgun(int ammo, const std::string& weaponName) : Weapon(weaponName, "
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<std::string, double>
|
std::map<std::string, double>
|
||||||
Shotgun::processFire(std::shared_ptr<World> world, std::shared_ptr<Camera> camera) {
|
Shotgun::processFire(std::function<std::pair<Point4D, std::string>(const Point4D&, const Point4D&)> rayCastFunction, const Point4D& pos, const Point4D& direction) {
|
||||||
std::map<std::string, double> damagedPlayers;
|
std::map<std::string, double> damagedPlayers;
|
||||||
|
|
||||||
for(int i = 0; i < 15; i++) {
|
for(int i = 0; i < 15; i++) {
|
||||||
|
@ -31,24 +33,14 @@ Shotgun::processFire(std::shared_ptr<World> world, std::shared_ptr<Camera> camer
|
||||||
Point4D randV(10*_spreading*(1.0 - 2.0*(double)rand()/RAND_MAX), 10*_spreading*(1.0 - 2.0*(double)rand()/RAND_MAX), 10*_spreading*(1.0 - 2.0*(double)rand()/RAND_MAX));
|
Point4D randV(10*_spreading*(1.0 - 2.0*(double)rand()/RAND_MAX), 10*_spreading*(1.0 - 2.0*(double)rand()/RAND_MAX), 10*_spreading*(1.0 - 2.0*(double)rand()/RAND_MAX));
|
||||||
|
|
||||||
// damage player
|
// damage player
|
||||||
auto rayCast = world->rayCast(camera->position(), camera->position() + camera->lookAt() * 1000 + randV);
|
auto rayCast = rayCastFunction(pos, pos + direction * 1000 + randV);
|
||||||
if (rayCast.second.find("Player") != std::string::npos) {
|
if (rayCast.second.find("Player") != std::string::npos) {
|
||||||
damagedPlayers[rayCast.second] += _damage / (1.0 + (camera->position() - rayCast.first).abs());
|
damagedPlayers[rayCast.second] += _damage / (1.0 + (pos - rayCast.first).abs());
|
||||||
}
|
}
|
||||||
|
|
||||||
// add trace line
|
Point4D to = rayCast.first.w() == -1 ? pos + direction * 1000 + randV: rayCast.first;
|
||||||
Point4D to = rayCast.first.w() == -1 ? camera->position() + camera->lookAt() * 1000 + randV: rayCast.first;
|
Point4D from = position() + triangles().back()[0];
|
||||||
string traceName = _name + "_trace_nr_" + std::to_string(fireTraces++);
|
_addTraceCallBack(from, to);
|
||||||
Point4D from = _objects[_name + "_" + to_string(9)]->position() +
|
|
||||||
_objects[_name + "_" + to_string(9)]->triangles()[0][0];
|
|
||||||
world->addBody(make_shared<RigidBody>(Mesh::LineTo(from, to, 0.05)), traceName);
|
|
||||||
world->body(traceName)->setCollider(false);
|
|
||||||
|
|
||||||
// remove trace line after some time
|
|
||||||
world->body(traceName)->a_color("color_trace", {255, 255, 255, 0}, 1, Animation::None, Animation::linear);
|
|
||||||
world->body("map_0")->a_function(traceName + "delete", [world, traceName]() { deleteTrace(world, traceName); },
|
|
||||||
1, 2);
|
|
||||||
addTraceCallBack(from, to);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
class Shotgun : public Weapon {
|
class Shotgun : public Weapon {
|
||||||
public:
|
public:
|
||||||
explicit Shotgun(int ammo = 15, const std::string& weaponName = "shotgun");
|
explicit Shotgun(int ammo = 15, const std::string& weaponName = "shotgun");
|
||||||
std::map<std::string, double> processFire(std::shared_ptr<World> world, std::shared_ptr<Camera> camera) override;
|
std::map<std::string, double> processFire(std::function<std::pair<Point4D, std::string>(const Point4D&, const Point4D&)> rayCastFunction, const Point4D& position, const Point4D& direction) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,15 +3,21 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <utility>
|
||||||
#include "Weapon.h"
|
#include "Weapon.h"
|
||||||
#include "ResourceManager.h"
|
#include "ResourceManager.h"
|
||||||
#include "utils/Log.h"
|
#include "utils/Log.h"
|
||||||
|
#include "animation/AColor.h"
|
||||||
|
#include "animation/AFunction.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
Weapon::Weapon(const std::string& weaponName, const std::string& objFileName, const std::string& matFileName, const Point4D& scale, const Point4D& translate, const Point4D& rotate) {
|
Weapon::Weapon(const std::string& weaponName, const std::string& objFileName, const std::string& matFileName, const Point4D& scale, const Point4D& t, const Point4D& r) {
|
||||||
_name = weaponName;
|
_name = weaponName;
|
||||||
|
|
||||||
|
/*
|
||||||
auto objs = Mesh::LoadObjects(objFileName, matFileName, scale);
|
auto objs = Mesh::LoadObjects(objFileName, matFileName, scale);
|
||||||
|
|
||||||
for(int i = 0; i < objs.size(); i++) {
|
for(int i = 0; i < objs.size(); i++) {
|
||||||
string meshName = _name + "_" + to_string(i);
|
string meshName = _name + "_" + to_string(i);
|
||||||
|
|
||||||
|
@ -25,10 +31,16 @@ Weapon::Weapon(const std::string& weaponName, const std::string& objFileName, co
|
||||||
|
|
||||||
_objects.insert({meshName, std::make_shared<RigidBody>(obj)});
|
_objects.insert({meshName, std::make_shared<RigidBody>(obj)});
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
loadObj(objFileName, matFileName, scale);
|
||||||
|
setCollider(false);
|
||||||
|
rotate(r);
|
||||||
|
translate(t);
|
||||||
|
|
||||||
noAmmoSound.setBuffer(*ResourceManager::loadSoundBuffer("../sound/weapons/no_ammo.ogg"));
|
noAmmoSound.setBuffer(*ResourceManager::loadSoundBuffer("../sound/weapons/no_ammo.ogg"));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map<std::string, double> Weapon::fire(std::shared_ptr<World> world, std::shared_ptr<Camera> camera) {
|
std::map<std::string, double> Weapon::fire(std::function<std::pair<Point4D, std::string>(const Point4D&, const Point4D&)> rayCastFunction, const Point4D& position, const Point4D& direction) {
|
||||||
if(_clipAmmo == 0) {
|
if(_clipAmmo == 0) {
|
||||||
reload();
|
reload();
|
||||||
if(_clipAmmo == 0)
|
if(_clipAmmo == 0)
|
||||||
|
@ -44,7 +56,7 @@ std::map<std::string, double> Weapon::fire(std::shared_ptr<World> world, std::sh
|
||||||
fireSound.play();
|
fireSound.play();
|
||||||
Log::log("Weapon::fire (" + std::to_string(_stockAmmo) + " : " + std::to_string(_clipAmmo) + ")");
|
Log::log("Weapon::fire (" + std::to_string(_stockAmmo) + " : " + std::to_string(_clipAmmo) + ")");
|
||||||
|
|
||||||
return processFire(world, camera);
|
return processFire(std::move(rayCastFunction), position, direction);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Weapon::reload() {
|
void Weapon::reload() {
|
||||||
|
@ -63,68 +75,22 @@ void Weapon::reload() {
|
||||||
_lastReloadTime = Time::time();
|
_lastReloadTime = Time::time();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Weapon::addToWorld(shared_ptr<World> world) {
|
std::map<std::string, double> Weapon::processFire(std::function<std::pair<Point4D, std::string>(const Point4D&, const Point4D&)> rayCastFunction, const Point4D& pos, const Point4D& direction) {
|
||||||
for(auto& obj : _objects) {
|
|
||||||
world->addBody(obj.second, obj.first);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Weapon::removeFromWorld(shared_ptr<World> world) {
|
|
||||||
for(auto& obj : _objects) {
|
|
||||||
world->removeBodyInstantly(obj.first);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Weapon::attachToPlayer(Mesh &player) {
|
|
||||||
for(auto& obj : _objects) {
|
|
||||||
player.attach(obj.second);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Weapon::rotate(const Point4D& point4D, double val) {
|
|
||||||
for(auto& mesh : _objects)
|
|
||||||
mesh.second->rotate(point4D, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Weapon::translate(const Point4D &point4D) {
|
|
||||||
for(auto& mesh : _objects)
|
|
||||||
mesh.second->translate(point4D);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Weapon::deleteTrace(shared_ptr<World> world, const std::string& traceName) {
|
|
||||||
world->removeBody(traceName);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Weapon::rotateRelativePoint(const Point4D &point4D, const Point4D &v, double val) {
|
|
||||||
for(auto& mesh : _objects)
|
|
||||||
mesh.second->rotateRelativePoint(point4D, v, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::map<std::string, double> Weapon::processFire(shared_ptr<World> world, shared_ptr<Camera> camera) {
|
|
||||||
std::map<std::string, double> damagedPlayers;
|
std::map<std::string, double> damagedPlayers;
|
||||||
|
|
||||||
//generate random vector
|
//generate random vector
|
||||||
Point4D randV(10.0*_spreading*(1.0 - 2.0*(double)rand()/RAND_MAX), 10.0*_spreading*(1.0 - 2.0*(double)rand()/RAND_MAX), 10.0*_spreading*(1.0 - 2.0*(double)rand()/RAND_MAX));
|
Point4D randV(10.0*_spreading*(1.0 - 2.0*(double)rand()/RAND_MAX), 10.0*_spreading*(1.0 - 2.0*(double)rand()/RAND_MAX), 10.0*_spreading*(1.0 - 2.0*(double)rand()/RAND_MAX));
|
||||||
|
|
||||||
// damage player
|
// damage player
|
||||||
auto rayCast = world->rayCast(camera->position(), camera->position() + camera->lookAt() * 1000 + randV);
|
auto rayCast = rayCastFunction(pos, pos + direction * 1000 + randV);
|
||||||
if(rayCast.second.find("Player") != std::string::npos) {
|
if(rayCast.second.find("Player") != std::string::npos) {
|
||||||
damagedPlayers[rayCast.second] += _damage/(1.0 + (camera->position() - rayCast.first).abs());
|
damagedPlayers[rayCast.second] += _damage/(1.0 + (pos - rayCast.first).abs());
|
||||||
}
|
}
|
||||||
|
|
||||||
// add trace line
|
// add trace line
|
||||||
Point4D to = rayCast.first.w() == -1 ? camera->position() + camera->lookAt() * 1000 + randV: rayCast.first;
|
Point4D to = rayCast.first.w() == -1 ? pos + direction * 1000 + randV: rayCast.first;
|
||||||
string traceName = _name + "_trace_nr_" + std::to_string(fireTraces++);
|
Point4D from = position() + triangles().back()[0];
|
||||||
Point4D from = _objects[_name + "_" + to_string(_objects.size()-1)]->position() + _objects[_name + "_" + to_string(_objects.size()-1)]->triangles()[0][0];
|
_addTraceCallBack(from, to);
|
||||||
world->addBody(make_shared<RigidBody>(Mesh::LineTo(from, to, 0.05)), traceName);
|
|
||||||
world->body(traceName)->setCollider(false);
|
|
||||||
|
|
||||||
// remove trace line after some time
|
|
||||||
world->body(traceName)->a_color("color_trace", {255, 255, 255, 0}, 1, Animation::None, Animation::linear);
|
|
||||||
world->body("Player_im")->a_function(traceName + "delete", [world, traceName](){deleteTrace(world, traceName); }, 1, 2);
|
|
||||||
|
|
||||||
addTraceCallBack(from, to);
|
|
||||||
|
|
||||||
return damagedPlayers;
|
return damagedPlayers;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
#include "Mesh.h"
|
#include "Mesh.h"
|
||||||
#include "utils/Time.h"
|
#include "utils/Time.h"
|
||||||
|
|
||||||
class Weapon {
|
class Weapon : public RigidBody {
|
||||||
protected:
|
protected:
|
||||||
int _initialPack = 100; // how much ammo do you have when you find the weapon
|
int _initialPack = 100; // how much ammo do you have when you find the weapon
|
||||||
|
|
||||||
|
@ -28,7 +28,6 @@ protected:
|
||||||
double _spreading = 2.0;
|
double _spreading = 2.0;
|
||||||
|
|
||||||
std::string _name = "Weapon_name";
|
std::string _name = "Weapon_name";
|
||||||
std::map<std::string, std::shared_ptr<RigidBody>> _objects;
|
|
||||||
|
|
||||||
double _lastFireTime = -INFINITY;
|
double _lastFireTime = -INFINITY;
|
||||||
double _lastReloadTime = -INFINITY;
|
double _lastReloadTime = -INFINITY;
|
||||||
|
@ -37,40 +36,28 @@ protected:
|
||||||
sf::Sound reloadSound;
|
sf::Sound reloadSound;
|
||||||
sf::Sound noAmmoSound;
|
sf::Sound noAmmoSound;
|
||||||
|
|
||||||
static void deleteTrace(std::shared_ptr<World> world, const std::string& traceName);
|
|
||||||
|
|
||||||
int fireTraces = 0;
|
int fireTraces = 0;
|
||||||
|
|
||||||
std::function<void(const Point4D&, const Point4D&)> addTraceCallBack;
|
std::function<void(const Point4D&, const Point4D&)> _addTraceCallBack;
|
||||||
|
|
||||||
|
virtual std::map<std::string, double> processFire(std::function<std::pair<Point4D, std::string>(const Point4D&, const Point4D&)> rayCastFunction, const Point4D& position, const Point4D& direction);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Weapon(const std::string& weaponName, const std::string& objFileName, const std::string& matFileName, const Point4D& scale, const Point4D& translate, const Point4D& rotate);
|
Weapon(const std::string& weaponName, const std::string& objFileName, const std::string& matFileName, const Point4D& scale, const Point4D& translate, const Point4D& rotate);
|
||||||
|
|
||||||
std::map<std::string, double> fire(std::shared_ptr<World> world, std::shared_ptr<Camera> camera);
|
std::map<std::string, double> fire(std::function<std::pair<Point4D, std::string>(const Point4D&, const Point4D&)> rayCastFunction, const Point4D& position, const Point4D& direction);
|
||||||
void reload();
|
void reload();
|
||||||
|
|
||||||
void addToWorld(std::shared_ptr<World> world);
|
|
||||||
void removeFromWorld(std::shared_ptr<World> world);
|
|
||||||
|
|
||||||
void attachToPlayer(Mesh& player);
|
|
||||||
|
|
||||||
[[nodiscard]] std::pair<double, double> balance() const{ return std::make_pair(_clipAmmo, _stockAmmo); }
|
[[nodiscard]] std::pair<double, double> balance() const{ return std::make_pair(_clipAmmo, _stockAmmo); }
|
||||||
|
|
||||||
void rotateRelativePoint(const Point4D& point4D, const Point4D& v, double val);
|
|
||||||
|
|
||||||
void rotate(const Point4D& point4D, double val);
|
|
||||||
void translate(const Point4D& point4D);
|
|
||||||
|
|
||||||
void setAddTraceCallBack(std::function<void(Point4D, Point4D)> add) {
|
void setAddTraceCallBack(std::function<void(Point4D, Point4D)> add) {
|
||||||
addTraceCallBack = std::move(add);
|
_addTraceCallBack = std::move(add);
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] std::string name() const { return _name; }
|
[[nodiscard]] std::string name() const { return _name; }
|
||||||
|
|
||||||
void addAmmo(int ammoAdd) { _stockAmmo += ammoAdd; }
|
void addAmmo(int ammoAdd) { _stockAmmo += ammoAdd; }
|
||||||
|
|
||||||
virtual std::map<std::string, double> processFire(std::shared_ptr<World> world, std::shared_ptr<Camera> camera);
|
|
||||||
|
|
||||||
[[nodiscard]] int initialPack() const {return _initialPack; }
|
[[nodiscard]] int initialPack() const {return _initialPack; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue