Implemented join screen

This commit is contained in:
Maximilian Giller 2023-07-09 23:51:34 +02:00
parent 24cc3cfd6b
commit 15c9632941
26 changed files with 369 additions and 50 deletions

View file

@ -138,7 +138,7 @@ set(SOURCES
src/typography/font_manager.cpp src/typography/font_manager.cpp
src/typography/font_manager.hpp src/typography/font_manager.hpp
src/screens/winner_screen.cpp src/screens/winner_screen.cpp
src/screens/winner_screen.hpp src/screens/screen.cpp src/screens/screen.hpp) src/screens/winner_screen.hpp src/screens/screen.cpp src/screens/screen.hpp src/screens/join_screen.cpp src/screens/join_screen.hpp)
set(PHYSICS_00_SOURCES set(PHYSICS_00_SOURCES
src/prototypes/physics_00.cpp) src/prototypes/physics_00.cpp)

Binary file not shown.

After

Width:  |  Height:  |  Size: 630 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

BIN
assets/grass-tiles.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

BIN
assets/player/player-0.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

BIN
assets/player/player-1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
assets/player/player-2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

BIN
assets/player/player-3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

BIN
assets/player/player.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View file

@ -9,9 +9,10 @@ std::map<std::string, CollectableConfig> const all_collectables = {
{"rose", CollectableConfig("rose", 1)}, {"rose", CollectableConfig("rose", 1)},
{"rosebush", CollectableConfig("rosebush", 3)}, {"rosebush", CollectableConfig("rosebush", 3)},
{"stone", CollectableConfig("stone", 5)}, {"stone", CollectableConfig("stone", 5)},
{"bike", CollectableConfig("bike", 10)}, {"bike", CollectableConfig("bike", 15)},
{"small-tree", CollectableConfig("small-tree", 20)}, {"small-tree", CollectableConfig("small-tree", 20)},
{"tram", CollectableConfig("tram", 50)} {"tram", CollectableConfig("tram", 50)},
{"lantern", CollectableConfig("lantern", 10)}
}; };
#endif //HOLESOME_COLLECTABLES_HPP #endif //HOLESOME_COLLECTABLES_HPP

View file

@ -6,12 +6,15 @@
#define DEVELOPER_MODE true #define DEVELOPER_MODE true
#define GAME_NAME "Holesome"
// Player // Player
#define DEFAULT_PLAYER_SPEED 5.f // World units per second #define DEFAULT_PLAYER_SPEED 5.f // World units per second
#define DEFAULT_PLAYER_POINTS 0 #define DEFAULT_PLAYER_POINTS 0
#define PLAYER_MIN_RADIUS 0.5f // World units #define PLAYER_MIN_RADIUS 0.5f // World units
#define PLAYER_RADIUS_PER_LEVEL 0.25f #define PLAYER_RADIUS_PER_LEVEL 0.25f
#define DEFAULT_MAX_PLAYER_NUMBER 4 #define DEFAULT_MAX_PLAYER_NUMBER 4
#define MIN_PLAYER_COUNT 2
// World // World
#define WORLD_GRAVITY b2Vec2(0.f, -9.8f) #define WORLD_GRAVITY b2Vec2(0.f, -9.8f)

View file

@ -9,6 +9,7 @@
#include "layer/global_layer.hpp" #include "layer/global_layer.hpp"
#include "player/player_collection.hpp" #include "player/player_collection.hpp"
#include "../screens/winner_screen.hpp" #include "../screens/winner_screen.hpp"
#include "../screens/join_screen.hpp"
Game::Game(std::shared_ptr<sf::RenderWindow> window) : window(std::move(window)) Game::Game(std::shared_ptr<sf::RenderWindow> window) : window(std::move(window))
{ {
@ -207,3 +208,13 @@ void Game::handleWinning()
GlobalLayer::getInstance()->add(winnerScreen); GlobalLayer::getInstance()->add(winnerScreen);
addGameObject(GlobalLayer::getInstance()); addGameObject(GlobalLayer::getInstance());
} }
void Game::showJoinScreen()
{
InputMapper::getInstance()->allowNewInputIdentities = true;
auto joinScreen = std::make_shared<JoinScreen>();
GlobalLayer::getInstance()->add(joinScreen);
addGameObject(GlobalLayer::getInstance());
PlayerCollection::getInstance()->deactivatePlayers();
addGameObject(PlayerCollection::getInstance());
}

View file

@ -38,6 +38,9 @@ public:
void addGameObject(const std::shared_ptr<GameObject> &gameObject); void addGameObject(const std::shared_ptr<GameObject> &gameObject);
std::shared_ptr<sf::RenderWindow> window; std::shared_ptr<sf::RenderWindow> window;
void showJoinScreen();
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 = {};

View file

@ -3,12 +3,7 @@
enum GameAction enum GameAction
{ {
CONFIRM, CONFIRM
CANCEL,
MENU,
GROW,
SHRINK
}; };
#endif //HOLESOME_GAME_ACTION_HPP #endif //HOLESOME_GAME_ACTION_HPP

View file

@ -21,12 +21,15 @@ void LevelLoader::loadLevel(const LevelConfig &levelConfig)
LOG(INFO) << "Loading level '" << levelConfig.name << "' ..."; LOG(INFO) << "Loading level '" << levelConfig.name << "' ...";
game->setLevel(levelConfig); game->setLevel(levelConfig);
InputMapper::getInstance()->allowNewInputIdentities = false;
PlayerCollection::getInstance()->activatePlayers();
MapSimulation::getInstance()->resetMap(levelConfig.worldMapSize); MapSimulation::getInstance()->resetMap(levelConfig.worldMapSize);
HolesSimulation::getInstance()->clear(); HolesSimulation::getInstance()->clear();
PlayerCollection::getInstance()->clear();
GlobalLayer::getInstance()->clear(); GlobalLayer::getInstance()->clear();
HoleLayout::getInstance()->clear(); HoleLayout::getInstance()->clear();
// Add views // Add views
game->addGameObject(MultiplayerView::getInstance()); game->addGameObject(MultiplayerView::getInstance());

View file

@ -5,7 +5,7 @@
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) : spawnPosition(initCoordinates), skinName(skinRessourceName)
{ {
playerId = playerCreationCounter++; playerId = playerCreationCounter++;
coordinates->setTranslated(spawnPosition); coordinates->setTranslated(spawnPosition);
@ -37,9 +37,9 @@ void Player::update()
return; return;
} }
auto moveDirection = input->direction.asIsometricVector(); if (!passiveMode) {
auto moveDelta = moveDirection * speed * FRAME_TIME.asSeconds(); performInteractiveUpdates();
coordinates->move(moveDelta); }
GameObject::update(); GameObject::update();
} }
@ -103,3 +103,25 @@ void Player::consume(int points)
updateRadiusBasedOnPoints(); updateRadiusBasedOnPoints();
} }
std::string Player::getSkinName() const
{
return skinName;
}
std::shared_ptr<InputIdentity> Player::getInput() const
{
return input;
}
void Player::setPassiveMode(bool newPassiveMode)
{
passiveMode = newPassiveMode;
}
void Player::performInteractiveUpdates()
{
auto moveDirection = input->direction.asIsometricVector();
auto moveDelta = moveDirection * speed * FRAME_TIME.asSeconds();
coordinates->move(moveDelta);
}

View file

@ -33,12 +33,22 @@ public:
void consume(int points); void consume(int points);
std::string getSkinName() const;
std::shared_ptr<InputIdentity> getInput() const;
void setPassiveMode(bool newPassiveMode);
TranslatedCoordinates spawnPosition; TranslatedCoordinates spawnPosition;
private: private:
std::shared_ptr<InputIdentity> input; std::shared_ptr<InputIdentity> input;
float radiusInWorld = 0.5f; // In world units float radiusInWorld = 0.5f; // In world units
std::shared_ptr<VersatileSprite> skinSprite; std::shared_ptr<VersatileSprite> skinSprite;
bool passiveMode = true;
std::string skinName;
long points = DEFAULT_PLAYER_POINTS; long points = DEFAULT_PLAYER_POINTS;
int playerId; int playerId;
@ -47,6 +57,8 @@ private:
void setWorldRadius(float newWorldRadius); void setWorldRadius(float newWorldRadius);
void updateRadiusBasedOnPoints(); void updateRadiusBasedOnPoints();
void performInteractiveUpdates();
}; };

View file

@ -35,6 +35,8 @@ void PlayerCollection::addPlayer(const std::shared_ptr<Player> &player)
void PlayerCollection::clear() void PlayerCollection::clear()
{ {
takenSkinIndices.clear();
newPlayerBuffer.clear(); newPlayerBuffer.clear();
removedPlayerBuffer.clear(); removedPlayerBuffer.clear();
@ -97,6 +99,16 @@ void PlayerCollection::setSpawnPoints(std::vector<GridCoordinates> newSpawnPoint
{ {
this->spawnPoints = std::move(newSpawnPoints); this->spawnPoints = std::move(newSpawnPoints);
nextSpawnPointIndex = 0; nextSpawnPointIndex = 0;
// Go through all players and update their spawn points
for (auto &player: getPlayers())
{
auto spawn = spawnPoints[nextSpawnPointIndex];
nextSpawnPointIndex = static_cast<int>((nextSpawnPointIndex + 1) % spawnPoints.size());
player->spawnPosition = TranslatedCoordinates(spawn);
player->coordinates->setGrid(spawn);
}
} }
void PlayerCollection::spawnPlayer(const std::shared_ptr<InputIdentity> &inputIdentity) void PlayerCollection::spawnPlayer(const std::shared_ptr<InputIdentity> &inputIdentity)
@ -105,7 +117,7 @@ void PlayerCollection::spawnPlayer(const std::shared_ptr<InputIdentity> &inputId
auto spawn = spawnPoints[nextSpawnPointIndex]; auto spawn = spawnPoints[nextSpawnPointIndex];
nextSpawnPointIndex = static_cast<int>((nextSpawnPointIndex + 1) % spawnPoints.size()); nextSpawnPointIndex = static_cast<int>((nextSpawnPointIndex + 1) % spawnPoints.size());
auto player = std::make_shared<Player>(inputIdentity, PLAYER_SKIN, spawn); auto player = std::make_shared<Player>(inputIdentity, getNextSkin(), spawn);
addPlayer(player); addPlayer(player);
} }
@ -145,7 +157,7 @@ void PlayerCollection::updateInputIdentityAllowance() const
InputMapper::getInstance()->allowNewInputIdentities = getPlayers().size() < maxPlayerCount; InputMapper::getInstance()->allowNewInputIdentities = getPlayers().size() < maxPlayerCount;
} }
std::shared_ptr<Player> PlayerCollection::getClosestPlayer(const TranslatedCoordinates& point) const std::shared_ptr<Player> PlayerCollection::getClosestPlayer(const TranslatedCoordinates &point) const
{ {
std::shared_ptr<Player> closestPlayer = nullptr; std::shared_ptr<Player> closestPlayer = nullptr;
float closestDistance = INFINITY; float closestDistance = INFINITY;
@ -163,3 +175,55 @@ std::shared_ptr<Player> PlayerCollection::getClosestPlayer(const TranslatedCoord
} }
return closestPlayer; return closestPlayer;
} }
std::string PlayerCollection::getNextSkin()
{
int numberOfSkins = static_cast<int>(PLAYER_SKINS.size());
// Count how often each skin index is taken
std::map<int, int> skinIndexCount;
for (int i = 0; i < numberOfSkins; i++)
{
skinIndexCount[i] = 0;
for (auto &takenSkinIndex: takenSkinIndices)
{
if (takenSkinIndex == i)
{
skinIndexCount[i]++;
}
}
}
// Find skin index with lowest count
int skinIndex = takenSkinIndices.size() % numberOfSkins;
int lowestCount = takenSkinIndices.size();
for (auto &pair: skinIndexCount)
{
if (pair.second < lowestCount)
{
lowestCount = pair.second;
skinIndex = pair.first;
}
}
takenSkinIndices.push_back(skinIndex);
return PLAYER_SKINS[skinIndex];
}
void PlayerCollection::activatePlayers()
{
for (auto player: getPlayers())
{
player->setPassiveMode(false);
newPlayerBuffer.push_back(player);
}
}
void PlayerCollection::deactivatePlayers()
{
for (auto player: getPlayers())
{
player->setPassiveMode(true);
}
}

View file

@ -34,6 +34,9 @@ public:
void clear(); void clear();
void activatePlayers();
void deactivatePlayers();
private: private:
static inline std::shared_ptr<PlayerCollection> singletonInstance = nullptr; static inline std::shared_ptr<PlayerCollection> singletonInstance = nullptr;
@ -45,6 +48,10 @@ private:
void spawnPlayer(const std::shared_ptr<InputIdentity> &inputIdentity); void spawnPlayer(const std::shared_ptr<InputIdentity> &inputIdentity);
std::vector<int> takenSkinIndices = {};
std::string getNextSkin();
int maxPlayerCount; int maxPlayerCount;
void updateInputIdentityAllowance() const; void updateInputIdentityAllowance() const;

View file

@ -3,6 +3,7 @@
#include <map> #include <map>
#include <string>
#include "game/input/input_device_group.h" #include "game/input/input_device_group.h"
#include "game/input/button_config.hpp" #include "game/input/button_config.hpp"
#include "game/input/game_action_config.hpp" #include "game/input/game_action_config.hpp"
@ -17,36 +18,48 @@ const std::map<sf::Keyboard::Key, ButtonConfig> KEY_CONFIGS = {
{sf::Keyboard::Down, ButtonConfig(InputDeviceGroup::KEYBOARD_ARROWS, HardDirection::DOWN)}, {sf::Keyboard::Down, ButtonConfig(InputDeviceGroup::KEYBOARD_ARROWS, HardDirection::DOWN)},
{sf::Keyboard::Left, ButtonConfig(InputDeviceGroup::KEYBOARD_ARROWS, HardDirection::LEFT)}, {sf::Keyboard::Left, ButtonConfig(InputDeviceGroup::KEYBOARD_ARROWS, HardDirection::LEFT)},
{sf::Keyboard::Right, ButtonConfig(InputDeviceGroup::KEYBOARD_ARROWS, HardDirection::RIGHT)}, {sf::Keyboard::Right, ButtonConfig(InputDeviceGroup::KEYBOARD_ARROWS, HardDirection::RIGHT)},
{sf::Keyboard::RControl, ButtonConfig(InputDeviceGroup::KEYBOARD_ARROWS, {GameAction::GROW})}, {sf::Keyboard::Space, ButtonConfig(InputDeviceGroup::KEYBOARD_ARROWS, {GameAction::CONFIRM})},
{sf::Keyboard::Numpad0, ButtonConfig(InputDeviceGroup::KEYBOARD_ARROWS, {GameAction::SHRINK})},
{sf::Keyboard::W, ButtonConfig(InputDeviceGroup::KEYBOARD_WASD, HardDirection::UP)}, {sf::Keyboard::W, ButtonConfig(InputDeviceGroup::KEYBOARD_WASD, HardDirection::UP)},
{sf::Keyboard::S, ButtonConfig(InputDeviceGroup::KEYBOARD_WASD, HardDirection::DOWN)}, {sf::Keyboard::S, ButtonConfig(InputDeviceGroup::KEYBOARD_WASD, HardDirection::DOWN)},
{sf::Keyboard::A, ButtonConfig(InputDeviceGroup::KEYBOARD_WASD, HardDirection::LEFT)}, {sf::Keyboard::A, ButtonConfig(InputDeviceGroup::KEYBOARD_WASD, HardDirection::LEFT)},
{sf::Keyboard::D, ButtonConfig(InputDeviceGroup::KEYBOARD_WASD, HardDirection::RIGHT)}, {sf::Keyboard::D, ButtonConfig(InputDeviceGroup::KEYBOARD_WASD, HardDirection::RIGHT)},
{sf::Keyboard::Space, ButtonConfig(InputDeviceGroup::KEYBOARD_WASD, {GameAction::GROW})}, {sf::Keyboard::Q, ButtonConfig(InputDeviceGroup::KEYBOARD_WASD, {GameAction::CONFIRM})},
{sf::Keyboard::Q, ButtonConfig(InputDeviceGroup::KEYBOARD_WASD, {GameAction::SHRINK})}, {sf::Keyboard::E, ButtonConfig(InputDeviceGroup::KEYBOARD_WASD, {GameAction::CONFIRM})},
{sf::Keyboard::I, ButtonConfig(InputDeviceGroup::KEYBOARD_IJKL, HardDirection::UP)}, {sf::Keyboard::I, ButtonConfig(InputDeviceGroup::KEYBOARD_IJKL, HardDirection::UP)},
{sf::Keyboard::K, ButtonConfig(InputDeviceGroup::KEYBOARD_IJKL, HardDirection::DOWN)}, {sf::Keyboard::K, ButtonConfig(InputDeviceGroup::KEYBOARD_IJKL, HardDirection::DOWN)},
{sf::Keyboard::J, ButtonConfig(InputDeviceGroup::KEYBOARD_IJKL, HardDirection::LEFT)}, {sf::Keyboard::J, ButtonConfig(InputDeviceGroup::KEYBOARD_IJKL, HardDirection::LEFT)},
{sf::Keyboard::L, ButtonConfig(InputDeviceGroup::KEYBOARD_IJKL, HardDirection::RIGHT)}, {sf::Keyboard::L, ButtonConfig(InputDeviceGroup::KEYBOARD_IJKL, HardDirection::RIGHT)},
{sf::Keyboard::U, ButtonConfig(InputDeviceGroup::KEYBOARD_IJKL, {GameAction::GROW})}, {sf::Keyboard::U, ButtonConfig(InputDeviceGroup::KEYBOARD_IJKL, {GameAction::CONFIRM})},
{sf::Keyboard::O, ButtonConfig(InputDeviceGroup::KEYBOARD_IJKL, {GameAction::SHRINK})} {sf::Keyboard::O, ButtonConfig(InputDeviceGroup::KEYBOARD_IJKL, {GameAction::CONFIRM})}
}; };
// Gamepad buttons // Gamepad buttons
const std::map<int, ButtonConfig> GAMEPAD_BUTTON_CONFIGS = { const std::map<int, ButtonConfig> GAMEPAD_BUTTON_CONFIGS = {
{GamepadButton::EAST, ButtonConfig(InputDeviceGroup::GAMEPAD, {GameAction::GROW})}, {GamepadButton::EAST, ButtonConfig(InputDeviceGroup::GAMEPAD, {GameAction::CONFIRM})},
{GamepadButton::SOUTH, ButtonConfig(InputDeviceGroup::GAMEPAD, {GameAction::SHRINK})} {GamepadButton::SOUTH, ButtonConfig(InputDeviceGroup::GAMEPAD, {GameAction::CONFIRM})}
}; };
// Actions // Actions
const std::map<GameAction, GameActionConfig> GAME_ACTION_CONFIGS = { const std::map<GameAction, GameActionConfig> GAME_ACTION_CONFIGS = {
{GameAction::GROW, GameActionConfig(InteractionMode::HOLD)}, {GameAction::CONFIRM, GameActionConfig(InteractionMode::PRESS)}
{GameAction::SHRINK, GameActionConfig(InteractionMode::HOLD)} };
const std::map<InputDeviceGroup, std::string> DEVICE_GROUP_NAMES = {
{InputDeviceGroup::KEYBOARD_WASD, "WASD"},
{InputDeviceGroup::KEYBOARD_IJKL, "IJKL"},
{InputDeviceGroup::KEYBOARD_ARROWS, "Arrow keys"},
{InputDeviceGroup::GAMEPAD, "Gamepad"}
};
const std::map<InputDeviceGroup, std::string> DEVICE_GROUP_CONFIRM = {
{InputDeviceGroup::KEYBOARD_WASD, "Q or E"},
{InputDeviceGroup::KEYBOARD_IJKL, "U or O"},
{InputDeviceGroup::KEYBOARD_ARROWS, "Space"},
{InputDeviceGroup::GAMEPAD, "A or B"}
}; };
#endif //HOLESOME_INPUT_CONFIG_H #endif //HOLESOME_INPUT_CONFIG_H

View file

@ -23,7 +23,7 @@ std::map<std::string, LevelConfig> const all_levels = {
CollectableInLevel("rose", {1, 2}), CollectableInLevel("rose", {1, 2}),
CollectableInLevel("small-tree", {4, 3}), CollectableInLevel("small-tree", {4, 3}),
CollectableInLevel("rose", {8, 3}), CollectableInLevel("rose", {8, 3}),
CollectableInLevel("rose", {6, 7}), CollectableInLevel("lantern", {6, 7}),
CollectableInLevel("rose", {5, 5}), CollectableInLevel("rose", {5, 5}),
CollectableInLevel("tram", {9, 5}), CollectableInLevel("tram", {9, 5}),
CollectableInLevel("rose", {0, 1}) CollectableInLevel("rose", {0, 1})

View file

@ -36,11 +36,9 @@ void loadAllFonts()
void runGame() void runGame()
{ {
LOG(INFO) << "Starting game ..."; LOG(INFO) << "Starting game ...";
auto game = GameFactory::createWindowed("Holesome"); auto game = GameFactory::createWindowed(GAME_NAME);
// Load initial level
LevelLoader::loadLevel(INITIAL_LEVEL);
game->showJoinScreen();
game->run(); game->run();
InputMapper::getInstance().reset(); InputMapper::getInstance().reset();

147
src/screens/join_screen.cpp Normal file
View file

@ -0,0 +1,147 @@
#include "join_screen.hpp"
#include "../config.h"
#include "../typography/font_manager.hpp"
#include "../game/player/player_collection.hpp"
#include "../levels.hpp"
#include "../game/level/level_loader.hpp"
JoinScreen::JoinScreen()
{
// Title text
auto titleText = std::make_shared<sf::Text>();
titleText->setString(GAME_NAME);
titleText->setFont(*FontManager::getInstance()->getDefaultFont());
titleText->setCharacterSize(150);
titleText->setStyle(sf::Text::Bold);
titleText->setFillColor(sf::Color::White);
titleText->setPosition(REFERENCE_SIZE.x / 2.f - titleText->getGlobalBounds().width / 2.f, 20);
add(titleText);
// Create join-player text
auto joinText = std::make_shared<sf::Text>();
joinText->setString("Press button to join");
joinText->setFont(*FontManager::getInstance()->getDefaultFont());
joinText->setCharacterSize(24);
joinText->setFillColor(sf::Color::White);
joinText->setPosition(REFERENCE_SIZE.x / 2.f - joinText->getGlobalBounds().width / 2.f, 200);
add(joinText);
}
void JoinScreen::update()
{
Screen::update();
// Did any player start game?
auto players = PlayerCollection::getInstance()->getPlayers();
for (auto &player: players)
{
auto input = player->getInput();
if (input->isPerformingAction(GameAction::CONFIRM))
{
// Start game
LevelLoader::loadLevel(INITIAL_LEVEL);
return;
}
}
// Update player list items
if (players.size() == lastPlayerCount)
{
return;
}
lastPlayerCount = players.size();
playerList.clear();
playerListObjects.clear();
int index = 0;
for (auto &player: players)
{
addPlayerAtIndex(player, index);
index++;
}
}
void JoinScreen::draw(sf::RenderWindow *window)
{
Screen::draw(window);
// Draw player list items
for (auto &item: playerList)
{
window->draw(*item);
}
for (auto &item: playerListObjects)
{
item->draw(window);
}
}
void JoinScreen::addPlayerAtIndex(std::shared_ptr<Player> &player, int index)
{
int numberOfMaxPlayers = PlayerCollection::getInstance()->getMaxPlayerCount();
int paddingLeftRight = 100;
int paddingTop = 400;
int relativePaddingPerColumn = 0.1;
int columnWidth = (REFERENCE_SIZE.x - 2 * paddingLeftRight) / numberOfMaxPlayers;
int paddingPerColumn = columnWidth * relativePaddingPerColumn;
int contentWidth = columnWidth - paddingPerColumn;
auto topLeft = sf::Vector2f(paddingLeftRight + columnWidth * index,
paddingTop);
// Create player character
auto skinSprite = std::make_shared<VersatileSprite>(player->getSkinName(),
sf::Vector2f(contentWidth, contentWidth * ISOMETRIC_SKEW) *
0.9f);
skinSprite->coordinates->setIsometric(IsometricCoordinates(topLeft));
playerListObjects.push_back(skinSprite);
skinSprite->update();
skinSprite->lateUpdate();
skinSprite->preRenderUpdate();
// Show device group
auto deviceGroupText = std::make_shared<sf::Text>();
InputDeviceGroup deviceGroup = player->getInput()->deviceGroup;
deviceGroupText->setString(DEVICE_GROUP_NAMES.at(deviceGroup));
deviceGroupText->setFont(*FontManager::getInstance()->getDefaultFont());
deviceGroupText->setCharacterSize(24);
deviceGroupText->setFillColor(sf::Color::White);
deviceGroupText->setPosition(topLeft.x + contentWidth / 2.f * 0.9f - deviceGroupText->getGlobalBounds().width / 2.f,
topLeft.y + skinSprite->getSize().y + 20);
playerList.push_back(deviceGroupText);
if (lastPlayerCount < MIN_PLAYER_COUNT)
{
return;
}
// Show button to press to start
auto pressText = std::make_shared<sf::Text>();
pressText->setString("Press");
pressText->setFont(*FontManager::getInstance()->getDefaultFont());
pressText->setCharacterSize(24);
pressText->setFillColor(sf::Color::Yellow);
pressText->setPosition(topLeft.x + contentWidth / 2.f * 0.9f - pressText->getGlobalBounds().width / 2.f,
topLeft.y + skinSprite->getSize().y + 100);
playerList.push_back(pressText);
std::string buttonToStart = DEVICE_GROUP_CONFIRM.at(deviceGroup);
auto buttonText = std::make_shared<sf::Text>();
buttonText->setString(buttonToStart);
buttonText->setFont(*FontManager::getInstance()->getDefaultFont());
buttonText->setCharacterSize(24);
buttonText->setFillColor(sf::Color::Yellow);
buttonText->setPosition(topLeft.x + contentWidth / 2.f * 0.9f - buttonText->getGlobalBounds().width / 2.f,
topLeft.y + skinSprite->getSize().y + 130);
playerList.push_back(buttonText);
auto toStartText = std::make_shared<sf::Text>();
toStartText->setString("to start");
toStartText->setFont(*FontManager::getInstance()->getDefaultFont());
toStartText->setCharacterSize(24);
toStartText->setFillColor(sf::Color::Yellow);
toStartText->setPosition(topLeft.x + contentWidth / 2.f * 0.9f - toStartText->getGlobalBounds().width / 2.f,
topLeft.y + skinSprite->getSize().y + 160);
playerList.push_back(toStartText);
}

View file

@ -0,0 +1,27 @@
#ifndef HOLESOME_JOIN_SCREEN_HPP
#define HOLESOME_JOIN_SCREEN_HPP
#include "screen.hpp"
#include "../game/player/player.hpp"
#include <SFML/Graphics/Text.hpp>
class JoinScreen : public Screen
{
public:
JoinScreen();
void update() override;
void draw(sf::RenderWindow *window) override;
private:
int lastPlayerCount = 0;
std::vector<std::shared_ptr<sf::Drawable>> playerList = {};
std::vector<std::shared_ptr<GameObject>> playerListObjects = {};
void addPlayerAtIndex(std::shared_ptr<Player> &player, int index);
};
#endif //HOLESOME_JOIN_SCREEN_HPP

View file

@ -17,7 +17,7 @@ WinnerScreen::WinnerScreen(const std::shared_ptr<Player> &winner)
add(winnerTitle); add(winnerTitle);
// Add graphic of the winner // Add graphic of the winner
auto winnerGraphic = std::make_shared<VersatileSprite>(PLAYER_SKIN); auto winnerGraphic = std::make_shared<VersatileSprite>(winner->getSkinName(), sf::Vector2f(500, 500 * ISOMETRIC_SKEW));
auto center = REFERENCE_SIZE / 2.f; auto center = REFERENCE_SIZE / 2.f;
auto winnerPosition = center - winnerGraphic->getSize() / 2.f; auto winnerPosition = center - winnerGraphic->getSize() / 2.f;
winnerGraphic->coordinates->setIsometric(IsometricCoordinates(winnerPosition)); winnerGraphic->coordinates->setIsometric(IsometricCoordinates(winnerPosition));

View file

@ -9,7 +9,7 @@
#include "sprites/tiling/tileset_config.hpp" #include "sprites/tiling/tileset_config.hpp"
#include "sprites/configs/masked_sprite_config.hpp" #include "sprites/configs/masked_sprite_config.hpp"
#define PLAYER_SKIN "hole" #define PLAYER_SKINS std::vector<std::string> { "player-0", "player-1", "player-2", "player-3" }
/** /**
* All textures used in the game. * All textures used in the game.
@ -18,7 +18,6 @@
std::map<std::string, std::string> const all_textures = { std::map<std::string, std::string> const all_textures = {
{"numbers", "assets/numbers.png"}, {"numbers", "assets/numbers.png"},
{"64", "assets/64.png"}, {"64", "assets/64.png"},
{"edge", "assets/edge.png"},
{"ring", "assets/ring.png"}, {"ring", "assets/ring.png"},
{"grasses", "assets/grass_plus.png"}, {"grasses", "assets/grass_plus.png"},
{"hole", "assets/hole.png"}, {"hole", "assets/hole.png"},
@ -28,7 +27,14 @@ std::map<std::string, std::string> const all_textures = {
{"small-tree", "assets/collectables/small-tree.png"}, {"small-tree", "assets/collectables/small-tree.png"},
{"stone", "assets/collectables/stone.png"}, {"stone", "assets/collectables/stone.png"},
{"tram", "assets/collectables/tram.png"}, {"tram", "assets/collectables/tram.png"},
{"iso-tiles", "assets/isometric-tiles.png"} {"lantern", "assets/collectables/lantern.png"},
{"player", "assets/player/player.png"},
{"player-0", "assets/player/player-0.png"},
{"player-1", "assets/player/player-1.png"},
{"player-2", "assets/player/player-2.png"},
{"player-3", "assets/player/player-3.png"},
{"iso-tiles", "assets/isometric-tiles.png"},
{"custom-grass-tiles", "assets/grass-tiles.png"}
}; };
/** /**
@ -38,7 +44,8 @@ std::map<std::string, std::string> const all_textures = {
std::map<std::string, SheetConfig> const all_sheets = { std::map<std::string, SheetConfig> const all_sheets = {
{"numbers", SheetConfig("numbers", 4, 2)}, {"numbers", SheetConfig("numbers", 4, 2)},
{"grasses", SheetConfig("grasses", 25, 14)}, {"grasses", SheetConfig("grasses", 25, 14)},
{"iso-tiles", SheetConfig("iso-tiles", 6, 2)} {"iso-tiles", SheetConfig("iso-tiles", 6, 2)},
{"custom-grass-tiles", SheetConfig("custom-grass-tiles", 6, 2)}
}; };
/** /**
@ -57,7 +64,12 @@ std::map<std::string, SpriteConfig> const all_sprites = {
{"64", SpriteConfig("64")}, {"64", SpriteConfig("64")},
{"edge", SpriteConfig("edge")}, {"edge", SpriteConfig("edge")},
{"ring", SpriteConfig("ring")}, {"ring", SpriteConfig("ring")},
{"hole", SpriteConfig("hole")} {"hole", SpriteConfig("hole")},
{"player", SpriteConfig("player")},
{"player-0", SpriteConfig("player-0")},
{"player-1", SpriteConfig("player-1")},
{"player-2", SpriteConfig("player-2")},
{"player-3", SpriteConfig("player-3")}
}; };
/** /**
@ -70,6 +82,7 @@ std::map<std::string, MaskedSpriteConfig> const all_masked_sprites = {
{"rosebush", MaskedSpriteConfig("rosebush")}, {"rosebush", MaskedSpriteConfig("rosebush")},
{"stone", MaskedSpriteConfig("stone")}, {"stone", MaskedSpriteConfig("stone")},
{"tram", MaskedSpriteConfig("tram")}, {"tram", MaskedSpriteConfig("tram")},
{"lantern", MaskedSpriteConfig("lantern")},
{"small-tree", MaskedSpriteConfig("small-tree")} {"small-tree", MaskedSpriteConfig("small-tree")}
}; };
@ -78,7 +91,7 @@ std::map<std::string, MaskedSpriteConfig> const all_masked_sprites = {
* The key is the name of the tileset, the value is the tileset config. * The key is the name of the tileset, the value is the tileset config.
*/ */
std::map<std::string, TileSetConfig> const all_tilesets = { std::map<std::string, TileSetConfig> const all_tilesets = {
{"iso-tiles", TileSetConfig("iso-tiles", {0, 1, 2, 3, 4, 5})} {"iso-tiles", TileSetConfig("custom-grass-tiles", {0, 1, 2, 3, 4, 5})}
}; };
#endif //HOLESOME_TEXTURE_CONFIG_H #endif //HOLESOME_TEXTURE_CONFIG_H