diff --git a/CMakeLists.txt b/CMakeLists.txt index 90cb5fe..669ae61 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -138,7 +138,7 @@ set(SOURCES src/typography/font_manager.cpp src/typography/font_manager.hpp 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 src/prototypes/physics_00.cpp) diff --git a/assets/collectables/lantern.png b/assets/collectables/lantern.png new file mode 100644 index 0000000..472538a Binary files /dev/null and b/assets/collectables/lantern.png differ diff --git a/assets/edge.png b/assets/edge.png deleted file mode 100644 index cde844b..0000000 Binary files a/assets/edge.png and /dev/null differ diff --git a/assets/grass-tiles.png b/assets/grass-tiles.png new file mode 100644 index 0000000..52d3cde Binary files /dev/null and b/assets/grass-tiles.png differ diff --git a/assets/player/player-0.png b/assets/player/player-0.png new file mode 100644 index 0000000..6eaa098 Binary files /dev/null and b/assets/player/player-0.png differ diff --git a/assets/player/player-1.png b/assets/player/player-1.png new file mode 100644 index 0000000..8cdc9b4 Binary files /dev/null and b/assets/player/player-1.png differ diff --git a/assets/player/player-2.png b/assets/player/player-2.png new file mode 100644 index 0000000..cdf9abc Binary files /dev/null and b/assets/player/player-2.png differ diff --git a/assets/player/player-3.png b/assets/player/player-3.png new file mode 100644 index 0000000..33fdc41 Binary files /dev/null and b/assets/player/player-3.png differ diff --git a/assets/player/player.png b/assets/player/player.png new file mode 100644 index 0000000..4d7900e Binary files /dev/null and b/assets/player/player.png differ diff --git a/src/collectables.hpp b/src/collectables.hpp index d742d90..cc1afb6 100644 --- a/src/collectables.hpp +++ b/src/collectables.hpp @@ -9,9 +9,10 @@ std::map const all_collectables = { {"rose", CollectableConfig("rose", 1)}, {"rosebush", CollectableConfig("rosebush", 3)}, {"stone", CollectableConfig("stone", 5)}, - {"bike", CollectableConfig("bike", 10)}, + {"bike", CollectableConfig("bike", 15)}, {"small-tree", CollectableConfig("small-tree", 20)}, - {"tram", CollectableConfig("tram", 50)} + {"tram", CollectableConfig("tram", 50)}, + {"lantern", CollectableConfig("lantern", 10)} }; #endif //HOLESOME_COLLECTABLES_HPP diff --git a/src/config.h b/src/config.h index 912d384..b80cbcc 100644 --- a/src/config.h +++ b/src/config.h @@ -6,12 +6,15 @@ #define DEVELOPER_MODE true +#define GAME_NAME "Holesome" + // Player #define DEFAULT_PLAYER_SPEED 5.f // World units per second #define DEFAULT_PLAYER_POINTS 0 #define PLAYER_MIN_RADIUS 0.5f // World units #define PLAYER_RADIUS_PER_LEVEL 0.25f #define DEFAULT_MAX_PLAYER_NUMBER 4 +#define MIN_PLAYER_COUNT 2 // World #define WORLD_GRAVITY b2Vec2(0.f, -9.8f) diff --git a/src/game/game.cpp b/src/game/game.cpp index 87e4b5c..f8bd729 100644 --- a/src/game/game.cpp +++ b/src/game/game.cpp @@ -9,6 +9,7 @@ #include "layer/global_layer.hpp" #include "player/player_collection.hpp" #include "../screens/winner_screen.hpp" +#include "../screens/join_screen.hpp" Game::Game(std::shared_ptr window) : window(std::move(window)) { @@ -207,3 +208,13 @@ void Game::handleWinning() GlobalLayer::getInstance()->add(winnerScreen); addGameObject(GlobalLayer::getInstance()); } + +void Game::showJoinScreen() +{ + InputMapper::getInstance()->allowNewInputIdentities = true; + auto joinScreen = std::make_shared(); + GlobalLayer::getInstance()->add(joinScreen); + addGameObject(GlobalLayer::getInstance()); + PlayerCollection::getInstance()->deactivatePlayers(); + addGameObject(PlayerCollection::getInstance()); +} diff --git a/src/game/game.h b/src/game/game.h index 7e7cd1b..35b1568 100644 --- a/src/game/game.h +++ b/src/game/game.h @@ -38,6 +38,9 @@ public: void addGameObject(const std::shared_ptr &gameObject); std::shared_ptr window; + + void showJoinScreen(); + private: static inline std::shared_ptr singletonInstance = nullptr; std::vector> gameObjects = {}; diff --git a/src/game/input/game_action.hpp b/src/game/input/game_action.hpp index 803129c..7896455 100644 --- a/src/game/input/game_action.hpp +++ b/src/game/input/game_action.hpp @@ -3,12 +3,7 @@ enum GameAction { - CONFIRM, - CANCEL, - MENU, - - GROW, - SHRINK + CONFIRM }; #endif //HOLESOME_GAME_ACTION_HPP diff --git a/src/game/level/level_loader.cpp b/src/game/level/level_loader.cpp index c50bc95..e4ed98a 100644 --- a/src/game/level/level_loader.cpp +++ b/src/game/level/level_loader.cpp @@ -21,12 +21,15 @@ void LevelLoader::loadLevel(const LevelConfig &levelConfig) LOG(INFO) << "Loading level '" << levelConfig.name << "' ..."; game->setLevel(levelConfig); + InputMapper::getInstance()->allowNewInputIdentities = false; + PlayerCollection::getInstance()->activatePlayers(); + MapSimulation::getInstance()->resetMap(levelConfig.worldMapSize); HolesSimulation::getInstance()->clear(); - PlayerCollection::getInstance()->clear(); GlobalLayer::getInstance()->clear(); HoleLayout::getInstance()->clear(); + // Add views game->addGameObject(MultiplayerView::getInstance()); diff --git a/src/game/player/player.cpp b/src/game/player/player.cpp index d6b6b12..a280ff2 100644 --- a/src/game/player/player.cpp +++ b/src/game/player/player.cpp @@ -5,7 +5,7 @@ Player::Player(std::shared_ptr assignedInput, const std::string &skinRessourceName, GridCoordinates initCoordinates) - : spawnPosition(initCoordinates) + : spawnPosition(initCoordinates), skinName(skinRessourceName) { playerId = playerCreationCounter++; coordinates->setTranslated(spawnPosition); @@ -37,9 +37,9 @@ void Player::update() return; } - auto moveDirection = input->direction.asIsometricVector(); - auto moveDelta = moveDirection * speed * FRAME_TIME.asSeconds(); - coordinates->move(moveDelta); + if (!passiveMode) { + performInteractiveUpdates(); + } GameObject::update(); } @@ -103,3 +103,25 @@ void Player::consume(int points) updateRadiusBasedOnPoints(); } + +std::string Player::getSkinName() const +{ + return skinName; +} + +std::shared_ptr 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); +} diff --git a/src/game/player/player.hpp b/src/game/player/player.hpp index 331f060..232e4ba 100644 --- a/src/game/player/player.hpp +++ b/src/game/player/player.hpp @@ -33,12 +33,22 @@ public: void consume(int points); + std::string getSkinName() const; + + std::shared_ptr getInput() const; + + void setPassiveMode(bool newPassiveMode); + TranslatedCoordinates spawnPosition; private: std::shared_ptr input; float radiusInWorld = 0.5f; // In world units std::shared_ptr skinSprite; + bool passiveMode = true; + + std::string skinName; + long points = DEFAULT_PLAYER_POINTS; int playerId; @@ -47,6 +57,8 @@ private: void setWorldRadius(float newWorldRadius); void updateRadiusBasedOnPoints(); + + void performInteractiveUpdates(); }; diff --git a/src/game/player/player_collection.cpp b/src/game/player/player_collection.cpp index 08d87e8..39f75be 100644 --- a/src/game/player/player_collection.cpp +++ b/src/game/player/player_collection.cpp @@ -35,6 +35,8 @@ void PlayerCollection::addPlayer(const std::shared_ptr &player) void PlayerCollection::clear() { + takenSkinIndices.clear(); + newPlayerBuffer.clear(); removedPlayerBuffer.clear(); @@ -97,6 +99,16 @@ void PlayerCollection::setSpawnPoints(std::vector newSpawnPoint { this->spawnPoints = std::move(newSpawnPoints); nextSpawnPointIndex = 0; + + // Go through all players and update their spawn points + for (auto &player: getPlayers()) + { + auto spawn = spawnPoints[nextSpawnPointIndex]; + nextSpawnPointIndex = static_cast((nextSpawnPointIndex + 1) % spawnPoints.size()); + + player->spawnPosition = TranslatedCoordinates(spawn); + player->coordinates->setGrid(spawn); + } } void PlayerCollection::spawnPlayer(const std::shared_ptr &inputIdentity) @@ -105,7 +117,7 @@ void PlayerCollection::spawnPlayer(const std::shared_ptr &inputId auto spawn = spawnPoints[nextSpawnPointIndex]; nextSpawnPointIndex = static_cast((nextSpawnPointIndex + 1) % spawnPoints.size()); - auto player = std::make_shared(inputIdentity, PLAYER_SKIN, spawn); + auto player = std::make_shared(inputIdentity, getNextSkin(), spawn); addPlayer(player); } @@ -145,7 +157,7 @@ void PlayerCollection::updateInputIdentityAllowance() const InputMapper::getInstance()->allowNewInputIdentities = getPlayers().size() < maxPlayerCount; } -std::shared_ptr PlayerCollection::getClosestPlayer(const TranslatedCoordinates& point) const +std::shared_ptr PlayerCollection::getClosestPlayer(const TranslatedCoordinates &point) const { std::shared_ptr closestPlayer = nullptr; float closestDistance = INFINITY; @@ -163,3 +175,55 @@ std::shared_ptr PlayerCollection::getClosestPlayer(const TranslatedCoord } return closestPlayer; } + +std::string PlayerCollection::getNextSkin() +{ + int numberOfSkins = static_cast(PLAYER_SKINS.size()); + + // Count how often each skin index is taken + std::map 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); + } +} diff --git a/src/game/player/player_collection.hpp b/src/game/player/player_collection.hpp index 04aed42..fd21d53 100644 --- a/src/game/player/player_collection.hpp +++ b/src/game/player/player_collection.hpp @@ -34,6 +34,9 @@ public: void clear(); + void activatePlayers(); + void deactivatePlayers(); + private: static inline std::shared_ptr singletonInstance = nullptr; @@ -45,6 +48,10 @@ private: void spawnPlayer(const std::shared_ptr &inputIdentity); + std::vector takenSkinIndices = {}; + + std::string getNextSkin(); + int maxPlayerCount; void updateInputIdentityAllowance() const; diff --git a/src/input_config.h b/src/input_config.h index 92d0215..38a6986 100644 --- a/src/input_config.h +++ b/src/input_config.h @@ -3,6 +3,7 @@ #include +#include #include "game/input/input_device_group.h" #include "game/input/button_config.hpp" #include "game/input/game_action_config.hpp" @@ -13,40 +14,52 @@ // Keys const std::map KEY_CONFIGS = { - {sf::Keyboard::Up, ButtonConfig(InputDeviceGroup::KEYBOARD_ARROWS, HardDirection::UP)}, - {sf::Keyboard::Down, ButtonConfig(InputDeviceGroup::KEYBOARD_ARROWS, HardDirection::DOWN)}, - {sf::Keyboard::Left, ButtonConfig(InputDeviceGroup::KEYBOARD_ARROWS, HardDirection::LEFT)}, - {sf::Keyboard::Right, ButtonConfig(InputDeviceGroup::KEYBOARD_ARROWS, HardDirection::RIGHT)}, - {sf::Keyboard::RControl, ButtonConfig(InputDeviceGroup::KEYBOARD_ARROWS, {GameAction::GROW})}, - {sf::Keyboard::Numpad0, ButtonConfig(InputDeviceGroup::KEYBOARD_ARROWS, {GameAction::SHRINK})}, + {sf::Keyboard::Up, ButtonConfig(InputDeviceGroup::KEYBOARD_ARROWS, HardDirection::UP)}, + {sf::Keyboard::Down, ButtonConfig(InputDeviceGroup::KEYBOARD_ARROWS, HardDirection::DOWN)}, + {sf::Keyboard::Left, ButtonConfig(InputDeviceGroup::KEYBOARD_ARROWS, HardDirection::LEFT)}, + {sf::Keyboard::Right, ButtonConfig(InputDeviceGroup::KEYBOARD_ARROWS, HardDirection::RIGHT)}, + {sf::Keyboard::Space, ButtonConfig(InputDeviceGroup::KEYBOARD_ARROWS, {GameAction::CONFIRM})}, - {sf::Keyboard::W, ButtonConfig(InputDeviceGroup::KEYBOARD_WASD, HardDirection::UP)}, - {sf::Keyboard::S, ButtonConfig(InputDeviceGroup::KEYBOARD_WASD, HardDirection::DOWN)}, - {sf::Keyboard::A, ButtonConfig(InputDeviceGroup::KEYBOARD_WASD, HardDirection::LEFT)}, - {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::SHRINK})}, + {sf::Keyboard::W, ButtonConfig(InputDeviceGroup::KEYBOARD_WASD, HardDirection::UP)}, + {sf::Keyboard::S, ButtonConfig(InputDeviceGroup::KEYBOARD_WASD, HardDirection::DOWN)}, + {sf::Keyboard::A, ButtonConfig(InputDeviceGroup::KEYBOARD_WASD, HardDirection::LEFT)}, + {sf::Keyboard::D, ButtonConfig(InputDeviceGroup::KEYBOARD_WASD, HardDirection::RIGHT)}, + {sf::Keyboard::Q, ButtonConfig(InputDeviceGroup::KEYBOARD_WASD, {GameAction::CONFIRM})}, + {sf::Keyboard::E, ButtonConfig(InputDeviceGroup::KEYBOARD_WASD, {GameAction::CONFIRM})}, - {sf::Keyboard::I, ButtonConfig(InputDeviceGroup::KEYBOARD_IJKL, HardDirection::UP)}, - {sf::Keyboard::K, ButtonConfig(InputDeviceGroup::KEYBOARD_IJKL, HardDirection::DOWN)}, - {sf::Keyboard::J, ButtonConfig(InputDeviceGroup::KEYBOARD_IJKL, HardDirection::LEFT)}, - {sf::Keyboard::L, ButtonConfig(InputDeviceGroup::KEYBOARD_IJKL, HardDirection::RIGHT)}, - {sf::Keyboard::U, ButtonConfig(InputDeviceGroup::KEYBOARD_IJKL, {GameAction::GROW})}, - {sf::Keyboard::O, ButtonConfig(InputDeviceGroup::KEYBOARD_IJKL, {GameAction::SHRINK})} + {sf::Keyboard::I, ButtonConfig(InputDeviceGroup::KEYBOARD_IJKL, HardDirection::UP)}, + {sf::Keyboard::K, ButtonConfig(InputDeviceGroup::KEYBOARD_IJKL, HardDirection::DOWN)}, + {sf::Keyboard::J, ButtonConfig(InputDeviceGroup::KEYBOARD_IJKL, HardDirection::LEFT)}, + {sf::Keyboard::L, ButtonConfig(InputDeviceGroup::KEYBOARD_IJKL, HardDirection::RIGHT)}, + {sf::Keyboard::U, ButtonConfig(InputDeviceGroup::KEYBOARD_IJKL, {GameAction::CONFIRM})}, + {sf::Keyboard::O, ButtonConfig(InputDeviceGroup::KEYBOARD_IJKL, {GameAction::CONFIRM})} }; // Gamepad buttons const std::map GAMEPAD_BUTTON_CONFIGS = { - {GamepadButton::EAST, ButtonConfig(InputDeviceGroup::GAMEPAD, {GameAction::GROW})}, - {GamepadButton::SOUTH, ButtonConfig(InputDeviceGroup::GAMEPAD, {GameAction::SHRINK})} + {GamepadButton::EAST, ButtonConfig(InputDeviceGroup::GAMEPAD, {GameAction::CONFIRM})}, + {GamepadButton::SOUTH, ButtonConfig(InputDeviceGroup::GAMEPAD, {GameAction::CONFIRM})} }; // Actions const std::map GAME_ACTION_CONFIGS = { - {GameAction::GROW, GameActionConfig(InteractionMode::HOLD)}, - {GameAction::SHRINK, GameActionConfig(InteractionMode::HOLD)} + {GameAction::CONFIRM, GameActionConfig(InteractionMode::PRESS)} +}; + + +const std::map DEVICE_GROUP_NAMES = { + {InputDeviceGroup::KEYBOARD_WASD, "WASD"}, + {InputDeviceGroup::KEYBOARD_IJKL, "IJKL"}, + {InputDeviceGroup::KEYBOARD_ARROWS, "Arrow keys"}, + {InputDeviceGroup::GAMEPAD, "Gamepad"} +}; +const std::map 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 diff --git a/src/levels.hpp b/src/levels.hpp index a4c97ab..1a71fbb 100644 --- a/src/levels.hpp +++ b/src/levels.hpp @@ -23,7 +23,7 @@ std::map const all_levels = { CollectableInLevel("rose", {1, 2}), CollectableInLevel("small-tree", {4, 3}), CollectableInLevel("rose", {8, 3}), - CollectableInLevel("rose", {6, 7}), + CollectableInLevel("lantern", {6, 7}), CollectableInLevel("rose", {5, 5}), CollectableInLevel("tram", {9, 5}), CollectableInLevel("rose", {0, 1}) diff --git a/src/main.cpp b/src/main.cpp index 607399e..49f1e13 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -36,11 +36,9 @@ void loadAllFonts() void runGame() { LOG(INFO) << "Starting game ..."; - auto game = GameFactory::createWindowed("Holesome"); - - // Load initial level - LevelLoader::loadLevel(INITIAL_LEVEL); + auto game = GameFactory::createWindowed(GAME_NAME); + game->showJoinScreen(); game->run(); InputMapper::getInstance().reset(); diff --git a/src/screens/join_screen.cpp b/src/screens/join_screen.cpp new file mode 100644 index 0000000..5a6a368 --- /dev/null +++ b/src/screens/join_screen.cpp @@ -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(); + 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(); + 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, 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(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(); + 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(); + 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(); + 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(); + 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); +} diff --git a/src/screens/join_screen.hpp b/src/screens/join_screen.hpp new file mode 100644 index 0000000..4caad06 --- /dev/null +++ b/src/screens/join_screen.hpp @@ -0,0 +1,27 @@ +#ifndef HOLESOME_JOIN_SCREEN_HPP +#define HOLESOME_JOIN_SCREEN_HPP + + +#include "screen.hpp" +#include "../game/player/player.hpp" +#include + +class JoinScreen : public Screen +{ +public: + JoinScreen(); + + void update() override; + + void draw(sf::RenderWindow *window) override; + +private: + int lastPlayerCount = 0; + std::vector> playerList = {}; + std::vector> playerListObjects = {}; + + void addPlayerAtIndex(std::shared_ptr &player, int index); +}; + + +#endif //HOLESOME_JOIN_SCREEN_HPP diff --git a/src/screens/winner_screen.cpp b/src/screens/winner_screen.cpp index 52528c3..7f00710 100644 --- a/src/screens/winner_screen.cpp +++ b/src/screens/winner_screen.cpp @@ -17,7 +17,7 @@ WinnerScreen::WinnerScreen(const std::shared_ptr &winner) add(winnerTitle); // Add graphic of the winner - auto winnerGraphic = std::make_shared(PLAYER_SKIN); + auto winnerGraphic = std::make_shared(winner->getSkinName(), sf::Vector2f(500, 500 * ISOMETRIC_SKEW)); auto center = REFERENCE_SIZE / 2.f; auto winnerPosition = center - winnerGraphic->getSize() / 2.f; winnerGraphic->coordinates->setIsometric(IsometricCoordinates(winnerPosition)); diff --git a/src/texture_config.h b/src/texture_config.h index 0b8ee3a..5630699 100644 --- a/src/texture_config.h +++ b/src/texture_config.h @@ -9,7 +9,7 @@ #include "sprites/tiling/tileset_config.hpp" #include "sprites/configs/masked_sprite_config.hpp" -#define PLAYER_SKIN "hole" +#define PLAYER_SKINS std::vector { "player-0", "player-1", "player-2", "player-3" } /** * All textures used in the game. @@ -18,7 +18,6 @@ std::map const all_textures = { {"numbers", "assets/numbers.png"}, {"64", "assets/64.png"}, - {"edge", "assets/edge.png"}, {"ring", "assets/ring.png"}, {"grasses", "assets/grass_plus.png"}, {"hole", "assets/hole.png"}, @@ -28,7 +27,14 @@ std::map const all_textures = { {"small-tree", "assets/collectables/small-tree.png"}, {"stone", "assets/collectables/stone.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 const all_textures = { std::map const all_sheets = { {"numbers", SheetConfig("numbers", 4, 2)}, {"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 const all_sprites = { {"64", SpriteConfig("64")}, {"edge", SpriteConfig("edge")}, {"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 const all_masked_sprites = { {"rosebush", MaskedSpriteConfig("rosebush")}, {"stone", MaskedSpriteConfig("stone")}, {"tram", MaskedSpriteConfig("tram")}, + {"lantern", MaskedSpriteConfig("lantern")}, {"small-tree", MaskedSpriteConfig("small-tree")} }; @@ -78,7 +91,7 @@ std::map const all_masked_sprites = { * The key is the name of the tileset, the value is the tileset config. */ std::map 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