Basic multiplayer view scaffolding
This commit is contained in:
parent
62f69a7593
commit
1aae9e6cb6
13 changed files with 134 additions and 50 deletions
|
@ -98,7 +98,7 @@ set(SOURCES
|
||||||
src/levels.hpp
|
src/levels.hpp
|
||||||
src/sprites/tiling/tilemap.cpp
|
src/sprites/tiling/tilemap.cpp
|
||||||
src/sprites/tiling/tilemap.hpp
|
src/sprites/tiling/tilemap.hpp
|
||||||
src/sprites/tiling/tilemap_config.hpp src/sprites/tiling/tileset_config.hpp src/sprites/tiling/tileset.cpp src/sprites/tiling/tileset.hpp src/game/frame_counter.cpp src/game/frame_counter.hpp src/game/level/level_renderer.cpp src/game/level/level_renderer.hpp src/sprites/skymap/skymap.cpp src/sprites/skymap/skymap.hpp)
|
src/sprites/tiling/tilemap_config.hpp src/sprites/tiling/tileset_config.hpp src/sprites/tiling/tileset.cpp src/sprites/tiling/tileset.hpp src/game/frame_counter.cpp src/game/frame_counter.hpp src/game/level/level_renderer.cpp src/game/level/level_renderer.hpp src/sprites/skymap/skymap.cpp src/sprites/skymap/skymap.hpp src/game/camera/multiplayer_view.cpp src/game/camera/multiplayer_view.hpp)
|
||||||
|
|
||||||
set(PHYSICS_00_SOURCES
|
set(PHYSICS_00_SOURCES
|
||||||
src/prototypes/physics_00.cpp)
|
src/prototypes/physics_00.cpp)
|
||||||
|
|
4
TODO.md
4
TODO.md
|
@ -4,6 +4,10 @@
|
||||||
|
|
||||||
- [ ] Split screen
|
- [ ] Split screen
|
||||||
|
|
||||||
|
## Bugs
|
||||||
|
|
||||||
|
- [ ] Player spawns initially at (0,0) and almost fails to jump to target spawn
|
||||||
|
|
||||||
## High priority
|
## High priority
|
||||||
|
|
||||||
- [ ] Procedural level generation
|
- [ ] Procedural level generation
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
#define KEY_REPEAT_ENABLED false
|
#define KEY_REPEAT_ENABLED false
|
||||||
|
|
||||||
// Graphic settings
|
// Graphic settings
|
||||||
#define ISOMETRIC_SKEW (15.f/32.f)
|
#define ISOMETRIC_SKEW (16.f/32.f)
|
||||||
#define MOVEMENT_SKEW sf::Vector2f(1.f, 1/ISOMETRIC_SKEW/2.f)
|
#define MOVEMENT_SKEW sf::Vector2f(1.f, 1/ISOMETRIC_SKEW/2.f)
|
||||||
#define WORLD_TO_ISO_SCALE 50.0f // 50.f, don't change. Rather adjust the zoom of the camera
|
#define WORLD_TO_ISO_SCALE 50.0f // 50.f, don't change. Rather adjust the zoom of the camera
|
||||||
|
|
||||||
|
@ -35,7 +35,8 @@
|
||||||
#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
|
#define MP_VIEW_ADD_NEW_PLAYERS true
|
||||||
|
#define MP_VIEW_REMOVE_DISCONNECTED_PLAYERS true
|
||||||
|
|
||||||
// Simulations
|
// Simulations
|
||||||
#define MAPSIM_WALL_THICKNESS 3.f
|
#define MAPSIM_WALL_THICKNESS 3.f
|
||||||
|
|
78
src/game/camera/multiplayer_view.cpp
Normal file
78
src/game/camera/multiplayer_view.cpp
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
#include "multiplayer_view.hpp"
|
||||||
|
#include "../player/player_collection.hpp"
|
||||||
|
#include "ITrackable.h"
|
||||||
|
|
||||||
|
std::shared_ptr<MultiplayerView> MultiplayerView::getInstance()
|
||||||
|
{
|
||||||
|
if (singletonInstance == nullptr)
|
||||||
|
{
|
||||||
|
singletonInstance = std::make_shared<MultiplayerView>();
|
||||||
|
}
|
||||||
|
|
||||||
|
return singletonInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MultiplayerView::update()
|
||||||
|
{
|
||||||
|
// Update based on PlayerCollection
|
||||||
|
// Add new
|
||||||
|
if (MP_VIEW_ADD_NEW_PLAYERS)
|
||||||
|
{
|
||||||
|
for (const auto &player: PlayerCollection::getInstance()->getNewPlayers())
|
||||||
|
{
|
||||||
|
if (player->getTrackableState() == TrackableState::TRACKING)
|
||||||
|
{
|
||||||
|
addPlayer(player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove old
|
||||||
|
if (MP_VIEW_REMOVE_DISCONNECTED_PLAYERS)
|
||||||
|
{
|
||||||
|
for (const auto &player: PlayerCollection::getInstance()->getRemovedPlayers())
|
||||||
|
{
|
||||||
|
removePlayer(player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GameObject::update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MultiplayerView::addPlayer(const std::shared_ptr<Player> &player)
|
||||||
|
{
|
||||||
|
// Player already added?
|
||||||
|
if (viewsForPlayers.find(player->getPlayerId()) != viewsForPlayers.end())
|
||||||
|
{
|
||||||
|
LOG(WARNING) << "Player " << player->getPlayerId() << " already added to MultiplayerView.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create new view
|
||||||
|
auto view = std::make_shared<TrackingView>();
|
||||||
|
view->addTrackable(player);
|
||||||
|
|
||||||
|
// TODO: Set viewport
|
||||||
|
|
||||||
|
viewsForPlayers[player->getPlayerId()] = view;
|
||||||
|
addChild(view);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MultiplayerView::removePlayer(const std::shared_ptr<Player> &player)
|
||||||
|
{
|
||||||
|
// Player already removed?
|
||||||
|
if (viewsForPlayers.find(player->getPlayerId()) == viewsForPlayers.end())
|
||||||
|
{
|
||||||
|
LOG(WARNING) << "Player " << player->getPlayerId() << " already removed from MultiplayerView.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make view show all remaining players
|
||||||
|
auto view = viewsForPlayers[player->getPlayerId()];
|
||||||
|
view->removeTrackable(player);
|
||||||
|
|
||||||
|
for (const auto &remainingPlayers: PlayerCollection::getInstance()->getPlayers())
|
||||||
|
{
|
||||||
|
view->addTrackable(remainingPlayers);
|
||||||
|
}
|
||||||
|
}
|
30
src/game/camera/multiplayer_view.hpp
Normal file
30
src/game/camera/multiplayer_view.hpp
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
#ifndef HOLESOME_MULTIPLAYER_VIEW_HPP
|
||||||
|
#define HOLESOME_MULTIPLAYER_VIEW_HPP
|
||||||
|
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include "../game_object.h"
|
||||||
|
#include "tracking_view.h"
|
||||||
|
#include "../player/player.hpp"
|
||||||
|
|
||||||
|
class MultiplayerView : public GameObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static std::shared_ptr<MultiplayerView> getInstance();
|
||||||
|
|
||||||
|
MultiplayerView() = default;
|
||||||
|
|
||||||
|
void update() override;
|
||||||
|
|
||||||
|
void addPlayer(const std::shared_ptr<Player>& player);
|
||||||
|
|
||||||
|
void removePlayer(const std::shared_ptr<Player>& player);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static inline std::shared_ptr<MultiplayerView> singletonInstance = nullptr;
|
||||||
|
|
||||||
|
std::map<int, std::shared_ptr<TrackingView>> viewsForPlayers; // Player ID => View
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif //HOLESOME_MULTIPLAYER_VIEW_HPP
|
|
@ -7,9 +7,7 @@ TrackingView::TrackingView(TrackingViewOptions options) : options(options),
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TrackingView::~TrackingView()
|
TrackingView::~TrackingView()
|
||||||
|
@ -275,33 +273,6 @@ float TrackingView::getRadius(float threshold) const
|
||||||
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)
|
void TrackingView::removeTrackable(const std::shared_ptr<ITrackable> &trackable)
|
||||||
{
|
{
|
||||||
trackables.erase(
|
trackables.erase(
|
||||||
|
|
|
@ -17,8 +17,6 @@ public:
|
||||||
|
|
||||||
~TrackingView();
|
~TrackingView();
|
||||||
|
|
||||||
void update() override;
|
|
||||||
|
|
||||||
void draw(sf::RenderWindow *window) override;
|
void draw(sf::RenderWindow *window) override;
|
||||||
|
|
||||||
void lateUpdate() override;
|
void lateUpdate() override;
|
||||||
|
@ -60,8 +58,6 @@ private:
|
||||||
float getRadius(float threshold) const;
|
float getRadius(float threshold) const;
|
||||||
|
|
||||||
sf::Vector2f getWindowSize() const;
|
sf::Vector2f getWindowSize() const;
|
||||||
|
|
||||||
void addPlayersDynamically();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -37,11 +37,6 @@ struct TrackingViewOptions
|
||||||
* Value between 0 and 1 to setWorld relative padding.
|
* Value between 0 and 1 to setWorld relative padding.
|
||||||
*/
|
*/
|
||||||
sf::Vector2f viewSizePadding = DEF_TV_VIEW_SIZE_PADDING;
|
sf::Vector2f viewSizePadding = DEF_TV_VIEW_SIZE_PADDING;
|
||||||
|
|
||||||
/**
|
|
||||||
* If setWorld 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
|
||||||
|
|
|
@ -123,11 +123,6 @@ std::shared_ptr<Game> Game::constructInstance(const std::shared_ptr<sf::RenderWi
|
||||||
return singletonInstance;
|
return singletonInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Game::registerView(TrackingView *view)
|
|
||||||
{
|
|
||||||
views.push_back(view);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Game::clearGameObjects()
|
void Game::clearGameObjects()
|
||||||
{
|
{
|
||||||
gameObjects.clear();
|
gameObjects.clear();
|
||||||
|
|
|
@ -32,10 +32,7 @@ public:
|
||||||
|
|
||||||
void addGameObject(const std::shared_ptr<GameObject>& gameObject);
|
void addGameObject(const std::shared_ptr<GameObject>& gameObject);
|
||||||
|
|
||||||
void registerView(TrackingView *view);
|
|
||||||
|
|
||||||
std::shared_ptr<sf::RenderWindow> window;
|
std::shared_ptr<sf::RenderWindow> window;
|
||||||
std::vector<TrackingView*> views = {};
|
|
||||||
private:
|
private:
|
||||||
static inline std::shared_ptr<Game> singletonInstance = nullptr;
|
static inline std::shared_ptr<Game> singletonInstance = nullptr;
|
||||||
std::vector<std::shared_ptr<GameObject>> gameObjects = {};
|
std::vector<std::shared_ptr<GameObject>> gameObjects = {};
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include "../physics/hole/hole_depth_simulation.hpp"
|
#include "../physics/hole/hole_depth_simulation.hpp"
|
||||||
#include "level_renderer.hpp"
|
#include "level_renderer.hpp"
|
||||||
#include "../../sprites/skymap/skymap.hpp"
|
#include "../../sprites/skymap/skymap.hpp"
|
||||||
|
#include "../camera/multiplayer_view.hpp"
|
||||||
|
|
||||||
void LevelLoader::loadLevel(const LevelConfig &levelConfig)
|
void LevelLoader::loadLevel(const LevelConfig &levelConfig)
|
||||||
{
|
{
|
||||||
|
@ -54,7 +55,7 @@ void LevelLoader::loadLevel(const LevelConfig &levelConfig)
|
||||||
game->addGameObject(MapSimulation::getInstance());
|
game->addGameObject(MapSimulation::getInstance());
|
||||||
|
|
||||||
// Add views
|
// Add views
|
||||||
game->addGameObject(std::make_shared<TrackingView>());
|
game->addGameObject(std::make_shared<MultiplayerView>());
|
||||||
|
|
||||||
LOG(INFO) << "Finished loading level '" << levelConfig.name << "'.";
|
LOG(INFO) << "Finished loading level '" << levelConfig.name << "'.";
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,3 +104,17 @@ void PlayerCollection::spawnPlayer(const std::shared_ptr<InputIdentity> &inputId
|
||||||
auto player = std::make_shared<Player>(inputIdentity, PLAYER_SKIN, spawn);
|
auto player = std::make_shared<Player>(inputIdentity, PLAYER_SKIN, spawn);
|
||||||
PlayerCollection::getInstance()->addPlayer(player);
|
PlayerCollection::getInstance()->addPlayer(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<std::shared_ptr<Player>> PlayerCollection::getPlayers() const
|
||||||
|
{
|
||||||
|
std::vector<std::shared_ptr<Player>> players = {};
|
||||||
|
for (auto &child: getChildren())
|
||||||
|
{
|
||||||
|
auto player = std::dynamic_pointer_cast<Player>(child);
|
||||||
|
if (player != nullptr)
|
||||||
|
{
|
||||||
|
players.push_back(player);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return players;
|
||||||
|
}
|
||||||
|
|
|
@ -18,6 +18,8 @@ public:
|
||||||
|
|
||||||
void removePlayer(const std::shared_ptr<Player>& player);
|
void removePlayer(const std::shared_ptr<Player>& player);
|
||||||
|
|
||||||
|
std::vector<std::shared_ptr<Player>> getPlayers() const;
|
||||||
|
|
||||||
std::vector<std::shared_ptr<Player>> getNewPlayers() const;
|
std::vector<std::shared_ptr<Player>> getNewPlayers() const;
|
||||||
|
|
||||||
std::vector<std::shared_ptr<Player>> getRemovedPlayers() const;
|
std::vector<std::shared_ptr<Player>> getRemovedPlayers() const;
|
||||||
|
|
Loading…
Reference in a new issue