Multiplayer viewports rendering now
This commit is contained in:
parent
1aae9e6cb6
commit
26561f5d13
7 changed files with 95 additions and 13 deletions
|
@ -51,11 +51,10 @@ void MultiplayerView::addPlayer(const std::shared_ptr<Player> &player)
|
|||
// Create new view
|
||||
auto view = std::make_shared<TrackingView>();
|
||||
view->addTrackable(player);
|
||||
|
||||
// TODO: Set viewport
|
||||
|
||||
viewsForPlayers[player->getPlayerId()] = view;
|
||||
addChild(view);
|
||||
|
||||
updateLayout();
|
||||
}
|
||||
|
||||
void MultiplayerView::removePlayer(const std::shared_ptr<Player> &player)
|
||||
|
@ -76,3 +75,60 @@ void MultiplayerView::removePlayer(const std::shared_ptr<Player> &player)
|
|||
view->addTrackable(remainingPlayers);
|
||||
}
|
||||
}
|
||||
|
||||
void MultiplayerView::updateLayout() const
|
||||
{
|
||||
if (viewsForPlayers.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int viewCount = viewsForPlayers.size();
|
||||
|
||||
// Handle simple cases
|
||||
if (viewCount == 1)
|
||||
{
|
||||
viewsForPlayers.begin()->second->setViewport({0, 0}, {1, 1});
|
||||
return;
|
||||
}
|
||||
if (viewCount == 2)
|
||||
{
|
||||
auto it = viewsForPlayers.begin();
|
||||
it->second->setViewport({0, 0}, {0.5, 1});
|
||||
it++;
|
||||
it->second->setViewport({0.5, 0}, {0.5, 1});
|
||||
return;
|
||||
}
|
||||
|
||||
// Calculate layout
|
||||
int firstRowViewCount = ceil(viewCount / 2.f);
|
||||
int secondRowViewCount = viewCount - firstRowViewCount;
|
||||
int index = 0;
|
||||
for (auto &view: getViews())
|
||||
{
|
||||
bool secondRow = index >= viewCount / 2.f;
|
||||
int rowViewCount = secondRow ? secondRowViewCount : firstRowViewCount;
|
||||
int rowIndexOfView = index - (secondRow ? firstRowViewCount : 0);
|
||||
|
||||
view->setViewport(
|
||||
{
|
||||
rowIndexOfView / (float) rowViewCount,
|
||||
secondRow ? 0.5f : 0
|
||||
}, {
|
||||
1.f / rowViewCount,
|
||||
0.5f
|
||||
}
|
||||
);
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<TrackingView>> MultiplayerView::getViews() const
|
||||
{
|
||||
std::vector<std::shared_ptr<TrackingView>> views;
|
||||
for (const auto &[_, view]: viewsForPlayers)
|
||||
{
|
||||
views.push_back(view);
|
||||
}
|
||||
return views;
|
||||
}
|
||||
|
|
|
@ -20,10 +20,13 @@ public:
|
|||
|
||||
void removePlayer(const std::shared_ptr<Player>& player);
|
||||
|
||||
std::vector<std::shared_ptr<TrackingView>> getViews() const;
|
||||
|
||||
private:
|
||||
static inline std::shared_ptr<MultiplayerView> singletonInstance = nullptr;
|
||||
|
||||
std::map<int, std::shared_ptr<TrackingView>> viewsForPlayers; // Player ID => View
|
||||
void updateLayout() const;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ TrackingView::TrackingView(TrackingViewOptions options) : options(options),
|
|||
hasViewChanged(false),
|
||||
trackables({})
|
||||
{
|
||||
initializeView();
|
||||
marker = new CircleObject(DB_CIRCLE_RADIUS, sf::Color::Yellow);
|
||||
}
|
||||
|
||||
|
@ -18,12 +19,6 @@ TrackingView::~TrackingView()
|
|||
|
||||
void TrackingView::lateUpdate()
|
||||
{
|
||||
// Initialize if necessary
|
||||
if (view == nullptr)
|
||||
{
|
||||
initializeView();
|
||||
}
|
||||
|
||||
processTrackableStates();
|
||||
|
||||
if (!trackables.empty())
|
||||
|
@ -35,7 +30,7 @@ void TrackingView::lateUpdate()
|
|||
// Update window if necessary
|
||||
if (hasViewChanged)
|
||||
{
|
||||
Game::getInstance()->window->setView(*this->view);
|
||||
this->setViewForWindow();
|
||||
hasViewChanged = false;
|
||||
}
|
||||
}
|
||||
|
@ -281,3 +276,14 @@ void TrackingView::removeTrackable(const std::shared_ptr<ITrackable> &trackable)
|
|||
return t == trackable;
|
||||
}), trackables.end());
|
||||
}
|
||||
|
||||
void TrackingView::setViewport(sf::Vector2f center, sf::Vector2f size)
|
||||
{
|
||||
// TODO: Resize content for viewport
|
||||
view->setViewport(sf::FloatRect(center.x, center.y, size.x, size.y));
|
||||
}
|
||||
|
||||
void TrackingView::setViewForWindow()
|
||||
{
|
||||
Game::getInstance()->window->setView(*this->view);
|
||||
}
|
||||
|
|
|
@ -25,6 +25,10 @@ public:
|
|||
|
||||
void removeTrackable(const std::shared_ptr<ITrackable> &trackable);
|
||||
|
||||
void setViewport(sf::Vector2f center, sf::Vector2f size);
|
||||
|
||||
void setViewForWindow();
|
||||
|
||||
sf::Vector2f getSize() const;
|
||||
|
||||
sf::Vector2f getCenter() const;
|
||||
|
|
|
@ -22,6 +22,9 @@ void LevelLoader::loadLevel(const LevelConfig &levelConfig)
|
|||
MapSimulation::getInstance()->resetMap(levelConfig.worldMapSize);
|
||||
PlayerCollection::getInstance()->clear();
|
||||
|
||||
// Add views
|
||||
game->addGameObject(MultiplayerView::getInstance());
|
||||
|
||||
// Add rendered level objects
|
||||
std::shared_ptr<LevelRenderer> levelRenderer = std::make_shared<LevelRenderer>();
|
||||
game->addGameObject(levelRenderer);
|
||||
|
@ -54,9 +57,6 @@ void LevelLoader::loadLevel(const LevelConfig &levelConfig)
|
|||
// Add physics simulations
|
||||
game->addGameObject(MapSimulation::getInstance());
|
||||
|
||||
// Add views
|
||||
game->addGameObject(std::make_shared<MultiplayerView>());
|
||||
|
||||
LOG(INFO) << "Finished loading level '" << levelConfig.name << "'.";
|
||||
}
|
||||
|
||||
|
|
|
@ -1 +1,12 @@
|
|||
#include "level_renderer.hpp"
|
||||
#include "../camera/multiplayer_view.hpp"
|
||||
#include "../../logging/easylogging++.h"
|
||||
|
||||
void LevelRenderer::draw(sf::RenderWindow *window)
|
||||
{
|
||||
for(auto &view : MultiplayerView::getInstance()->getViews())
|
||||
{
|
||||
view->setViewForWindow();
|
||||
GameObject::draw(window);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
class LevelRenderer : public GameObject
|
||||
{
|
||||
public:
|
||||
void draw(sf::RenderWindow *window) override;
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue