Added Collectables collections and other scaffolding required for further development
This commit is contained in:
parent
12b73c00ba
commit
88f19ae5e4
23 changed files with 493 additions and 34 deletions
|
@ -89,7 +89,14 @@ set(SOURCES
|
||||||
src/game/level/level_config.hpp
|
src/game/level/level_config.hpp
|
||||||
src/game/level/level_loader.cpp
|
src/game/level/level_loader.cpp
|
||||||
src/game/level/level_loader.hpp
|
src/game/level/level_loader.hpp
|
||||||
src/levels.hpp)
|
src/levels.hpp src/collectables.hpp
|
||||||
|
src/game/collectables/collectable_config.hpp
|
||||||
|
src/game/physics/hole/hole_depth_simulation.cpp
|
||||||
|
src/game/physics/hole/hole_depth_simulation.hpp
|
||||||
|
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)
|
||||||
|
|
||||||
set(PHYSICS_00_SOURCES
|
set(PHYSICS_00_SOURCES
|
||||||
src/prototypes/physics_00.cpp)
|
src/prototypes/physics_00.cpp)
|
||||||
|
|
12
src/collectables.hpp
Normal file
12
src/collectables.hpp
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
#ifndef HOLESOME_COLLECTABLES_HPP
|
||||||
|
#define HOLESOME_COLLECTABLES_HPP
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <map>
|
||||||
|
#include "game/collectables/collectable_config.hpp"
|
||||||
|
|
||||||
|
std::map<std::string, CollectableConfig> const all_collectables = {
|
||||||
|
{"box", CollectableConfig("numbers")}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //HOLESOME_COLLECTABLES_HPP
|
15
src/config.h
15
src/config.h
|
@ -2,6 +2,7 @@
|
||||||
#define HOLESOME_CONFIG_H
|
#define HOLESOME_CONFIG_H
|
||||||
|
|
||||||
#include <SFML/Graphics.hpp>
|
#include <SFML/Graphics.hpp>
|
||||||
|
#include <box2d/box2d.h>
|
||||||
|
|
||||||
#define DEVELOPER_MODE true
|
#define DEVELOPER_MODE true
|
||||||
|
|
||||||
|
@ -10,6 +11,9 @@
|
||||||
#define DEFAULT_PLAYER_RADIUS .5f // In World units
|
#define DEFAULT_PLAYER_RADIUS .5f // In World units
|
||||||
#define PLAYER_PROPORTIONAL_SIZE_CHANGE_SPEED 0.4f
|
#define PLAYER_PROPORTIONAL_SIZE_CHANGE_SPEED 0.4f
|
||||||
|
|
||||||
|
// World
|
||||||
|
#define WORLD_GRAVITY b2Vec2(0.f, 9.8f)
|
||||||
|
|
||||||
// FPS
|
// FPS
|
||||||
#define FRAME_RATE 60
|
#define FRAME_RATE 60
|
||||||
#define FRAME_TIME sf::Time(sf::seconds(1.0f / FRAME_RATE))
|
#define FRAME_TIME sf::Time(sf::seconds(1.0f / FRAME_RATE))
|
||||||
|
@ -27,18 +31,25 @@
|
||||||
#define DEF_TV_FREE_MOVE_THRESHOLD 0.f
|
#define DEF_TV_FREE_MOVE_THRESHOLD 0.f
|
||||||
#define DEF_TV_SOFT_FOLLOW_SPEED 2.5f
|
#define DEF_TV_SOFT_FOLLOW_SPEED 2.5f
|
||||||
#define DEF_TV_SOFT_RESIZE_SPEED 5.f
|
#define DEF_TV_SOFT_RESIZE_SPEED 5.f
|
||||||
#define DEF_TV_MIN_VIEW_SIZE sf::Vector2f(300, 300)
|
#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)
|
||||||
|
|
||||||
// Simulations
|
// Simulations
|
||||||
#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_POSITION_ITERATIONS 3
|
||||||
|
#define HOLESIM_COLLECTABLE_LINEAR_DAMPING 0.5f
|
||||||
|
#define HOLESIM_COLLECTABLE_ANGULAR_DAMPING 0.5f
|
||||||
|
#define HOLESIM_COLLECTABLE_DENSITY 1.f
|
||||||
|
#define HOLESIM_COLLECTABLE_FRICTION 0.3f
|
||||||
|
#define HOLESIM_COLLECTABLE_RESTITUTION 0.5f
|
||||||
|
|
||||||
// Directions
|
// Directions
|
||||||
#define DIRECTION_HARD_ACTIVATION_THRESHOLD 0.1f
|
#define DIRECTION_HARD_ACTIVATION_THRESHOLD 0.1f
|
||||||
|
|
||||||
// DEBUG
|
// DEBUG
|
||||||
#define DB_ISOPLANE_CORNER_RADIUS 2
|
#define DB_CIRCLE_RADIUS 1
|
||||||
|
|
||||||
#endif //HOLESOME_CONFIG_H
|
#endif //HOLESOME_CONFIG_H
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
#include "coordinate_transformer.h"
|
#include "coordinate_transformer.h"
|
||||||
#include "../config.h"
|
#include "../config.h"
|
||||||
|
#include "../logging/easylogging++.h"
|
||||||
|
|
||||||
// Initialize matrix
|
// Initialize matrix
|
||||||
const Eigen::Matrix<float, 3, 3> CoordinateTransformer::worldToIsometricMatrix =
|
const Eigen::Matrix<float, 3, 3> CoordinateTransformer::worldToIsometricMatrix =
|
||||||
(Eigen::Matrix<float, 3, 3>() <<
|
(Eigen::Matrix<float, 3, 3>() <<
|
||||||
1, -1, 0,
|
1, -1, 0,
|
||||||
-ISOMETRIC_SKEW, -ISOMETRIC_SKEW, -1,
|
-ISOMETRIC_SKEW, -ISOMETRIC_SKEW, -1,
|
||||||
1, 1, 0
|
1, 1, 0
|
||||||
).finished();
|
).finished();
|
||||||
|
@ -14,11 +15,11 @@ IsometricCoordinates CoordinateTransformer::worldToIsometric(WorldCoordinates wo
|
||||||
Eigen::Vector3f worldCoordinatesVector;
|
Eigen::Vector3f worldCoordinatesVector;
|
||||||
worldCoordinatesVector << worldCoordinates.x, worldCoordinates.y, worldCoordinates.z;
|
worldCoordinatesVector << worldCoordinates.x, worldCoordinates.y, worldCoordinates.z;
|
||||||
|
|
||||||
Eigen::Vector3f isoCoordinatesVector = worldToIsometricMatrix * worldCoordinatesVector * WORLD_TO_ISO_SCALE;
|
Eigen::Vector3f isoCoordinatesVector = worldToIsometricMatrix * worldCoordinatesVector;
|
||||||
|
|
||||||
return IsometricCoordinates(
|
return IsometricCoordinates(
|
||||||
isoCoordinatesVector.x(), // x
|
isoCoordinatesVector.x() * WORLD_TO_ISO_SCALE, // x
|
||||||
isoCoordinatesVector.y(), // y
|
isoCoordinatesVector.y() * WORLD_TO_ISO_SCALE, // y
|
||||||
isoCoordinatesVector.z() // depth
|
isoCoordinatesVector.z() // depth
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ GridDebugLayer::GridDebugLayer(int minX, int maxX, int minY, int maxY)
|
||||||
color = sf::Color::Blue;
|
color = sf::Color::Blue;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto gameObject = std::make_shared<CircleObject>(DB_ISOPLANE_CORNER_RADIUS, color);
|
auto gameObject = std::make_shared<CircleObject>(DB_CIRCLE_RADIUS, color);
|
||||||
addChildWorldOffset(gameObject, WorldCoordinates(x, y));
|
addChildWorldOffset(gameObject, WorldCoordinates(x, y));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ TrackingView::TrackingView(TrackingViewOptions options) : options(options),
|
||||||
hasViewChanged(false)
|
hasViewChanged(false)
|
||||||
{
|
{
|
||||||
trackables = std::vector<ITrackable *>();
|
trackables = std::vector<ITrackable *>();
|
||||||
marker = new CircleObject(2, sf::Color::Yellow);
|
marker = new CircleObject(DB_CIRCLE_RADIUS, sf::Color::Yellow);
|
||||||
Game::getInstance()->registerView(this);
|
Game::getInstance()->registerView(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,33 @@
|
||||||
#include "collectable.hpp"
|
#include "collectable.hpp"
|
||||||
|
#include "../../sprites/versatile_sprite.hpp"
|
||||||
|
#include "../../config.h"
|
||||||
|
|
||||||
Collectable::Collectable(GridCoordinates position)
|
Collectable::Collectable()
|
||||||
{
|
{
|
||||||
coordinates->set(position);
|
collectableId = collectableCount;
|
||||||
|
collectableCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Collectable::draw(sf::RenderWindow *window)
|
void Collectable::draw(sf::RenderWindow *window)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Collectable::setRotation(float angle)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int Collectable::getDepth() const
|
||||||
|
{
|
||||||
|
return static_cast<int>(coordinates->isometric().depth);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Collectable::setSprite(const std::string &spriteName)
|
||||||
|
{
|
||||||
|
// Create versatile sprite
|
||||||
|
float sizeWidth = 1.f * WORLD_TO_ISO_SCALE;
|
||||||
|
auto size = sf::Vector2f{sizeWidth, sizeWidth};
|
||||||
|
auto sprite = std::make_shared<VersatileSprite>(spriteName, size);
|
||||||
|
addChildScreenOffset(sprite, IsometricCoordinates(-sizeWidth / 2.f, -sizeWidth));
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#ifndef HOLESOME_ENVIRONMENT_COLLECTABLE_HPP
|
#ifndef HOLESOME_COLLECTABLE_HPP
|
||||||
#define HOLESOME_ENVIRONMENT_COLLECTABLE_HPP
|
#define HOLESOME_COLLECTABLE_HPP
|
||||||
|
|
||||||
|
|
||||||
#include "../game_object.h"
|
#include "../game_object.h"
|
||||||
|
@ -7,10 +7,25 @@
|
||||||
class Collectable : public GameObject
|
class Collectable : public GameObject
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Collectable(GridCoordinates position);
|
Collectable();
|
||||||
|
|
||||||
void draw(sf::RenderWindow *window) override;
|
void draw(sf::RenderWindow *window) override;
|
||||||
|
|
||||||
|
void setSprite(const std::string &spriteName);
|
||||||
|
|
||||||
|
void setRotation(float angle);
|
||||||
|
|
||||||
|
int getDepth() const;
|
||||||
|
|
||||||
|
int getId() const
|
||||||
|
{
|
||||||
|
return collectableId;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
int collectableId = 0;
|
||||||
|
static inline int collectableCount = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif //HOLESOME_ENVIRONMENT_COLLECTABLE_HPP
|
#endif //HOLESOME_COLLECTABLE_HPP
|
||||||
|
|
22
src/game/collectables/collectable_config.hpp
Normal file
22
src/game/collectables/collectable_config.hpp
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
#ifndef HOLESOME_COLLECTABLE_CONFIG_HPP
|
||||||
|
#define HOLESOME_COLLECTABLE_CONFIG_HPP
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
struct CollectableConfig
|
||||||
|
{
|
||||||
|
std::string spriteName;
|
||||||
|
|
||||||
|
explicit CollectableConfig(std::string spriteName)
|
||||||
|
: spriteName(std::move(spriteName))
|
||||||
|
{}
|
||||||
|
|
||||||
|
CollectableConfig() = default;
|
||||||
|
|
||||||
|
bool isValid() const
|
||||||
|
{
|
||||||
|
return !spriteName.empty();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //HOLESOME_COLLECTABLE_CONFIG_HPP
|
12
src/game/collectables/collectable_factory.cpp
Normal file
12
src/game/collectables/collectable_factory.cpp
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
#include "collectable_factory.hpp"
|
||||||
|
|
||||||
|
std::shared_ptr<Collectable> CollectableFactory::createFromInLevelConfig(const CollectableInLevel &config)
|
||||||
|
{
|
||||||
|
auto collectableConfig = config.collectableConfig;
|
||||||
|
auto collectable = std::make_shared<Collectable>();
|
||||||
|
|
||||||
|
collectable->coordinates->set(config.position);
|
||||||
|
collectable->setSprite(collectableConfig.spriteName);
|
||||||
|
|
||||||
|
return collectable;
|
||||||
|
}
|
15
src/game/collectables/collectable_factory.hpp
Normal file
15
src/game/collectables/collectable_factory.hpp
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
#ifndef HOLESOME_COLLECTABLE_FACTORY_HPP
|
||||||
|
#define HOLESOME_COLLECTABLE_FACTORY_HPP
|
||||||
|
|
||||||
|
|
||||||
|
#include "collectable_in_level.hpp"
|
||||||
|
#include "collectable.hpp"
|
||||||
|
|
||||||
|
class CollectableFactory
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static std::shared_ptr<Collectable> createFromInLevelConfig(const CollectableInLevel &config);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //HOLESOME_COLLECTABLE_FACTORY_HPP
|
35
src/game/collectables/collectable_in_level.hpp
Normal file
35
src/game/collectables/collectable_in_level.hpp
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
#ifndef HOLESOME_COLLECTABLE_IN_LEVEL_HPP
|
||||||
|
#define HOLESOME_COLLECTABLE_IN_LEVEL_HPP
|
||||||
|
|
||||||
|
#include "../../coordinates/coordinates.h"
|
||||||
|
#include "collectable_config.hpp"
|
||||||
|
#include "../../logging/easylogging++.h"
|
||||||
|
#include "../../collectables.hpp"
|
||||||
|
|
||||||
|
struct CollectableInLevel
|
||||||
|
{
|
||||||
|
std::string name;
|
||||||
|
GridCoordinates position;
|
||||||
|
CollectableConfig collectableConfig;
|
||||||
|
|
||||||
|
CollectableInLevel(const std::string &name, GridCoordinates position)
|
||||||
|
: name(name),
|
||||||
|
position(position)
|
||||||
|
{
|
||||||
|
if (all_collectables.find(name) == all_collectables.end())
|
||||||
|
{
|
||||||
|
LOG(ERROR) << "Collectable config " << name << " not found. Skipping collectable.";
|
||||||
|
this->name = ""; // Make this invalid
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->collectableConfig = all_collectables.at(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isValid() const
|
||||||
|
{
|
||||||
|
return !name.empty();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //HOLESOME_COLLECTABLE_IN_LEVEL_HPP
|
89
src/game/collectables/collection/collectables_collection.cpp
Normal file
89
src/game/collectables/collection/collectables_collection.cpp
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
#include "collectables_collection.hpp"
|
||||||
|
#include "collectables_depth_collection.hpp"
|
||||||
|
#include "../../../logging/easylogging++.h"
|
||||||
|
|
||||||
|
std::shared_ptr<CollectablesCollection> CollectablesCollection::getInstance()
|
||||||
|
{
|
||||||
|
if (singletonInstance == nullptr)
|
||||||
|
{
|
||||||
|
singletonInstance = std::make_shared<CollectablesCollection>();
|
||||||
|
}
|
||||||
|
return singletonInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CollectablesCollection::createEmpty(int maxDepth)
|
||||||
|
{
|
||||||
|
// Remove previous collections
|
||||||
|
depthCollections.clear();
|
||||||
|
|
||||||
|
LOG(INFO) << "Creating empty collectables collection with a max depth of " << maxDepth << " ...";
|
||||||
|
// Create new collections
|
||||||
|
for (int d = 0; d < maxDepth; d++)
|
||||||
|
{
|
||||||
|
auto depthCollection = std::make_shared<CollectablesDepthCollection>(d);
|
||||||
|
depthCollections[d] = depthCollection;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CollectablesCollection::remove(const std::shared_ptr<Collectable> &collectable)
|
||||||
|
{
|
||||||
|
depthCollections[collectable->getDepth()]->remove(collectable);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void CollectablesCollection::add(const std::shared_ptr<Collectable> &collectable)
|
||||||
|
{
|
||||||
|
depthCollections[collectable->getDepth()]->add(collectable);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CollectablesCollection::update()
|
||||||
|
{
|
||||||
|
updateCollectables();
|
||||||
|
|
||||||
|
// Move collectables to new depth collections if necessary
|
||||||
|
|
||||||
|
// First, clear history of all depth collections
|
||||||
|
for (auto &[depth, depthCollection]: depthCollections)
|
||||||
|
{
|
||||||
|
depthCollection->clearHistory();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Then, move collectables to new depth collections
|
||||||
|
for (auto &[depth, depthCollection]: depthCollections)
|
||||||
|
{
|
||||||
|
for (auto &collectable: depthCollection->collectables)
|
||||||
|
{
|
||||||
|
auto newDepth = collectable->getDepth();
|
||||||
|
if (newDepth != depth)
|
||||||
|
{
|
||||||
|
depthCollection->remove(collectable);
|
||||||
|
depthCollections[newDepth]->add(collectable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CollectablesCollection::draw(sf::RenderWindow *window)
|
||||||
|
{
|
||||||
|
// Render collectables in reverse order of depth
|
||||||
|
int maxDepth = depthCollections.size();
|
||||||
|
for (int depth = maxDepth - 1; depth >= 0; depth--)
|
||||||
|
{
|
||||||
|
auto depthCollection = depthCollections.at(depth);
|
||||||
|
for (auto &collectable: depthCollection->collectables)
|
||||||
|
{
|
||||||
|
collectable->draw(window);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CollectablesCollection::updateCollectables()
|
||||||
|
{
|
||||||
|
for (auto &[depth, depthCollection]: depthCollections)
|
||||||
|
{
|
||||||
|
for (auto &collectable: depthCollection->collectables)
|
||||||
|
{
|
||||||
|
collectable->update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
35
src/game/collectables/collection/collectables_collection.hpp
Normal file
35
src/game/collectables/collection/collectables_collection.hpp
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
#ifndef HOLESOME_COLLECTABLES_COLLECTION_HPP
|
||||||
|
#define HOLESOME_COLLECTABLES_COLLECTION_HPP
|
||||||
|
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <map>
|
||||||
|
#include "collectables_depth_collection.hpp"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Collection of all collections for each depth.
|
||||||
|
*/
|
||||||
|
class CollectablesCollection : public GameObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static std::shared_ptr<CollectablesCollection> getInstance();
|
||||||
|
|
||||||
|
void createEmpty(int maxDepth);
|
||||||
|
|
||||||
|
void update() override;
|
||||||
|
|
||||||
|
void draw(sf::RenderWindow *window) override;
|
||||||
|
|
||||||
|
void add(const std::shared_ptr<Collectable>& collectable);
|
||||||
|
void remove(const std::shared_ptr<Collectable>& collectable);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static inline std::shared_ptr<CollectablesCollection> singletonInstance = nullptr;
|
||||||
|
|
||||||
|
std::map<int, std::shared_ptr<CollectablesDepthCollection>> depthCollections = {};
|
||||||
|
|
||||||
|
void updateCollectables();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //HOLESOME_COLLECTABLES_COLLECTION_HPP
|
|
@ -0,0 +1,23 @@
|
||||||
|
#include "collectables_depth_collection.hpp"
|
||||||
|
|
||||||
|
CollectablesDepthCollection::CollectablesDepthCollection(int depth)
|
||||||
|
: depth(depth)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void CollectablesDepthCollection::clearHistory()
|
||||||
|
{
|
||||||
|
recentlyAdded.clear();
|
||||||
|
recentlyRemoved.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CollectablesDepthCollection::add(const std::shared_ptr<Collectable> &collectable)
|
||||||
|
{
|
||||||
|
collectables.insert(collectable);
|
||||||
|
recentlyAdded.insert(collectable);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CollectablesDepthCollection::remove(const std::shared_ptr<Collectable> &collectable)
|
||||||
|
{
|
||||||
|
recentlyRemoved.insert(collectable);
|
||||||
|
collectables.erase(collectable);
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
#ifndef HOLESOME_COLLECTABLES_DEPTH_COLLECTION_HPP
|
||||||
|
#define HOLESOME_COLLECTABLES_DEPTH_COLLECTION_HPP
|
||||||
|
|
||||||
|
|
||||||
|
#include <set>
|
||||||
|
#include <memory>
|
||||||
|
#include "../collectable.hpp"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Collection of collectables for a specific depth.
|
||||||
|
*/
|
||||||
|
struct CollectablesDepthCollection
|
||||||
|
{
|
||||||
|
int depth;
|
||||||
|
std::set<std::shared_ptr<Collectable>> collectables = {};
|
||||||
|
std::set<std::shared_ptr<Collectable>> recentlyRemoved = {};
|
||||||
|
std::set<std::shared_ptr<Collectable>> recentlyAdded = {};
|
||||||
|
|
||||||
|
explicit CollectablesDepthCollection(int depth);
|
||||||
|
|
||||||
|
void clearHistory();
|
||||||
|
|
||||||
|
void add(const std::shared_ptr<Collectable>& collectable);
|
||||||
|
void remove(const std::shared_ptr<Collectable>& collectable);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //HOLESOME_COLLECTABLES_DEPTH_COLLECTION_HPP
|
|
@ -4,7 +4,8 @@
|
||||||
|
|
||||||
#include <SFML/System/Vector2.hpp>
|
#include <SFML/System/Vector2.hpp>
|
||||||
#include "../../coordinates/coordinates.h"
|
#include "../../coordinates/coordinates.h"
|
||||||
#include <utility>
|
#include "../../logging/easylogging++.h"
|
||||||
|
#include "../collectables/collectable_in_level.hpp"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
struct LevelConfig
|
struct LevelConfig
|
||||||
|
@ -12,15 +13,30 @@ struct LevelConfig
|
||||||
std::string name;
|
std::string name;
|
||||||
sf::Vector2f worldMapSize = {};
|
sf::Vector2f worldMapSize = {};
|
||||||
std::vector<GridCoordinates> playerSpawnPoints = {};
|
std::vector<GridCoordinates> playerSpawnPoints = {};
|
||||||
|
std::vector<CollectableInLevel> collectables = {};
|
||||||
|
|
||||||
LevelConfig(std::string name, const sf::Vector2f &worldMapSize,
|
LevelConfig(std::string name,
|
||||||
const std::vector<GridCoordinates> &playerSpawnPoints)
|
const sf::Vector2f &worldMapSize,
|
||||||
: name(std::move(name)), worldMapSize(worldMapSize), playerSpawnPoints(playerSpawnPoints)
|
const std::vector<GridCoordinates> &playerSpawnPoints,
|
||||||
{ }
|
const std::vector<CollectableInLevel> &collectables = {})
|
||||||
|
: name(std::move(name)),
|
||||||
|
worldMapSize(worldMapSize),
|
||||||
|
playerSpawnPoints(playerSpawnPoints)
|
||||||
|
{
|
||||||
|
// Remove invalid collectables
|
||||||
|
for (auto &collectable : collectables)
|
||||||
|
{
|
||||||
|
if (collectable.isValid())
|
||||||
|
{
|
||||||
|
this->collectables.push_back(collectable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
LevelConfig() = default;
|
LevelConfig() = default;
|
||||||
|
|
||||||
bool isValid() const {
|
bool isValid() const
|
||||||
|
{
|
||||||
return !name.empty();
|
return !name.empty();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,24 +4,38 @@
|
||||||
#include "../../debug/grid_debug_layer.h"
|
#include "../../debug/grid_debug_layer.h"
|
||||||
#include "../player/player_spawner.hpp"
|
#include "../player/player_spawner.hpp"
|
||||||
#include "../../levels.hpp"
|
#include "../../levels.hpp"
|
||||||
|
#include "../collectables/collection/collectables_collection.hpp"
|
||||||
|
#include "../collectables/collectable_factory.hpp"
|
||||||
|
|
||||||
void LevelLoader::loadLevel(LevelConfig levelConfig)
|
void LevelLoader::loadLevel(LevelConfig levelConfig)
|
||||||
{
|
{
|
||||||
Game::getInstance()->clearGameObjects();
|
auto game = Game::getInstance();
|
||||||
|
game->clearGameObjects();
|
||||||
|
|
||||||
LOG(INFO) << "Loading level '" << levelConfig.name << "' ...";
|
LOG(INFO) << "Loading level '" << levelConfig.name << "' ...";
|
||||||
|
|
||||||
Game::getInstance()->setLevel(levelConfig);
|
game->setLevel(levelConfig);
|
||||||
MapSimulation::getInstance()->resetMap(levelConfig.worldMapSize);
|
MapSimulation::getInstance()->resetMap(levelConfig.worldMapSize);
|
||||||
|
|
||||||
// Add basic game objects
|
// Add basic game objects
|
||||||
if (DEVELOPER_MODE)
|
if (DEVELOPER_MODE)
|
||||||
{
|
{
|
||||||
Game::getInstance()->addGameObject(new GridDebugLayer(0, 50, 0, 50));
|
game->addGameObject(new GridDebugLayer(0, 50, 0, 50));
|
||||||
}
|
}
|
||||||
|
|
||||||
Game::getInstance()->addGameObject(new TrackingView());
|
game->addGameObject(new TrackingView());
|
||||||
Game::getInstance()->addGameObject(new PlayerSpawner(levelConfig.playerSpawnPoints));
|
game->addGameObject(new PlayerSpawner(levelConfig.playerSpawnPoints));
|
||||||
|
|
||||||
|
// Prepare collectables framework
|
||||||
|
auto maxDepth = levelConfig.worldMapSize.x * 2;
|
||||||
|
CollectablesCollection::getInstance()->createEmpty(maxDepth);
|
||||||
|
game->addGameObject(CollectablesCollection::getInstance().get());
|
||||||
|
|
||||||
|
// Spawn collectibles
|
||||||
|
for (auto const &collectableInfo: levelConfig.collectables)
|
||||||
|
{
|
||||||
|
spawnCollectable(collectableInfo);
|
||||||
|
}
|
||||||
|
|
||||||
LOG(INFO) << "Finished loading level '" << levelConfig.name << "'.";
|
LOG(INFO) << "Finished loading level '" << levelConfig.name << "'.";
|
||||||
}
|
}
|
||||||
|
@ -29,11 +43,19 @@ void LevelLoader::loadLevel(LevelConfig levelConfig)
|
||||||
void LevelLoader::loadLevel(const std::string &levelName)
|
void LevelLoader::loadLevel(const std::string &levelName)
|
||||||
{
|
{
|
||||||
// Does level exist?
|
// Does level exist?
|
||||||
if (!LEVELS.contains(levelName))
|
if (!all_levels.contains(levelName))
|
||||||
{
|
{
|
||||||
LOG(ERROR) << "Level '" << levelName << "' not found. Could not load it.";
|
LOG(ERROR) << "Level '" << levelName << "' not found. Could not load it.";
|
||||||
throw std::invalid_argument("Could not load level.");
|
throw std::invalid_argument("Could not load level.");
|
||||||
}
|
}
|
||||||
|
|
||||||
LevelLoader::loadLevel(LEVELS.at(levelName));
|
LevelLoader::loadLevel(all_levels.at(levelName));
|
||||||
|
}
|
||||||
|
|
||||||
|
void LevelLoader::spawnCollectable(const CollectableInLevel &collectableInfo)
|
||||||
|
{
|
||||||
|
LOG(INFO) << "Spawning collectable '" << collectableInfo.name << "' ...";
|
||||||
|
auto collectable = CollectableFactory::createFromInLevelConfig(collectableInfo);
|
||||||
|
LOG(DEBUG) << "Has depth " << collectable->getDepth() << ".";
|
||||||
|
CollectablesCollection::getInstance()->add(collectable);
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,8 @@ public:
|
||||||
static void loadLevel(LevelConfig levelConfig);
|
static void loadLevel(LevelConfig levelConfig);
|
||||||
|
|
||||||
static void loadLevel(const std::string &levelName);
|
static void loadLevel(const std::string &levelName);
|
||||||
|
|
||||||
|
static void spawnCollectable(const CollectableInLevel &collectableInfo);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
61
src/game/physics/hole/hole_depth_simulation.cpp
Normal file
61
src/game/physics/hole/hole_depth_simulation.cpp
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
#include "hole_depth_simulation.hpp"
|
||||||
|
#include "../../../config.h"
|
||||||
|
|
||||||
|
HoleDepthSimulation::HoleDepthSimulation(std::shared_ptr<CollectablesDepthCollection> collectables) : collectables(
|
||||||
|
std::move(collectables))
|
||||||
|
{
|
||||||
|
simWorld = std::make_shared<b2World>(WORLD_GRAVITY);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HoleDepthSimulation::updateSimulation()
|
||||||
|
{
|
||||||
|
updateBodiesFromCollectionHistory();
|
||||||
|
|
||||||
|
simWorld->Step(FRAME_TIME.asSeconds(), HOLESIM_VELOCITY_ITERATIONS, HOLESIM_POSITION_ITERATIONS);
|
||||||
|
|
||||||
|
updateCollectables();
|
||||||
|
}
|
||||||
|
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create bodies for new collectables
|
||||||
|
for (auto &collectable: collectables->recentlyAdded)
|
||||||
|
{
|
||||||
|
bodies[collectable->getId()] = createBody(collectable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HoleDepthSimulation::updateCollectables()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
b2Body *HoleDepthSimulation::createBody(const std::shared_ptr<Collectable> &collectable)
|
||||||
|
{
|
||||||
|
b2BodyDef bodyDef;
|
||||||
|
bodyDef.type = b2_dynamicBody;
|
||||||
|
bodyDef.position.Set(collectable->coordinates->isometric().x, collectable->coordinates->isometric().y);
|
||||||
|
bodyDef.linearDamping = HOLESIM_COLLECTABLE_LINEAR_DAMPING;
|
||||||
|
bodyDef.angularDamping = HOLESIM_COLLECTABLE_ANGULAR_DAMPING;
|
||||||
|
bodyDef.allowSleep = false;
|
||||||
|
bodyDef.awake = true;
|
||||||
|
auto body = simWorld->CreateBody(&bodyDef);
|
||||||
|
|
||||||
|
b2PolygonShape shape;
|
||||||
|
shape.SetAsBox(1, 1);
|
||||||
|
b2FixtureDef fixtureDef;
|
||||||
|
fixtureDef.shape = &shape;
|
||||||
|
fixtureDef.density = HOLESIM_COLLECTABLE_DENSITY;
|
||||||
|
fixtureDef.friction = HOLESIM_COLLECTABLE_FRICTION;
|
||||||
|
fixtureDef.restitution = HOLESIM_COLLECTABLE_RESTITUTION;
|
||||||
|
body->CreateFixture(&fixtureDef);
|
||||||
|
|
||||||
|
return body;
|
||||||
|
}
|
33
src/game/physics/hole/hole_depth_simulation.hpp
Normal file
33
src/game/physics/hole/hole_depth_simulation.hpp
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
#ifndef HOLESOME_HOLE_DEPTH_SIMULATION_HPP
|
||||||
|
#define HOLESOME_HOLE_DEPTH_SIMULATION_HPP
|
||||||
|
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <box2d/box2d.h>
|
||||||
|
#include <map>
|
||||||
|
#include "../../collectables/collection/collectables_depth_collection.hpp"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Simulates the hole(s) for the specific depth
|
||||||
|
*/
|
||||||
|
class HoleDepthSimulation
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
HoleDepthSimulation(std::shared_ptr<CollectablesDepthCollection> collectables);
|
||||||
|
|
||||||
|
void updateSimulation();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::shared_ptr<CollectablesDepthCollection> collectables;
|
||||||
|
std::shared_ptr<b2World> simWorld;
|
||||||
|
|
||||||
|
void updateBodiesFromCollectionHistory();
|
||||||
|
|
||||||
|
void updateCollectables();
|
||||||
|
|
||||||
|
std::map<int, b2Body*> bodies = {}; // Collectable ID -> Body
|
||||||
|
b2Body *createBody(const std::shared_ptr<Collectable> &collectable);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //HOLESOME_HOLE_DEPTH_SIMULATION_HPP
|
|
@ -7,8 +7,10 @@
|
||||||
|
|
||||||
#define INITIAL_LEVEL "default"
|
#define INITIAL_LEVEL "default"
|
||||||
|
|
||||||
std::map<std::string, LevelConfig> const LEVELS = {
|
std::map<std::string, LevelConfig> const all_levels = {
|
||||||
{"default", LevelConfig("Default", {25, 25}, {{0, 0}})}
|
{"default", LevelConfig("Default", {25, 25}, {{0, 0}}, {
|
||||||
|
CollectableInLevel("box", {5, 5})
|
||||||
|
})}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //HOLESOME_LEVELS_HPP
|
#endif //HOLESOME_LEVELS_HPP
|
||||||
|
|
|
@ -1,9 +1,5 @@
|
||||||
#include <iostream>
|
|
||||||
#include "logging/easylogging++.h"
|
#include "logging/easylogging++.h"
|
||||||
#include "game/game_factory.hpp"
|
#include "game/game_factory.hpp"
|
||||||
#include "debug/grid_debug_layer.h"
|
|
||||||
#include "game/camera/tracking_view.h"
|
|
||||||
#include "game/player/player_spawner.hpp"
|
|
||||||
#include "sprites/texture_manager.hpp"
|
#include "sprites/texture_manager.hpp"
|
||||||
#include "texture_config.h"
|
#include "texture_config.h"
|
||||||
#include "game/level/level_loader.hpp"
|
#include "game/level/level_loader.hpp"
|
||||||
|
|
Loading…
Reference in a new issue