Files
Sokoban/script/display.c
2025-01-08 15:19:03 +01:00

384 lines
12 KiB
C

/**
* \file display.c
* Fichier contient tout les fonctions pour l'affichage.
*/
#include "../include/display.h"
#include "../include/function.h"
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <SDL2/SDL_mutex.h>
#include <SDL2/SDL_mixer.h>
#include <SDL2/SDL_rect.h>
#include <SDL2/SDL_render.h>
#include <SDL2/SDL_surface.h>
#include <SDL2/SDL_ttf.h>
#include <stdio.h>
#include <stdlib.h>
/**
* \brief La fonction permet d'afficher simplement le plateau de jeu dans le
* terminal.
* \param tab Le tableau 2d du plateau.
* \param x Le mombre de ligne.
* \param y Le nombre de colonnes.
* \return Void
*/
void screenDisplay (char **tab, int x ,int y )
{
// puts("0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 ");
char element[9] = { '#', '_', 'S', '.', '*', '@', '+' , 'o', 'O'};
for (int i = 0; i < x; ++i)
{
for (int j = 0; j < y; ++j)
{
printf ("%c ", element[(int)tab[i][j]]);
}
puts ("");
}
}
/**
* \brief La fonction affiche a l'aide de SDL la zone de jeu.
* \param tab Le tableau 2d de la zone de jeu.
* \param display_user La structure qui possede tous ce qu'il faut pour
* l'affichage SDL
* \param player_pos la position du joueur
* \param fov Le fov de la vision du joueur, -1 si desactiver.
* \param direction La direction du personnage.
* \return Void
*/
void screenDisplayGameSDL (char **tab,vect dim_tab, dis *display_user, vect *player_pos, int fov, vect direction)
{
unsigned int display_game
= display_user->size_window - display_user->size_menu;
int size = display_game / display_user->size_box;
unsigned int marge = display_user->size_menu / 2;
unsigned int i, j, x = 0, y = 0;
int start_i = 0, start_j = 0;
unsigned int limit_i = display_user->size_box, limit_j = display_user->size_box;
if (fov >= 0 )
{
start_i = player_pos->y - fov+1;
if(start_i < 0) start_i = 0;
start_j = player_pos->x - fov +1 ;
if(start_j < 0) start_j = 0;
limit_i = player_pos->y + fov+1;
//if(limit_i > display_user->size_box) limit_i = display_user->size_box;
if(limit_i > dim_tab.y) limit_i = dim_tab.y;
limit_j = player_pos->x + fov;
//if(limit_j > display_user->size_box) limit_j = display_user->size_box;
if(limit_j > dim_tab.x) limit_j = dim_tab.x;
size = display_game / (fov*2);
}
SDL_Surface *img;
SDL_Texture *texture;
for (i = start_i; i < limit_i; ++i)
{
for (j = start_j; j < limit_j; ++j)
{
vect pos = { x * size + marge, y * size};
switch (tab[j][i])
{
case EMPTY:
srand(seed+i*15+j*13);
int rand_int = rand() % 45;
if(rand_int==26){img = IMG_Load ("image/empty_grass.png");}
else if(rand_int==27){img = IMG_Load ("image/empty_mud.png");}
else if(rand_int==28){img = IMG_Load ("image/empty_mushroom.png");}
else if(rand_int==29){img = IMG_Load ("image/empty_mushroom2.png");}
else{img = IMG_Load ("image/empty.png");}
break;
case WALL:
srand(seed+i*15+j*13);
rand_int = rand() % 6;
if(rand_int==5){img = IMG_Load ("image/wall3.png");}
else if(rand_int==4){img = IMG_Load ("image/wall2.png");}
else{img = IMG_Load ("image/wall.png");}
break;
case PLAYER:
if(direction.y == 1){ img = IMG_Load ("image/player.png");}
else if(direction.y == -1){ img = IMG_Load ("image/playerLeft.png");}
else if(direction.x == -1){ img = IMG_Load ("image/playerUp.png");}
else if(direction.x == 1){ img = IMG_Load ("image/playerDown.png");}
else if(direction.y == 0 && direction.x == 0){ img = IMG_Load ("image/playerFall.png");}
break;
case TARGET:
img = IMG_Load ("image/target.png");
break;
case BOX:
img = IMG_Load ("image/box.png");
break;
case BOX_ON_TARGET:
img = IMG_Load ("image/box_on_target.png");
break;
case PLAYER_ON_TARGET:
img = IMG_Load ("image/player_on_target.png");
break;
case BUTTON:
img = IMG_Load("image/button.png");
break;
case PLAYER_ON_BUTTON:
img = IMG_Load("image/player_on_button.png");
break;
case BUTTON_CUSTOM:
img = IMG_Load("image/button_c.png");
break;
}
texture
= SDL_CreateTextureFromSurface (display_user->renderer, img);
vect sizeV = {size, size};
displayImage (display_user->renderer, texture, pos, sizeV);
SDL_FreeSurface (img);
SDL_DestroyTexture (texture);
y++;
}
y = 0;
x++;
}
SDL_RenderPresent (display_user->renderer);
}
/**
* \brief Taille de l'ecrant carre en fonction de l'ecrant du joueur avec une
* marge.
* \param display_user Qui serra modifier pour stoquer les information.
* \return La taille max pour la fenetre de l'utilisateur.
*/
int getMaxSize (dis display_user)
{
SDL_Init (SDL_INIT_VIDEO); // init if error
SDL_DisplayMode display;
SDL_GetCurrentDisplayMode (0, &display); // get dim display user
int result = 0;
if (display.w <= display.h)
{
result = display.w;
}
else
{
result = display.h;
}
SDL_Quit ();
int minus_mod = (result - 50) % display_user.size_box;
// printf("DIS :%d, size : %d ,mod : %d\n",result, size_box,minus_mod);
return (result - 50 - minus_mod); // margin
}
/**
* \brief Initialise SDL.
* \param display_user Stockage d'éléments SDL.
* \return Void
*/
void initSDL (dis *display_user)
{
SDL_Init (SDL_INIT_VIDEO);
TTF_Init ();
display_user->window
= SDL_CreateWindow ("Sokoban", SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED, display_user->size_window,
display_user->size_window, SDL_WINDOW_SHOWN);
if (!display_user->window)
{
SDL_Quit ();
perror ("Window null");
exit (-1);
}
display_user->renderer
= SDL_CreateRenderer (display_user->window, -1, SDL_RENDERER_SOFTWARE);
if (!display_user->renderer)
{
SDL_Quit ();
perror ("Renderer null");
exit (-1);
}
}
/**
* \brief Cette fonction affiche l'image dans la fenetre de l'utilisateur.
* \param renderer Le renderer de l'utilisateur.
* \param texture La texture de l'image à appliquer.
* \param pos La position de l'image à afficher.
* \param size La taile de l'image.
* \return Void
**/
void displayImage (SDL_Renderer *renderer, SDL_Texture *texture, vect pos,
vect size)
{
SDL_Rect rect = { pos.x, pos.y, size.x, size.y };
SDL_RenderCopy (renderer, texture, NULL, &rect);
}
/**
* \brief Cette fonction affiche du texte dans la fenetre de l'utilisateur.
* \param display_user Tous les éléments SDL de l'utilisateur.
* \param text Le string à afficher.
* \param coor Les coordonnée du texte.
* \param size La taille du texte.
* \param font_size La taille de la font.
* \return Void
*/
void displayTextSDL (dis *display_user, char *text, vect coor, vect size,
int font_size)
{
TTF_Font *Sans = TTF_OpenFont ("Roboto-Regular.ttf", font_size);
SDL_Color white = { 255, 255, 255, 255 };
int text_width, text_height;
SDL_Rect background;
SDL_Surface *surface_text = TTF_RenderText_Solid (Sans, text, white);
TTF_SizeText (Sans, text, &text_height, &text_width);
SDL_Rect message_rect;
message_rect.x = coor.x;
message_rect.y = coor.y;
message_rect.w = text_height;
message_rect.h = text_width;
background.x = coor.x;
background.y = coor.y;
background.w = text_height;
background.h = text_width;
if (message_rect.w > size.y)
{
message_rect.w = size.y;
background.w = size.y;
}
if (message_rect.h > size.x)
{
message_rect.h = size.x;
background.h = size.x;
}
SDL_Texture *message
= SDL_CreateTextureFromSurface (display_user->renderer, surface_text);
SDL_SetRenderDrawColor (display_user->renderer, 0, 0, 0, 255);
SDL_RenderFillRect (display_user->renderer, &background);
SDL_RenderCopy (display_user->renderer, message, NULL, &message_rect);
SDL_RenderPresent (display_user->renderer);
SDL_FreeSurface (surface_text);
SDL_DestroyTexture (message);
TTF_CloseFont (Sans);
}
/**
* \brief Afficher l'arriere plan.
* \param display_user Tout les information du display de l'utilisateur utile.
* \param bg quel back ground afficher.
*/
void backgroundDisplay(dis *display_user,int bg)
{
SDL_Surface *img;
SDL_Texture *texture;
unsigned int display_game
= display_user->size_window - display_user->size_menu;
int size = display_game / display_user->size_box;
unsigned int marge = display_user->size_menu / 2;
unsigned int i, j, x = 0, y = 0;
int start_i = 0, start_j = 0;
unsigned int limit_i = display_user->size_box, limit_j = display_user->size_box;
img = IMG_Load("image/background.png");
if(bg==1)
{
img = IMG_Load("image/backgroundInGame.png");
}
else if(bg==2)
{
img = IMG_Load("image/backgroundInEditor.png");
}
else if(bg==3)
{
img = IMG_Load("image/backgroundInGame.png");
}
texture = SDL_CreateTextureFromSurface (display_user->renderer, img);
vect pos3 = {0,display_game};
vect sizeV3 = {display_user->size_window , display_user->size_menu };
displayImage(display_user->renderer, texture, pos3, sizeV3);
img = IMG_Load("image/BGColumn.png");
texture = SDL_CreateTextureFromSurface (display_user->renderer, img);
vect pos = {0, 0};
vect sizeV = {marge, display_game };
displayImage(display_user->renderer, texture, pos, sizeV);
texture = SDL_CreateTextureFromSurface (display_user->renderer, img);
vect pos2 = {display_game+marge, 0};
vect sizeV2= {marge, display_game };
displayImage(display_user->renderer, texture, pos2, sizeV2);
SDL_RenderPresent (display_user->renderer);
SDL_Delay(100);
SDL_FreeSurface (img);
SDL_DestroyTexture (texture);
return;
}
/**
* \brief Cette fonction permet de joueur des effet sonor.
* \param sfx un int designant le numero du son a jouer.
* du joueur.
* \return Void
*
*/
void playAudio(int sfx)
{
// Charger un fichier son
Mix_Chunk* sfx_win = Mix_LoadWAV("sfx/win.wav");
Mix_Chunk* sfx_lose = Mix_LoadWAV("sfx/lose.wav");
Mix_Chunk* sfx_cant_move = Mix_LoadWAV("sfx/cantmove.wav");
Mix_Chunk* sfx_block_on_target = Mix_LoadWAV("sfx/blockontarget.wav");
Mix_Chunk* sfx_move = Mix_LoadWAV("sfx/move.mp3");
Mix_Chunk* sfx_move_block = Mix_LoadWAV("sfx/moveblock.wav");
switch (sfx)
{
case 0:
Mix_PlayChannel(-1, sfx_win, 0);
return;
case 1:
Mix_PlayChannel(-1, sfx_lose, 0);
return;
case 2:
Mix_PlayChannel(-1, sfx_cant_move, 0);
return;
case 3:
Mix_PlayChannel(-1, sfx_block_on_target, 0);
return;
case 4:
Mix_PlayChannel(-1, sfx_move, 0);
return;
case 5:
Mix_PlayChannel(-1, sfx_move_block, 0);
return;
}
Mix_FreeChunk(sfx_win);
Mix_FreeChunk(sfx_lose);
Mix_FreeChunk(sfx_cant_move);
Mix_FreeChunk(sfx_block_on_target);
Mix_FreeChunk(sfx_move);
Mix_FreeChunk(sfx_move_block);
}