add result table

master
Vectozavr 2021-10-26 13:40:35 +07:00
parent 0f29f9c1c6
commit 832f174664
8 changed files with 65 additions and 31 deletions

View File

@ -12,7 +12,7 @@
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->headAngle(); packet << MsgType::ClientUpdate << _player->position().x() << _player->position().y() << _player->position().z() << _player->angle().y() << _player->headAngle() << _player->playerName();
_socket.send(packet, _socket.serverId()); _socket.send(packet, _socket.serverId());
} }
@ -35,20 +35,22 @@ void Client::processInit(sf::Packet& packet) {
void Client::processUpdate(sf::Packet& packet) { void Client::processUpdate(sf::Packet& packet) {
sf::Uint16 targetId; sf::Uint16 targetId;
double buf[6]; double buf[6];
std::string playerName;
while (packet >> targetId >> buf[0] >> buf[1] >> buf[2] >> buf[3] >> buf[4] >> buf[5]) { while (packet >> targetId >> buf[0] >> buf[1] >> buf[2] >> buf[3] >> buf[4] >> buf[5] >> playerName) {
if (_players.count(targetId)) { if (_players.count(targetId)) {
std::string name = "Player_" + std::to_string(targetId); std::string tagName = "Player_" + std::to_string(targetId);
// old approach (no animation): // old approach (no animation):
//_players[targetId]->translateToPoint(Vec3D{buf[0], buf[1], buf[2]}); //_players[targetId]->translateToPoint(Vec3D{buf[0], buf[1], buf[2]});
// new approach (linear extrapolational animations) // new approach (linear extrapolational animations)
double duration = 1.0 / Consts::NETWORK_WORLD_UPDATE_RATE; double duration = 1.0 / Consts::NETWORK_WORLD_UPDATE_RATE;
Timeline::animate(AnimationListTag(name + "_linearTranslation"), new ATranslateToPoint(_players[targetId], Vec3D{buf[0], buf[1], buf[2]}, duration, Animation::LoopOut::None, Animation::InterpolationType::linear)); Timeline::animate(AnimationListTag(tagName + "_linearTranslation"), new ATranslateToPoint(_players[targetId], Vec3D{buf[0], buf[1], buf[2]}, duration, Animation::LoopOut::None, Animation::InterpolationType::linear));
_players[targetId]->setHealth(buf[3]); _players[targetId]->setHealth(buf[3]);
_players[targetId]->rotateToAngle(Vec3D{0, buf[4], 0}); _players[targetId]->rotateToAngle(Vec3D{0, buf[4], 0});
_players[targetId]->setPlayerName(playerName);
auto head = _players[targetId]->attached(ObjectNameTag("head")); auto head = _players[targetId]->attached(ObjectNameTag("head"));
auto weapon = _players[targetId]->attached(ObjectNameTag("Weapon")); auto weapon = _players[targetId]->attached(ObjectNameTag("Weapon"));

View File

@ -50,6 +50,7 @@ public:
void changeWeapon(const std::string& weaponName); void changeWeapon(const std::string& weaponName);
void addPlayer(sf::Uint16 id, std::shared_ptr<Player> player); void addPlayer(sf::Uint16 id, std::shared_ptr<Player> player);
std::map<sf::Uint16, std::shared_ptr<Player>>const & players() const { return _players; }
}; };

View File

@ -30,6 +30,8 @@ private:
std::vector<std::shared_ptr<Weapon>> _weapons; std::vector<std::shared_ptr<Weapon>> _weapons;
size_t _selectedWeapon = 0; size_t _selectedWeapon = 0;
std::string _name = ShooterConsts::PLAYER_NAME;
std::function<void(sf::Uint16 targetId, double)> _damagePlayerCallBack; std::function<void(sf::Uint16 targetId, double)> _damagePlayerCallBack;
std::function<void(const Vec3D&, const Vec3D&)> _addTraceCallBack; std::function<void(const Vec3D&, const Vec3D&)> _addTraceCallBack;
std::function<void(const std::string&)> _takeBonusCallBack; std::function<void(const std::string&)> _takeBonusCallBack;
@ -94,6 +96,9 @@ public:
[[nodiscard]] double headAngle() const { return _headAngle; }; [[nodiscard]] double headAngle() const { return _headAngle; };
void collisionWithObject(const ObjectNameTag& tag, std::shared_ptr<RigidBody> obj); void collisionWithObject(const ObjectNameTag& tag, std::shared_ptr<RigidBody> obj);
[[nodiscard]] std::string playerName() const { return _name; }
void setPlayerName(const std::string& name) { _name = name; }
}; };

View File

@ -9,8 +9,8 @@ void Server::broadcast() {
sf::Packet updatePacket; sf::Packet updatePacket;
updatePacket << MsgType::Update; updatePacket << MsgType::Update;
for (auto& player : _players) { for (auto& [playerId, player] : _players) {
updatePacket << player.first << player.second->position().x() << player.second->position().y() << player.second->position().z() << player.second->health() << player.second->angle().y() << player.second->headAngle(); updatePacket << playerId << player->position().x() << player->position().y() << player->position().z() << player->health() << player->angle().y() << player->headAngle() << player->playerName();
} }
for (auto& player : _players) { for (auto& player : _players) {
@ -47,11 +47,13 @@ void Server::processConnect(sf::Uint16 targetId) {
void Server::processClientUpdate(sf::Uint16 senderId, sf::Packet& packet) { void Server::processClientUpdate(sf::Uint16 senderId, sf::Packet& packet) {
double buf[5]; double buf[5];
std::string playerName;
packet >> buf[0] >> buf[1] >> buf[2] >> buf[3] >> buf[4]; packet >> buf[0] >> buf[1] >> buf[2] >> buf[3] >> buf[4] >> playerName;
_players.at(senderId)->translateToPoint(Vec3D{ buf[0], buf[1], buf[2] }); _players.at(senderId)->translateToPoint(Vec3D{ buf[0], buf[1], buf[2] });
_players.at(senderId)->rotateToAngle(Vec3D{0, buf[3], 0}); _players.at(senderId)->rotateToAngle(Vec3D{0, buf[3], 0});
_players.at(senderId)->setHeadAngle(buf[4]); _players.at(senderId)->setHeadAngle(buf[4]);
_players.at(senderId)->setPlayerName(playerName);
} }
void Server::processDisconnect(sf::Uint16 senderId) { void Server::processDisconnect(sf::Uint16 senderId) {
@ -138,31 +140,31 @@ void Server::processStop() {
} }
void Server::generateBonuses() { void Server::generateBonuses() {
_bonuses.insert({"Bonus_gun_1", std::make_shared<BonusInfo>(BonusInfo{Vec3D(-10, -2, -15), -2*_bonusRechargeTime, true})}); _bonuses.insert({"Bonus_gun_1", std::make_shared<BonusInfo>(BonusInfo{Vec3D(-10, -2, -15), -2*ShooterConsts::BONUS_RECHARGE_TIME, true})});
_bonuses.insert({"Bonus_gun_2", std::make_shared<BonusInfo>(BonusInfo{Vec3D(10, -2, 15), -2*_bonusRechargeTime, true})}); _bonuses.insert({"Bonus_gun_2", std::make_shared<BonusInfo>(BonusInfo{Vec3D(10, -2, 15), -2*ShooterConsts::BONUS_RECHARGE_TIME, true})});
_bonuses.insert({"Bonus_shotgun_1", std::make_shared<BonusInfo>(BonusInfo{Vec3D(-10, 13, -24), -2*_bonusRechargeTime, true})}); _bonuses.insert({"Bonus_shotgun_1", std::make_shared<BonusInfo>(BonusInfo{Vec3D(-10, 13, -24), -2*ShooterConsts::BONUS_RECHARGE_TIME, true})});
_bonuses.insert({"Bonus_shotgun_2", std::make_shared<BonusInfo>(BonusInfo{Vec3D(10, 13, 24), -2*_bonusRechargeTime, true})}); _bonuses.insert({"Bonus_shotgun_2", std::make_shared<BonusInfo>(BonusInfo{Vec3D(10, 13, 24), -2*ShooterConsts::BONUS_RECHARGE_TIME, true})});
_bonuses.insert({"Bonus_ak47_1", std::make_shared<BonusInfo>(BonusInfo{Vec3D(-25, 30, 50), -2*_bonusRechargeTime, true})}); _bonuses.insert({"Bonus_ak47_1", std::make_shared<BonusInfo>(BonusInfo{Vec3D(-25, 30, 50), -2*ShooterConsts::BONUS_RECHARGE_TIME, true})});
_bonuses.insert({"Bonus_ak47_2", std::make_shared<BonusInfo>(BonusInfo{Vec3D(25, 30, -50), -2*_bonusRechargeTime, true})}); _bonuses.insert({"Bonus_ak47_2", std::make_shared<BonusInfo>(BonusInfo{Vec3D(25, 30, -50), -2*ShooterConsts::BONUS_RECHARGE_TIME, true})});
_bonuses.insert({"Bonus_gold_ak47_1", std::make_shared<BonusInfo>(BonusInfo{Vec3D(-35, 80, 25), -2*_bonusRechargeTime, true})}); _bonuses.insert({"Bonus_gold_ak47_1", std::make_shared<BonusInfo>(BonusInfo{Vec3D(-35, 80, 25), -2*ShooterConsts::BONUS_RECHARGE_TIME, true})});
_bonuses.insert({"Bonus_gold_ak47_2", std::make_shared<BonusInfo>(BonusInfo{Vec3D(35, 80, -25), -2*_bonusRechargeTime, true})}); _bonuses.insert({"Bonus_gold_ak47_2", std::make_shared<BonusInfo>(BonusInfo{Vec3D(35, 80, -25), -2*ShooterConsts::BONUS_RECHARGE_TIME, true})});
_bonuses.insert({"Bonus_rifle_1", std::make_shared<BonusInfo>(BonusInfo{Vec3D(40, -2, 45), -2*_bonusRechargeTime, true})}); _bonuses.insert({"Bonus_rifle_1", std::make_shared<BonusInfo>(BonusInfo{Vec3D(40, -2, 45), -2*ShooterConsts::BONUS_RECHARGE_TIME, true})});
_bonuses.insert({"Bonus_rifle_2", std::make_shared<BonusInfo>(BonusInfo{Vec3D(-40, -2, -45), -2*_bonusRechargeTime, true})}); _bonuses.insert({"Bonus_rifle_2", std::make_shared<BonusInfo>(BonusInfo{Vec3D(-40, -2, -45), -2*ShooterConsts::BONUS_RECHARGE_TIME, true})});
_bonuses.insert({"Bonus_hill_1", std::make_shared<BonusInfo>(BonusInfo{Vec3D(-40, -2, 45), -2*_bonusRechargeTime, true})}); _bonuses.insert({"Bonus_hill_1", std::make_shared<BonusInfo>(BonusInfo{Vec3D(-40, -2, 45), -2*ShooterConsts::BONUS_RECHARGE_TIME, true})});
_bonuses.insert({"Bonus_hill_2", std::make_shared<BonusInfo>(BonusInfo{Vec3D(40, -2, -45), -2*_bonusRechargeTime, true})}); _bonuses.insert({"Bonus_hill_2", std::make_shared<BonusInfo>(BonusInfo{Vec3D(40, -2, -45), -2*ShooterConsts::BONUS_RECHARGE_TIME, true})});
_bonuses.insert({"Bonus_ability_1", std::make_shared<BonusInfo>(BonusInfo{Vec3D(25, 18, -33), -2*_bonusRechargeTime, true})}); _bonuses.insert({"Bonus_ability_1", std::make_shared<BonusInfo>(BonusInfo{Vec3D(25, 18, -33), -2*ShooterConsts::BONUS_RECHARGE_TIME, true})});
_bonuses.insert({"Bonus_ability_2", std::make_shared<BonusInfo>(BonusInfo{Vec3D(-25, 18, 33), -2*_bonusRechargeTime, true})}); _bonuses.insert({"Bonus_ability_2", std::make_shared<BonusInfo>(BonusInfo{Vec3D(-25, 18, 33), -2*ShooterConsts::BONUS_RECHARGE_TIME, true})});
} }
void Server::updateInfo() { void Server::updateInfo() {
for(auto& [bonusName, bonusInfo] : _bonuses) { for(auto& [bonusName, bonusInfo] : _bonuses) {
if(!bonusInfo->onTheMap && std::abs(Time::time() - bonusInfo->lastTake) > _bonusRechargeTime) { if(!bonusInfo->onTheMap && std::abs(Time::time() - bonusInfo->lastTake) > ShooterConsts::BONUS_RECHARGE_TIME) {
sf::Packet sendPacket; sf::Packet sendPacket;
sendPacket << MsgType::AddBonus << bonusName << bonusInfo->position.x() << bonusInfo->position.y() << bonusInfo->position.z(); sendPacket << MsgType::AddBonus << bonusName << bonusInfo->position.x() << bonusInfo->position.y() << bonusInfo->position.z();
for (const auto& player : _players) for (const auto& player : _players)

View File

@ -19,8 +19,6 @@ class Server final : public ServerUDP {
private: private:
std::map<sf::Uint16, std::shared_ptr<Player>> _players{}; std::map<sf::Uint16, std::shared_ptr<Player>> _players{};
std::map<std::string, std::shared_ptr<BonusInfo>> _bonuses{}; std::map<std::string, std::shared_ptr<BonusInfo>> _bonuses{};
double _bonusRechargeTime = 60;
public: public:
Server() = default; Server() = default;

View File

@ -21,17 +21,19 @@ void Shooter::InitNetwork()
std::string clientIp; std::string clientIp;
sf::Uint16 clientPort; sf::Uint16 clientPort;
sf::Uint16 serverPort; sf::Uint16 serverPort;
std::string playerName;
std::ifstream connectFile("connect.txt", std::ifstream::in); std::ifstream connectFile("connect.txt", std::ifstream::in);
// If failed to read client settings // If failed to read client settings
if (!connectFile.is_open() || !(connectFile >> clientIp >> clientPort) || sf::IpAddress(clientIp) == sf::IpAddress::None) if (!connectFile.is_open() || !(connectFile >> clientIp >> clientPort >> playerName) || sf::IpAddress(clientIp) == sf::IpAddress::None)
{ {
connectFile.close(); connectFile.close();
// Create file and write default settings // Create file and write default settings
clientIp = "127.0.0.1"; clientIp = "127.0.0.1";
clientPort = 54000; clientPort = 54000;
playerName = "PlayerName";
std::ofstream temp("connect.txt", std::ofstream::out); std::ofstream temp("connect.txt", std::ofstream::out);
temp << clientIp << std::endl << clientPort; temp << clientIp << std::endl << clientPort << std::endl << playerName;
temp.close(); temp.close();
} }
connectFile.close(); connectFile.close();
@ -56,6 +58,7 @@ void Shooter::InitNetwork()
} }
client->connect(clientIp, clientPort); client->connect(clientIp, clientPort);
player->setPlayerName(playerName);
// TODO: encapsulate call backs inside Client // TODO: encapsulate call backs inside Client
client->setSpawnPlayerCallBack([this](sf::Uint16 id){ spawnPlayer(id); }); client->setSpawnPlayerCallBack([this](sf::Uint16 id){ spawnPlayer(id); });
@ -68,7 +71,7 @@ void Shooter::InitNetwork()
void Shooter::start() { void Shooter::start() {
// This code executed once in the beginning: // This code executed once in the beginning:
//setDebugText(false); setDebugText(false);
setUpdateWorld(false); setUpdateWorld(false);
mouse->setMouseCursorVisible(true); mouse->setMouseCursorVisible(true);
@ -122,7 +125,6 @@ void Shooter::start() {
mainMenu.addButton(screen->width()/2, 350, 200, 20, [this] () { this->player->translateToPoint(Vec3D{0, 0, 0}); this->player->setVelocity({}); this->play(); SoundController::playSound(SoundTag("click"), ShooterConsts::CLICK_SOUND);}, "Respawn", 5, 5, ShooterConsts::MAIN_MENU_GUI, {0, 66}, {0, 86}, {0, 46}, Consts::MEDIUM_FONT, {255, 255, 255}); mainMenu.addButton(screen->width()/2, 350, 200, 20, [this] () { this->player->translateToPoint(Vec3D{0, 0, 0}); this->player->setVelocity({}); this->play(); SoundController::playSound(SoundTag("click"), ShooterConsts::CLICK_SOUND);}, "Respawn", 5, 5, ShooterConsts::MAIN_MENU_GUI, {0, 66}, {0, 86}, {0, 46}, Consts::MEDIUM_FONT, {255, 255, 255});
mainMenu.addButton(screen->width()/2, 500, 200, 20, [this] () { client->disconnect(); server->stop(); this->exit();}, "Exit", 5, 5, ShooterConsts::MAIN_MENU_GUI, {0, 66}, {0, 86}, {0, 46}, Consts::MEDIUM_FONT, {255, 255, 255}); mainMenu.addButton(screen->width()/2, 500, 200, 20, [this] () { client->disconnect(); server->stop(); this->exit();}, "Exit", 5, 5, ShooterConsts::MAIN_MENU_GUI, {0, 66}, {0, 86}, {0, 46}, Consts::MEDIUM_FONT, {255, 255, 255});
} }
void Shooter::update() { void Shooter::update() {
@ -162,11 +164,31 @@ void Shooter::gui() {
sprite.setTextureRect(sf::IntRect(243, 3, 9, 9)); sprite.setTextureRect(sf::IntRect(243, 3, 9, 9));
sprite.scale(3, 3); sprite.scale(3, 3);
sprite.setPosition(screen->width() / 2.0f - 27.0f/2.0f, screen->height() / 2.0f - 27.0f/2.0f); sprite.setPosition(screen->width() / 2.0f - 27.0f/2.0f, screen->height() / 2.0f - 27.0f/2.0f);
sprite.setColor(sf::Color(0, 0, 0, 200)); sprite.setColor(sf::Color(0, 0, 0, 250));
screen->drawSprite(sprite); screen->drawSprite(sprite);
// health player stats // health player stats
drawPlayerStats(); drawPlayerStats();
drawStatsTable();
}
void Shooter::drawStatsTable() {
int i = 0;
vector<shared_ptr<Player>> allPlayers;
allPlayers.push_back(player);
for(auto& [playerId, player] : client->players())
allPlayers.push_back(player);
std::sort(allPlayers.begin(), allPlayers.end(), [](std::shared_ptr<Player> p1, std::shared_ptr<Player> p2){
return p1->kills() - p1->deaths() > p2->kills() - p2->deaths();
} );
for(auto& p : allPlayers) {
screen->drawText(std::to_string(i + 1) + "\t" + p->playerName() + "\t" + std::to_string(p->kills()) + " / " + std::to_string(p->deaths()),
Vec2D{10, 10 + 35.0*i}, 25, sf::Color(0, 0, 0, 150));
i++;
}
} }
void Shooter::drawPlayerStats() { void Shooter::drawPlayerStats() {
@ -194,8 +216,8 @@ void Shooter::drawPlayerStats() {
screen->drawText(std::to_string((int)balance.first), Vec2D{150, static_cast<double>(screen->height() - 150)}, 100, sf::Color(0, 0, 0, 100)); screen->drawText(std::to_string((int)balance.first), Vec2D{150, static_cast<double>(screen->height() - 150)}, 100, sf::Color(0, 0, 0, 100));
screen->drawText(std::to_string((int)balance.second), Vec2D{50, static_cast<double>(screen->height() - 100)}, 50, sf::Color(0, 0, 0, 70)); screen->drawText(std::to_string((int)balance.second), Vec2D{50, static_cast<double>(screen->height() - 100)}, 50, sf::Color(0, 0, 0, 70));
screen->drawText("KILLS: " + std::to_string(player->kills()) + " | " + "DEATHS: " + std::to_string(player->deaths()), //screen->drawText("KILLS: " + std::to_string(player->kills()) + " | " + "DEATHS: " + std::to_string(player->deaths()),
Vec2D{10, 10},25, sf::Color(0, 0, 0, 100)); // Vec2D{10, 10},25, sf::Color(0, 0, 0, 100));
} }
void Shooter::play() { void Shooter::play() {
@ -265,6 +287,7 @@ void Shooter::addBonus(const string &bonusName, const Vec3D &position) {
void Shooter::removeBonus(const ObjectNameTag &bonusName) { void Shooter::removeBonus(const ObjectNameTag &bonusName) {
world->removeBody(bonusName); world->removeBody(bonusName);
Timeline::deleteAnimationList(AnimationListTag(bonusName.str() + "_rotation"));
} }
void Shooter::addWeapon(std::shared_ptr<Weapon> weapon) { void Shooter::addWeapon(std::shared_ptr<Weapon> weapon) {

View File

@ -39,6 +39,7 @@ private:
void play(); void play();
void drawPlayerStats(); void drawPlayerStats();
void drawStatsTable();
void InitNetwork(); void InitNetwork();
void spawnPlayer(sf::Uint16 id); void spawnPlayer(sf::Uint16 id);

View File

@ -14,7 +14,9 @@ namespace ShooterConsts {
const double MOUSE_SENSITIVITY = 1.0 / 1000.0; const double MOUSE_SENSITIVITY = 1.0 / 1000.0;
const double SLOW_MO_COEFFICIENT = 5; const double SLOW_MO_COEFFICIENT = 5;
const double FIRE_DISTANCE = 1000; const double FIRE_DISTANCE = 1000;
const double BONUS_RECHARGE_TIME = 30;
const std::string PLAYER_NAME = "Player";
const std::string PROJECT_NAME = "Shooter"; const std::string PROJECT_NAME = "Shooter";
const std::string ABILITY_OBJ = "obj/ability.obj"; const std::string ABILITY_OBJ = "obj/ability.obj";