diff --git a/include/constant.h b/include/constant.h index c505104..f783851 100644 --- a/include/constant.h +++ b/include/constant.h @@ -23,7 +23,13 @@ #define MONSTER_SPEED 7 // the less, the faster #define ANIMATION_SPEED 2 -// General sprites +// General sprites and colors +#define GAME_BG_COLOR_R 153 +#define GAME_BG_COLOR_G 204 +#define GAME_BG_COLOR_B 204 +/*#define GAME_BG_COLOR_R 255 +#define GAME_BG_COLOR_G 255 +#define GAME_BG_COLOR_B 255*/ #define IMG_MAP_WALL "sprite/wall.png" #define IMG_MAP_BOX "sprite/box.png" #define IMG_MAP_GOAL "sprite/objectif.png" diff --git a/include/game.h b/include/game.h index dfede3e..7318d2d 100644 --- a/include/game.h +++ b/include/game.h @@ -33,6 +33,8 @@ struct s_game { t_bomb list_bombs; t_flamme list_flammes; t_monster list_monsters; + bool viewport_mode; + bool must_clear_screen; }; typedef struct s_game * t_game; diff --git a/include/player.h b/include/player.h index 66d0e96..f4c2a43 100644 --- a/include/player.h +++ b/include/player.h @@ -15,49 +15,59 @@ enum e_player { PLAYER_STD, PLAYER_MONSTER }; +struct s_player { + int x, y, portee_bomb, win; + SDL_Surface * directed_img[4]; + enum e_way current_way; + int lives; + int nb_bomb; + int nb_bomb_max;//cette variable est utile pour les bonus. Elle sert à ce que, par exemple, si le joueur a posé toutes ses bombes (disons 2) et qu'avant qu'elles explosent le joueur prend un bonus decrease_nb_bombs, il ne sera autorisé qu'à poser une seule bombe après l'explosion des deux sur la map. + int dead; +}; typedef struct s_player * t_player; + // Creates a new player with a given number of available bombs -extern t_player player_init(int nb_bomb, int portee_bomb, int lives, int no_joueur); -extern void player_free(t_player player); +t_player player_init(int nb_bomb, int portee_bomb, int lives, int no_joueur); +void player_free(t_player player); // Returns the current position of the player -extern int player_get_x(t_player player); -extern int player_get_y(t_player player); +int player_get_x(t_player player); +int player_get_y(t_player player); // Confirm if the player has won the game -extern int player_win(t_player player); +int player_win(t_player player); // Return the caracteristics of the player -extern int player_portee_bomb(t_player player); +int player_portee_bomb(t_player player); //manage the lives of the player -extern int player_get_lives(t_player player); -extern void player_increase_lives(t_player player); -extern void player_decrease_lives(t_player player); -extern void player_die(t_player player); -extern int player_get_dead(t_player player); +int player_get_lives(t_player player); +void player_increase_lives(t_player player); +void player_decrease_lives(t_player player); +void player_die(t_player player); +int player_get_dead(t_player player); // Set the direction of the next move of the player -extern void player_set_current_way(t_player player, enum e_way way); +void player_set_current_way(t_player player, enum e_way way); // Load the player position from the map -extern int player_from_map(t_player player, t_map map); -extern void player2_from_map(t_player player, t_map map); +int player_from_map(t_player player, t_map map); +void player2_from_map(t_player player, t_map map); // Move the player according to the current direction -extern int player_move(t_player player, t_map map); +int player_move(t_player player, t_map map); //Manage the number of bombs available -extern int player_get_nb_bomb(t_player player); -extern int player_get_nb_bomb_max(t_player player); -extern void player_set_nb_bomb(t_player player, int bomb_number); -extern void player_increase_nb_bomb(t_player player); -extern void player_decrease_nb_bomb(t_player player); -extern void player_increase_nb_bomb_max(t_player player); -extern void player_decrease_nb_bomb_max(t_player player); +int player_get_nb_bomb(t_player player); +int player_get_nb_bomb_max(t_player player); +void player_set_nb_bomb(t_player player, int bomb_number); +void player_increase_nb_bomb(t_player player); +void player_decrease_nb_bomb(t_player player); +void player_increase_nb_bomb_max(t_player player); +void player_decrease_nb_bomb_max(t_player player); // Display the player on the screen -extern void player_display(t_player player, SDL_Surface *screen); +void player_display(t_player player, SDL_Surface *screen); #endif /* PLAYER_H_ */ diff --git a/src/game.c b/src/game.c index d4bff34..3a0fa54 100644 --- a/src/game.c +++ b/src/game.c @@ -58,13 +58,15 @@ t_game game_new(int nb_joueur, int niveau, int mode, int kill_bomb) { the_game.nb_joueur=nb_joueur; the_game.list_flammes=NULL; the_game.list_monsters=NULL; + the_game.viewport_mode=false; + the_game.must_clear_screen=false; #ifdef SOUND_FMOD_ACTIVATED bomb_explose = FSOUND_Sample_Load(FSOUND_FREE, "audio/bomb.wav", 0, 0, 0); #elif defined(SOUND_SDL_ACTIVATED) bomb_explose = Mix_LoadWAV("audio/bomb.wav"); //Mix_VolumeChunk(bomb_explose, MIX_MAX_VOLUME/2); - Mix_VolumeChunk(bomb_explose, 20); + if(bomb_explose != NULL) Mix_VolumeChunk(bomb_explose, 20); #endif //SOUND_FMOD_ACTIVATED return &the_game; @@ -1133,7 +1135,8 @@ void kill_bomb(t_game game, int x, int y) { void game_display(t_game game, SDL_Surface *screen) { assert(game); - SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 153, 204, 204)); + SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, + GAME_BG_COLOR_R, GAME_BG_COLOR_G, GAME_BG_COLOR_B)); t_bomb temp_bomb= game->list_bombs; t_monster temp_monster= game->list_monsters; t_flamme temp_flamme= game->list_flammes; @@ -1143,6 +1146,10 @@ void game_display(t_game game, SDL_Surface *screen) { int lives_player2 = 0; int bombs_player2 = 0; int range_player2 = 0; + + static uint16_t viewport_x = 0; + static uint16_t viewport_y = 0; + if (game->nb_joueur == 2){ lives_player2 = player_get_lives(game->player2); bombs_player2 = player_get_nb_bomb(game->player2); @@ -1179,9 +1186,52 @@ void game_display(t_game game, SDL_Surface *screen) { /** Flip screen */ #ifdef HW_SCREEN_RESIZE - flip_NNOptimized_AllowOutOfScreen(screen, hw_screen, - HW_SCREEN_WIDTH, - MIN(screen->h*HW_SCREEN_WIDTH/screen->w, HW_SCREEN_HEIGHT)); + if(game->must_clear_screen){ + SDL_FillRect(hw_screen, NULL, 0x000000); + game->must_clear_screen = false; + } + + if(!game->viewport_mode){ + + /******* Scaled Zoom */ + flip_NNOptimized_AllowOutOfScreen(screen, hw_screen, + HW_SCREEN_WIDTH, + MIN(screen->h*HW_SCREEN_WIDTH/screen->w, HW_SCREEN_HEIGHT)); + } + else{ + + /****** Viewport view */ +#define MIN_BLOCKS_VISIBLE_IN_VIEWPORT_MODE 1 + /* Adapt on the right */ + if(SIZE_BLOC*player_get_x(game->player1) >= viewport_x+HW_SCREEN_WIDTH - MIN_BLOCKS_VISIBLE_IN_VIEWPORT_MODE*SIZE_BLOC){ + //printf("%d, %d\n", SIZE_BLOC*player_get_x(game->player1), viewport_x+HW_SCREEN_WIDTH); + viewport_x = MIN(SIZE_BLOC*(player_get_x(game->player1)+1+MIN_BLOCKS_VISIBLE_IN_VIEWPORT_MODE) - HW_SCREEN_WIDTH, + SIZE_BLOC*map_get_width(game->map)-HW_SCREEN_WIDTH); + //printf("viewport_x = %d\n", viewport_x); + } + /* Adapt on the left */ + if(SIZE_BLOC*player_get_x(game->player1) < viewport_x+MIN_BLOCKS_VISIBLE_IN_VIEWPORT_MODE*SIZE_BLOC){ + viewport_x = MIN(SIZE_BLOC*(MAX(player_get_x(game->player1), MIN_BLOCKS_VISIBLE_IN_VIEWPORT_MODE)-MIN_BLOCKS_VISIBLE_IN_VIEWPORT_MODE), + SIZE_BLOC*map_get_width(game->map)-HW_SCREEN_WIDTH); + } + /* Adapt on the bottom */ + if(SIZE_BLOC*player_get_y(game->player1) >= viewport_y+HW_SCREEN_HEIGHT - MIN_BLOCKS_VISIBLE_IN_VIEWPORT_MODE*SIZE_BLOC){ + viewport_y = MIN(SIZE_BLOC*(player_get_y(game->player1)+1+MIN_BLOCKS_VISIBLE_IN_VIEWPORT_MODE)- HW_SCREEN_HEIGHT, + SIZE_BLOC*map_get_height(game->map)-HW_SCREEN_HEIGHT); + } + /* Adapt on the top */ + if(SIZE_BLOC*player_get_y(game->player1) < viewport_y+MIN_BLOCKS_VISIBLE_IN_VIEWPORT_MODE*SIZE_BLOC){ + viewport_y = MIN(SIZE_BLOC*(MAX(player_get_y(game->player1), MIN_BLOCKS_VISIBLE_IN_VIEWPORT_MODE)-MIN_BLOCKS_VISIBLE_IN_VIEWPORT_MODE), + SIZE_BLOC*map_get_height(game->map)-HW_SCREEN_HEIGHT); + } + + /*uint16_t viewport_x = MIN(SIZE_BLOC*player_get_x(game->player1), SIZE_BLOC*map_get_width(game->map)-HW_SCREEN_WIDTH); + uint16_t viewport_y = MIN(SIZE_BLOC*player_get_y(game->player1), SIZE_BLOC*map_get_height(game->map)-HW_SCREEN_HEIGHT);*/ + SDL_Rect viewport_rect = {viewport_x, viewport_y, HW_SCREEN_WIDTH, HW_SCREEN_HEIGHT}; + SDL_BlitSurface(screen, &viewport_rect, hw_screen, NULL); + } + + /** Flip screen */ SDL_Flip(hw_screen); #else //HW_SCREEN_RESIZE SDL_Flip(screen); diff --git a/src/main.c b/src/main.c index 1108ceb..d52807b 100644 --- a/src/main.c +++ b/src/main.c @@ -13,6 +13,9 @@ #include "../include/editeur.h" #include "../include/niveau.h" + +//printf("File: %s, func: %s, l.%d \n",__FILE__, __func__, __LINE__); + #ifdef SOUND_FMOD_ACTIVATED #include #elif defined(SOUND_SDL_ACTIVATED) @@ -96,6 +99,16 @@ int input_update(t_game game, int nb_joueur) { } break; + case SDLK_v: +#ifdef FUNKEY + case SDLK_x: + case SDLK_y: +#endif //FUNKEY + game->viewport_mode = !game->viewport_mode; + game->must_clear_screen = true; + //printf("Changed viewport mode to: %d\n", game->viewport_mode); + break; + //sert à poser une bombe pour le joueur 1 case SDLK_END: //cette touche sert pour les ordinateurs portables qui n'ont pas forcément la touce 0 à côté des flèches directionnelles) case SDLK_KP0: @@ -226,7 +239,8 @@ int main_game(SDL_Surface *screen, int nb_joueur, int niveau, int mode, int kill //SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_INTERVAL, SDL_DEFAULT_REPEAT_INTERVAL); - if (nb_joueur==1){ // boucle principale d'un jeu à 1 joueur: + if (nb_joueur==1){ + // boucle principale d'un jeu à 1 joueur: while (done==0 && player_get_dead(player1)!=0) { game_time_update(); @@ -265,7 +279,8 @@ int main_game(SDL_Surface *screen, int nb_joueur, int niveau, int mode, int kill } } - else if (nb_joueur==2){ // boucle principale d'un jeu à 2 joueurs: + else if (nb_joueur==2){ + // boucle principale d'un jeu à 2 joueurs: while (done==0 && player_get_dead(player1)!=0 && player_get_dead(player2)!=0) { game_time_update(); @@ -370,7 +385,6 @@ int main_game(SDL_Surface *screen, int nb_joueur, int niveau, int mode, int kill } } - SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0)); if(menu != NULL){ SDL_BlitSurface(menu, NULL, screen, &positionMenu); @@ -395,6 +409,7 @@ int main_game(SDL_Surface *screen, int nb_joueur, int niveau, int mode, int kill switch(event.type) { case SDL_QUIT: + case SDLK_q: continu = true; break; case SDL_KEYDOWN: @@ -582,6 +597,7 @@ int main(int argc, char *argv[]) { } //SDL_WaitEvent(&event); + event.type = 0; // somehow we need to reset here the last event, or it keep being "a" while (SDL_PollEvent(&event)); switch(event.type) { @@ -688,7 +704,7 @@ int main(int argc, char *argv[]) { } #endif //SOUND_SDL_ACTIVATED } - while (niveau_reussi< 10){ //En effet il n'y a que 10 niveaux dans ce jeu + while (niveau_reussi<10){ //En effet il n'y a que 10 niveaux dans ce jeu if(game_over<0){ niveau_reussi=0; //après game over le joueur repart du niveau 1; @@ -924,7 +940,8 @@ int main(int argc, char *argv[]) { break; - default: break; + default: + break; } break; @@ -933,11 +950,14 @@ int main(int argc, char *argv[]) { break; } + break; + default: break; } + /** Reset main menu screen */ if (resize==1){ #ifdef HW_SCREEN_RESIZE SDL_FillRect(hw_screen, NULL, 0x000000); @@ -950,15 +970,15 @@ int main(int argc, char *argv[]) { exit(1); } #endif //HW_SCREEN_RESIZE - resize=0; } // Effacement de l'écran - if(menu_change){ + if(menu_change || resize){ //SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0)); SDL_BlitSurface(menu, NULL, screen, &positionMenu); menu_change = false; } + resize=0; #ifdef HW_SCREEN_RESIZE flip_NNOptimized_AllowOutOfScreen(screen, hw_screen, @@ -996,7 +1016,7 @@ int main(int argc, char *argv[]) { #endif //SOUND_SDL_ACTIVATED } - SDL_FreeSurface(menu); + if(menu != NULL) SDL_FreeSurface(menu); SDL_Quit(); return EXIT_SUCCESS; diff --git a/src/player.c b/src/player.c index a77b887..97003a3 100644 --- a/src/player.c +++ b/src/player.c @@ -5,16 +5,6 @@ #include "SDL_image.h" #include "../include/game.h" -struct s_player { - int x, y, portee_bomb, win; - SDL_Surface * directed_img[4]; - enum e_way current_way; - int lives; - int nb_bomb; - int nb_bomb_max;//cette variable est utile pour les bonus. Elle sert à ce que, par exemple, si le joueur a posé toutes ses bombes (disons 2) et qu'avant qu'elles explosent le joueur prend un bonus decrease_nb_bombs, il ne sera autorisé qu'à poser une seule bombe après l'explosion des deux sur la map. - int dead; -}; - static void player_load_img(t_player player, enum e_way way, const char *filename) { player->directed_img[way] = IMG_Load(filename);