Le code doit-il être obligatoirement commenté; comme je code seul, je ne commente jamais mes sources (d'ailleurs, je crois que je n'ai jamais écrit un seul commentaire )?
Non, mais il faut que les noms soient explicite et que le code le soit aussi. Un code compliqué DOIT être commenté (la partie compliquée), le reste, pas besoin.
Bonsoir voila mon post pour le concours sdl que j'éditerais au fur et à mesure , si vous ne connaissez pas je vous conseille de l’essayer pour mieux comprendre le jeu la
Sinon Space Invaders est l'un des plus grands succès de l'histoire du jeu vidéo sur borne d'arcade14.
Mon projet c'est de refaire ce jeu .
Le jeu
Le jeu avance très bien avec un .exe pour voir l'ensemble du jeu en bas.
Ce qui est fait et reste à faire :
Le menu X (Faire un plus beau) Collisions avec les boutons du menu V Entrez dans le bouton jouer V Afficher un fond V Faire déplacer le perso V Lui faire tirer un missile mais améliorer la gestion V Corriger le code avec les variables globales V Mettre du son dans le menu V afficher tous les monstres à l'écran X Faire bouger les monstres V verifier les collisions entre le perso et les tirs ennemies X verifier les collisions entre les missiles du perso et les ennemies Gérer le score X
Faire les autres bouton EN COURS
Le screen de la V.01 :
Le Menu un peu sombre mais il va être amélioré
Les Bugs Non résolus : -Parfois le perso ne veux plus tirer en plein parti , si quelqu'un pourrait m'aider je lui en serais reconnaissant .
J'ai réussi
Le Code Source
main.c :
//Main.c : Contient la boucle principale du jeu //
//Crée par HomerEro le 15 avril 2011//
#include"main.h"
int main ( int argc , char *argv[] ) ///Fonction principale
{
(void) argc; // pour éviter les wargning
(void) argv;
//déclaration des variables
Tir tir;
int continuer = 1;
SDL_Surface *screen = NULL;
Input input;
Menu menu;
Perso perso;
Jeu jeu;
All_AABB allAABB;
Ennemi ennemi[18];
Song song;
Gagner gagner;
Boutique boutique;
if(init_all(screen , &menu , &allAABB , &jeu , &perso , ennemi , &song , &tir , &gagner , &boutique ) == 1 )//on initialise tous
{
fprintf(stderr,"Erreur fonction Init_all\n");
return 1;
}
Mix_PlayMusic(song.music , -1); // on joue la music à l'infini
while(continuer == 1)
{
TestInput(&input , &menu , &jeu , &perso , ennemi , &song);
Update(&tir , &input , &menu , &perso , &allAABB , &jeu , ennemi , &gagner , &song , &boutique);
TestCollision(&tir , ennemi , &perso );
draw(&menu , &jeu , &perso , &tir , ennemi , &gagner , &boutique );
SDL_Delay(20);
}
clean_up(&menu , &jeu , &perso , ennemi , &song);
return 0;
}
void clean_up(Menu *menu , Jeu *jeu , Perso *perso , Ennemi ennemi[] , Song *song) ///On libère la mémoire : important
{
int i;
for( i = 1; i < NBR_ENNEMI ; i++)
{
SDL_FreeSurface(ennemi[i].image);
}
SDL_FreeSurface(menu->image);
SDL_FreeSurface(jeu->image);
SDL_FreeSurface(perso->image);
//ne pas oublier de free le tir et la boutique
Mix_FreeMusic(song->music);
Mix_CloseAudio();
SDL_Quit();
}
///Ce qu'il reste à faire :
///Le menu X (Faire un plus beau)
///Collisions avec les boutons du menu V
///Entrez dans le bouton jouer V
///Afficher un fond V
///Faire déplacer le perso V
///Lui faire tirer un missile mais améliorer la gestion V
///Corriger le code avec les variables globales V
///Mettre du son dans le menu V
///afficher tous les monstres à l'écran NON FAIT
///Faire bouger les monstres FAIT
///verifier les collisions entre le perso et les tirs ennemies NON FAIT
///verifier les collisions entre les missiles du perso et les ennemies NON FAIT
///Faire les autres bouton NON FAIT
///Faire les amélioration que reino a dit NON FAIT
///Faire des fonctions et améliorés le code NON FAIT
#include"dessiner.h"
void draw(Menu *menu , Jeu *jeu , Perso *perso , Tir *tir , Ennemi ennemi[] , Gagner *gagner , Boutique *boutique) /// dessine tous à l'écran : Fonction à améliorer
{
SDL_FillRect(SDL_GetVideoSurface() , NULL , 0);// on vide l'écran en noir
//SI ON EST DANS LE MENU
if(menu->dans_menu == 1)
{
SDL_BlitSurface(menu->image , NULL , SDL_GetVideoSurface() , &menu->dest);// On blitte le menu
}
if(boutique->dans_boutique == 1)
{
SDL_BlitSurface(boutique->image , NULL , SDL_GetVideoSurface() , &boutique->dest);
}
//SI ON EST DANS LE JEU
else if(jeu->dans_jeu == 1)
{
SDL_BlitSurface(jeu->image , NULL ,SDL_GetVideoSurface(), &jeu->dest); // on blitte le fond
if(perso->mort == 1) //si le perso n'est pas mort
{
SDL_BlitSurface(perso->image , NULL , SDL_GetVideoSurface(), &perso->dest);
if(tir->sort == 1)//si le perso tire
{
SDL_BlitSurface(tir->image , &tir->source , SDL_GetVideoSurface() , &tir->dest);
}
}
draw_ennemi(ennemi);// on dessine les méchants
}
else if(gagner->dans_gagner == 1)
{
SDL_BlitSurface(gagner->image , NULL , SDL_GetVideoSurface() , &gagner->dest);
}
//ON MET A JOUR
if(SDL_Flip(SDL_GetVideoSurface()) == -1)
{
fprintf(stderr,"Erreur : %s",SDL_GetError());
exit(0);
}
}
#include"init.h"
//Fichier pour toutes les initialisations
SDL_Surface *init_img(const char *file)///Charge une image
{
SDL_Surface *imageRecente = NULL;
SDL_Surface *ancienneImage = NULL;
ancienneImage = IMG_Load(file);
if(ancienneImage == NULL)
{
fprintf(stderr,"Erreur avec l'image : %s\n" , file);
}
imageRecente = SDL_DisplayFormat(ancienneImage);
SDL_SetColorKey(imageRecente , (SDL_SRCCOLORKEY | SDL_RLEACCEL) , SDL_MapRGB( SDL_GetVideoSurface()->format , 0 , 0 , 0));
SDL_SetColorKey(imageRecente , (SDL_SRCCOLORKEY | SDL_RLEACCEL) , SDL_MapRGB( SDL_GetVideoSurface()->format , 211 , 249 , 188));
SDL_FreeSurface(ancienneImage);
return imageRecente ;
}
int init_all(SDL_Surface *screen , Menu *menu , All_AABB *allAABB , Jeu *jeu , Perso *perso , Ennemi ennemi[] , Song *song , Tir *tir , Gagner *gagner , Boutique *boutique) /// Cette fonction appelle toute les fonction qui initialisent quelques chose
{
if(init_sdl(screen) == 1) // initialise la sdl
{
fprintf(stderr, "Erreur dans la fonction init_sdl\n");
return 1;
}
if(init_struct(menu , allAABB , jeu , perso , ennemi , tir , gagner , boutique ) == 1) // initialise les structures
{
fprintf(stderr,"Erreur dans la fonction init_struct\n");
return 1;
}
if(init_sound(song) == 1)
{
return 1;
}
return 0;
}
int init_sdl(SDL_Surface *screen) ///Charge les fonction basic de la SDL
{
if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) == -1)
{
fprintf(stderr,"Erreur lors de l'initialisation de la SDL");
return 1;
}
screen = SDL_SetVideoMode( 700, 700 , 32 , SDL_SWSURFACE | SDL_DOUBLEBUF );
if(SDL_GetVideoSurface() == NULL)
{
fprintf(stderr , "Erreur avec l'écran\n ");
return 1;
}
SDL_WM_SetCaption("Space Invader" , NULL );
return 0;
}
int init_struct(Menu *menu , All_AABB *allAABB , Jeu *jeu , Perso *perso , Ennemi ennemi[] , Tir *tir , Gagner *gagner , Boutique *boutique ) ///Fonction qui remplit toute les structures utilisé dans le programme
{
if( init_ennemi(ennemi) == 1) // initialise la structure ennemi
{
return 1;
}
if(init_menu(menu) == 1) //initialise la structure menu
{
return 1;
}
init_AABB(allAABB); //initialise la structure pour les AABB
if(init_jeu (jeu) == 1)//initialise la structure jeu
{
return 1;
}
init_boutique(boutique);
if(init_perso(perso) == 1)
{
return 1;
}
if(init_tir(tir ) == 1)
{
return 1;
}
init_gagner(gagner);
init_position(ennemi); //sert au position des ennemies
return 0;
}
int init_sound(Song *song)
{
if(Mix_OpenAudio(44100 , MIX_DEFAULT_FORMAT , 2 , 1024) == 1)
{
fprintf(stderr,"Erreur Mix_OpenAudio fonction init_sound\n");
return 1;
}
song->music = Mix_LoadMUS("sound\\song.mp3");
if(song->music == NULL)
{
fprintf(stderr , "Erreur song->music\n");
return 1;
}
return 0;
}
int init_tir(Tir *tir ) // initialise la structure tir
{
load_tir(tir , 1 , "img\\tir.png" , 1 , 0 );
return 0;
}
void init_position(Ennemi ennemi[])
{
ennemi[6].dest.x = 50;
ennemi[6].dest.y = 100;
ennemi[6].dest.w = 30;
ennemi[6].dest.h = 23;
ennemi[6].mort = 1;
ennemi[2].dest.x = 170;
ennemi[2].dest.y = 100;
ennemi[2].dest.h = 21 ;
ennemi[2].dest.w = 30 ;
ennemi[2].mort = 1 ;
ennemi[15].dest.x = 110;
ennemi[15].dest.y = 100;
ennemi[15].dest.h = 21;
ennemi[15].dest.w = 30;
ennemi[15].mort = 1 ;
ennemi[9].dest.x = 230;
ennemi[9].dest.y = 100;
ennemi[9].dest.w = 30;
ennemi[9].dest.h = 21;
ennemi[9].mort = 1;
ennemi[4].dest.x = 290;
ennemi[4].dest.y = 100;
ennemi[4].dest.w = 30;
ennemi[4].dest.h = 21;
ennemi[4].mort = 1;
ennemi[5].dest.x = 350;
ennemi[5].dest.y = 100;
ennemi[5].dest.w = 30;
ennemi[5].dest.h = 21;
ennemi[5].mort = 1;
ennemi[7].dest.x = 410;
ennemi[7].dest.y = 100;
ennemi[7].dest.w = 30;
ennemi[7].dest.h = 21;
ennemi[7].mort = 1;
ennemi[3].dest.x = 470;
ennemi[3].dest.y = 100;
ennemi[3].dest.w = 30;
ennemi[3].dest.h = 21;
ennemi[3].mort = 1;
}
input.c
#include"input.h"
void TestInput(Input *input , Menu *menu , Jeu *jeu , Perso *perso , Ennemi ennemi[] , Song *song) ///Met a jour la structure input quand on appui sur une touche : Fonction vue
{
SDL_Event event;
while(SDL_PollEvent(&event))
{
switch(event.type)
{
case SDL_QUIT :
clean_up(menu , jeu , perso , ennemi , song);
exit(0);
break;
case SDL_KEYDOWN :
switch(event.key.keysym.sym)
{
case SDLK_ESCAPE :
clean_up(menu , jeu , perso , ennemi , song);
exit(0);
break;
case SDLK_RIGHT :
input->droite = 1;
break;
case SDLK_LEFT :
input->gauche = 1;
break;
case SDLK_SPACE :
input->space = 1;
break;
default :
;
break;
}
break;
case SDL_KEYUP :
switch(event.key.keysym.sym)
{
case SDLK_RIGHT :
input->droite = 0;
break;
case SDLK_LEFT :
input->gauche = 0;
break;
case SDLK_SPACE :
input->space = 0;
break;
default :
;
break;
}
break;
case SDL_MOUSEBUTTONDOWN :
switch(event.button.button)
{
case SDL_BUTTON_LEFT :
input->positionSouris.x = event.button.x;
input->positionSouris.y = event.button.y;
input->clic = 1;
break;
}
break;
case SDL_MOUSEBUTTONUP :
switch(event.button.button)
{
case SDL_BUTTON_LEFT :
input->clic = 0;
break;
}
break;
}
}
}
menu.c
#include"menu.h"
///Initialise les structure pour tous le menu(Jeu , options etc..)
int init_menu(Menu *menu)
{
menu->dans_menu = 1;//On est dans le menu par défault
menu->image = init_img("img\\menu.png");
menu->dest.x = 0;
menu->dest.y = 0;
return 0;
}
int init_jeu(Jeu *jeu)///initialise la structure de l'arriere fond pour le jeu : Fonction Vue
{
jeu->image = init_img("img\\fondJeu.png");
jeu->dest.x = 0;
jeu->dest.y = 0;
jeu->dans_jeu = 0; // on n'est pas dans le jeu par défault
return 0;
}
void init_gagner(Gagner *gagner)
{
gagner->image = init_img("img\\gagner.png");
gagner->music = Mix_LoadMUS("sound\\gagner.ogg");
gagner->dest.x = 0;
gagner->dest.y = 0;
gagner->dans_gagner = 0; // on ne gagne pas par défault
}
void init_boutique(Boutique *boutique)
{
boutique->image = init_img("img\\boutique.png");
boutique->music = Mix_LoadMUS("sound\\boutique.ogg");
boutique->dest.x = 0;
boutique->dest.y = 0;
boutique->dans_boutique = 0;//on n'est pas dans la boutique par défault
}
perso.c :
#include"perso.h"
int init_perso(Perso *perso) ///initialise la structure perso pour le jeu
{
perso->image = init_img("img\\perso.png");
perso->dest.x = 700 / 2;//position...
perso->dest.y = 630;//...du perso
perso->nombre_de_vie = 3; //le perso a trois vie par défault
perso->mort = 1; //le perso est vivant par défault
return 0;
}
#include"tir.h"
//Continet la fonction pour tirer et la fonction du timer
void load_tir(Tir *tir , int num , char *file , int activeOuNon , int sort )
{
if(num == 1)
{
tir->image = init_img(file); // on charge l'image du tir qu'une seule fois
tir->active = activeOuNon; // dit si on peux l'utiliser ou pas
tir->sort = sort; // valeur par défault
tir->source.x = 1;
tir->source.y = 1;
tir->source.h = 15;
tir->source.w = 10;
}
}
void tirer(Tir *tir , Perso *perso )///fonction pour que le perso tire un missile
{
tir->sort = 1;
tir->dest.x = perso->dest.x + 29 ;
tir->dest.y = perso->dest.y - 20;
tir->timer = SDL_AddTimer(5, bouger_tir , tir);
}
update.c
#include"update.h"
int droite = 1 , gauche = 0 , bas = 0 , oui = 0, max = 0;
void Update(Tir *tir , Input *input , Menu *menu , Perso *perso , All_AABB *allAABB , Jeu *jeu , Ennemi ennemi[] , Gagner *gagner , Song *song , Boutique *boutique )///Met tous à jour : Fonction Vue
{
if(menu->dans_menu == 1)//si on est dans le menu
{
if(input->clic == 1)//si on clique avec le bouton de la souris
{
if(Collision(input->positionSouris.x , input->positionSouris.y , allAABB->clicJouer) == 1) //voit si on est sur le bouton Jouer
{
menu->dans_menu = 0;
jeu->dans_jeu = 1; // et hop on est dans le jeu
}
if(Collision(input->positionSouris.x , input->positionSouris.y , allAABB->clicScore) == 1) //voit si on est sur le bouton score
{
exit(0);
}
if(Collision(input->positionSouris.x , input->positionSouris.y , allAABB->clicOptions) == 1) // voit si on est sur le bouton option
{
exit(0);
}
if(Collision(input->positionSouris.x , input->positionSouris.y , allAABB->clicBoutique) == 1) // voit si on est sur le outon quitter
{
menu->dans_menu = 0;
boutique->dans_boutique = 1;
}
if(Collision(input->positionSouris.x , input->positionSouris.y , allAABB->clicCredit) == 1) // voit si on est sur le outon quitter
{
exit(0);
}
if(Collision(input->positionSouris.x , input->positionSouris.y , allAABB->clicInventaire) == 1) // voit si on est sur le outon quitter
{
exit(0);
}
}
}
//--------------------------------------------------------------------------------------------------------------------
///Pour le perso :
if(jeu->dans_jeu == 1)//si on est dans le jeu
{
if(input->droite == 1)//si on appuis sur le bouton droit
{
perso->dest.x += VITESSE_PERSO;
}
if(input->gauche == 1)//si on appuis sur le bouton gauche
{
perso->dest.x -= VITESSE_PERSO;
}
if(input->space == 1)//si on appuis sur espace
{
if(tir->active == 1)
{
tirer(tir ,perso );
//input->space = 0; pour que le peros ne réappuis pas sur entré sans arret
}
}
/// Gestion des ennemi
if(droite == 1)
{
ennemi[15].dest.x +=1; // on bouge l'enemi de 1 pixel à chaque fois qu'on passe dans update et qu'on est dans le jeu
ennemi[2].dest.x+=1;
ennemi[6].dest.x+=1;
ennemi[9].dest.x+=1;
ennemi[4].dest.x+=1;
ennemi[5].dest.x += 1;
ennemi[7].dest.x += 1;
ennemi[3].dest.x += 1;
if(ennemi[3].dest.x >= 640)
{
if(oui == 0)
{
bas = 1;
}
}
}
if(bas == 1)
{
ennemi[2].dest.y += 32;
ennemi[15].dest.y += 32;
ennemi[6].dest.y += 32;
ennemi[9].dest.y += 32;
ennemi[4].dest.y += 32;
ennemi[5].dest.y += 32;
ennemi[7].dest.y += 32;
ennemi[3].dest.y += 32;
if(ennemi[15].dest.x >=10)
{
bas = 0;
gauche = 1;
droite = 0;
oui = 1;
}
else
{
bas = 0;
gauche = 0;
oui = 0;
droite = 1;
}
}
if(gauche == 1)
{
ennemi[15].dest.x -=1;
ennemi[2].dest.x-=1;
ennemi[6].dest.x-=1;
ennemi[9].dest.x-=1;
ennemi[4].dest.x-=1;
ennemi[5].dest.x-=1;
ennemi[7].dest.x-=1;
ennemi[3].dest.x-=1;
if(ennemi[15].dest.x <= 0)
{
bas = 1;
oui = 1;
}
}
if(gagnerVar == 0 && max == 0)//si on les tuent tous
{
jeu->dans_jeu = 0;//on quitte le jeu
gagner->dans_gagner = 1;
Mix_HaltMusic();
Mix_PlayMusic(gagner->music , -1 );
max = 6;
}
}
//-----------------------------------------------------------------------------------------------------
if(gagner->dans_gagner == 1)
{
if(input->space == 1)
{
gagner->dans_gagner = 0;
jeu->dans_jeu = 1;
droite = 1 , gauche = 0 , bas = 0 , oui = 0, max = 0,gagnerVar = 8;
init_position(ennemi);
Mix_HaltMusic();
Mix_PlayMusic(song->music , -1);
}
}
if(boutique->dans_boutique == 1 && max == 0)
{
Mix_HaltMusic();
Mix_PlayMusic(boutique->music , -1);
max = 6;
}
}
#include"structs.h"
SDL_Surface *init_img(const char *file);//prototype
Uint32 bouger_ennemi_droite(Uint32 temp , void *ennemi );
Uint32 bouger_ennemi_bas(Uint32 temp , void *ennemi );
extern int droite;
extern int gauche;
extern int max;
init.h
#include"structs.h"
///Prototype utilisés
int init_sdl(SDL_Surface *screen);
int init_struct(Menu *menu , All_AABB *allAABB , Jeu *jeu , Perso *perso , Ennemi ennemi[] , Tir *tir , Gagner *gagner , Boutique *boutique );
int init_ennemi();
int init_menu(Menu *menu);
void init_AABB();
int init_jeu();
int init_perso();
int init_sound(Song *song);
int init_tir(Tir *tir);
void load_tir(Tir *tir , int num , char *file , int activeOuNon , int sort );
void init_position(Ennemi ennemi[]);
void init_gagner(Gagner *gagner);
input.h
#include"structs.h"
void clean_up(Menu *menu , Jeu *jeu , Perso *perso , Ennemi ennemi[] , Song *song);///prototypes
main.h
#include"structs.h"
///Prototype
int init_all(SDL_Surface *screen , Menu *menu , All_AABB *allAABB , Jeu *jeu , Perso *perso , Ennemi ennemi[] , Song *song , Tir *tir , Gagner *gagner , Boutique *boutique);
void TestInput(Input *input , Menu *menu , Jeu *jeu , Perso *perso , Ennemi ennemi[] , Song *song);
void draw(Menu *menu , Jeu *jeu , Perso *perso , Tir *tir , Ennemi ennemi[] , Gagner *gagner , Boutique *boutique);
void clean_up(Menu *menu , Jeu *jeu , Perso *perso , Ennemi ennemi[] , Song *song);
void Update(Tir *tir , Input *input , Menu *menu , Perso *perso , All_AABB *allAABB , Jeu *jeu , Ennemi ennemi[] , Gagner *gagner , Song *song , Boutique *boutique);
SDL_Surface *init_img(const char *file);
void TestCollision(Tir *tir , Ennemi ennemi[], Perso *perso );
void gestion_ennemi(Ennemi ennemi[] , Jeu *jeu);
int gagnerVar = 8 ;
#include"defs.h"
///Toute les structures utilisés dans le programme
typedef struct
{
SDL_Surface *image;
SDL_Rect dest;
int mort; // pour voir si l'ennemi est encore en vie ou pas
}Ennemi;
typedef struct
{
int droite , gauche , space;
SDL_Rect positionSouris;
int clic;
}Input;
typedef struct
{
SDL_Surface *image;
SDL_Surface *fondJeu;
SDL_Rect dest;
int dans_menu; // 1 = dans le menu ; 0 = autre part
}Menu;
typedef struct
{
SDL_Surface *image;
SDL_Rect dest;
int nombre_de_vie;//le nombre de vie qu'a le perso
int mort; //si le perso est mort
}Perso;
typedef struct
{
int x,y,h,w;
}AABB;
typedef struct
{
AABB clicJouer;
AABB clicOptions;
AABB clicScore;
AABB clicCredit;
AABB clicBoutique;
AABB clicInventaire;
}All_AABB;
typedef struct
{
SDL_Surface *image;
SDL_Rect dest;
int dans_jeu;//1 = dans le jeu ; 0 = autre part
}Jeu;
typedef struct
{
SDL_Surface *image;
SDL_Rect dest;
Mix_Music *music;
int dans_gagner;
}Gagner;
typedef struct
{
SDL_Surface *image;
SDL_Rect dest;
Mix_Music *music;
int dans_boutique; // 1 = dans la boutique ; 0 = autre part
}Boutique;
typedef struct
{
SDL_Surface *image;
SDL_Rect dest;
SDL_Rect source;
SDL_TimerID timer;
int sort; // 1 = dans l'écran . 0 = hors de l'écran
int active;
}Tir;
typedef struct
{
Mix_Music *music;
}Song;
Enfin
La nouvelle version sort plus vite que prévue aujourd'hui au lieu de mercredi avec le premier niveau terminé et l'accès à la boutique qui n'est pas terminé
bonjour,
Comme je vais être très occupé ces prochaines semaines, je ne pourrai plus pousser plus loin mon projet pour le concours. En même temps, comme j'avais visé le 1er Mai, il est comme je l'aurais rendu à cette date ou presque.
Ceci dit, je ne me retire pas, je vais simplement être moins ambitieux sur le projet (pas de mode défi) et le rendre dans son état actuel, il est opérationnel et testé.
Cela permettra aux correcteurs de prendre un peu d'avance et leur éviter de se retrouver avec une charge excessive.
Juste une question : Je le rend à qui et sous quelle forme ?
Salut,
Je vois ce concours, l'idée est super!
Je m'inscris, en 1 mois (heureusement la date D à été retardée) j'ai le temps de faire un petit quelque chose pas mal...
Un Bomberman. Il n'est pas ici parceque je m'étais retiré quand la date limite était fixée au 1er mai, mais maintenant j'ai reppris, mais dans le doute je ne montrerais que mon projet fini. Sinon y'a un topic ici mais tout n'est pas à jour, loin de là.
Bon, mon premier message étant passé inaperçu sans doute du fait qu'il soit mal expliqué, je vais faire une jolie présentation de mon projet pour plus de clarté.
Shaak
</span></span>
Description du jeu
Shaak est un jeu de rôle fantastique. Au départ, le joueur choisit une classe de personnage (archer, guerrier, magicien, nécromancien, mort-vivant, etc...) puis il est ensuite placé sur la carte dans la ville. A partir de là il aura le choix entre aller acheter des objets dans les magasins, aller chercher une quête à la taverne, améliorer ses compétences d'attaque de défense et de chance de coups critiques au temple de compétences, aller déposer/retirer des objets à la banque, aller dans un souterrain plein de monstres pour une quête, vous soigner à la fontaine ou encore aller combattre plein de monstres en dehors de la ville.
Le joueur améliorera au fur et à mesure ses armes, armures, compétences afin de pouvoir un jour battre le boss de fin de jeu pour libérer la princesse du royaume de Shaak qui a été kidnappée (très original le scénario n'est-ce pas ? )
Carte du jeu
Voici la carte principale du jeu en taille réelle. C'est celle qui fait le lien avec toutes les autres cartes (magasin, armurerie, etc...) Elle n'a pas encore d'images car j’attends un contact que le graphiste de l'équipe me contacte (pour ceux qui veulent savoir qui est le graphiste, c'est sismic)
N'hésitez pas à aller voir le topic de présentation du jeu et à y poster un petit commentaire ça fait toujours plaisir de savoir que des gens suivent le projet
C'est le premier programme qui tourne sur mac sans que j'ai à le compiler.
Après, sans la Segmentation fault qui intervient tout de suite après le démarrage, le jeu dois être bien.
Oui il y a un petit bug avec la version mac, en fait elle ne vient pas de moi c'est mon cousin qui l'a faite je vais essayer de voir avec lui pourquoi ça ne marche pas. En fait on a vraiment pris la peine de le recompiler car il fallait changer plein de choses. En particulier les system("cls") et les Sleep()
Je vous tiens au courant quand la version console-mac marchera
Tiens j'ai juste vu ce topic, alors j'ai code un petit programme nomme SDFx
But de SDFx (Simple DirectMedia Effects)
SDFx utilise la SDL pour appliquer des effets simples au images chargees, comme des effets de blur ou un effet de clapotis.
Code
Le code est ecrit en C++ et utilise la SDL et les modules SDL_ttf et SDL_Image
Voici le code actuel
main.cpp
#include "Ripple.h"
#include "Blur.h"
#include "Negative.h"
#include "Sobel.h"
#include "Emboss.h"
#include "Sharpen.h"
#include "Menu.h"
int main ( int argc, char *argv[] )
{
// initialize SDL video
if(!SDL::Init()) return 1;
// make sure SDL cleans up before exit
atexit(SDL_Quit);
// create a new window
SDL_Surface* screen = SDL_SetVideoMode(800, 600, 16,
SDL_HWSURFACE|SDL_DOUBLEBUF);
if ( !screen ) return 1;
if (SDL_MUSTLOCK(screen)) {
if (SDL_LockSurface(screen) < 0) {
return 1;
}
}
// Set window title to SDLFx, with no icon
SDL_WM_SetCaption("SDLFx",NULL);
// Load the font used to show the status text
TTF_Font* font = TTF_OpenFont("kiddysans.ttf",18);
//Load the background image and use command line arguments
SDL_Surface* bg;
if(argc > 1) {
bg = IMG_Load(argv[1]); // First argument -> image path
if(argc > 3) { // Second and third arguments -> window size (width and height)
screen = SDL_SetVideoMode(atoi(argv[2]),atoi(argv[3]),16,
SDL_HWSURFACE|SDL_DOUBLEBUF);
}
} else {
bg = IMG_Load("img.png"); // No arguments -> automatically open img.png
}
// Initialize effects
std::vector<Effect*> effects;
effects.push_back(new Ripple(screen->w,screen->h)); // Ripple effect
effects.push_back(new Blur()); // Blur effect
effects.push_back(new Negative()); // Negative colors effect
effects.push_back(new Sobel()); // Sobel effect
effects.push_back(new Emboss()); // Emboss effect
effects.push_back(new Sharpen()); // Sharpen effect
// Start menu
Menu menu(effects,screen,font);
// Loop up
bool loop = true;
while(loop) {
SDL_Event event;
while (SDL_PollEvent(&event)) {
if(event.type == SDL_QUIT) {
// If the user closed the window, break the loop
loop = false;
} else {
// Else let the menu process the event
menu.process(event);
}
}
SDL::Clear(screen);
// Blit the background
SDL::Blit(bg,screen,0,0);
// Blit the menu button to the screen
menu.draw();
SDL_Flip(screen);
}
//Free stuff
TTF_CloseFont(font);
SDL_FreeSurface(bg);
TTF_Quit();
return 0;
}
SDLPP.h
#ifndef SDLPP_H
#define SDLPP_H
#ifdef __APPLE__
#include <SDL/SDL.h>
#include <SDL/SDL_ttf.h>
#else
#include <SDL.h>
#include <SDL_ttf.h>
#include <SDL_image.h>
#endif
#include <cstdlib>
// SDL namespace containing some helper functions
namespace SDL {
// getpixel: Returns a pixel given the surface we want to retrieve it from and its coordinates
Uint32 getpixel(SDL_Surface *surface, int x, int y);
// putpixel: basically does the inverse than getpixel, changes the value of a pixel on the surface "surface" at the coordinates (x,y) to "pixel"
void putpixel(SDL_Surface *surface, int x, int y, Uint32 pixel);
// Blit: blit function that requires no SDL_Rect arguments (automatically build them from the coordinates passed)
void Blit(SDL_Surface* surface, SDL_Surface* screen, Sint16 x, Sint16 y);
// Clear: fills the surface "screen" with black
void Clear(SDL_Surface* screen);
// Init: calls the initialization functions for SDL and SDL_ttf and returns wether all went well or if there was a problem on initialization
bool Init();
// Transforms a surface to its grayscale equivalent
void toGrayscale(SDL_Surface* screen);
// Copies the specified image (the two images will NOT point on the same pixel data)
SDL_Surface* copy(SDL_Surface* s);
}
#endif//SDLPP_H
SDLPP.cpp
#include "SDLPP.h"
Uint32 SDL::getpixel(SDL_Surface *surface, int x, int y) {
int bpp = surface->format->BytesPerPixel;
/* Here p is the address to the pixel we want to retrieve */
Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
switch (bpp) {
case 1:
return *p;
case 2:
return *(Uint16 *)p;
case 3:
if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
return p[0] << 16 | p[1] << 8 | p[2];
else
return p[0] | p[1] << 8 | p[2] << 16;
case 4:
return *(Uint32 *)p;
default:
return 0; /* shouldn't happen, but avoids warnings */
} // switch
}
void SDL::putpixel(SDL_Surface *surface, int x, int y, Uint32 pixel){
int bpp = surface->format->BytesPerPixel;
/* Here p is the address to the pixel we want to set */
Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
switch (bpp) {
case 1:
*p = pixel;
break;
case 2:
*(Uint16 *)p = pixel;
break;
case 3:
if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
p[0] = (pixel >> 16) & 0xff;
p[1] = (pixel >> 8) & 0xff;
p[2] = pixel & 0xff;
}
else {
p[0] = pixel & 0xff;
p[1] = (pixel >> 8) & 0xff;
p[2] = (pixel >> 16) & 0xff;
}
break;
case 4:
*(Uint32 *)p = pixel;
break;
default:
break; /* shouldn't happen, but avoids warnings */
} // switch
}
void SDL::Blit(SDL_Surface* surface, SDL_Surface* screen, Sint16 x, Sint16 y) {
SDL_Rect pos;
pos.x = x;
pos.y = y;
SDL_BlitSurface(surface,NULL,screen,&pos);
}
void SDL::Clear(SDL_Surface* screen) {
SDL_FillRect(screen, 0, SDL_MapRGB(screen->format, 0, 0, 0));
}
bool SDL::Init() {
return ((SDL_Init(SDL_INIT_VIDEO) >= 0 ) && (TTF_Init() >= 0));
}
void SDL::toGrayscale(SDL_Surface* screen) {
//0.2989 * R + 0.5870 * G + 0.1140 * B
Uint8 r = 0, g = 0, b = 0;
for(int x = 0; x < screen->w; x++) {
for(int y = 0; y < screen->h; y++) {
SDL_GetRGB(SDL::getpixel(screen,x,y),screen->format,&r,&g,&b);
Uint8 col = r * 0.2989 + g * 0.5879 + b * 0.1140;
SDL::putpixel(screen,x,y,SDL_MapRGB(screen->format,col,col,col));
}
}
}
SDL_Surface* SDL::copy(SDL_Surface* s) {
SDL_Surface* ret;
ret = SDL_CreateRGBSurface(SDL_HWSURFACE,s->w,s->h,s->format->BitsPerPixel,s->format->Rmask,s->format->Gmask,s->format->Bmask,s->format->Amask);
SDL::Blit(s,ret,0,0);
return ret;
}
Button.h
#ifndef BUTTON_H
#define BUTTON_H
#include "SDLPP.h"
// Simple button class that holds an image for the button as well as its coordinates and can check wether its being clicked through the checkPressed function.
class CheckButton {
public:
CheckButton(int _x, int _y, SDL_Surface* screen);
~CheckButton();
void process(const SDL_Event& event);
void draw();
bool isChecked() const;
private:
void setPressed(bool n);
bool pressed;
int x;
int y;
SDL_Surface* bg;
SDL_Surface* outline;
SDL_Surface* screen;
};
#endif//BUTTON_H
#ifndef EFFECT_H
#define EFFECT_H
#include <string>
#include "SDLPP.h"
// Effect abstract class
// Base class for all effects
class Effect {
public:
// Initialize effect with its name (used by Menu to open the button image for the effect)
Effect(const std::string& _name) {
name = _name;
}
// Get the name of the effect
const std::string& getName() const {
return name;
}
// Renders the effect on the surface given
virtual void render(SDL_Surface* screen) =0;
// Processes events to change parameters
virtual void process(const SDL_Event& event) =0;
private:
std::string name;
};
#endif//EFFECT_H
Ripple.h
#ifndef RIPPLE_H
#define RIPPLE_H
#include "Effect.h"
#include <algorithm>
// Ripple effect
// Effect based on heightmaps that simulates a ripple on a liquid (usually water ;D)
class Ripple : public Effect {
public:
Ripple(int width, int height);
~Ripple();
void render(SDL_Surface* screen);
void process(const SDL_Event& event);
private:
int** Buffer1;
int** Buffer2;
int w;
int h;
float damping;
int incentive;
bool mouseDown;
int ips;
};
#endif//RIPPLE_H
Ripple.cpp
#include "Ripple.h"
// Initialize parameters
Ripple::Ripple(int width, int height) : Effect("ripple") {
damping = 0.95f;
incentive = 120;
w = width;
h = height;
mouseDown = false;
ips = 60; // ips: images per second
// This is used so that the speed the water "falls" is the same on every computer with the same settings
Buffer1 = new int* [w]; // Create the buffers (ugly two-dimensional variable-length allocation)
Buffer2 = new int* [w]; // but is better for performance than using a two-dimensional vector
for(register int i=0; i<w; i++) {
Buffer1[i] = new int [h];
Buffer2[i] = new int[h];
for(int j = 0; j < h; j++) {
Buffer1[i][j] = 0; // Also fill the Buffers with 0 values (This avoids strange behaviour :p)
Buffer2[i][j] = 0;
}
}
}
// process events and change parameters accordingly
void Ripple::process(const SDL_Event& event) {
switch(event.type) {
case SDL_MOUSEBUTTONDOWN:
mouseDown = true;
break;
case SDL_MOUSEBUTTONUP:
mouseDown = false;
break;
case SDL_KEYDOWN:
switch(event.key.keysym.sym) {
case SDLK_UP:
damping += 0.05f;
if(damping > 1.f) damping = 1.f;
break;
case SDLK_DOWN:
damping -= 0.05f;
if(damping < 0.f) damping = 0.f;
break;
case SDLK_RIGHT:
incentive += 10;
break;
case SDLK_LEFT:
incentive -= 10;
break;
default:
break;
}
break;
default:
break;
}
// If mouse is down, go ahead and heighten the water, thus provoccing a ripple
if(mouseDown) {
Buffer1[event.button.x][event.button.y] = incentive;
}
}
void Ripple::render(SDL_Surface* screen) {
// Computation //
// For each point of the height map
for (int i = 0; i < w; i++) {
for (int j = 0; j < h; j++) {
if(i != 0 && j != 0 && i != w-1 && j != h-1) {
// That is not on the edge
// The new height of the point is
// The sum of all the points around it divided by two
// Then substracted by the height it had two ticks before
// Then we use the damping parameter to regulate how tall the point will finally be
Buffer2[i][j] = (Buffer1[i-1][j] + Buffer1[i+1][j] + Buffer1[i][j+1] + Buffer1[i][j-1]) / 2 - Buffer2[i][j];
Buffer2[i][j] = damping*Buffer2[i][j];
}
}
}
// Render //
// r,g,b values that will be used many times in the render loop
Uint8 r = 0 , g = 0, b = 0;
// For each point in the heightmaps (and subsequently each pixel on the screen)
for(int i = 0; i < w; i++) {
for(int j = 0; j < h; j++) {
if(i != 0 && j != 0 && i != w-1 && j != h-1) {
// If the point is not on the edge
int xOff = Buffer2[i-1][j] - Buffer2[i+1][j];
// Get the height offset between the two adjacent points of the current point on the x and y directions
int yOff = Buffer2[i][j-1] - Buffer2[i][j+1];
if(i+xOff < w-1 && j+yOff < h-1 && i+xOff > 0 && j+yOff > 0) {
// Get the color of the point situated at (current point x + x height offset , current point y + y height offset)
int col = SDL::getpixel(screen,i+xOff,j+yOff);
SDL_GetRGB(col,screen->format,&r,&g,&b);
//The more the offset, the darker the color
r = (r - xOff < 0) ? 0 : r - xOff;
g = (g - xOff < 0) ? 0 : g - xOff;
b = (b - xOff < 0) ? 0 : b - xOff;
// Color the current pixel with the resulting color
col = SDL_MapRGB(screen->format,r,g,b);
SDL::putpixel(screen,i,j,col);
}
}
}
}
// Finally, swap the two heightmaps.
std::swap(Buffer1,Buffer2);
// Wait 1000/ips milliseconds to re-loop
// This regulates fps to be approximately equal to ips
// Thus, the ripple will render the same on any computer (that is not 10+ years old ;o)
SDL_Delay(1000/ips);
}
Ripple::~Ripple() {
// Ugly variable size two-dimensional array de-allocation
for(register int i=w-1; i>=0; i--) {
delete [] Buffer1[i];
delete [] Buffer2[i];
}
delete [] Buffer1;
delete [] Buffer2;
}
Blur.h
#ifndef BLUR_H
#define BLUR_H
#include "Effect.h"
// The blur effect is an effect that "smoothens" an image
class Blur : public Effect {
public:
Blur();
void render(SDL_Surface* screen);
void process(const SDL_Event& event);
private:
void horizontalBlur(SDL_Surface* screen);
void verticalBlur(SDL_Surface* screen);
int radius;
int iterations;
};
#endif//BLUR_H
Blur.cpp
#include "Blur.h"
// Initialize parameters
Blur::Blur() : Effect("blur") {
radius = 1;
iterations = 1;
}
// Horizontal-only blur
void Blur::horizontalBlur(SDL_Surface* screen) {
Uint8 r = 0 , g = 0, b = 0;
for(int y = 0; y < screen->h; y++) {
for(int x = 0; x < screen->w; x++) {
// For each pixel in screen
int totalr = 0, totalg = 0, totalb = 0;
// Get the sum of the colors of the pixels from radius left from the current pixel to radius right of it
for(int kx = -radius; kx <= radius; kx++) {
if(x+kx < screen->w && x+kx > 0) {
int col = SDL::getpixel(screen,x+kx,y);
SDL_GetRGB(col,screen->format,&r,&g,&b);
totalr += r;
totalg += g;
totalb += b;
}
}
// And then fnd the average
totalr /= radius*2+1;
totalg /= radius*2+1;
totalb /= radius*2+1;
// This average color is the smoothened color of the pixel
Uint32 final = SDL_MapRGB(screen->format,totalr,totalg,totalb);
SDL::putpixel(screen,x,y,final);
}
}
}
void Blur::verticalBlur(SDL_Surface* screen) {
// Vertical-only blur
// This is pretty much the same as above, only the radius extends up and above the current pixel instead of left and right
// And the order the pixels are processed is different
Uint8 r = 0 , g = 0, b = 0;
for(int x = 0; x < screen->w; x++) {
for(int y = 0; y < screen->h; y++) {
int totalr = 0, totalg = 0, totalb = 0;
for(int ky = -radius; ky <= radius; ky++) {
if(y+ky < screen->h && y+ky > 0) {
int col = SDL::getpixel(screen,x,y+ky);
SDL_GetRGB(col,screen->format,&r,&g,&b);
totalr += r;
totalg += g;
totalb += b;
}
}
totalr /= radius*2+1; // Average color of the pixels in radius
totalg /= radius*2+1;
totalb /= radius*2+1;
Uint32 final = SDL_MapRGB(screen->format,totalr,totalg,totalb);
SDL::putpixel(screen,x,y,final);
}
}
}
void Blur::render(SDL_Surface* screen) {
// Blur the image iteration times
for(int i = 0 ; i < iterations; i++) {
horizontalBlur(screen); // Blur horizontally only
verticalBlur(screen); // And then blur vertically =D
// == total blur
}
}
// Change blur parameters
void Blur::process(const SDL_Event& event) {
if(event.type == SDL_KEYDOWN) {
if(event.key.keysym.sym == SDLK_UP) {
radius += 1;
} else if(event.key.keysym.sym == SDLK_DOWN) {
radius -= 1;
} else if(event.key.keysym.sym == SDLK_RIGHT) {
iterations++;
} else if(event.key.keysym.sym == SDLK_LEFT) {
iterations--;
}
}
}
Negative.h
#ifndef NEGATIVE_H
#define NEGATIVE_H
#include "Effect.h"
// Effect that shows the image in negative colors
class Negative : public Effect {
public:
Negative();
void render(SDL_Surface* screen);
void process(const SDL_Event&);
};
#endif//NEGATIVE_H
Negative.cpp
#include "Negative.h"
Negative::Negative() : Effect("negative") {
}
void Negative::render(SDL_Surface* screen) {
Uint8 r = 0 , g = 0, b = 0;
for(int x = 0; x < screen->w; x++) {
for(int y = 0; y < screen->h; y++) {
int col = SDL::getpixel(screen,x,y);
SDL_GetRGB(col,screen->format,&r,&g,&b);
// Negate the color of each pixel. To negate an rgb color, you just have to change
// Its r,g,b channels to 255-r,255-g,255-b
SDL::putpixel(screen,x,y,SDL_MapRGB(screen->format,255-r,255-g,255-b));
}
}
}
void Negative::process(const SDL_Event&) {
// Simpler effect, evar, nothing to process
}
Sobel.h
#ifndef SOBEL_H
#define SOBEL_H
#include "Effect.h"
#include "Convolution.h"
#include <cmath> // Pow and sqrt
// The SObel effect is an implementation of the Sobel edge detection operator using 2d kernel convolution
class Sobel : public Effect {
public:
Sobel();
void render(SDL_Surface* screen);
void process(const SDL_Event&);
const std::string getStatusText() const;
private:
Kernel horizontal;
Kernel vertical;
};
#endif//SOBEL_H
Sobel.cpp
#include "Sobel.h"
Sobel::Sobel() : Effect("sobel") {
// Setup the kernels
std::vector<float> row;
row.push_back(-1);
row.push_back(0);
row.push_back(1);
horizontal.push_back(row);
row.clear();
row.push_back(-2);
row.push_back(0);
row.push_back(2);
horizontal.push_back(row);
row.clear();
row.push_back(-1);
row.push_back(0);
row.push_back(1);
horizontal.push_back(row);
row.clear();
row.push_back(1);
row.push_back(2);
row.push_back(1);
vertical.push_back(row);
row.clear();
row.push_back(0);
row.push_back(0);
row.push_back(0);
vertical.push_back(row);
row.clear();
row.push_back(-1);
row.push_back(-2);
row.push_back(-1);
vertical.push_back(row);
}
const std::string Sobel::getStatusText() const {
return getName();
}
void Sobel::render(SDL_Surface* screen) {
// Convert screen to grayscale for better rendering
SDL::toGrayscale(screen);
// Copy the original screen
SDL_Surface* in = SDL::copy(screen);
if( SDL_MUSTLOCK(in) ) {
SDL_LockSurface(in); // And make sure we can access its pixels
}
// Apply G = sqrt ( Gx^2 + Gy^2 ) , where G is final render
// Gx*A = applied vertical kernel
// Gy*A = applied horizontal kernel
for(int x = 0; x < screen->w; x++) { // Maybe i should put a method like this directly in Convolution.h ? It seems pretty used overall
for(int y = 0; y < screen->h; y++) {
int color1 = horizontal.applyToPixel(in,x,y);
int color2 = vertical.applyToPixel(in,x,y);
Uint8 r1 = 0, r2 = 0, g1 = 0, g2 = 0, b1 = 0, b2 = 0;
SDL_GetRGB(color1,in->format,&r1,&g1,&b1);
SDL_GetRGB(color2,in->format,&r2,&g2,&b2);
int r = std::sqrt(r1*r1+r2*r2);
int g = std::sqrt(g1*g1+g2*g2);
int b = std::sqrt(b1*b1+b2*b2);
if(r > 255) r = 255;
if(g > 255) g = 255;
if(b > 255) b = 255;
SDL::putpixel(screen,x,y,SDL_MapRGB(screen->format,r,g,b));
}
}
SDL_FreeSurface(in); // And free the original image
}
void Sobel::process(const SDL_Event&) {
}
Convolution.h
#ifndef CONVOLUTION_H
#define CONVOLUTION_H
#include <vector>
#include "Effect.h"
// Kernel is a vector of rows (rows are vectors of floats :D) used to apply 2d convolution to images
// And thus apply effects just based on an array of numbers
class Kernel : public std::vector<std::vector<float> > {
public:
Kernel();
bool valid() const;
void apply(SDL_Surface* screen);
Uint32 applyToPixel(SDL_Surface* screen,int x,int y);
};
// ConvolutionEffect abstract class declaration
// Effect that uses 1 kernel and simply applies it
class ConvolutionEffect : public Effect {
public:
ConvolutionEffect(const std::string& name) : Effect(name) {}
void render(SDL_Surface* screen) {
kernel.apply(screen);
}
void process(const SDL_Event&) {}
protected:
Kernel kernel;
};
#endif//CONVOLUTION_H
Convolution.cpp
#include "Convolution.h"
// Just initialize the kernel
Kernel::Kernel() : std::vector<std::vector <float> >() {}
// Checks if all rows have the same number of columns
bool Kernel::valid() const {
unsigned int first_size = front().size();
for(unsigned int i = 1; i < size(); i++) {
if(at(i).size() != first_size) return false;
}
return true;
}
// Applies the kernel to a specific pixel of a specific iamge and return the final color the pixel will take
Uint32 Kernel::applyToPixel(SDL_Surface* screen,int x,int y) {
// Will be used in loop
Uint8 r = 0, g = 0, b = 0;
float rSum = 0.f , gSum = 0.f, bSum = 0.f, kSum = 0.f;
for(unsigned int i = 0; i < size(); i++) {
int ky = size() - 1 - i; // Get the cells y position. In fact, we go through the loop as if we would take the cells in a upper-left corner to lower-right corner fashion
// When in fact we start taking them from the lower-right corner. This is done because we will have to take the pixel that is "across" the current cell
// If we transpose the kernel on the pixels
// Its a difficult enough thing to understand
// More info on http://www.songho.ca/dsp/convolution/convolution.html
for(unsigned int j = 0; j < at(0).size(); j++) { // For each cell in the kernel
int kx = at(0).size() - 1 - j; // Get the cell's x position in the same fashion
float fKernel = at(ky).at(kx); // Get the content of current cell
int nx = x + (j - at(0).size()/2); // Get the pixel "accross" the current cell
int ny = y + (i - size()/2); // (If we transpose kernel on the image so that the center of the kernel is on top of the current pixel [(x,y)])
if(nx > 0 && nx < screen->w && ny > 0 && ny < screen->h) { // Check the pixel is inside the image
SDL_GetRGB(SDL::getpixel(screen,nx,ny),screen->format,&r,&g,&b); // And if so get its rgb components
rSum += r*fKernel; // Wich we then multiply by the current cell and add up to the sum of each component
gSum += g*fKernel;
bSum += b*fKernel;
kSum += fKernel; // And finally add the cell to the sum of the cells
}
}
}
if(kSum <= 0) kSum = 1.f; // Make sure we dont divide by zero
rSum /= kSum; // Think of this like an average of each component of a 2d array of pixels
gSum /= kSum; // Only in fact each pixel has a more or less important role (weight) in this average
bSum /= kSum; // According to a number that we associate it with
if(rSum > 255) rSum = 255.f; // make sure our components are inside the rgb bounds (0..255)
if(gSum > 255) gSum = 255.f;
if(bSum > 255) bSum = 255.f;
if(rSum < 0) rSum = 0.f;
if(gSum < 0) gSum = 0.f;
if(bSum < 0) bSum = 0.f;
return SDL_MapRGB(screen->format,rSum,gSum,bSum); // And return the color that the components form
}
// Applies the kernel convolution to the screen
void Kernel::apply(SDL_Surface* screen) {
// Copy the original image
SDL_Surface* in = SDL::copy(screen);
if( SDL_MUSTLOCK(in) ) {
SDL_LockSurface(in); // Make sure we can access its pixels
}
for(int x = 0; x < screen->w; x++) {
for(int y = 0; y < screen->h; y++) { // For every pixel in screen do
Uint32 n = applyToPixel(in,x,y); // Apply the kernel
SDL::putpixel(screen,x,y,n); // And show new pixel color =D
}
}
SDL_FreeSurface(in); // Then free the original image ;D
}
Menu.h
#ifndef MENU_H
#define MENU_H
#include <vector>
#include "Button.h"
#include "Effect.h"
// Class that takes a vector of effects and shows a menu to the user to pick wich ones to apply
// // Render the menu at 3 * w/4, h/4
class Menu {
public:
Menu(const std::vector<Effect*>& _effects, SDL_Surface* screen, TTF_Font* font);
~Menu();
void draw();
void process(const SDL_Event& event);
private:
int x;
int y;
SDL_Surface* bg;
SDL_Surface* screen;
std::vector<CheckButton*> checkButtons;
std::vector<SDL_Surface*> texts;
const std::vector<Effect*>& effects;
};
#endif//MENU_H
Menu.cpp
#include "Menu.h"
// Construct the menu from the vector of effects an the width of the screen (used to calibrate the buttons' position)
Menu::Menu(const std::vector<Effect*>& _effects, SDL_Surface* _screen, TTF_Font* font) : effects(_effects) {
screen = _screen;
SDL_Color textCol = {255,255,255,0};
// First button's coordinates
x = screen->w - 100;
y = screen->h/4;
bg = SDL_CreateRGBSurface(SDL_HWSURFACE,100,effects.size()*30 + 10,32,0,0,0,0);
SDL_FillRect(bg,NULL,SDL_MapRGB(screen->format,51,204,255));
for(unsigned int i = 0 ; i < effects.size(); i++) {
// Create a button for each effect
checkButtons.push_back(new CheckButton(x+75,y + i*30 + 10,screen));
texts.push_back(TTF_RenderText_Blended(font,effects.at(i)->getName().c_str(),textCol));
}
}
void Menu::draw() {
// Run the effects
for(unsigned int i = 0; i < effects.size(); i++) {
if(checkButtons[i]->isChecked()) {
effects[i]->render(screen);
}
}
SDL::Blit(bg,screen,x,y);
for(unsigned int i = 0; i < effects.size(); i++) {
SDL::Blit(texts[i],screen,x+5,y + i*30 + 10);
checkButtons[i]->draw();
}
}
void Menu::process(const SDL_Event& event) {
for(unsigned int i = 0; i < checkButtons.size(); i++) {
checkButtons[i]->process(event);
effects[i]->process(event);
}
}
Menu::~Menu() {
// Delete assigned buttons
for(unsigned int i = 0; i < checkButtons.size(); i++) {
delete checkButtons[i];
SDL_FreeSurface(texts[i]);
}
SDL_FreeSurface(bg);
}
Emboss.h
#ifndef EMBOSS_H
#define EMBOSS_H
#include "Convolution.h"
class Emboss : public ConvolutionEffect {
public:
Emboss();
};
#endif//EMBOSS_H
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
Bonhomme !! | Jeu de plateforme : Prototype.