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/sprites/tiling/tilemap.cpp
|
||||
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
|
||||
src/prototypes/physics_00.cpp)
|
||||
|
|
4
TODO.md
4
TODO.md
|
@ -4,6 +4,10 @@
|
|||
|
||||
- [ ] Split screen
|
||||
|
||||
## Bugs
|
||||
|
||||
- [ ] Player spawns initially at (0,0) and almost fails to jump to target spawn
|
||||
|
||||
## High priority
|
||||
|
||||
- [ ] Procedural level generation
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#define KEY_REPEAT_ENABLED false
|
||||
|
||||
// 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 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_MAX_VIEW_SIZE sf::Vector2f(0, 0)
|
||||
#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
|
||||
#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),
|
||||
trackables({})
|
||||
{
|
||||
;
|
||||
marker = new CircleObject(DB_CIRCLE_RADIUS, sf::Color::Yellow);
|
||||
Game::getInstance()->registerView(this);
|
||||
}
|
||||
|
||||
TrackingView::~TrackingView()
|
||||
|
@ -275,33 +273,6 @@ float TrackingView::getRadius(float threshold) const
|
|||
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(
|
||||
|
|
|
@ -17,8 +17,6 @@ public:
|
|||
|
||||
~TrackingView();
|
||||
|
||||
void update() override;
|
||||
|
||||
void draw(sf::RenderWindow *window) override;
|
||||
|
||||
void lateUpdate() override;
|
||||
|
@ -60,8 +58,6 @@ private:
|
|||
float getRadius(float threshold) const;
|
||||
|
||||
sf::Vector2f getWindowSize() const;
|
||||
|
||||
void addPlayersDynamically();
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -37,11 +37,6 @@ struct TrackingViewOptions
|
|||
* Value between 0 and 1 to setWorld relative 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
|
||||
|
|
|
@ -123,11 +123,6 @@ std::shared_ptr<Game> Game::constructInstance(const std::shared_ptr<sf::RenderWi
|
|||
return singletonInstance;
|
||||
}
|
||||
|
||||
void Game::registerView(TrackingView *view)
|
||||
{
|
||||
views.push_back(view);
|
||||
}
|
||||
|
||||
void Game::clearGameObjects()
|
||||
{
|
||||
gameObjects.clear();
|
||||
|
|
|
@ -32,10 +32,7 @@ public:
|
|||
|
||||
void addGameObject(const std::shared_ptr<GameObject>& gameObject);
|
||||
|
||||
void registerView(TrackingView *view);
|
||||
|
||||
std::shared_ptr<sf::RenderWindow> window;
|
||||
std::vector<TrackingView*> views = {};
|
||||
private:
|
||||
static inline std::shared_ptr<Game> singletonInstance = nullptr;
|
||||
std::vector<std::shared_ptr<GameObject>> gameObjects = {};
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "../physics/hole/hole_depth_simulation.hpp"
|
||||
#include "level_renderer.hpp"
|
||||
#include "../../sprites/skymap/skymap.hpp"
|
||||
#include "../camera/multiplayer_view.hpp"
|
||||
|
||||
void LevelLoader::loadLevel(const LevelConfig &levelConfig)
|
||||
{
|
||||
|
@ -54,7 +55,7 @@ void LevelLoader::loadLevel(const LevelConfig &levelConfig)
|
|||
game->addGameObject(MapSimulation::getInstance());
|
||||
|
||||
// Add views
|
||||
game->addGameObject(std::make_shared<TrackingView>());
|
||||
game->addGameObject(std::make_shared<MultiplayerView>());
|
||||
|
||||
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);
|
||||
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);
|
||||
|
||||
std::vector<std::shared_ptr<Player>> getPlayers() const;
|
||||
|
||||
std::vector<std::shared_ptr<Player>> getNewPlayers() const;
|
||||
|
||||
std::vector<std::shared_ptr<Player>> getRemovedPlayers() const;
|
||||
|
|
Loading…
Reference in a new issue