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
|
||||
|
||||
- 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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in a new issue