This commit is contained in:
Maximilian Giller 2023-06-14 01:06:11 +02:00
parent 414f3b79fc
commit 9dc26a6b06
15 changed files with 222 additions and 25 deletions

View file

@ -94,7 +94,7 @@ set(SOURCES
src/game/collectables/collection/collectables_collection.cpp
src/game/collectables/collection/collectables_collection.hpp
src/game/collectables/collection/collectables_depth_collection.cpp
src/game/collectables/collection/collectables_depth_collection.hpp src/game/collectables/collectable_in_level.hpp src/game/collectables/collectable_factory.cpp src/game/collectables/collectable_factory.hpp src/game/player/player_collection.cpp src/game/player/player_collection.hpp)
src/game/collectables/collection/collectables_depth_collection.hpp src/game/collectables/collectable_in_level.hpp src/game/collectables/collectable_factory.cpp src/game/collectables/collectable_factory.hpp src/game/player/player_collection.cpp src/game/player/player_collection.hpp src/game/physics/hole/hole_sim_player.cpp src/game/physics/hole/hole_sim_player.hpp src/game/collectables/collectable_sim_parameters.hpp src/game/collectables/sim_collectable.hpp)
set(PHYSICS_00_SOURCES
src/prototypes/physics_00.cpp)

View file

@ -1,3 +1,3 @@
# Holesome - ToDos
- [ ] Try button mapping for other controllers
- [ ] Optimize hole depth simulations by not simulating when nothing happens

View file

@ -47,6 +47,8 @@
#define HOLESIM_COLLECTABLE_DENSITY 1.f
#define HOLESIM_COLLECTABLE_FRICTION 0.3f
#define HOLESIM_COLLECTABLE_RESTITUTION 0.5f
#define HOLESIM_FLOOR_THICKNESS 0.5f
#define HOLESIM_WALL_HEIGHT 5.f
// Directions
#define DIRECTION_HARD_ACTIVATION_THRESHOLD 0.1f

View file

@ -8,11 +8,6 @@ Collectable::Collectable()
collectableCount++;
}
void Collectable::setRotation(float angle)
{
}
int Collectable::getDepth() const
{
return static_cast<int>(coordinates->isometric().depth);
@ -26,3 +21,13 @@ void Collectable::setSprite(const std::string &spriteName)
auto sprite = std::make_shared<VersatileSprite>(spriteName, size);
addChildScreenOffset(sprite, IsometricCoordinates(-sizeWidth / 2.f, -sizeWidth));
}
int Collectable::getId() const
{
return collectableId;
}
void Collectable::setSpriteAngle(float angle)
{
// TODO
}

View file

@ -1,8 +1,9 @@
#ifndef HOLESOME_COLLECTABLE_HPP
#define HOLESOME_COLLECTABLE_HPP
#include <SFML/System/Vector2.hpp>
#include "../game_object.h"
#include "collectable_sim_parameters.hpp"
class Collectable : public GameObject
{
@ -11,14 +12,13 @@ public:
void setSprite(const std::string &spriteName);
void setRotation(float angle);
void setSpriteAngle(float angle);
int getDepth() const;
[[nodiscard]] int getDepth() const;
int getId() const
{
return collectableId;
}
[[nodiscard]] int getId() const;
CollectableSimParameters simParameters = {};
private:
int collectableId = 0;

View file

@ -0,0 +1,15 @@
#ifndef HOLESOME_COLLECTABLE_SIM_PARAMETERS_HPP
#define HOLESOME_COLLECTABLE_SIM_PARAMETERS_HPP
#include <box2d/box2d.h>
struct CollectableSimParameters
{
float angle = 0;
float angularVelocity = 0;
b2Vec2 linearVelocity = {0, 0};
CollectableSimParameters() = default;
};
#endif //HOLESOME_COLLECTABLE_SIM_PARAMETERS_HPP

View file

@ -0,0 +1,21 @@
#ifndef HOLESOME_SIM_COLLECTABLE_HPP
#define HOLESOME_SIM_COLLECTABLE_HPP
#include "collectable.hpp"
#include <memory>
struct SimCollectable
{
std::shared_ptr<Collectable> collectable = nullptr;
b2Body *body = nullptr;
SimCollectable(std::shared_ptr<Collectable> collectable, b2Body *body)
{
this->collectable = std::move(collectable);
this->body = body;
}
SimCollectable() = default;
};
#endif //HOLESOME_SIM_COLLECTABLE_HPP

View file

@ -1,5 +1,6 @@
#include "hole_depth_simulation.hpp"
#include "../../../config.h"
#include "../../player/player_collection.hpp"
HoleDepthSimulation::HoleDepthSimulation(std::shared_ptr<CollectablesDepthCollection> collectables) : collectables(
std::move(collectables))
@ -11,6 +12,10 @@ void HoleDepthSimulation::physicsUpdate()
{
updateBodiesFromCollectionHistory();
preparePlayers();
updateGroundBodies();
simWorld->Step(FRAME_TIME.asSeconds(), HOLESIM_VELOCITY_ITERATIONS, HOLESIM_POSITION_ITERATIONS);
updateCollectables();
@ -21,20 +26,38 @@ void HoleDepthSimulation::updateBodiesFromCollectionHistory()
// Remove bodies that are no longer in the collection
for (auto &collectable: collectables->recentlyRemoved)
{
auto body = bodies[collectable->getId()];
simWorld->DestroyBody(body);
bodies.erase(collectable->getId());
auto simCollectable = simCollectables.at(collectable->getId());
simWorld->DestroyBody(simCollectable.body);
simCollectables.erase(collectable->getId());
}
// Create bodies for new collectables
for (auto &collectable: collectables->recentlyAdded)
{
bodies[collectable->getId()] = createBody(collectable);
simCollectables[collectable->getId()] = SimCollectable(collectable, createBody(collectable));
}
}
void HoleDepthSimulation::updateCollectables()
{
for (auto &[id, simCollectable]: simCollectables)
{
auto collectable = simCollectable.collectable;
auto body = simCollectable.body;
auto position = body->GetPosition();
collectable->coordinates->set(IsometricCoordinates{
position.x,
position.y,
collectable->coordinates->isometric().depth
});
collectable->simParameters.angle = body->GetAngle();
collectable->simParameters.linearVelocity = body->GetLinearVelocity();
collectable->simParameters.angularVelocity = body->GetAngularVelocity();
collectable->setSpriteAngle(collectable->simParameters.angle);
}
}
b2Body *HoleDepthSimulation::createBody(const std::shared_ptr<Collectable> &collectable)
@ -57,5 +80,57 @@ b2Body *HoleDepthSimulation::createBody(const std::shared_ptr<Collectable> &coll
fixtureDef.restitution = HOLESIM_COLLECTABLE_RESTITUTION;
body->CreateFixture(&fixtureDef);
// Update simulation parameters from existing collectable
body->SetTransform(
b2Vec2{
collectable->coordinates->isometric().x,
collectable->coordinates->isometric().y
},
collectable->simParameters.angle);
body->SetLinearVelocity(collectable->simParameters.linearVelocity);
body->SetAngularVelocity(collectable->simParameters.angularVelocity);
return body;
}
int HoleDepthSimulation::getDepth() const
{
return collectables->depth;
}
void HoleDepthSimulation::preparePlayers()
{
for (const auto &player: PlayerCollection::getInstance()->getPlayers())
{
if (player->getDepth() == getDepth())
{
addToSim(player);
} else
{
removeFromSim(player);
}
}
}
void HoleDepthSimulation::addToSim(const std::shared_ptr<Player> &player)
{
int playerId = player->getPlayerId();
if (simPlayers.find(playerId) == simPlayers.end())
{
simPlayers[playerId] = HoleSimPlayer(player);
}
}
void HoleDepthSimulation::removeFromSim(const std::shared_ptr<Player> &player)
{
int playerId = player->getPlayerId();
if (simPlayers.find(playerId) != simPlayers.end())
{
simPlayers.erase(playerId);
}
}
void HoleDepthSimulation::updateGroundBodies()
{
}

View file

@ -6,6 +6,8 @@
#include <box2d/box2d.h>
#include <map>
#include "../../collectables/collection/collectables_depth_collection.hpp"
#include "hole_sim_player.hpp"
#include "../../collectables/sim_collectable.hpp"
/**
* @brief Simulates the hole(s) for the specific depth
@ -17,16 +19,27 @@ public:
void physicsUpdate() override;
[[nodiscard]] int getDepth() const;
private:
std::shared_ptr<CollectablesDepthCollection> collectables;
std::shared_ptr<b2World> simWorld;
std::map<int, HoleSimPlayer> simPlayers = {}; // Player ID -> HoleSimPlayer
void updateBodiesFromCollectionHistory();
void updateCollectables();
std::map<int, b2Body*> bodies = {}; // Collectable ID -> Body
std::map<int, SimCollectable> simCollectables = {}; // Collectable ID -> Body
b2Body *createBody(const std::shared_ptr<Collectable> &collectable);
void preparePlayers();
void addToSim(const std::shared_ptr<Player> &player);
void removeFromSim(const std::shared_ptr<Player> &player);
void updateGroundBodies();
};

View file

@ -0,0 +1,18 @@
#include "hole_sim_player.hpp"
void HoleSimPlayer::updateSimulationPosition()
{
xPosition = player->coordinates->isometric().x;
width = player->getIsoHoleWidth();
}
HoleSimPlayer::HoleSimPlayer(std::shared_ptr<Player> player)
{
this->player = std::move(player);
updateSimulationPosition();
}
HoleSimPlayer::HoleSimPlayer()
{
player = nullptr;
}

View file

@ -0,0 +1,23 @@
#ifndef HOLESOME_HOLE_SIM_PLAYER_HPP
#define HOLESOME_HOLE_SIM_PLAYER_HPP
#include <memory>
#include "../../player/player.hpp"
#include <box2d/box2d.h>
struct HoleSimPlayer
{
HoleSimPlayer();
std::shared_ptr<Player> player;
float xPosition = 0;
float width = 0;
explicit HoleSimPlayer(std::shared_ptr<Player> player);
void updateSimulationPosition();
};
#endif //HOLESOME_HOLE_SIM_PLAYER_HPP

View file

@ -99,3 +99,15 @@ Player::~Player()
{
LOG(INFO) << "Player " << playerId << " destroyed.";
}
float Player::getIsoHoleWidth() const
{
// Assuming 10% of the player's size is border
float holeFactor = .9f;
return getIsoSize().x * holeFactor;
}
int Player::getDepth() const
{
return ceil(coordinates->isometric().depth);
}

View file

@ -31,6 +31,10 @@ public:
[[nodiscard]] float getWorldRadius() const;
[[nodiscard]] float getIsoHoleWidth() const;
[[nodiscard]] int getDepth() const;
TranslatedCoordinates spawnPosition;
private:
std::shared_ptr<InputIdentity> input;

View file

@ -28,6 +28,7 @@ std::shared_ptr<PlayerCollection> PlayerCollection::getInstance()
void PlayerCollection::addPlayer(const std::shared_ptr<Player> &player)
{
newPlayerBuffer.push_back(player);
players.push_back(player);
addChild(player);
}
@ -37,15 +38,15 @@ void PlayerCollection::clear()
removedPlayerBuffer.clear();
// Fill in removed players
for (auto &child: getChildren())
for (auto &player: players)
{
auto player = std::dynamic_pointer_cast<Player>(child);
if (player != nullptr)
{
removedPlayerBuffer.push_back(player);
}
}
players.clear();
clearChildren();
}
@ -67,8 +68,7 @@ void PlayerCollection::lateUpdate()
{
if (child != nullptr && !child->getActive())
{
removedPlayerBuffer.push_back(std::dynamic_pointer_cast<Player>(child));
removeChild(child);
removePlayer(std::dynamic_pointer_cast<Player>(child));
}
}
}
@ -76,6 +76,7 @@ void PlayerCollection::lateUpdate()
void PlayerCollection::removePlayer(const std::shared_ptr<Player> &player)
{
removedPlayerBuffer.push_back(player);
players.erase(std::remove(players.begin(), players.end(), player), players.end());
removeChild(player);
}
@ -104,3 +105,8 @@ void PlayerCollection::spawnPlayer(const std::shared_ptr<InputIdentity> &inputId
auto player = std::make_shared<Player>(inputIdentity, PLAYER_SKIN, spawn);
PlayerCollection::getInstance()->addPlayer(player);
}
std::vector<std::shared_ptr<Player>> PlayerCollection::getPlayers() const
{
return players;
}

View file

@ -18,9 +18,11 @@ public:
void removePlayer(const std::shared_ptr<Player>& player);
std::vector<std::shared_ptr<Player>> getNewPlayers() const;
[[nodiscard]] std::vector<std::shared_ptr<Player>> getPlayers() 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;
@ -29,6 +31,7 @@ public:
private:
static inline std::shared_ptr<PlayerCollection> singletonInstance = nullptr;
std::vector<std::shared_ptr<Player>> players = {};
std::vector<std::shared_ptr<Player>> newPlayerBuffer = {};
std::vector<std::shared_ptr<Player>> removedPlayerBuffer = {};