added viewport support

This commit is contained in:
Vincent-FK 2021-06-08 18:39:39 +02:00
parent dfc5c53d43
commit 71c8d22457
6 changed files with 125 additions and 47 deletions

View File

@ -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"

View File

@ -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;

View File

@ -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_ */

View File

@ -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);

View File

@ -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 <FMOD/fmod.h>
#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;

View File

@ -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);