From 9473c0c2b40203e802885ecd780c4b3d9dc9390c Mon Sep 17 00:00:00 2001 From: marouault Date: Sun, 13 Feb 2022 20:32:58 +0100 Subject: [PATCH] Multiplayer available, EndGameMenu better than ever --- Pontu/entryPoints/main.c | 23 +++-- Pontu/src/engine/Button.c | 2 + Pontu/src/model/Game.c | 74 +++++++------ Pontu/src/view/GameMain.c | 2 +- Pontu/src/view/MenuEndGame.c | 194 ++++++++++++++++++----------------- 5 files changed, 162 insertions(+), 133 deletions(-) diff --git a/Pontu/entryPoints/main.c b/Pontu/entryPoints/main.c index de9f73e..834c110 100644 --- a/Pontu/entryPoints/main.c +++ b/Pontu/entryPoints/main.c @@ -10,10 +10,9 @@ #include "model/Player.h" int main(int argc, char *argv[]) { - GeneralState generalState; - - SDL_Window* window = NULL; SDL_Rect windowSize = {10, 10, 900, 900}; + + SDL_Window* window = NULL; SDL_Renderer* renderer = NULL; int statut = EXIT_FAILURE; @@ -44,7 +43,7 @@ int main(int argc, char *argv[]) { FontHandler fontHandler = loadFonts(); AudioHandler audioHandler = newAudioHandler(128, 128, 128); - generalState = GS_MainMenu; + GeneralState generalState = GS_MainMenu; while(generalState != GS_Quit){ switch (generalState) { case GS_MainMenu: @@ -56,11 +55,12 @@ int main(int argc, char *argv[]) { SDL_GetWindowSize(window, &windowW, &windowH); - size_t nbPlayers = 2; + size_t nbPlayers = 3; Player players[] = { newPlayer("Bépo", PlayerViolet), - newPlayer("Azeryty", PlayerYellow), - //newPlayer("Adcsg", PlayerRed) + newPlayer("Azeryty", PlayerBlue), + newPlayer("Adcsg", PlayerRed), + //newPlayer("qsdfqsdfq", PlayerYellow) }; //players[2] = ; @@ -73,6 +73,15 @@ int main(int argc, char *argv[]) { generalState = GS_Game; gameView(&generalState, window, renderer, players, nbPlayers, &fontHandler); + + //Pour tester le endGameMenu directement + /*generalState = GS_EndOfGameMenu; + players[0].eliminationTurn = 10; + players[0].rank = 3; + players[1].eliminationTurn = 15; + players[1].rank = 2; + players[2].eliminationTurn = 0; + players[2].rank = 1;*/ endGameMenu(&generalState, window, renderer, &fontHandler, players, nbPlayers); break; diff --git a/Pontu/src/engine/Button.c b/Pontu/src/engine/Button.c index 273c962..2feeabe 100644 --- a/Pontu/src/engine/Button.c +++ b/Pontu/src/engine/Button.c @@ -63,8 +63,10 @@ bool isButtonEntry(P_Button * button,const int x,const int y){ coord.y = y; if(isHover(button)){ button->hover = SDL_PointInRect(&coord,&(button->rect)); + button->drawn = button->hover; return false; } button->hover = SDL_PointInRect(&coord,&(button->rect)); + button->drawn = !button->hover; return button->hover; } diff --git a/Pontu/src/model/Game.c b/Pontu/src/model/Game.c index 396d5d3..d63a881 100644 --- a/Pontu/src/model/Game.c +++ b/Pontu/src/model/Game.c @@ -65,6 +65,25 @@ void eliminatePlayer(Game* game, const size_t playerId) { void endGame(Game* game) { game->phase = GAME_ENDED; + + for (size_t i=0; inbPlayers; ++i) { + if (game->arrPlayers[i].rank==1) { + game->arrPlayers[i].eliminationTurn = game->nb_rounds; + return; + } + } +} + + +Piece* getNonPlacedPieceFromPlayer(Piece arrPieces[], const size_t nbPieces, const size_t currentPlayerID) { + for (size_t i = 0; i < nbPieces; ++i) + { + if (arrPieces[i].idJ == currentPlayerID && islandEqual(arrPieces[i].island, newIsland(-1,-1))) + { + return &arrPieces[i]; + } + } + return NULL; } void changePhaseOrPlayerTurn(Game* game) @@ -72,28 +91,31 @@ void changePhaseOrPlayerTurn(Game* game) switch (game->phase) { case PLACEMENT: - if (game->currentPlayerID == 0) - { - game->phase = MOVE_PIECE; + //Joueur suivant + if (game->currentPlayerID == 0) { + game->currentPlayerID = game->nbPlayers-1; } - else - { + else { game->currentPlayerID--; } + + if (getNonPlacedPieceFromPlayer(game->board.arrPieces, game->board.nbPieces, game->currentPlayerID) == NULL) { + game->phase = MOVE_PIECE; + } break; case MOVE_PIECE: game->phase = RM_BRIDGE; break; case RM_BRIDGE: - { - const size_t lastPlayerId = game->currentPlayerID; - if (areAllPlayerPiecesStucked(lastPlayerId, game->board.arrPieces, game->board.nbPieces)) { - eliminatePlayer(game, lastPlayerId); - if (game->lastRank == 2) { - endGame(game); - return; - } + { + // check if all players are eliminated + if (game->lastRank == 2) { + endGame(game); + return; } + + + do { @@ -102,19 +124,6 @@ void changePhaseOrPlayerTurn(Game* game) { game->currentPlayerID = 0; } - /*if (lastPlayerId == game->currentPlayerID) { - game->phase = GAME_ENDED; - return; - }*/ - - if (game->arrPlayers[game->currentPlayerID].eliminationTurn != 0 && areAllPlayerPiecesStucked(game->currentPlayerID, game->board.arrPieces, game->board.nbPieces)) { - eliminatePlayer(game, game->currentPlayerID); - if (game->lastRank == 2) { - endGame(game); - return; - } - } - } while (game->arrPlayers[game->currentPlayerID].eliminationTurn != 0); @@ -286,11 +295,16 @@ void updatePieceIsolated(Game* game, const Island* island) { Piece* piecePotentialyIsolated = getPieceFromIsland(game->board.arrPieces, game->board.nbPieces, *island); if (piecePotentialyIsolated != NULL && isPieceIsolated(piecePotentialyIsolated, &game->board)) - { // Check is a piece is isolated //and then if the player is eliminated + { // Check is a piece is isolated and then if the player is eliminated piecePotentialyIsolated->stuck = true; + if (areAllPlayerPiecesStucked(piecePotentialyIsolated->idJ, game->board.arrPieces, game->board.nbPieces)) { + eliminatePlayer(game, piecePotentialyIsolated->idJ); + } } } + + GameAction clickOnBoard(const Coord coord, Game* game) { const IslandOrBridge islandOrBridge = coordToEntity(coord); @@ -301,7 +315,9 @@ GameAction clickOnBoard(const Coord coord, Game* game) if (islandOrBridge.type == ISLAND) { Piece* piece = getPieceFromIsland(game->board.arrPieces, game->board.nbPieces, islandOrBridge.data.island); - if (piece != NULL) { + if (piece == NULL) { // No piece here + piece = getNonPlacedPieceFromPlayer(game->board.arrPieces, game->board.nbPieces, game->currentPlayerID); + if (placePiece(piece, islandOrBridge.data.island, &game->board)) { changePhaseOrPlayerTurn(game); return GameAction_PlacePiece; @@ -362,8 +378,8 @@ GameAction moveOnBoard(const Coord start, const Coord end, Game* game) if (pieceMoved) { changePhaseOrPlayerTurn(game); + return GameAction_MovePiece; } - return pieceMoved ? GameAction_MovePiece : GameAction_None; } } break; diff --git a/Pontu/src/view/GameMain.c b/Pontu/src/view/GameMain.c index 9379667..0dc182e 100644 --- a/Pontu/src/view/GameMain.c +++ b/Pontu/src/view/GameMain.c @@ -106,7 +106,7 @@ void gameView(GeneralState* generalState, SDL_Window* window, SDL_Renderer* rend switch (actionRealized) { case GameAction_PlacePiece: - drawPlacePiece(renderer, &boardRect, &textureHandler, game.arrPlayers[(game.currentPlayerID-1>0) ? game.currentPlayerID-1 : game.nbPlayers-1].color, &inputElement.data.coord); + drawPlacePiece(renderer, &boardRect, &textureHandler, game.arrPlayers[(game.currentPlayerIDarg) = GS_MainMenu; } +SDL_Rect getEndGameMenuRect(SDL_Window* window) { + int windowW; + int windowH; + SDL_GetWindowSize(window, &windowW, &windowH); + + SDL_Rect rect = { + .x=windowW/10, + .y=0, + .w=windowW*80/100, + .h=windowH + }; + return rect; +} + /** * @brief Create button For EndGameMenu * @@ -55,96 +69,71 @@ P_Button createButtonForEndGameMenu(SDL_Renderer* renderer, TTF_Font* font, cons return buttonMenuEndGame; } -/** - * @brief Draw Pseudo and rank for end game menu - * - * @param renderer The renderer where pseudo and rank will be drawn - * @param rect Rect in which the endGameMenu is drawn - * @param height Height of line in score table - * @param font Font used for pseudo and rank - * @param color Color used for pseudo and rank - * @param rank - * @param pseudo - */ -void drawPseudoAndRank(SDL_Renderer* renderer, const SDL_Rect* rect, const int height, TTF_Font* font, const SDL_Color* color, const size_t rank, const char *const pseudo) { - const SDL_Point posRangPseudo = { - .x = rect->x+rect->w*0.05, - .y = height - }; +TextLabel createTitleLabel(SDL_Renderer* renderer, TTF_Font* font) { + SDL_Color color = {0,0,0,0}; - char *const text = (char*) malloc(sizeof(char)*(4+strlen(pseudo)));// potentialy one character wider than necesarry + return createUnsizedTextLabel("Scores", &color, font, renderer); +} + +TextLabel createEliminationTurnLabel(SDL_Renderer* renderer, TTF_Font* font, const SDL_Color* color, const int eliminationTurn) { + char *const text = (char*) malloc(sizeof(char*) * 10); if (text == NULL) { fprintf(stderr,"allocation error\n"); fflush(stderr); - return; + return createUnsizedTextLabel("Error allocation", color, font, renderer); } - sprintf(text, "%lld. %s", rank, pseudo); + sprintf(text, "Tour: %d", eliminationTurn); - TextLabel joueur = createTextLabel(text, &posRangPseudo, 1, color, font, renderer, POSX_LEFT, POSY_TOP); + TextLabel label = createUnsizedTextLabel(text, color, font, renderer); + free(text); - drawTextLabel(renderer, &joueur); - - freeTextLabel(&joueur); + return label; } -void drawEliminationTurn(SDL_Renderer* renderer, const SDL_Rect* rect, const int height, TTF_Font* font, const SDL_Color* color, const int eliminationTurn) { - SDL_Point posTourElimination = { - .x = rect->x+rect->w*0.95, - .y = height - }; - - - char *const text = (char*) malloc(sizeof(char*) * 10); +TextLabel createPseudoAndRankLabel(SDL_Renderer* renderer, TTF_Font* font, const SDL_Color* color, const int rank, const char *const pseudo) { + char *const text = (char*) malloc(sizeof(char)*(4+strlen(pseudo)));// potentialy one character wider than necesarry if (text == NULL) { fprintf(stderr,"allocation error\n"); fflush(stderr); - return; + return createUnsizedTextLabel("Error allocation", color, font, renderer); } - sprintf(text, "Tour: %d", eliminationTurn); + sprintf(text, "%d. %s", rank, pseudo); - TextLabel label = createTextLabel(text, &posTourElimination, 1, color, font, renderer, POSX_RIGHT, POSY_TOP); - + TextLabel pseudoRankLbl = createUnsizedTextLabel(text, color, font, renderer); free(text); - drawTextLabel(renderer, &label); - - freeTextLabel(&label); - -} - -void drawPlayersScores(SDL_Renderer* renderer, const Player players[], const size_t nbPlayers, const SDL_Rect* rect, TTF_Font* font) { - SDL_Color black = {0,0,0,0}; - for (size_t i=0; iy+(players[i].rank+1)*rect->h/10+rect->y+rect->h/100; - drawPseudoAndRank(renderer, rect, height, font, &black, i, players[i].pseudo); - - drawEliminationTurn(renderer, rect, height, font, &black, players[i].eliminationTurn); - } + return pseudoRankLbl; } -void drawEndGameMenu(SDL_Renderer* renderer, const Player players[], const size_t nbPlayers, const SDL_Rect* rect, FontHandler* fontHandler) { - - SDL_SetRenderDrawColor(renderer, 220,220,220,255); - SDL_RenderFillRect(renderer, rect); - - drawPlayersScores(renderer, players, nbPlayers, rect, fontHandler->fonts[FONT_retro]); +PositionSpecifier getPseudoAndRankPositionSpecifier(const SDL_Rect* labelSize, const int rank) { + SDL_Rect base100 = { + .x=2, + .y=20+8*(rank-1), + .w = 5*labelSize->w/labelSize->h, + .h = 5 + }; + return newPositionSpecifier(&base100, POSX_LEFT, POSY_TOP, ASPECT_KEEP_FIT); } -TextLabel createTitleLabel(SDL_Renderer* renderer, TTF_Font* font) { - SDL_Color color = {0,0,0,0}; - - return createUnsizedTextLabel("Scores", &color, font, renderer); +PositionSpecifier getEliminationTurnPositionSpecifier(const SDL_Rect* labelSize, const int rank) { + SDL_Rect base100 = { + .x=98, + .y=20+8*(rank-1), + .w = 5*labelSize->w/labelSize->h, + .h = 5 + }; + return newPositionSpecifier(&base100, POSX_RIGHT, POSY_TOP, ASPECT_KEEP_FIT); } -PositionSpecifier getTitleRect100(SDL_Rect* labelSize) { +PositionSpecifier getTitlePositionClassifier(const SDL_Rect* labelSize) { SDL_Rect base100 = { .x=50, .y=1, - .w = 30, - .h = 30*labelSize->h/labelSize->w + .w = 15*labelSize->w/labelSize->h, + .h = 15 }; - return newPositionSpecifier(&base100, POSX_CENTER, POSY_TOP, ASPECT_KEEP_W); + return newPositionSpecifier(&base100, POSX_CENTER, POSY_TOP, ASPECT_KEEP_FIT); } struct endGameMenuTextLabel createLabels(SDL_Renderer* renderer, const Player players[], const size_t nbPlayers, FontHandler* fontHandler) { @@ -155,43 +144,51 @@ struct endGameMenuTextLabel createLabels(SDL_Renderer* renderer, const Player pl // Titre array_TextLabel_AddElement(&labels.textLabels, createTitleLabel(renderer, fontHandler->fonts[FONT_retro])); - array_PositionSpecifier_AddElement(&labels.positionSpecifiers, getTitleRect100(&array_TextLabel_Last(&labels.textLabels)->textZone)); + array_PositionSpecifier_AddElement(&labels.positionSpecifiers, getTitlePositionClassifier(&array_TextLabel_Last(&labels.textLabels)->textZone)); // Lignes de score - + for (size_t i=0; ifonts[FONT_retro], &PLAYER_SDL_COLORS[players[i].color], players[i].rank, players[i].pseudo)); + array_PositionSpecifier_AddElement(&labels.positionSpecifiers, getPseudoAndRankPositionSpecifier(&array_TextLabel_Last(&labels.textLabels)->textZone, players[i].rank)); + + array_TextLabel_AddElement(&labels.textLabels, createEliminationTurnLabel(renderer, fontHandler->fonts[FONT_retro], &PLAYER_SDL_COLORS[players[i].color], players[i].eliminationTurn)); + array_PositionSpecifier_AddElement(&labels.positionSpecifiers, getEliminationTurnPositionSpecifier(&array_TextLabel_Last(&labels.textLabels)->textZone, players[i].rank)); + } return labels; } -void endGameMenu(GeneralState* generalState, SDL_Window* window, SDL_Renderer* renderer, FontHandler* fontHandler, const Player players[], const size_t nbPlayers) { - int windowW; - int windowH; - - SDL_GetWindowSize(window, &windowW, &windowH); - SDL_Rect rectMenuEndGame = { - .x=windowW/10, - .y=0, - .w=windowW*80/100, - .h=windowH - }; +void drawEndGameMenu(SDL_Renderer* renderer, const SDL_Rect rectMenuEndGame, struct endGameMenuTextLabel* labels) { + SDL_SetRenderDrawColor(renderer, 220,220,220,255); + SDL_RenderFillRect(renderer, &rectMenuEndGame); + + for (size_t i=0; itextLabels.size; ++i) { + labels->textLabels.elems[i].textZone = adaptPosToRect(&labels->positionSpecifiers.elems[i], &rectMenuEndGame); + drawTextLabel(renderer, &labels->textLabels.elems[i]); + } + + SDL_RenderPresent(renderer); +} + +void endGameMenu(GeneralState* generalState, SDL_Window* window, SDL_Renderer* renderer, FontHandler* fontHandler, const Player players[], const size_t nbPlayers) { InputProcessor inputProcessor = createInputProcessor(); - array_P_Button_AddElement(&inputProcessor.tabButton, createButtonForEndGameMenu(renderer, fontHandler->fonts[FONT_retro], &rectMenuEndGame, generalState)); + const SDL_Rect endGameMenuRect = getEndGameMenuRect(window); + array_P_Button_AddElement(&inputProcessor.tabButton, createButtonForEndGameMenu(renderer, fontHandler->fonts[FONT_retro], &endGameMenuRect, generalState)); P_Button* buttonMenuEndGame = array_P_Button_Last(&inputProcessor.tabButton); SDL_Rect base100 = { .x = 50, .y = 99, - .w = 30, - .h = 30*buttonMenuEndGame->rect.h/buttonMenuEndGame->rect.w + .w = 90, + .h = 90*buttonMenuEndGame->rect.h/buttonMenuEndGame->rect.w }; - PositionSpecifier positionSpecifierButtonRetour = newPositionSpecifier(&base100, POSX_CENTER, POSY_BOTTOM, ASPECT_KEEP_H); - drawEndGameMenu(renderer, players, nbPlayers, &rectMenuEndGame, fontHandler); + PositionSpecifier positionSpecifierButtonRetour = newPositionSpecifier(&base100, POSX_CENTER, POSY_BOTTOM, ASPECT_KEEP_FIT); + buttonMenuEndGame->rect = adaptPosToRect(&positionSpecifierButtonRetour, &endGameMenuRect); + buttonMenuEndGame->drawn = false; struct endGameMenuTextLabel labels = createLabels(renderer, players, nbPlayers, fontHandler); - for (size_t i=0; irect = adaptPosToRect(&positionSpecifierButtonRetour, &rectM); - drawButtonOnRenderer(renderer, buttonMenuEndGame); + buttonMenuEndGame->drawn = false; fprintf(stderr, "Resize\n"); fflush(stderr); } @@ -241,12 +233,22 @@ void endGameMenu(GeneralState* generalState, SDL_Window* window, SDL_Renderer* r } } - drawButtonOnRenderer(renderer, buttonMenuEndGame); - + if (!buttonMenuEndGame->drawn) { + drawButtonOnRenderer(renderer, buttonMenuEndGame); + SDL_RenderPresent(renderer); + } - SDL_RenderPresent(renderer); SDL_Delay(50); } freeInputProcessor(&inputProcessor); + + for (size_t i=0; i