Sync commit

This commit is contained in:
Maximilian Giller 2023-06-28 01:13:10 +02:00
parent cf6ab330c6
commit 8034b9164d
10 changed files with 137 additions and 24 deletions

View file

@ -2,18 +2,19 @@
## Next
- Player spawns initially at (0,0) and almost fails to jump to target spawn
- Damage other players on contact
## 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
## High priority
- Procedural level generation
- Physics
- Damage other players on contact
- Players-join-screen before the game starts
- Procedural points generation
- Game over screen
- Proper player graphics
- Collectables with graphics

View file

@ -8,8 +8,9 @@
// Player
#define DEFAULT_PLAYER_SPEED 5.f // World units per second
#define DEFAULT_PLAYER_RADIUS .5f // In World units
#define PLAYER_PROPORTIONAL_SIZE_CHANGE_SPEED 0.4f
#define DEFAULT_PLAYER_POINTS 0
#define PLAYER_MIN_RADIUS 0.5f // World units
#define PLAYER_RADIUS_PER_LEVEL 0.25f
// World
#define WORLD_GRAVITY b2Vec2(0.f, 9.8f)

View file

@ -1,4 +1,5 @@
#include "map_player.hpp"
#include "map_simulation.hpp"
void MapPlayer::updateSimulationPosition()
{
@ -43,3 +44,55 @@ void MapPlayer::updateShape()
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();
}

View file

@ -14,6 +14,7 @@ public:
std::shared_ptr<Player> player;
b2Body *body;
float shapeRadius = 0;
std::vector<int> collidingWithPlayers = {};
MapPlayer(std::shared_ptr<Player> player, b2Body *body) : player(std::move(player)), body(body)
{
@ -21,10 +22,15 @@ public:
}
void updateSimulationPosition();
void updatePlayer();
void updateShape();
private:
void updatePlayerPosition() const;
void updateShape();
void updateCollidingWithPlayers();
};

View file

@ -26,10 +26,10 @@ void MapSimulation::physicsUpdate()
world->Step(FRAME_TIME.asSeconds(), MAPSIM_VELOCITY_ITERATIONS, MAPSIM_POSITION_ITERATIONS);
// Update player positions
// Update players
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));
// Create map borders
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
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
}
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);
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;
}

View file

@ -22,6 +22,7 @@ public:
void addPlayer(const std::shared_ptr<Player>& player);
[[nodiscard]] std::shared_ptr<MapPlayer> getMapPlayerByBody(b2Body* body) const;
private:
static inline std::shared_ptr<MapSimulation> singletonInstance = nullptr;

View file

@ -9,12 +9,13 @@ Player::Player(std::shared_ptr<InputIdentity> assignedInput, const std::string &
{
playerId = playerCreationCounter++;
coordinates->setTranslated(spawnPosition);
input = std::move(assignedInput);
skinSprite = std::make_shared<VersatileSprite>(skinRessourceName, getIsoSize());
addChildScreenOffset(skinSprite, IsometricCoordinates(-getIsoSize() / 2.f));
updateRadiusBasedOnLevel();
LOG(INFO) << "Player " << playerId << " created.";
}
@ -42,17 +43,17 @@ void Player::update()
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))
{
auto newRadius = radiusInWorld * (1 - PLAYER_PROPORTIONAL_SIZE_CHANGE_SPEED * FRAME_TIME.asSeconds());
if (newRadius <= DEFAULT_PLAYER_RADIUS)
{
newRadius = DEFAULT_PLAYER_RADIUS;
points *= 1 - 1 * FRAME_TIME.asSeconds();
if (points < 0) {
points = 0;
}
setWorldRadius(newRadius);
}
updateRadiusBasedOnLevel();
GameObject::update();
}
@ -94,3 +95,16 @@ void Player::setWorldRadius(float newWorldRadius)
skinSprite->setSize(newSize);
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);
}

View file

@ -29,16 +29,22 @@ public:
[[nodiscard]] float getWorldRadius() const;
[[nodiscard]] long getPoints() const;
TranslatedCoordinates spawnPosition;
private:
std::shared_ptr<InputIdentity> input;
float radiusInWorld = DEFAULT_PLAYER_RADIUS;
float radiusInWorld = 0.5f; // In world units
std::shared_ptr<VersatileSprite> skinSprite;
long points = DEFAULT_PLAYER_POINTS;
int playerId;
static inline int playerCreationCounter = 0;
void setWorldRadius(float newWorldRadius);
void updateRadiusBasedOnLevel();
};

View file

@ -118,3 +118,15 @@ std::vector<std::shared_ptr<Player>> PlayerCollection::getPlayers() const
}
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");
}

View file

@ -18,11 +18,13 @@ public:
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;