Improved map wallout, fixed spawned player in wall glitch and now actually rendering collectables. Player handling has also been reworked
This commit is contained in:
parent
d3e6e35c9b
commit
414f3b79fc
27 changed files with 345 additions and 111 deletions
|
@ -52,8 +52,6 @@ set(SOURCES
|
||||||
src/game/camera/ITrackable.h
|
src/game/camera/ITrackable.h
|
||||||
src/game/input/input_identity.h
|
src/game/input/input_identity.h
|
||||||
src/utilities/magic_enum.hpp
|
src/utilities/magic_enum.hpp
|
||||||
src/game/player/player_spawner.cpp
|
|
||||||
src/game/player/player_spawner.hpp
|
|
||||||
src/game/camera/tracking_area.h
|
src/game/camera/tracking_area.h
|
||||||
src/game/camera/tracking_view_options.hpp
|
src/game/camera/tracking_view_options.hpp
|
||||||
src/game/collectables/collectable.cpp
|
src/game/collectables/collectable.cpp
|
||||||
|
@ -96,7 +94,7 @@ set(SOURCES
|
||||||
src/game/collectables/collection/collectables_collection.cpp
|
src/game/collectables/collection/collectables_collection.cpp
|
||||||
src/game/collectables/collection/collectables_collection.hpp
|
src/game/collectables/collection/collectables_collection.hpp
|
||||||
src/game/collectables/collection/collectables_depth_collection.cpp
|
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/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)
|
||||||
|
|
||||||
set(PHYSICS_00_SOURCES
|
set(PHYSICS_00_SOURCES
|
||||||
src/prototypes/physics_00.cpp)
|
src/prototypes/physics_00.cpp)
|
||||||
|
|
|
@ -34,8 +34,10 @@
|
||||||
#define DEF_TV_MIN_VIEW_SIZE sf::Vector2f(6, 6) * WORLD_TO_ISO_SCALE
|
#define DEF_TV_MIN_VIEW_SIZE sf::Vector2f(6, 6) * WORLD_TO_ISO_SCALE
|
||||||
#define DEF_TV_MAX_VIEW_SIZE sf::Vector2f(0, 0)
|
#define DEF_TV_MAX_VIEW_SIZE sf::Vector2f(0, 0)
|
||||||
#define DEF_TV_VIEW_SIZE_PADDING sf::Vector2f(0.5f, 0.5f)
|
#define DEF_TV_VIEW_SIZE_PADDING sf::Vector2f(0.5f, 0.5f)
|
||||||
|
#define DEF_TV_ADD_PLAYERS_DYNAMICALLY true
|
||||||
|
|
||||||
// Simulations
|
// Simulations
|
||||||
|
#define MAPSIM_WALL_THICKNESS 3.f
|
||||||
#define MAPSIM_VELOCITY_ITERATIONS 6
|
#define MAPSIM_VELOCITY_ITERATIONS 6
|
||||||
#define MAPSIM_POSITION_ITERATIONS 2
|
#define MAPSIM_POSITION_ITERATIONS 2
|
||||||
#define HOLESIM_VELOCITY_ITERATIONS 8
|
#define HOLESIM_VELOCITY_ITERATIONS 8
|
||||||
|
|
|
@ -68,3 +68,8 @@ void TranslatedCoordinates::setScreenOffset(IsometricCoordinates offset)
|
||||||
{
|
{
|
||||||
setWorldOffset(CoordinateTransformer::isometricToWorld(offset));
|
setWorldOffset(CoordinateTransformer::isometricToWorld(offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TranslatedCoordinates::TranslatedCoordinates(GridCoordinates gridCoordinates)
|
||||||
|
{
|
||||||
|
set(gridCoordinates);
|
||||||
|
}
|
||||||
|
|
|
@ -9,12 +9,13 @@ class TranslatedCoordinates
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit TranslatedCoordinates(WorldCoordinates worldCoordinates);
|
explicit TranslatedCoordinates(WorldCoordinates worldCoordinates);
|
||||||
|
explicit TranslatedCoordinates(GridCoordinates gridCoordinates);
|
||||||
|
|
||||||
WorldCoordinates world() const;
|
[[nodiscard]] WorldCoordinates world() const;
|
||||||
|
|
||||||
IsometricCoordinates isometric() const;
|
[[nodiscard]] IsometricCoordinates isometric() const;
|
||||||
|
|
||||||
GridCoordinates grid() const;
|
[[nodiscard]] GridCoordinates grid() const;
|
||||||
|
|
||||||
void set(WorldCoordinates newWorldCoordinates);
|
void set(WorldCoordinates newWorldCoordinates);
|
||||||
|
|
||||||
|
@ -35,7 +36,7 @@ public:
|
||||||
void setScreenOffset(IsometricCoordinates offset);
|
void setScreenOffset(IsometricCoordinates offset);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
WorldCoordinates worldCoordinates;
|
WorldCoordinates worldCoordinates{};
|
||||||
|
|
||||||
std::shared_ptr<TranslatedCoordinates> parent = nullptr;
|
std::shared_ptr<TranslatedCoordinates> parent = nullptr;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
#include "tracking_view.h"
|
#include "tracking_view.h"
|
||||||
#include "../../utilities/vector_utils.hpp"
|
#include "../../utilities/vector_utils.hpp"
|
||||||
|
#include "../player/player_collection.hpp"
|
||||||
|
|
||||||
TrackingView::TrackingView(TrackingViewOptions options) : options(options),
|
TrackingView::TrackingView(TrackingViewOptions options) : options(options),
|
||||||
view(nullptr),
|
view(nullptr),
|
||||||
hasViewChanged(false),
|
hasViewChanged(false),
|
||||||
trackables({})
|
trackables({})
|
||||||
{;
|
{
|
||||||
|
;
|
||||||
marker = new CircleObject(DB_CIRCLE_RADIUS, sf::Color::Yellow);
|
marker = new CircleObject(DB_CIRCLE_RADIUS, sf::Color::Yellow);
|
||||||
Game::getInstance()->registerView(this);
|
Game::getInstance()->registerView(this);
|
||||||
}
|
}
|
||||||
|
@ -65,7 +67,8 @@ void TrackingView::setSize(sf::Vector2f newSize)
|
||||||
didAspectRationChange = true;
|
didAspectRationChange = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (options.softResizeSpeed != 0 && !didAspectRationChange) {
|
if (options.softResizeSpeed != 0 && !didAspectRationChange)
|
||||||
|
{
|
||||||
// Smooth out transition to new size
|
// Smooth out transition to new size
|
||||||
newSize = size + (newSize - size) * options.softResizeSpeed * FRAME_TIME.asSeconds();
|
newSize = size + (newSize - size) * options.softResizeSpeed * FRAME_TIME.asSeconds();
|
||||||
}
|
}
|
||||||
|
@ -142,7 +145,7 @@ void TrackingView::draw(sf::RenderWindow *window)
|
||||||
marker->draw(window);
|
marker->draw(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TrackingView::addTrackable(const std::shared_ptr<ITrackable>& trackable)
|
void TrackingView::addTrackable(const std::shared_ptr<ITrackable> &trackable)
|
||||||
{
|
{
|
||||||
trackables.push_back(trackable);
|
trackables.push_back(trackable);
|
||||||
}
|
}
|
||||||
|
@ -271,3 +274,39 @@ float TrackingView::getRadius(float threshold) const
|
||||||
// Only half of the side, since we are calculating radius
|
// Only half of the side, since we are calculating radius
|
||||||
return smallestSide / 2.f * threshold;
|
return smallestSide / 2.f * threshold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TrackingView::update()
|
||||||
|
{
|
||||||
|
if (options.addPlayersDynamically)
|
||||||
|
{
|
||||||
|
addPlayersDynamically();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TrackingView::addPlayersDynamically()
|
||||||
|
{
|
||||||
|
// Update based on PlayerCollection
|
||||||
|
// Add new
|
||||||
|
for (const auto &player: PlayerCollection::getInstance()->getNewPlayers())
|
||||||
|
{
|
||||||
|
if (player->getTrackableState() == TrackableState::TRACKING)
|
||||||
|
{
|
||||||
|
addTrackable(player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove old
|
||||||
|
for (const auto &player: PlayerCollection::getInstance()->getRemovedPlayers())
|
||||||
|
{
|
||||||
|
removeTrackable(player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TrackingView::removeTrackable(const std::shared_ptr<ITrackable> &trackable)
|
||||||
|
{
|
||||||
|
trackables.erase(
|
||||||
|
std::remove_if(trackables.begin(), trackables.end(), [&trackable](const std::shared_ptr<ITrackable> &t)
|
||||||
|
{
|
||||||
|
return t == trackable;
|
||||||
|
}), trackables.end());
|
||||||
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ public:
|
||||||
|
|
||||||
~TrackingView();
|
~TrackingView();
|
||||||
|
|
||||||
|
void update() override;
|
||||||
|
|
||||||
void draw(sf::RenderWindow *window) override;
|
void draw(sf::RenderWindow *window) override;
|
||||||
|
|
||||||
|
@ -24,6 +25,8 @@ public:
|
||||||
|
|
||||||
void addTrackable(const std::shared_ptr<ITrackable>& trackable);
|
void addTrackable(const std::shared_ptr<ITrackable>& trackable);
|
||||||
|
|
||||||
|
void removeTrackable(const std::shared_ptr<ITrackable> &trackable);
|
||||||
|
|
||||||
sf::Vector2f getSize() const;
|
sf::Vector2f getSize() const;
|
||||||
|
|
||||||
sf::Vector2f getCenter() const;
|
sf::Vector2f getCenter() const;
|
||||||
|
@ -57,6 +60,8 @@ private:
|
||||||
float getRadius(float threshold) const;
|
float getRadius(float threshold) const;
|
||||||
|
|
||||||
sf::Vector2f getWindowSize() const;
|
sf::Vector2f getWindowSize() const;
|
||||||
|
|
||||||
|
void addPlayersDynamically();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,11 @@ struct TrackingViewOptions
|
||||||
* Value between 0 and 1 to set relative padding.
|
* Value between 0 and 1 to set relative padding.
|
||||||
*/
|
*/
|
||||||
sf::Vector2f viewSizePadding = DEF_TV_VIEW_SIZE_PADDING;
|
sf::Vector2f viewSizePadding = DEF_TV_VIEW_SIZE_PADDING;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If set to true, view will add all new players automatically and remove them accordingly, based on PlayerCollection.
|
||||||
|
*/
|
||||||
|
bool addPlayersDynamically = DEF_TV_ADD_PLAYERS_DYNAMICALLY;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //HOLESOME_TRACKING_VIEW_OPTIONS_HPP
|
#endif //HOLESOME_TRACKING_VIEW_OPTIONS_HPP
|
||||||
|
|
|
@ -8,11 +8,6 @@ Collectable::Collectable()
|
||||||
collectableCount++;
|
collectableCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Collectable::draw(sf::RenderWindow *window)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void Collectable::setRotation(float angle)
|
void Collectable::setRotation(float angle)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
@ -9,8 +9,6 @@ class Collectable : public GameObject
|
||||||
public:
|
public:
|
||||||
Collectable();
|
Collectable();
|
||||||
|
|
||||||
void draw(sf::RenderWindow *window) override;
|
|
||||||
|
|
||||||
void setSprite(const std::string &spriteName);
|
void setSprite(const std::string &spriteName);
|
||||||
|
|
||||||
void setRotation(float angle);
|
void setRotation(float angle);
|
||||||
|
|
|
@ -66,7 +66,7 @@ void CollectablesCollection::update()
|
||||||
void CollectablesCollection::draw(sf::RenderWindow *window)
|
void CollectablesCollection::draw(sf::RenderWindow *window)
|
||||||
{
|
{
|
||||||
// Render collectables in reverse order of depth
|
// Render collectables in reverse order of depth
|
||||||
int maxDepth = depthCollections.size();
|
int maxDepth = (int) depthCollections.size();
|
||||||
for (int depth = maxDepth - 1; depth >= 0; depth--)
|
for (int depth = maxDepth - 1; depth >= 0; depth--)
|
||||||
{
|
{
|
||||||
auto depthCollection = depthCollections.at(depth);
|
auto depthCollection = depthCollections.at(depth);
|
||||||
|
@ -87,3 +87,14 @@ void CollectablesCollection::updateCollectables()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<CollectablesDepthCollection> CollectablesCollection::getDepthCollection(int depth)
|
||||||
|
{
|
||||||
|
if (depthCollections.find(depth) == depthCollections.end())
|
||||||
|
{
|
||||||
|
LOG(ERROR) << "Depth collection for depth " << depth << " does not exist! Returning empty collection ...";
|
||||||
|
return std::make_shared<CollectablesDepthCollection>(depth);
|
||||||
|
}
|
||||||
|
|
||||||
|
return depthCollections[depth];
|
||||||
|
}
|
||||||
|
|
|
@ -23,6 +23,8 @@ public:
|
||||||
void add(const std::shared_ptr<Collectable>& collectable);
|
void add(const std::shared_ptr<Collectable>& collectable);
|
||||||
void remove(const std::shared_ptr<Collectable>& collectable);
|
void remove(const std::shared_ptr<Collectable>& collectable);
|
||||||
|
|
||||||
|
std::shared_ptr<CollectablesDepthCollection> getDepthCollection(int depth);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static inline std::shared_ptr<CollectablesCollection> singletonInstance = nullptr;
|
static inline std::shared_ptr<CollectablesCollection> singletonInstance = nullptr;
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include "game.h"
|
#include "game.h"
|
||||||
#include "level/level_loader.hpp"
|
#include "level/level_loader.hpp"
|
||||||
#include "physics/map/map_simulation.hpp"
|
#include "physics/map/map_simulation.hpp"
|
||||||
|
#include "../logging/easylogging++.h"
|
||||||
|
|
||||||
Game::Game(std::shared_ptr<sf::RenderWindow> window) : window(std::move(window))
|
Game::Game(std::shared_ptr<sf::RenderWindow> window) : window(std::move(window))
|
||||||
{
|
{
|
||||||
|
@ -15,6 +16,7 @@ void Game::run()
|
||||||
sf::Clock clock;
|
sf::Clock clock;
|
||||||
sf::Time TimeSinceLastUpdate = sf::seconds(0);
|
sf::Time TimeSinceLastUpdate = sf::seconds(0);
|
||||||
|
|
||||||
|
LOG(INFO) << "Game loop started ...";
|
||||||
while (window->isOpen())
|
while (window->isOpen())
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -29,6 +31,8 @@ void Game::run()
|
||||||
}
|
}
|
||||||
drawFrame();
|
drawFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LOG(INFO) << "Game closing ...";
|
||||||
}
|
}
|
||||||
|
|
||||||
void Game::exit()
|
void Game::exit()
|
||||||
|
@ -83,12 +87,16 @@ void Game::update()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
InputMapper::getInstance()->updateIdentities();
|
// Physics updates
|
||||||
|
for (const auto &gameObject: gameObjects)
|
||||||
if (isLevelLoaded())
|
|
||||||
{
|
{
|
||||||
MapSimulation::getInstance()->updateSimulation();
|
if (gameObject->getActive())
|
||||||
|
{
|
||||||
|
gameObject->physicsUpdate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
InputMapper::getInstance()->updateIdentities();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<Game> Game::getInstance()
|
std::shared_ptr<Game> Game::getInstance()
|
||||||
|
|
|
@ -57,3 +57,25 @@ void GameObject::addChild(const std::shared_ptr<GameObject> &child)
|
||||||
{
|
{
|
||||||
addChildWorldOffset(child, {0, 0});
|
addChildWorldOffset(child, {0, 0});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GameObject::removeChild(const std::shared_ptr<GameObject> &child)
|
||||||
|
{
|
||||||
|
auto it = std::find(children.begin(), children.end(), child);
|
||||||
|
if (it != children.end())
|
||||||
|
{
|
||||||
|
children.erase(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameObject::clearChildren()
|
||||||
|
{
|
||||||
|
children.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GameObject::physicsUpdate()
|
||||||
|
{
|
||||||
|
for (auto &child: children)
|
||||||
|
{
|
||||||
|
child->physicsUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -18,12 +18,16 @@ public:
|
||||||
|
|
||||||
virtual void lateUpdate();
|
virtual void lateUpdate();
|
||||||
|
|
||||||
|
virtual void physicsUpdate();
|
||||||
|
|
||||||
void setActive(bool active);
|
void setActive(bool active);
|
||||||
bool getActive() const { return isActive; }
|
bool getActive() const { return isActive; }
|
||||||
|
|
||||||
void addChildScreenOffset(const std::shared_ptr<GameObject> &child, IsometricCoordinates offset = {0, 0});
|
void addChildScreenOffset(const std::shared_ptr<GameObject> &child, IsometricCoordinates offset = {0, 0});
|
||||||
void addChildWorldOffset(const std::shared_ptr<GameObject> &child, WorldCoordinates offset);
|
void addChildWorldOffset(const std::shared_ptr<GameObject> &child, WorldCoordinates offset);
|
||||||
void addChild(const std::shared_ptr<GameObject> &child);
|
void addChild(const std::shared_ptr<GameObject> &child);
|
||||||
|
void removeChild(const std::shared_ptr<GameObject> &child);
|
||||||
|
void clearChildren();
|
||||||
[[nodiscard]] std::vector<std::shared_ptr<GameObject>> getChildren() const { return children; }
|
[[nodiscard]] std::vector<std::shared_ptr<GameObject>> getChildren() const { return children; }
|
||||||
|
|
||||||
std::shared_ptr<TranslatedCoordinates> coordinates;
|
std::shared_ptr<TranslatedCoordinates> coordinates;
|
||||||
|
|
|
@ -2,12 +2,13 @@
|
||||||
#include "../game.h"
|
#include "../game.h"
|
||||||
#include "../physics/map/map_simulation.hpp"
|
#include "../physics/map/map_simulation.hpp"
|
||||||
#include "../../debug/grid_debug_layer.h"
|
#include "../../debug/grid_debug_layer.h"
|
||||||
#include "../player/player_spawner.hpp"
|
|
||||||
#include "../../levels.hpp"
|
#include "../../levels.hpp"
|
||||||
#include "../collectables/collection/collectables_collection.hpp"
|
#include "../collectables/collection/collectables_collection.hpp"
|
||||||
#include "../collectables/collectable_factory.hpp"
|
#include "../collectables/collectable_factory.hpp"
|
||||||
|
#include "../player/player_collection.hpp"
|
||||||
|
#include "../physics/hole/hole_depth_simulation.hpp"
|
||||||
|
|
||||||
void LevelLoader::loadLevel(const LevelConfig& levelConfig)
|
void LevelLoader::loadLevel(const LevelConfig &levelConfig)
|
||||||
{
|
{
|
||||||
auto game = Game::getInstance();
|
auto game = Game::getInstance();
|
||||||
game->clearGameObjects();
|
game->clearGameObjects();
|
||||||
|
@ -16,6 +17,7 @@ void LevelLoader::loadLevel(const LevelConfig& levelConfig)
|
||||||
|
|
||||||
game->setLevel(levelConfig);
|
game->setLevel(levelConfig);
|
||||||
MapSimulation::getInstance()->resetMap(levelConfig.worldMapSize);
|
MapSimulation::getInstance()->resetMap(levelConfig.worldMapSize);
|
||||||
|
PlayerCollection::getInstance()->clear();
|
||||||
|
|
||||||
// Add basic game objects
|
// Add basic game objects
|
||||||
if (DEVELOPER_MODE)
|
if (DEVELOPER_MODE)
|
||||||
|
@ -24,12 +26,14 @@ void LevelLoader::loadLevel(const LevelConfig& levelConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
game->addGameObject(std::make_shared<TrackingView>());
|
game->addGameObject(std::make_shared<TrackingView>());
|
||||||
game->addGameObject(std::make_shared<PlayerSpawner>(levelConfig.playerSpawnPoints));
|
game->addGameObject(PlayerCollection::getInstance());
|
||||||
|
PlayerCollection::getInstance()->setSpawnPoints(levelConfig.playerSpawnPoints);
|
||||||
|
|
||||||
// Prepare collectables framework
|
// Prepare collectables framework
|
||||||
auto maxDepth = levelConfig.worldMapSize.x * 2;
|
auto maxDepth = (int) levelConfig.worldMapSize.x * 2;
|
||||||
CollectablesCollection::getInstance()->createEmpty(maxDepth);
|
auto collectablesCollection = CollectablesCollection::getInstance();
|
||||||
game->addGameObject(CollectablesCollection::getInstance());
|
collectablesCollection->createEmpty(maxDepth);
|
||||||
|
game->addGameObject(collectablesCollection);
|
||||||
|
|
||||||
// Spawn collectibles
|
// Spawn collectibles
|
||||||
for (auto const &collectableInfo: levelConfig.collectables)
|
for (auto const &collectableInfo: levelConfig.collectables)
|
||||||
|
@ -37,6 +41,15 @@ void LevelLoader::loadLevel(const LevelConfig& levelConfig)
|
||||||
spawnCollectable(collectableInfo);
|
spawnCollectable(collectableInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add physics simulations
|
||||||
|
game->addGameObject(MapSimulation::getInstance());
|
||||||
|
// For every depth, add a hole depth simulation
|
||||||
|
for (int depth = 0; depth < maxDepth; depth++)
|
||||||
|
{
|
||||||
|
auto depthCollection = collectablesCollection->getDepthCollection(depth);
|
||||||
|
game->addGameObject(std::make_shared<HoleDepthSimulation>(depthCollection));
|
||||||
|
}
|
||||||
|
|
||||||
LOG(INFO) << "Finished loading level '" << levelConfig.name << "'.";
|
LOG(INFO) << "Finished loading level '" << levelConfig.name << "'.";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ HoleDepthSimulation::HoleDepthSimulation(std::shared_ptr<CollectablesDepthCollec
|
||||||
simWorld = std::make_shared<b2World>(WORLD_GRAVITY);
|
simWorld = std::make_shared<b2World>(WORLD_GRAVITY);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HoleDepthSimulation::updateSimulation()
|
void HoleDepthSimulation::physicsUpdate()
|
||||||
{
|
{
|
||||||
updateBodiesFromCollectionHistory();
|
updateBodiesFromCollectionHistory();
|
||||||
|
|
||||||
|
|
|
@ -10,12 +10,12 @@
|
||||||
/**
|
/**
|
||||||
* @brief Simulates the hole(s) for the specific depth
|
* @brief Simulates the hole(s) for the specific depth
|
||||||
*/
|
*/
|
||||||
class HoleDepthSimulation
|
class HoleDepthSimulation : public GameObject
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
HoleDepthSimulation(std::shared_ptr<CollectablesDepthCollection> collectables);
|
explicit HoleDepthSimulation(std::shared_ptr<CollectablesDepthCollection> collectables);
|
||||||
|
|
||||||
void updateSimulation();
|
void physicsUpdate() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<CollectablesDepthCollection> collectables;
|
std::shared_ptr<CollectablesDepthCollection> collectables;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "map_simulation.hpp"
|
#include "map_simulation.hpp"
|
||||||
#include "../../../config.h"
|
#include "../../../config.h"
|
||||||
|
#include "../../player/player_collection.hpp"
|
||||||
|
|
||||||
MapSimulation::MapSimulation()
|
MapSimulation::MapSimulation()
|
||||||
{
|
{
|
||||||
|
@ -15,7 +16,7 @@ std::shared_ptr<MapSimulation> MapSimulation::getInstance()
|
||||||
return singletonInstance;
|
return singletonInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapSimulation::updateSimulation()
|
void MapSimulation::physicsUpdate()
|
||||||
{
|
{
|
||||||
// Update simulation positions
|
// Update simulation positions
|
||||||
for (auto &mapPlayer: mapPlayersById)
|
for (auto &mapPlayer: mapPlayersById)
|
||||||
|
@ -34,15 +35,20 @@ void MapSimulation::updateSimulation()
|
||||||
|
|
||||||
void MapSimulation::resetMap(sf::Vector2f worldMapSize)
|
void MapSimulation::resetMap(sf::Vector2f worldMapSize)
|
||||||
{
|
{
|
||||||
|
// Clear all players
|
||||||
|
for (auto &mapPlayer: mapPlayersById)
|
||||||
|
{
|
||||||
|
removePlayer(mapPlayer.second->player);
|
||||||
|
}
|
||||||
|
|
||||||
// No gravity, since this a top-down view of the map
|
// No gravity, since this a top-down view of the map
|
||||||
world = std::make_shared<b2World>(b2Vec2(0.0f, 0.0f));
|
world = std::make_shared<b2World>(b2Vec2(0.0f, 0.0f));
|
||||||
mapPlayersById.clear();
|
|
||||||
|
|
||||||
// Create map borders
|
// Create map borders
|
||||||
constructSquareObstacle(-1, 0, 0, worldMapSize.y);
|
constructSquareObstacle(-MAPSIM_WALL_THICKNESS, -MAPSIM_WALL_THICKNESS, 0, worldMapSize.y + MAPSIM_WALL_THICKNESS); // Bottom left
|
||||||
constructSquareObstacle(0, -1, worldMapSize.x, 0);
|
constructSquareObstacle(0, -MAPSIM_WALL_THICKNESS, worldMapSize.x, 0); // Bottom right
|
||||||
constructSquareObstacle(worldMapSize.x, 0, worldMapSize.x + 1, worldMapSize.y);
|
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 + 1);
|
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)
|
||||||
|
@ -62,11 +68,34 @@ void MapSimulation::constructSquareObstacle(float minX, float minY, float maxX,
|
||||||
body->CreateFixture(&fixtureDef);
|
body->CreateFixture(&fixtureDef);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapSimulation::addPlayer(const std::shared_ptr<Player>& player)
|
void MapSimulation::addPlayer(const std::shared_ptr<Player> &player)
|
||||||
{
|
{
|
||||||
b2BodyDef bodyDef;
|
b2BodyDef bodyDef;
|
||||||
bodyDef.type = b2_dynamicBody;
|
bodyDef.type = b2_dynamicBody;
|
||||||
bodyDef.position.Set(player->coordinates->world().x, player->coordinates->world().y);
|
bodyDef.position.Set(player->spawnPosition.world().x, player->spawnPosition.world().y);
|
||||||
b2Body *body = world->CreateBody(&bodyDef);
|
b2Body *body = world->CreateBody(&bodyDef);
|
||||||
mapPlayersById[player->getPlayerId()] = std::make_shared<MapPlayer>(player, body);
|
mapPlayersById[player->getPlayerId()] = std::make_shared<MapPlayer>(player, body);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
|
@ -7,12 +7,14 @@
|
||||||
#include "../../player/player.hpp"
|
#include "../../player/player.hpp"
|
||||||
#include "map_player.hpp"
|
#include "map_player.hpp"
|
||||||
|
|
||||||
class MapSimulation
|
class MapSimulation : public GameObject
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MapSimulation();
|
MapSimulation();
|
||||||
|
|
||||||
void updateSimulation();
|
void update() override;
|
||||||
|
|
||||||
|
void physicsUpdate() override;
|
||||||
|
|
||||||
void resetMap(sf::Vector2f worldMapSize);
|
void resetMap(sf::Vector2f worldMapSize);
|
||||||
|
|
||||||
|
@ -29,6 +31,7 @@ private:
|
||||||
|
|
||||||
void constructSquareObstacle(float minX, float minY, float maxX, float maxY);
|
void constructSquareObstacle(float minX, float minY, float maxX, float maxY);
|
||||||
|
|
||||||
|
void removePlayer(std::shared_ptr<Player> &player);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,19 +1,21 @@
|
||||||
#include "player.hpp"
|
#include "player.hpp"
|
||||||
#include "../../config.h"
|
#include "../../logging/easylogging++.h"
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
Player::Player(std::shared_ptr<InputIdentity> assignedInput, const std::string &skinRessourceName,
|
Player::Player(std::shared_ptr<InputIdentity> assignedInput, const std::string &skinRessourceName,
|
||||||
GridCoordinates initCoordinates)
|
GridCoordinates initCoordinates)
|
||||||
|
: spawnPosition(initCoordinates)
|
||||||
{
|
{
|
||||||
playerId = playerCreationCounter++;
|
playerId = playerCreationCounter++;
|
||||||
this->spawnPosition = initCoordinates;
|
coordinates->set(spawnPosition);
|
||||||
coordinates->set(initCoordinates);
|
|
||||||
|
|
||||||
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));
|
||||||
|
|
||||||
|
LOG(INFO) << "Player " << playerId << " created.";
|
||||||
}
|
}
|
||||||
|
|
||||||
sf::Vector2f Player::getTrackablePosition() const
|
sf::Vector2f Player::getTrackablePosition() const
|
||||||
|
@ -92,3 +94,8 @@ 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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Player::~Player()
|
||||||
|
{
|
||||||
|
LOG(INFO) << "Player " << playerId << " destroyed.";
|
||||||
|
}
|
||||||
|
|
|
@ -13,6 +13,8 @@ public:
|
||||||
Player(std::shared_ptr<InputIdentity> assignedInput, const std::string &skinRessourceName,
|
Player(std::shared_ptr<InputIdentity> assignedInput, const std::string &skinRessourceName,
|
||||||
GridCoordinates initCoordinates);
|
GridCoordinates initCoordinates);
|
||||||
|
|
||||||
|
~Player();
|
||||||
|
|
||||||
void update() override;
|
void update() override;
|
||||||
|
|
||||||
[[nodiscard]] sf::Vector2f getTrackablePosition() const override;
|
[[nodiscard]] sf::Vector2f getTrackablePosition() const override;
|
||||||
|
@ -29,13 +31,12 @@ public:
|
||||||
|
|
||||||
[[nodiscard]] float getWorldRadius() const;
|
[[nodiscard]] float getWorldRadius() const;
|
||||||
|
|
||||||
|
TranslatedCoordinates spawnPosition;
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<InputIdentity> input;
|
std::shared_ptr<InputIdentity> input;
|
||||||
float radiusInWorld = DEFAULT_PLAYER_RADIUS;
|
float radiusInWorld = DEFAULT_PLAYER_RADIUS;
|
||||||
std::shared_ptr<VersatileSprite> skinSprite;
|
std::shared_ptr<VersatileSprite> skinSprite;
|
||||||
|
|
||||||
GridCoordinates spawnPosition;
|
|
||||||
|
|
||||||
int playerId;
|
int playerId;
|
||||||
static inline int playerCreationCounter = 0;
|
static inline int playerCreationCounter = 0;
|
||||||
|
|
||||||
|
|
106
src/game/player/player_collection.cpp
Normal file
106
src/game/player/player_collection.cpp
Normal file
|
@ -0,0 +1,106 @@
|
||||||
|
#include "player_collection.hpp"
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
#include "../input/input_mapper.h"
|
||||||
|
#include "../../texture_config.h"
|
||||||
|
|
||||||
|
PlayerCollection::PlayerCollection()
|
||||||
|
{
|
||||||
|
// Set default spawn point
|
||||||
|
setSpawnPoints({{0, 0}});
|
||||||
|
|
||||||
|
// Create player for existing input identities
|
||||||
|
for (auto &inputIdentity: InputMapper::getInstance()->getInputIdentities())
|
||||||
|
{
|
||||||
|
spawnPlayer(inputIdentity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<PlayerCollection> PlayerCollection::getInstance()
|
||||||
|
{
|
||||||
|
if (singletonInstance == nullptr)
|
||||||
|
{
|
||||||
|
singletonInstance = std::make_shared<PlayerCollection>();
|
||||||
|
}
|
||||||
|
return singletonInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlayerCollection::addPlayer(const std::shared_ptr<Player> &player)
|
||||||
|
{
|
||||||
|
newPlayerBuffer.push_back(player);
|
||||||
|
addChild(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlayerCollection::clear()
|
||||||
|
{
|
||||||
|
newPlayerBuffer.clear();
|
||||||
|
removedPlayerBuffer.clear();
|
||||||
|
|
||||||
|
// Fill in removed players
|
||||||
|
for (auto &child: getChildren())
|
||||||
|
{
|
||||||
|
auto player = std::dynamic_pointer_cast<Player>(child);
|
||||||
|
if (player != nullptr)
|
||||||
|
{
|
||||||
|
removedPlayerBuffer.push_back(player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
clearChildren();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlayerCollection::lateUpdate()
|
||||||
|
{
|
||||||
|
GameObject::lateUpdate();
|
||||||
|
|
||||||
|
newPlayerBuffer.clear();
|
||||||
|
removedPlayerBuffer.clear();
|
||||||
|
|
||||||
|
// Create player for new input identities
|
||||||
|
for (auto &inputIdentity: InputMapper::getInstance()->newInputIdentities)
|
||||||
|
{
|
||||||
|
spawnPlayer(inputIdentity);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove players, that are not active anymore
|
||||||
|
for (auto &child: getChildren())
|
||||||
|
{
|
||||||
|
if (child != nullptr && !child->getActive())
|
||||||
|
{
|
||||||
|
removedPlayerBuffer.push_back(std::dynamic_pointer_cast<Player>(child));
|
||||||
|
removeChild(child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlayerCollection::removePlayer(const std::shared_ptr<Player> &player)
|
||||||
|
{
|
||||||
|
removedPlayerBuffer.push_back(player);
|
||||||
|
removeChild(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::shared_ptr<Player>> PlayerCollection::getNewPlayers() const
|
||||||
|
{
|
||||||
|
return newPlayerBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::shared_ptr<Player>> PlayerCollection::getRemovedPlayers() const
|
||||||
|
{
|
||||||
|
return removedPlayerBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlayerCollection::setSpawnPoints(std::vector<GridCoordinates> newSpawnPoints)
|
||||||
|
{
|
||||||
|
this->spawnPoints = std::move(newSpawnPoints);
|
||||||
|
nextSpawnPointIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlayerCollection::spawnPlayer(const std::shared_ptr<InputIdentity> &inputIdentity)
|
||||||
|
{
|
||||||
|
// Get proper Spawn point, if available
|
||||||
|
auto spawn = spawnPoints[nextSpawnPointIndex];
|
||||||
|
nextSpawnPointIndex = static_cast<int>((nextSpawnPointIndex + 1) % spawnPoints.size());
|
||||||
|
|
||||||
|
auto player = std::make_shared<Player>(inputIdentity, PLAYER_SKIN, spawn);
|
||||||
|
PlayerCollection::getInstance()->addPlayer(player);
|
||||||
|
}
|
42
src/game/player/player_collection.hpp
Normal file
42
src/game/player/player_collection.hpp
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
#ifndef HOLESOME_PLAYER_COLLECTION_HPP
|
||||||
|
#define HOLESOME_PLAYER_COLLECTION_HPP
|
||||||
|
|
||||||
|
|
||||||
|
#include "../game_object.h"
|
||||||
|
#include "player.hpp"
|
||||||
|
|
||||||
|
class PlayerCollection : public GameObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PlayerCollection();
|
||||||
|
|
||||||
|
static std::shared_ptr<PlayerCollection> getInstance();
|
||||||
|
|
||||||
|
void setSpawnPoints(std::vector<GridCoordinates> newSpawnPoints);
|
||||||
|
|
||||||
|
void addPlayer(const std::shared_ptr<Player>& player);
|
||||||
|
|
||||||
|
void removePlayer(const std::shared_ptr<Player>& player);
|
||||||
|
|
||||||
|
std::vector<std::shared_ptr<Player>> getNewPlayers() const;
|
||||||
|
|
||||||
|
std::vector<std::shared_ptr<Player>> getRemovedPlayers() const;
|
||||||
|
|
||||||
|
void lateUpdate() override;
|
||||||
|
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
private:
|
||||||
|
static inline std::shared_ptr<PlayerCollection> singletonInstance = nullptr;
|
||||||
|
|
||||||
|
std::vector<std::shared_ptr<Player>> newPlayerBuffer = {};
|
||||||
|
std::vector<std::shared_ptr<Player>> removedPlayerBuffer = {};
|
||||||
|
|
||||||
|
std::vector<GridCoordinates> spawnPoints;
|
||||||
|
int nextSpawnPointIndex = 0;
|
||||||
|
|
||||||
|
void spawnPlayer(const std::shared_ptr<InputIdentity> &inputIdentity);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //HOLESOME_PLAYER_COLLECTION_HPP
|
|
@ -1,39 +0,0 @@
|
||||||
#include "player_spawner.hpp"
|
|
||||||
#include "player.hpp"
|
|
||||||
#include "../../texture_config.h"
|
|
||||||
#include "../physics/map/map_simulation.hpp"
|
|
||||||
|
|
||||||
PlayerSpawner::PlayerSpawner(std::vector<GridCoordinates> spawnPoints)
|
|
||||||
{
|
|
||||||
this->spawnPoints = spawnPoints;
|
|
||||||
|
|
||||||
// Create player for existing input identities
|
|
||||||
for (auto &inputIdentity: InputMapper::getInstance()->getInputIdentities())
|
|
||||||
{
|
|
||||||
spawnPlayer(inputIdentity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PlayerSpawner::update()
|
|
||||||
{
|
|
||||||
// Create player for new input identities
|
|
||||||
for (auto &inputIdentity: InputMapper::getInstance()->newInputIdentities)
|
|
||||||
{
|
|
||||||
spawnPlayer(inputIdentity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void PlayerSpawner::spawnPlayer(const std::shared_ptr<InputIdentity> &inputIdentity)
|
|
||||||
{
|
|
||||||
// Get proper Spawn point, if available
|
|
||||||
auto spawn = spawnPoints[nextSpawnPointIndex];
|
|
||||||
nextSpawnPointIndex = static_cast<int>((nextSpawnPointIndex + 1) % spawnPoints.size());
|
|
||||||
|
|
||||||
auto player = std::make_shared<Player>(inputIdentity, PLAYER_SKIN, spawn);
|
|
||||||
|
|
||||||
MapSimulation::getInstance()->addPlayer(player);
|
|
||||||
Game::getInstance()->addGameObject(player);
|
|
||||||
|
|
||||||
// TODO: Better view handling
|
|
||||||
Game::getInstance()->views[0]->addTrackable(player);
|
|
||||||
}
|
|
|
@ -1,23 +0,0 @@
|
||||||
#ifndef HOLESOME_PLAYER_SPAWNER_HPP
|
|
||||||
#define HOLESOME_PLAYER_SPAWNER_HPP
|
|
||||||
|
|
||||||
|
|
||||||
#include "../game_object.h"
|
|
||||||
#include "../game.h"
|
|
||||||
|
|
||||||
class PlayerSpawner : public GameObject
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
PlayerSpawner(std::vector<GridCoordinates> spawnPoints);
|
|
||||||
|
|
||||||
void update() override;
|
|
||||||
|
|
||||||
void spawnPlayer(const std::shared_ptr<InputIdentity> &inputIdentity);
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::vector<GridCoordinates> spawnPoints;
|
|
||||||
int nextSpawnPointIndex = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif //HOLESOME_PLAYER_SPAWNER_HPP
|
|
|
@ -3870,7 +3870,7 @@ class Loggers : base::StaticClass {
|
||||||
private:
|
private:
|
||||||
LoggingFlag m_flag;
|
LoggingFlag m_flag;
|
||||||
};
|
};
|
||||||
/// @brief Removes flag and add it when scope goes out
|
/// @brief Removes flag and addPlayer it when scope goes out
|
||||||
class ScopedRemoveFlag {
|
class ScopedRemoveFlag {
|
||||||
public:
|
public:
|
||||||
ScopedRemoveFlag(LoggingFlag flag) : m_flag(flag) {
|
ScopedRemoveFlag(LoggingFlag flag) : m_flag(flag) {
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
#include "sprites/configs/sheet_config.hpp"
|
#include "sprites/configs/sheet_config.hpp"
|
||||||
#include "sprites/configs/sprite_config.hpp"
|
#include "sprites/configs/sprite_config.hpp"
|
||||||
|
|
||||||
#define PLAYER_SKIN "hole"
|
#define PLAYER_SKIN "ring"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* All textures used in the game.
|
* All textures used in the game.
|
||||||
|
|
Loading…
Reference in a new issue