diff --git a/.gitmodules b/.gitmodules index e57110f..bfa520c 100644 --- a/.gitmodules +++ b/.gitmodules @@ -10,3 +10,7 @@ path = extern/SDL_mixer url = https://github.com/libsdl-org/SDL_mixer.git branch = release-2.8.x +[submodule "extern/SDL_ttf"] + path = extern/SDL_ttf + url = https://github.com/libsdl-org/SDL_ttf.git + branch = release-2.22.x diff --git a/CMakeLists.txt b/CMakeLists.txt index 88a83a1..1905143 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,10 +13,12 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON) set(BUILD_SHARED_LIBS FALSE) set(SDL2MIXER_VENDORED ON) +set(SDL2TTF_VENDORED ON) add_subdirectory(extern/SDL EXCLUDE_FROM_ALL) add_subdirectory(extern/SDL_image EXCLUDE_FROM_ALL) add_subdirectory(extern/SDL_mixer EXCLUDE_FROM_ALL) +add_subdirectory(extern/SDL_ttf EXCLUDE_FROM_ALL) file(GLOB_RECURSE SOURCES ${PROJECT_SOURCE_DIR}/src/*.cpp) add_executable(${PROJECT_NAME} ${SOURCES}) @@ -28,6 +30,7 @@ target_link_libraries(${PROJECT_NAME} PRIVATE SDL2::SDL2-static SDL2_image::SDL2_image-static SDL2_mixer::SDL2_mixer-static + SDL2_ttf::SDL2_ttf-static ) if(CMAKE_BUILD_TYPE MATCHES "Debug") diff --git a/assets/Player1Victory.png b/assets/Player1Victory.png new file mode 100644 index 0000000..f50a386 Binary files /dev/null and b/assets/Player1Victory.png differ diff --git a/assets/Player2Victory.png b/assets/Player2Victory.png new file mode 100644 index 0000000..7a20be3 Binary files /dev/null and b/assets/Player2Victory.png differ diff --git a/assets/VictoryBackup.aseprite b/assets/VictoryBackup.aseprite new file mode 100644 index 0000000..b53cd97 Binary files /dev/null and b/assets/VictoryBackup.aseprite differ diff --git a/assets/chicken_gentleman_spritesheet.png b/assets/chicken_gentleman_spritesheet.png new file mode 100644 index 0000000..848c426 Binary files /dev/null and b/assets/chicken_gentleman_spritesheet.png differ diff --git a/assets/chicken_wizzard_spritesheet.png b/assets/chicken_wizzard_spritesheet.png new file mode 100644 index 0000000..27e8796 Binary files /dev/null and b/assets/chicken_wizzard_spritesheet.png differ diff --git a/assets/iconImage.bmp b/assets/iconImage.bmp new file mode 100644 index 0000000..6eddbef Binary files /dev/null and b/assets/iconImage.bmp differ diff --git a/extern/SDL_ttf b/extern/SDL_ttf new file mode 160000 index 0000000..4a318f8 --- /dev/null +++ b/extern/SDL_ttf @@ -0,0 +1 @@ +Subproject commit 4a318f8dfaa1bb6f10e0c5e54052e25d3c7f3440 diff --git a/include/Game.h b/include/Game.h index bfef43a..1f76a8f 100644 --- a/include/Game.h +++ b/include/Game.h @@ -36,9 +36,11 @@ public: static TextureManager* textureManager; static SoundManager* soundManager; + void refreshPlayers(); + TeamLabel getWinner() const; + private: void setWinner(TeamLabel winningTeam); - TeamLabel getWinner(); int counter = 0; bool isRunning = false; diff --git a/include/HealthComponent.h b/include/HealthComponent.h index 78b9451..fad7a23 100644 --- a/include/HealthComponent.h +++ b/include/HealthComponent.h @@ -13,6 +13,7 @@ public: ~HealthComponent() {} void modifyHealth(int health = -1); + void setHealth(int health); int getHealth() { return this->health; } void init() override; @@ -20,6 +21,7 @@ public: void refreshHearts(); void createHeartComponents(int x); + private: int health; diff --git a/include/PopupWindow.h b/include/PopupWindow.h new file mode 100644 index 0000000..2ee3202 --- /dev/null +++ b/include/PopupWindow.h @@ -0,0 +1,27 @@ +#pragma once +#include +#include +#include + +class Game; +enum class TeamLabel; + +class PopupWindow { + +public: + PopupWindow(const char* title, const std::string& message); + ~PopupWindow(); + + void handleWinnerEvents(); + bool shouldContinue() const; + + bool interacted; + + void renderWinnerPopup(TeamLabel winner); + +private: + SDL_Renderer* renderer; + SDL_Window* window; + SDL_Texture* texture; + bool continueGame; +}; \ No newline at end of file diff --git a/src/Game.cpp b/src/Game.cpp index f100369..33c50c8 100644 --- a/src/Game.cpp +++ b/src/Game.cpp @@ -63,6 +63,15 @@ void Game::init(const char* title, int xpos, int ypos, int width, int height, bo return; } + SDL_Surface* icon = SDL_LoadBMP("assets/iconImage.bmp"); + if(!icon) + { + std::cout << "ERROR: Couldn't create icon!" << std::endl; + return; + } + + SDL_SetWindowIcon(window, icon); + renderer = SDL_CreateRenderer(window, -1, 0); if (!renderer) { @@ -139,17 +148,17 @@ void Game::init(const char* title, int xpos, int ypos, int width, int height, bo //adding textures to the library in AssetManager + /* assets->addTexture("player1", "assets/chicken_neutral_knight.png"); assets->addTexture("player2", "assets/chicken_neutral.png"); assets->addTexture("egg", "assets/egg.png"); - + */ // loading sounds assets->addSoundEffect("throw_egg", "assets/sound/throw_egg.wav"); assets->addSoundEffect("steps", "assets/sound/steps.wav"); //ecs implementation - player1.setTeam(TeamLabel::BLUE); player1.addComponent(80,80,2); //posx, posy, scale player1.addComponent(player1Sprite, true); //adds sprite (32x32px), path needed @@ -168,7 +177,6 @@ void Game::init(const char* title, int xpos, int ypos, int width, int height, bo player2.addComponent(5, Direction::RIGHT); player2.addComponent(); player2.addGroup((size_t) GroupLabel::PLAYERS); - } void Game::selectCharacters(const char* &playerSprite, const char* &enemySprite) @@ -359,7 +367,24 @@ void Game::setWinner(TeamLabel winningTeam) this->isRunning = false; } -TeamLabel Game::getWinner() +TeamLabel Game::getWinner() const { return this->winner; } + +void Game::refreshPlayers() { + + for(auto& p : projectiles) { + p->destroy(); + } + + player1.getComponent().position = Vector2D(80, 80); + player2.getComponent().position = Vector2D(600, 500); + + player1.getComponent().setHealth(5); + player2.getComponent().setHealth(5); + + isRunning = true; + + update(); +} diff --git a/src/HealthComponent.cpp b/src/HealthComponent.cpp index 77c9e0e..b134b54 100644 --- a/src/HealthComponent.cpp +++ b/src/HealthComponent.cpp @@ -17,6 +17,12 @@ void HealthComponent::modifyHealth(int health) this->refreshHearts(); } +void HealthComponent::setHealth(int health) +{ + this->health = health; + this->refreshHearts(); +} + void HealthComponent::refreshHearts() { // clear hearts if exist diff --git a/src/PopupWindow.cpp b/src/PopupWindow.cpp new file mode 100644 index 0000000..d41c127 --- /dev/null +++ b/src/PopupWindow.cpp @@ -0,0 +1,85 @@ +#include +#include + +#include "Entity.h" +#include "PopupWindow.h" +#include "TextureManager.h" +#include "Game.h" + +PopupWindow::PopupWindow(const char* title, const std::string &message) : +continueGame(false), interacted(false) { + this->window = SDL_CreateWindow(title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 400, 250, 0); + //font = TTF_OpenFont("assets/Trajan.ttf", 24); // Change the path and size as needed + + this->renderer = SDL_CreateRenderer(window, -1, 0); + SDL_SetRenderDrawColor(this->renderer, 255, 255, 255, 255); + + //SDL_Surface* surface = TTF_RenderText_Blended(font, message.c_str(), {255, 255, 255}); + //texture = SDL_CreateTextureFromSurface(renderer, surface); + + //SDL_FreeSurface(surface); +} + +PopupWindow::~PopupWindow() { + SDL_DestroyTexture(this->texture); + SDL_DestroyRenderer(this->renderer); + SDL_DestroyWindow(this->window); +} + +void PopupWindow::handleWinnerEvents() { + + SDL_Event e; + + while (SDL_PollEvent(&e)) + { + if (e.type == SDL_QUIT) + { + continueGame = false; + interacted = true; + return; + } + + if(e.type != SDL_KEYDOWN) + continue; + + switch (e.key.keysym.sym) { + + case SDLK_q: { + continueGame = false; + interacted = true; + break; + } + case SDLK_c: { + continueGame = true; + interacted = true; + break; + } + } + } +} + +bool PopupWindow::shouldContinue() const { + return continueGame; +} + +void PopupWindow::renderWinnerPopup(TeamLabel winner) { + + SDL_RenderClear(this->renderer); + + //Maybe use texture manager (changes need to be made that it does not use game::renderer automatically, but receives one instead) + this->texture = winner == TeamLabel::BLUE ? + IMG_LoadTexture(this->renderer, "assets/Player1Victory.png") : + IMG_LoadTexture(this->renderer, "assets/Player2Victory.png"); + + SDL_RenderCopy(this->renderer, this->texture, NULL, NULL); + + SDL_RenderPresent(this->renderer); + + //Error handling for debugging + const char* sdlError = SDL_GetError(); + if (*sdlError != '\0') { + std::cerr << "SDL Error: " << sdlError << std::endl; + SDL_ClearError(); + } + +} diff --git a/src/main.cpp b/src/main.cpp index f33d4c6..c07c71b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,12 +1,18 @@ +#include +#include + +#include "Entity.h" #include "Game.h" #include "Constants.h" -#include +#include "PopupWindow.h" Game* game = nullptr; int main(int argc, char* argv[]) { srand(time(NULL)); + bool playing = true; + const int frameDelay = 1000 / FPS; Uint32 frameStart; @@ -15,23 +21,37 @@ int main(int argc, char* argv[]) game = new Game(); game->init("No_Name_Chicken_Game", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, SCREEN_SIZE_WIDTH, SCREEN_SIZE_HEIGHT, false); - while (game->running()) - { - frameStart = SDL_GetTicks(); + while(playing) { + while (game->running()) { + frameStart = SDL_GetTicks(); - game->handleEvents(); - game->update(); - game->render(); + game->handleEvents(); + game->update(); + game->render(); - frameTime = SDL_GetTicks() - frameStart; + frameTime = SDL_GetTicks() - frameStart; - if (frameDelay > frameTime) - { - SDL_Delay(frameDelay - frameTime); - } - } + if (frameDelay > frameTime) { + SDL_Delay(frameDelay - frameTime); + } + } + TeamLabel winner = game->getWinner(); - game->clean(); + PopupWindow popupWindow("Game over", winner == TeamLabel::BLUE ? + "Player1 won! Press 'C' to continue or 'Q' to quit." : + "Player2 won! Press 'C' to continue or 'Q' to quit."); + + popupWindow.renderWinnerPopup(winner); + + while (!popupWindow.interacted) { + popupWindow.handleWinnerEvents(); + SDL_Delay(10); + } + playing = popupWindow.shouldContinue(); + game->refreshPlayers(); + } + + game->clean(); return 0; } \ No newline at end of file