Sync commit
This commit is contained in:
parent
cf6ab330c6
commit
8034b9164d
10 changed files with 137 additions and 24 deletions
7
TODO.md
7
TODO.md
|
@ -2,18 +2,19 @@
|
||||||
|
|
||||||
## Next
|
## Next
|
||||||
|
|
||||||
- Player spawns initially at (0,0) and almost fails to jump to target spawn
|
- Damage other players on contact
|
||||||
|
|
||||||
## Bugs
|
## Bugs
|
||||||
|
|
||||||
|
- Player spawns initially at (0,0) and almost fails to jump to target spawn
|
||||||
- Player disconnect in multiplayer sometimes targeting disconnected player or something like that
|
- Player disconnect in multiplayer sometimes targeting disconnected player or something like that
|
||||||
|
|
||||||
## High priority
|
## High priority
|
||||||
|
|
||||||
- Procedural level generation
|
|
||||||
- Physics
|
- Physics
|
||||||
- Damage other players on contact
|
|
||||||
- Players-join-screen before the game starts
|
- Players-join-screen before the game starts
|
||||||
|
|
||||||
|
- Procedural points generation
|
||||||
- Game over screen
|
- Game over screen
|
||||||
- Proper player graphics
|
- Proper player graphics
|
||||||
- Collectables with graphics
|
- Collectables with graphics
|
||||||
|
|
|
@ -8,8 +8,9 @@
|
||||||
|
|
||||||
// Player
|
// Player
|
||||||
#define DEFAULT_PLAYER_SPEED 5.f // World units per second
|
#define DEFAULT_PLAYER_SPEED 5.f // World units per second
|
||||||
#define DEFAULT_PLAYER_RADIUS .5f // In World units
|
#define DEFAULT_PLAYER_POINTS 0
|
||||||
#define PLAYER_PROPORTIONAL_SIZE_CHANGE_SPEED 0.4f
|
#define PLAYER_MIN_RADIUS 0.5f // World units
|
||||||
|
#define PLAYER_RADIUS_PER_LEVEL 0.25f
|
||||||
|
|
||||||
// World
|
// World
|
||||||
#define WORLD_GRAVITY b2Vec2(0.f, 9.8f)
|
#define WORLD_GRAVITY b2Vec2(0.f, 9.8f)
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "map_player.hpp"
|
#include "map_player.hpp"
|
||||||
|
#include "map_simulation.hpp"
|
||||||
|
|
||||||
void MapPlayer::updateSimulationPosition()
|
void MapPlayer::updateSimulationPosition()
|
||||||
{
|
{
|
||||||
|
@ -42,4 +43,56 @@ void MapPlayer::updateShape()
|
||||||
fixtureDef.density = 1.0f;
|
fixtureDef.density = 1.0f;
|
||||||
|
|
||||||
body->CreateFixture(&fixtureDef);
|
body->CreateFixture(&fixtureDef);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MapPlayer::updateCollidingWithPlayers()
|
||||||
|
{
|
||||||
|
collidingWithPlayers.clear();
|
||||||
|
|
||||||
|
for (b2ContactEdge *contactEdge = body->GetContactList(); contactEdge != nullptr; contactEdge = contactEdge->next)
|
||||||
|
{
|
||||||
|
b2Contact *contact = contactEdge->contact;
|
||||||
|
if (!contact->IsTouching())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
b2Fixture *fixtureA = contact->GetFixtureA();
|
||||||
|
b2Fixture *fixtureB = contact->GetFixtureB();
|
||||||
|
|
||||||
|
if (fixtureA->IsSensor() || fixtureB->IsSensor())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
b2Body *bodyA = fixtureA->GetBody();
|
||||||
|
b2Body *bodyB = fixtureB->GetBody();
|
||||||
|
|
||||||
|
if (bodyA->GetType() != b2_dynamicBody || bodyB->GetType() != b2_dynamicBody)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<MapPlayer> mapPlayerA = MapSimulation::getInstance()->getMapPlayerByBody(bodyA);
|
||||||
|
std::shared_ptr<MapPlayer> mapPlayerB = MapSimulation::getInstance()->getMapPlayerByBody(bodyA);
|
||||||
|
|
||||||
|
if (mapPlayerA == nullptr || mapPlayerB == nullptr)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mapPlayerA->player->getPlayerId() == player->getPlayerId())
|
||||||
|
{
|
||||||
|
collidingWithPlayers.push_back(mapPlayerB->player->getPlayerId());
|
||||||
|
} else if (mapPlayerB->player->getPlayerId() == player->getPlayerId())
|
||||||
|
{
|
||||||
|
collidingWithPlayers.push_back(mapPlayerA->player->getPlayerId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MapPlayer::updatePlayer()
|
||||||
|
{
|
||||||
|
updatePlayerPosition();
|
||||||
|
updateCollidingWithPlayers();
|
||||||
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ public:
|
||||||
std::shared_ptr<Player> player;
|
std::shared_ptr<Player> player;
|
||||||
b2Body *body;
|
b2Body *body;
|
||||||
float shapeRadius = 0;
|
float shapeRadius = 0;
|
||||||
|
std::vector<int> collidingWithPlayers = {};
|
||||||
|
|
||||||
MapPlayer(std::shared_ptr<Player> player, b2Body *body) : player(std::move(player)), body(body)
|
MapPlayer(std::shared_ptr<Player> player, b2Body *body) : player(std::move(player)), body(body)
|
||||||
{
|
{
|
||||||
|
@ -21,10 +22,15 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateSimulationPosition();
|
void updateSimulationPosition();
|
||||||
|
void updatePlayer();
|
||||||
|
|
||||||
|
void updateShape();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
void updatePlayerPosition() const;
|
void updatePlayerPosition() const;
|
||||||
|
|
||||||
void updateShape();
|
void updateCollidingWithPlayers();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -26,10 +26,10 @@ void MapSimulation::physicsUpdate()
|
||||||
|
|
||||||
world->Step(FRAME_TIME.asSeconds(), MAPSIM_VELOCITY_ITERATIONS, MAPSIM_POSITION_ITERATIONS);
|
world->Step(FRAME_TIME.asSeconds(), MAPSIM_VELOCITY_ITERATIONS, MAPSIM_POSITION_ITERATIONS);
|
||||||
|
|
||||||
// Update player positions
|
// Update players
|
||||||
for (auto &mapPlayer: mapPlayersById)
|
for (auto &mapPlayer: mapPlayersById)
|
||||||
{
|
{
|
||||||
mapPlayer.second->updatePlayerPosition();
|
mapPlayer.second->updatePlayer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,10 +45,15 @@ void MapSimulation::resetMap(sf::Vector2<int> worldMapSize)
|
||||||
world = std::make_shared<b2World>(b2Vec2(0.0f, 0.0f));
|
world = std::make_shared<b2World>(b2Vec2(0.0f, 0.0f));
|
||||||
|
|
||||||
// Create map borders
|
// Create map borders
|
||||||
constructSquareObstacle(-MAPSIM_WALL_THICKNESS, -MAPSIM_WALL_THICKNESS, 0, worldMapSize.y + MAPSIM_WALL_THICKNESS); // Bottom left
|
constructSquareObstacle(-MAPSIM_WALL_THICKNESS, -MAPSIM_WALL_THICKNESS,
|
||||||
constructSquareObstacle(0, -MAPSIM_WALL_THICKNESS, worldMapSize.x, 0); // Bottom right
|
0, worldMapSize.y + MAPSIM_WALL_THICKNESS); // Bottom left
|
||||||
constructSquareObstacle(worldMapSize.x, -MAPSIM_WALL_THICKNESS, worldMapSize.x + MAPSIM_WALL_THICKNESS, worldMapSize.y + MAPSIM_WALL_THICKNESS); // Top right
|
constructSquareObstacle(0, -MAPSIM_WALL_THICKNESS,
|
||||||
constructSquareObstacle(0, worldMapSize.y, worldMapSize.x, worldMapSize.y + MAPSIM_WALL_THICKNESS); // Top left
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapSimulation::constructSquareObstacle(float minX, float minY, float maxX, float maxY)
|
void MapSimulation::constructSquareObstacle(float minX, float minY, float maxX, float maxY)
|
||||||
|
@ -99,3 +104,15 @@ void MapSimulation::removePlayer(std::shared_ptr<Player> &player)
|
||||||
world->DestroyBody(mapPlayersById[playerId]->body);
|
world->DestroyBody(mapPlayersById[playerId]->body);
|
||||||
mapPlayersById.erase(playerId);
|
mapPlayersById.erase(playerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<MapPlayer> MapSimulation::getMapPlayerByBody(b2Body *body) const
|
||||||
|
{
|
||||||
|
for (auto &mapPlayer: mapPlayersById)
|
||||||
|
{
|
||||||
|
if (mapPlayer.second->body == body)
|
||||||
|
{
|
||||||
|
return mapPlayer.second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ public:
|
||||||
|
|
||||||
void addPlayer(const std::shared_ptr<Player>& player);
|
void addPlayer(const std::shared_ptr<Player>& player);
|
||||||
|
|
||||||
|
[[nodiscard]] std::shared_ptr<MapPlayer> getMapPlayerByBody(b2Body* body) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static inline std::shared_ptr<MapSimulation> singletonInstance = nullptr;
|
static inline std::shared_ptr<MapSimulation> singletonInstance = nullptr;
|
||||||
|
|
|
@ -9,12 +9,13 @@ Player::Player(std::shared_ptr<InputIdentity> assignedInput, const std::string &
|
||||||
{
|
{
|
||||||
playerId = playerCreationCounter++;
|
playerId = playerCreationCounter++;
|
||||||
coordinates->setTranslated(spawnPosition);
|
coordinates->setTranslated(spawnPosition);
|
||||||
|
|
||||||
input = std::move(assignedInput);
|
input = std::move(assignedInput);
|
||||||
|
|
||||||
skinSprite = std::make_shared<VersatileSprite>(skinRessourceName, getIsoSize());
|
skinSprite = std::make_shared<VersatileSprite>(skinRessourceName, getIsoSize());
|
||||||
addChildScreenOffset(skinSprite, IsometricCoordinates(-getIsoSize() / 2.f));
|
addChildScreenOffset(skinSprite, IsometricCoordinates(-getIsoSize() / 2.f));
|
||||||
|
|
||||||
|
updateRadiusBasedOnLevel();
|
||||||
|
|
||||||
LOG(INFO) << "Player " << playerId << " created.";
|
LOG(INFO) << "Player " << playerId << " created.";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,17 +43,17 @@ void Player::update()
|
||||||
|
|
||||||
if (input->isPerformingAction(GameAction::GROW))
|
if (input->isPerformingAction(GameAction::GROW))
|
||||||
{
|
{
|
||||||
setWorldRadius(radiusInWorld * (1 + PLAYER_PROPORTIONAL_SIZE_CHANGE_SPEED * FRAME_TIME.asSeconds()));
|
points = (points + 1) * (1 + 1 * FRAME_TIME.asSeconds());
|
||||||
} else if (input->isPerformingAction(GameAction::SHRINK))
|
} else if (input->isPerformingAction(GameAction::SHRINK))
|
||||||
{
|
{
|
||||||
auto newRadius = radiusInWorld * (1 - PLAYER_PROPORTIONAL_SIZE_CHANGE_SPEED * FRAME_TIME.asSeconds());
|
points *= 1 - 1 * FRAME_TIME.asSeconds();
|
||||||
if (newRadius <= DEFAULT_PLAYER_RADIUS)
|
if (points < 0) {
|
||||||
{
|
points = 0;
|
||||||
newRadius = DEFAULT_PLAYER_RADIUS;
|
|
||||||
}
|
}
|
||||||
setWorldRadius(newRadius);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateRadiusBasedOnLevel();
|
||||||
|
|
||||||
GameObject::update();
|
GameObject::update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,3 +95,16 @@ void Player::setWorldRadius(float newWorldRadius)
|
||||||
skinSprite->setSize(newSize);
|
skinSprite->setSize(newSize);
|
||||||
skinSprite->coordinates->setScreenOffset(IsometricCoordinates(-newSize / 2.f));
|
skinSprite->coordinates->setScreenOffset(IsometricCoordinates(-newSize / 2.f));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
long Player::getPoints() const
|
||||||
|
{
|
||||||
|
return points;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Player::updateRadiusBasedOnLevel()
|
||||||
|
{
|
||||||
|
long points = getPoints();
|
||||||
|
float newWorldRadius = PLAYER_MIN_RADIUS + PLAYER_RADIUS_PER_LEVEL * pow(points / 100.f, 2);
|
||||||
|
|
||||||
|
setWorldRadius(newWorldRadius);
|
||||||
|
}
|
||||||
|
|
|
@ -29,16 +29,22 @@ public:
|
||||||
|
|
||||||
[[nodiscard]] float getWorldRadius() const;
|
[[nodiscard]] float getWorldRadius() const;
|
||||||
|
|
||||||
|
[[nodiscard]] long getPoints() const;
|
||||||
|
|
||||||
TranslatedCoordinates spawnPosition;
|
TranslatedCoordinates spawnPosition;
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<InputIdentity> input;
|
std::shared_ptr<InputIdentity> input;
|
||||||
float radiusInWorld = DEFAULT_PLAYER_RADIUS;
|
float radiusInWorld = 0.5f; // In world units
|
||||||
std::shared_ptr<VersatileSprite> skinSprite;
|
std::shared_ptr<VersatileSprite> skinSprite;
|
||||||
|
|
||||||
|
long points = DEFAULT_PLAYER_POINTS;
|
||||||
|
|
||||||
int playerId;
|
int playerId;
|
||||||
static inline int playerCreationCounter = 0;
|
static inline int playerCreationCounter = 0;
|
||||||
|
|
||||||
void setWorldRadius(float newWorldRadius);
|
void setWorldRadius(float newWorldRadius);
|
||||||
|
|
||||||
|
void updateRadiusBasedOnLevel();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -118,3 +118,15 @@ std::vector<std::shared_ptr<Player>> PlayerCollection::getPlayers() const
|
||||||
}
|
}
|
||||||
return players;
|
return players;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<Player> PlayerCollection::getPlayerById(int playerId) const
|
||||||
|
{
|
||||||
|
for (auto &player: getPlayers())
|
||||||
|
{
|
||||||
|
if (player->getPlayerId() == playerId)
|
||||||
|
{
|
||||||
|
return player;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw std::runtime_error("Player with id " + std::to_string(playerId) + " not found");
|
||||||
|
}
|
||||||
|
|
|
@ -18,11 +18,13 @@ public:
|
||||||
|
|
||||||
void removePlayer(const std::shared_ptr<Player>& player);
|
void removePlayer(const std::shared_ptr<Player>& player);
|
||||||
|
|
||||||
std::vector<std::shared_ptr<Player>> getPlayers() const;
|
[[nodiscard]] std::vector<std::shared_ptr<Player>> getPlayers() const;
|
||||||
|
|
||||||
std::vector<std::shared_ptr<Player>> getNewPlayers() const;
|
[[nodiscard]] std::shared_ptr<Player> getPlayerById(int playerId) const;
|
||||||
|
|
||||||
std::vector<std::shared_ptr<Player>> getRemovedPlayers() const;
|
[[nodiscard]] std::vector<std::shared_ptr<Player>> getNewPlayers() const;
|
||||||
|
|
||||||
|
[[nodiscard]] std::vector<std::shared_ptr<Player>> getRemovedPlayers() const;
|
||||||
|
|
||||||
void lateUpdate() override;
|
void lateUpdate() override;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue