2023-06-10 14:48:16 +02:00
|
|
|
#include "map_simulation.hpp"
|
2023-06-11 15:54:05 +02:00
|
|
|
#include "../../../config.h"
|
2023-06-13 21:59:50 +02:00
|
|
|
#include "../../player/player_collection.hpp"
|
2023-06-10 14:48:16 +02:00
|
|
|
|
|
|
|
MapSimulation::MapSimulation()
|
|
|
|
{
|
|
|
|
mapPlayersById = std::map<int, std::shared_ptr<MapPlayer>>();
|
|
|
|
}
|
|
|
|
|
|
|
|
std::shared_ptr<MapSimulation> MapSimulation::getInstance()
|
|
|
|
{
|
|
|
|
if (singletonInstance == nullptr)
|
|
|
|
{
|
|
|
|
singletonInstance = std::make_shared<MapSimulation>();
|
|
|
|
}
|
|
|
|
return singletonInstance;
|
|
|
|
}
|
|
|
|
|
2023-06-13 21:59:50 +02:00
|
|
|
void MapSimulation::physicsUpdate()
|
2023-06-10 14:48:16 +02:00
|
|
|
{
|
2023-06-10 15:24:03 +02:00
|
|
|
// Update simulation positions
|
2023-06-10 14:48:16 +02:00
|
|
|
for (auto &mapPlayer: mapPlayersById)
|
|
|
|
{
|
2023-06-10 15:24:03 +02:00
|
|
|
mapPlayer.second->updateSimulationPosition();
|
2023-06-10 14:48:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
world->Step(FRAME_TIME.asSeconds(), MAPSIM_VELOCITY_ITERATIONS, MAPSIM_POSITION_ITERATIONS);
|
|
|
|
|
|
|
|
// Update player positions
|
|
|
|
for (auto &mapPlayer: mapPlayersById)
|
|
|
|
{
|
2023-06-10 15:24:03 +02:00
|
|
|
mapPlayer.second->updatePlayerPosition();
|
2023-06-10 14:48:16 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-06-17 19:48:51 +02:00
|
|
|
void MapSimulation::resetMap(sf::Vector2<int> worldMapSize)
|
2023-06-10 14:48:16 +02:00
|
|
|
{
|
2023-06-13 21:59:50 +02:00
|
|
|
// Clear all players
|
|
|
|
for (auto &mapPlayer: mapPlayersById)
|
|
|
|
{
|
|
|
|
removePlayer(mapPlayer.second->player);
|
|
|
|
}
|
|
|
|
|
2023-06-10 14:48:16 +02:00
|
|
|
// No gravity, since this a top-down view of the map
|
|
|
|
world = std::make_shared<b2World>(b2Vec2(0.0f, 0.0f));
|
|
|
|
|
|
|
|
// Create map borders
|
2023-06-13 21:59:50 +02:00
|
|
|
constructSquareObstacle(-MAPSIM_WALL_THICKNESS, -MAPSIM_WALL_THICKNESS, 0, worldMapSize.y + MAPSIM_WALL_THICKNESS); // Bottom left
|
|
|
|
constructSquareObstacle(0, -MAPSIM_WALL_THICKNESS, worldMapSize.x, 0); // Bottom right
|
|
|
|
constructSquareObstacle(worldMapSize.x, -MAPSIM_WALL_THICKNESS, worldMapSize.x + MAPSIM_WALL_THICKNESS, worldMapSize.y + MAPSIM_WALL_THICKNESS); // Top right
|
|
|
|
constructSquareObstacle(0, worldMapSize.y, worldMapSize.x, worldMapSize.y + MAPSIM_WALL_THICKNESS); // Top left
|
2023-06-10 14:48:16 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void MapSimulation::constructSquareObstacle(float minX, float minY, float maxX, float maxY)
|
|
|
|
{
|
|
|
|
b2BodyDef bodyDef;
|
|
|
|
bodyDef.type = b2_staticBody;
|
2023-06-10 18:53:57 +02:00
|
|
|
bodyDef.position.Set((maxX + minX) / 2.f, (maxY + minY) / 2.f);
|
2023-06-10 14:48:16 +02:00
|
|
|
b2Body *body = world->CreateBody(&bodyDef);
|
|
|
|
|
|
|
|
b2PolygonShape shape;
|
2023-06-10 18:53:57 +02:00
|
|
|
shape.SetAsBox((maxX - minX) / 2.f, (maxY - minY) / 2.f);
|
2023-06-10 14:48:16 +02:00
|
|
|
|
|
|
|
b2FixtureDef fixtureDef;
|
|
|
|
fixtureDef.shape = &shape;
|
|
|
|
fixtureDef.density = 1.0f;
|
|
|
|
|
|
|
|
body->CreateFixture(&fixtureDef);
|
|
|
|
}
|
|
|
|
|
2023-06-13 21:59:50 +02:00
|
|
|
void MapSimulation::addPlayer(const std::shared_ptr<Player> &player)
|
2023-06-10 14:48:16 +02:00
|
|
|
{
|
|
|
|
b2BodyDef bodyDef;
|
2023-06-10 15:24:03 +02:00
|
|
|
bodyDef.type = b2_dynamicBody;
|
2023-06-13 21:59:50 +02:00
|
|
|
bodyDef.position.Set(player->spawnPosition.world().x, player->spawnPosition.world().y);
|
2023-06-10 14:48:16 +02:00
|
|
|
b2Body *body = world->CreateBody(&bodyDef);
|
|
|
|
mapPlayersById[player->getPlayerId()] = std::make_shared<MapPlayer>(player, body);
|
|
|
|
}
|
2023-06-13 21:59:50 +02:00
|
|
|
|
|
|
|
void MapSimulation::update()
|
|
|
|
{
|
|
|
|
// Update players from player collection
|
|
|
|
// New player
|
|
|
|
for (auto &player: PlayerCollection::getInstance()->getNewPlayers())
|
|
|
|
{
|
|
|
|
addPlayer(player);
|
|
|
|
}
|
|
|
|
// Removed players
|
|
|
|
for (auto &player: PlayerCollection::getInstance()->getRemovedPlayers())
|
|
|
|
{
|
|
|
|
removePlayer(player);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void MapSimulation::removePlayer(std::shared_ptr<Player> &player)
|
|
|
|
{
|
|
|
|
// Remove body from simulation
|
|
|
|
int playerId = player->getPlayerId();
|
|
|
|
world->DestroyBody(mapPlayersById[playerId]->body);
|
|
|
|
mapPlayersById.erase(playerId);
|
|
|
|
}
|