diff --git a/Space Invaders/Envahisseurs/Graphique/Lutins/Coeur.bmp b/Space Invaders/Envahisseurs/Graphique/Lutins/Coeur.bmp new file mode 100644 index 0000000..823e8a0 Binary files /dev/null and b/Space Invaders/Envahisseurs/Graphique/Lutins/Coeur.bmp differ diff --git a/Space Invaders/Envahisseurs/Graphique/Lutins/invader_bombe.bmp b/Space Invaders/Envahisseurs/Graphique/Lutins/invader_bombe.bmp new file mode 100644 index 0000000..0b3e39b Binary files /dev/null and b/Space Invaders/Envahisseurs/Graphique/Lutins/invader_bombe.bmp differ diff --git a/Space Invaders/Envahisseurs/Graphique/Lutins/invader_bouclier.bmp b/Space Invaders/Envahisseurs/Graphique/Lutins/invader_bouclier.bmp new file mode 100644 index 0000000..f71e3f3 Binary files /dev/null and b/Space Invaders/Envahisseurs/Graphique/Lutins/invader_bouclier.bmp differ diff --git a/Space Invaders/Envahisseurs/Graphique/Lutins/invader_canon.bmp b/Space Invaders/Envahisseurs/Graphique/Lutins/invader_canon.bmp new file mode 100644 index 0000000..2b450dd Binary files /dev/null and b/Space Invaders/Envahisseurs/Graphique/Lutins/invader_canon.bmp differ diff --git a/Space Invaders/Envahisseurs/Graphique/Lutins/invader_canon_ferraille.bmp b/Space Invaders/Envahisseurs/Graphique/Lutins/invader_canon_ferraille.bmp new file mode 100644 index 0000000..575ec72 Binary files /dev/null and b/Space Invaders/Envahisseurs/Graphique/Lutins/invader_canon_ferraille.bmp differ diff --git a/Space Invaders/Envahisseurs/Graphique/Lutins/invader_missile.bmp b/Space Invaders/Envahisseurs/Graphique/Lutins/invader_missile.bmp new file mode 100644 index 0000000..592caa4 Binary files /dev/null and b/Space Invaders/Envahisseurs/Graphique/Lutins/invader_missile.bmp differ diff --git a/Space Invaders/Envahisseurs/Graphique/Lutins/invader_monstre1_1.bmp b/Space Invaders/Envahisseurs/Graphique/Lutins/invader_monstre1_1.bmp new file mode 100644 index 0000000..cf56472 Binary files /dev/null and b/Space Invaders/Envahisseurs/Graphique/Lutins/invader_monstre1_1.bmp differ diff --git a/Space Invaders/Envahisseurs/Graphique/Lutins/invader_monstre1_2.bmp b/Space Invaders/Envahisseurs/Graphique/Lutins/invader_monstre1_2.bmp new file mode 100644 index 0000000..cf56472 Binary files /dev/null and b/Space Invaders/Envahisseurs/Graphique/Lutins/invader_monstre1_2.bmp differ diff --git a/Space Invaders/Envahisseurs/Graphique/Lutins/invader_monstre2_1.bmp b/Space Invaders/Envahisseurs/Graphique/Lutins/invader_monstre2_1.bmp new file mode 100644 index 0000000..40bbf1f Binary files /dev/null and b/Space Invaders/Envahisseurs/Graphique/Lutins/invader_monstre2_1.bmp differ diff --git a/Space Invaders/Envahisseurs/Graphique/Lutins/invader_monstre2_2.bmp b/Space Invaders/Envahisseurs/Graphique/Lutins/invader_monstre2_2.bmp new file mode 100644 index 0000000..f99ec39 Binary files /dev/null and b/Space Invaders/Envahisseurs/Graphique/Lutins/invader_monstre2_2.bmp differ diff --git a/Space Invaders/Envahisseurs/Graphique/Lutins/invader_monstre3_1.bmp b/Space Invaders/Envahisseurs/Graphique/Lutins/invader_monstre3_1.bmp new file mode 100644 index 0000000..a17556a Binary files /dev/null and b/Space Invaders/Envahisseurs/Graphique/Lutins/invader_monstre3_1.bmp differ diff --git a/Space Invaders/Envahisseurs/Graphique/Lutins/invader_monstre3_2.bmp b/Space Invaders/Envahisseurs/Graphique/Lutins/invader_monstre3_2.bmp new file mode 100644 index 0000000..a17556a Binary files /dev/null and b/Space Invaders/Envahisseurs/Graphique/Lutins/invader_monstre3_2.bmp differ diff --git a/Space Invaders/Envahisseurs/Graphique/Lutins/invader_monstre_bouillie.bmp b/Space Invaders/Envahisseurs/Graphique/Lutins/invader_monstre_bouillie.bmp new file mode 100644 index 0000000..fa89282 Binary files /dev/null and b/Space Invaders/Envahisseurs/Graphique/Lutins/invader_monstre_bouillie.bmp differ diff --git a/Space Invaders/Envahisseurs/Graphique/Lutins/invader_ovni.bmp b/Space Invaders/Envahisseurs/Graphique/Lutins/invader_ovni.bmp new file mode 100644 index 0000000..da5fbd8 Binary files /dev/null and b/Space Invaders/Envahisseurs/Graphique/Lutins/invader_ovni.bmp differ diff --git a/Space Invaders/Envahisseurs/Graphique/Lutins/millepatte_champi.bmp b/Space Invaders/Envahisseurs/Graphique/Lutins/millepatte_champi.bmp new file mode 100644 index 0000000..6126777 Binary files /dev/null and b/Space Invaders/Envahisseurs/Graphique/Lutins/millepatte_champi.bmp differ diff --git a/Space Invaders/Envahisseurs/Graphique/Lutins/millepatte_corps_bas.bmp b/Space Invaders/Envahisseurs/Graphique/Lutins/millepatte_corps_bas.bmp new file mode 100644 index 0000000..ed4f660 Binary files /dev/null and b/Space Invaders/Envahisseurs/Graphique/Lutins/millepatte_corps_bas.bmp differ diff --git a/Space Invaders/Envahisseurs/Graphique/Lutins/millepatte_corps_droite.bmp b/Space Invaders/Envahisseurs/Graphique/Lutins/millepatte_corps_droite.bmp new file mode 100644 index 0000000..36b049d Binary files /dev/null and b/Space Invaders/Envahisseurs/Graphique/Lutins/millepatte_corps_droite.bmp differ diff --git a/Space Invaders/Envahisseurs/Graphique/Lutins/millepatte_corps_gauche.bmp b/Space Invaders/Envahisseurs/Graphique/Lutins/millepatte_corps_gauche.bmp new file mode 100644 index 0000000..a67092c Binary files /dev/null and b/Space Invaders/Envahisseurs/Graphique/Lutins/millepatte_corps_gauche.bmp differ diff --git a/Space Invaders/Envahisseurs/Graphique/Lutins/millepatte_corps_haut.bmp b/Space Invaders/Envahisseurs/Graphique/Lutins/millepatte_corps_haut.bmp new file mode 100644 index 0000000..92dd3c7 Binary files /dev/null and b/Space Invaders/Envahisseurs/Graphique/Lutins/millepatte_corps_haut.bmp differ diff --git a/Space Invaders/Envahisseurs/Graphique/Lutins/millepatte_tete_bas.bmp b/Space Invaders/Envahisseurs/Graphique/Lutins/millepatte_tete_bas.bmp new file mode 100644 index 0000000..c582ab3 Binary files /dev/null and b/Space Invaders/Envahisseurs/Graphique/Lutins/millepatte_tete_bas.bmp differ diff --git a/Space Invaders/Envahisseurs/Graphique/Lutins/millepatte_tete_droite.bmp b/Space Invaders/Envahisseurs/Graphique/Lutins/millepatte_tete_droite.bmp new file mode 100644 index 0000000..7bce015 Binary files /dev/null and b/Space Invaders/Envahisseurs/Graphique/Lutins/millepatte_tete_droite.bmp differ diff --git a/Space Invaders/Envahisseurs/Graphique/Lutins/millepatte_tete_gauche.bmp b/Space Invaders/Envahisseurs/Graphique/Lutins/millepatte_tete_gauche.bmp new file mode 100644 index 0000000..f94c70b Binary files /dev/null and b/Space Invaders/Envahisseurs/Graphique/Lutins/millepatte_tete_gauche.bmp differ diff --git a/Space Invaders/Envahisseurs/Graphique/Lutins/millepatte_tete_haut.bmp b/Space Invaders/Envahisseurs/Graphique/Lutins/millepatte_tete_haut.bmp new file mode 100644 index 0000000..c74c0c1 Binary files /dev/null and b/Space Invaders/Envahisseurs/Graphique/Lutins/millepatte_tete_haut.bmp differ diff --git a/Space Invaders/Envahisseurs/Graphique/src/Graphique/Makefile b/Space Invaders/Envahisseurs/Graphique/src/Graphique/Makefile new file mode 100644 index 0000000..5791d72 --- /dev/null +++ b/Space Invaders/Envahisseurs/Graphique/src/Graphique/Makefile @@ -0,0 +1,29 @@ +# +# Makefile pour la bibliotheque graphique +# + +SOURCES = $(wildcard *.c) +OBJETS = $(SOURCES:.c=.o) +CIBLE = libgraph.a + +# +# Nom de la cible principale +# + +all: $(CIBLE) + +# +# Cible de nettoyage +# + +clean: + rm -f core *.o $(CIBLE) + +# +# Dependances pour la bibliotheque +# + +$(CIBLE): $(OBJETS) + $(AR) rs $@ $? + +$(CIBLE:.a=).o: $(CIBLE:.a=).c $(CIBLE:.a=).h diff --git a/Space Invaders/Envahisseurs/Graphique/src/Graphique/libgraph.c b/Space Invaders/Envahisseurs/Graphique/src/Graphique/libgraph.c new file mode 100644 index 0000000..99658e1 --- /dev/null +++ b/Space Invaders/Envahisseurs/Graphique/src/Graphique/libgraph.c @@ -0,0 +1,239 @@ +/**** Bibliotheque graphique ****/ + +/** Fichiers d'inclusion **/ + +#include +#include +#include "libgraph.h" + +/** Types **/ + +typedef struct +{ + int r, v, b; +} couleur; + +/** Constantes **/ + +#define BITS_PAR_PIXEL 32 +#define TAILLE_POLICE 20 + +static const couleur couleurs[] = { { 255, 255, 255 }, { 0, 0, 0 }, { 255, 0, 0 }, + { 0, 255, 0 }, { 0, 0, 255 }, { 255, 105, 180 }, + { 150, 150, 150 }, { -1, -1, -1 } }; + +static const char policeDefaut[]="/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf"; + +/** Variables globales **/ + +static SDL_Surface *surface; +TTF_Font* police; + +/** Fonctions **/ + +void choisirPolice(const char *chemin, int taille){ + police=TTF_OpenFont(chemin, taille); +} + +void initialiserTexte() { + TTF_Init(); + choisirPolice(policeDefaut, TAILLE_POLICE); +} + +/* Initialisation de la surface dessinable */ +unsigned char creerSurface (int largeur, int hauteur, char *titre) +{ + SDL_Init (SDL_INIT_VIDEO); + SDL_WM_SetCaption (titre, titre); + surface = SDL_SetVideoMode (largeur, hauteur, BITS_PAR_PIXEL, SDL_DOUBLEBUF); + initialiserTexte(); + + return (surface != NULL && police != NULL); +} + +/* Fermeture de la surface dessinable */ + +void fermerSurface (void) +{ + if (surface != NULL) SDL_FreeSurface (surface); + if (police != NULL) TTF_CloseFont(police); + TTF_Quit(); + SDL_Quit (); +} + +/* Creation d'une couleur */ + +static int creerCouleur (int ncouleur) +{ + couleur c = couleurs[ncouleur]; + return SDL_MapRGB (surface->format, c.r, c.v, c.b); +} + +/* Dessin d'un rectangle plein */ + +void rectanglePlein (int x, int y, int l, int h, int c) +{ + SDL_Rect rectangle = { x, y, l, h }; + SDL_FillRect (surface, &rectangle, creerCouleur (c)); + // SDL_Flip(surface); +} + +/* Manipulation de lutins */ + +static SDL_Surface *lutins[MAX_LUTINS]; +static int lutins_nb = 0; + +int lutinTexte(char* texte, int couleurTexte) { + couleur c=couleurs[couleurTexte]; + SDL_Color couleur={c.r, c.v, c.b}; + SDL_Surface* lutin=TTF_RenderText_Solid(police, texte, couleur); + if (lutin != NULL) + { + lutins[lutins_nb++] = lutin; + return lutins_nb - 1; + } + return -1; +} + +static void configurerLutin (SDL_Surface *lutin, int ncouleur) +{ + couleur c = couleurs[ncouleur]; + int fond = SDL_MapRGB (lutin->format, c.r, c.v, c.b); + SDL_SetColorKey (lutin, SDL_SRCCOLORKEY | SDL_RLEACCEL, fond); +} + +int chargerLutin (char *fichier, int couleur) +{ + if (lutins_nb >= MAX_LUTINS) return -2; + SDL_Surface *lutin = SDL_LoadBMP (fichier); + if (lutin != NULL) + { + lutins[lutins_nb++] = lutin; + if (couleur >= 0) configurerLutin (lutin, couleur); + return lutins_nb - 1; + } + return -1; +} + +void afficherLutin (int lutin, int x, int y) +{ + SDL_Rect position; + position.x = x; + position.y = y; + SDL_BlitSurface (lutins[lutin], NULL, surface, &position); +} + +int creerLutin (int x, int y, int largeur, int hauteur, int couleur) +{ + if (lutins_nb >= MAX_LUTINS) return -2; + int rmask, gmask, bmask, amask; +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + rmask = 0xff000000; + gmask = 0x00ff0000; + bmask = 0x0000ff00; + amask = 0x000000ff; +#else + rmask = 0x000000ff; + gmask = 0x0000ff00; + bmask = 0x00ff0000; + amask = 0xff000000; +#endif + if (couleur < 0) amask = 0x00000000; + SDL_Surface *lutin = + SDL_CreateRGBSurface (0, largeur, hauteur, BITS_PAR_PIXEL, rmask, gmask, bmask, amask); + SDL_Rect fenetre; + fenetre.x = x; + fenetre.y = y; + fenetre.h = hauteur; + fenetre.w = largeur; + SDL_BlitSurface (surface, &fenetre, lutin, NULL); + lutins[lutins_nb++] = lutin; + if (couleur >= 0) configurerLutin (lutin, couleur); + return lutins_nb - 1; +} + +void tailleLutin (int lutin, int *largeur, int *hauteur) +{ + *largeur = lutins[lutin]->w; + *hauteur = lutins[lutin]->h; +} + +int sauverLutin (int lutin, char *nom) { return SDL_SaveBMP (lutins[lutin], nom); } + +/* Manipulation de copie de surface en BMP */ + +int sauverSurface (char *fichier) { return SDL_SaveBMP (surface, fichier); } + +unsigned char chargerSurface (char *fichier) +{ + SDL_Surface *image = SDL_LoadBMP (fichier); + if (image != NULL) + { + SDL_BlitSurface (image, NULL, surface, NULL); + SDL_Flip (surface); + } + return (image != NULL); +} + +void majSurface (void) { SDL_Flip (surface); } + +/* Trouver la couleur d'un pixel */ + +int couleurPixel (int x, int y) +{ + int bpp = surface->format->BytesPerPixel; + Uint32 *p = (Uint32 *)(surface->pixels + y * surface->pitch + x * bpp); + Uint8 r, v, b; + SDL_GetRGB (*p, surface->format, &r, &v, &b); + int i = 0; + while (1) + { + if (couleurs[i].r < 0) break; + if (r == couleurs[i].r && v == couleurs[i].v && b == couleurs[i].b) break; + i++; + } + if (couleurs[i].r < 0) + return -1; + else + return i; +} + +/* Fonction de traitement des événements */ + +void lireEvenement (evenement *evt, char *touche, void **detail) +{ + static SDL_keysym _detail; + SDL_Event event; + while (SDL_PollEvent (&event)) + { + if (event.type == SDL_QUIT) *evt = quitter; + if (event.type == SDL_KEYDOWN || event.type == SDL_KEYUP) + { + *evt = (event.type == SDL_KEYDOWN) ? toucheBas : toucheHaut; + char *nom = SDL_GetKeyName (event.key.keysym.sym); + if (strlen (nom) == 1 && nom[0] >= 32 && nom[0] < 128) + *touche = nom[0]; + else + *touche = 0; + if (detail != NULL) + { + _detail = event.key.keysym; + *detail = &_detail; + } + break; + } + } +} + +void attendreEvenement (void) +{ + SDL_Event event; + while (SDL_WaitEvent (&event)) switch (event.type) + { + case SDL_QUIT: + exit (0); + case SDL_KEYDOWN: + case SDL_MOUSEBUTTONDOWN: + return; + } +} diff --git a/Space Invaders/Envahisseurs/Graphique/src/Graphique/libgraph.h b/Space Invaders/Envahisseurs/Graphique/src/Graphique/libgraph.h new file mode 100644 index 0000000..f518cff --- /dev/null +++ b/Space Invaders/Envahisseurs/Graphique/src/Graphique/libgraph.h @@ -0,0 +1,156 @@ +/**** Bibliotheque graphique (definitions) ****/ + +/** Constantes **/ + +#define COULEUR_BLANC 0 +#define COULEUR_NOIR 1 +#define COULEUR_ROUGE 2 +#define COULEUR_VERT 3 +#define COULEUR_BLEU 4 +#define COULEUR_ROSE 5 +#define COULEUR_GRIS 6 + +#define MAX_LUTINS 16 + +typedef enum {toucheBas, toucheHaut, quitter} evenement; + +/** Prototypes **/ + +/** + * @brief cree une fenetre 2D + * + * @param largeur en pixels de la fenetre + * @param hauteur en pixels de la fenetre + * @param titre de la fenetre (chaine de caractere) + */ +unsigned char creerSurface (int largeur, int hauteur, char *titre); + +/** + * @brief permet de charger un fichier image au format bmp (bitmap) + * + * @param fichier nom du fichier + */ +unsigned char chargerSurface (char *fichier); + + +/** + * @brief permet de sauvegarder une surface en image (format bmp) + * + * @param fichier nom du fichier + * @return 0 si OK, valeur negative sinon + */ +int sauverSurface (char *fichier); + +/** + * @brief met a jour la surface d'affichage + */ +void majSurface (void); + + +/** + * @brief libere la surface d'affichage + * a faire lors de la fermeture + * du programme + */ +void fermerSurface (void); + +/** + * @brief choisit la police de caractères à utiliser pour afficher du texte + * @param chemin nom du fichier de police (format .ttf, voir /usr/share/fonts/truetype) + * @param taille taille de la police + */ +void choisirPolice(const char *chemin, int taille); + +/** + * @brief dessine un rectange de taille (l,h) aux coordonnêes + * (x,y) et de couleur c + * + * @param x 0 <= x <= l_surface + * @param y 0 <= y <= h_surface + * @param l largeur en pixels + * @param h longueur en pixels + * @param c indice de couleur voir variable couleurs dans le fichier .c + */ +void rectanglePlein (int x, int y, int l, int h, int c); + + +/** + * @brief permet de determiner l'indice du tableau de couleur du + * pixel aux coordonnees (x,y) + * + * @param x 0 <= x <= l_surface + * @param y 0 <= y <= h_surface + * @return indice de couleur voire variable couleurs dans le fichier .c + */ +int couleurPixel (int x, int y); + +/** + * @brief crée un lutin à partir d'un texte + * + * @param texte le texte + * @param couleur indice de couleur du texte + * @return numero de lutin dans le tableau dynamique de lutin (< MAX_LUTINS) + */ +int lutinTexte(char *texte, int couleur); + +/** + * @brief charge un lutin à partir du fichier + * + * @param fichier image bitmap du lutin à charger + * @param couleur indice de couleurs à charger + * @return numero de lutin dans le tableau dynamique de lutin (< MAX_LUTINS) + */ +int chargerLutin (char *fichier, int couleur); + +/** + * @brief afficher un lutin aux coordonnées (x,y) + * + * @param lutin numero du lutin à afficher (< MAX_LUTINS) + * @param x abscisse de départ + * @param y ordonnée de départ + */ +void afficherLutin (int lutin, int x, int y); + +/** + * @brief creer un lutin de taille (l,h) aux coordonnées (x,y) + * + * @param x abscisse de départ + * @param y ordonnée de départ + * @param largeur largeur du lutin + * @param hauteur hauteur du lutin + * @param couleur indice de couleur à partir du tableau _couleurs_ + * @return indice du lutin dans le tableau global (< MAX_LUTINS) + */ +int creerLutin (int x, int y, int largeur, int hauteur, int couleur); + +/** + * @brief sauvegarde un lutin dans un fichier + * + * @param lutin numero de lutin à sauvegarder (< MAX_LUTINS) + * @param nom fichier pour la sauvegarde + * @return 0 si OK valeur négative sinon + */ +int sauverLutin (int lutin, char *nom); + +/** + * @brief calcule la taille (largeur,hauteur) d'un lutin + * + * @param lutin index du lutin (< MAX_LUTINS) + * @param largeur pointeur sur la largeur + * @param hauteur pointeur sur la hauteur + */ +void tailleLutin (int lutin, int *largeur, int *hauteur); + +/** + * @brief lire une touche au clavier + * + * @param evt pointeur sur evenement + * @param touche pointeur sur la touche pressée + * @param detail NULL ou keysim + */ +void lireEvenement (evenement *evt, char *touche, void **detail); + +/** + * @brief attente d'un evenement bouton, souris, fin de programme + */ +void attendreEvenement (void); diff --git a/Space Invaders/Envahisseurs/Graphique/src/Interactif/Interactif.c b/Space Invaders/Envahisseurs/Graphique/src/Interactif/Interactif.c new file mode 100644 index 0000000..0a75322 --- /dev/null +++ b/Space Invaders/Envahisseurs/Graphique/src/Interactif/Interactif.c @@ -0,0 +1,375 @@ +#include +#include + +#include "../Graphique/libgraph.h" +#include "../ListeC/Liste.h" +#include "Interactif.h" +#include "../Main/init.h" + +#define TailleX 500 +#define TailleY 500 +#define Sol 475 +#define ErreurHitbox 2 +#define TailleX9_10 (9 * TailleX / 10) +#define TailleX1_10 (TailleX / 10) + +#define ValeurDeplacementTire 5 +#define ValeurDeplacementJoueur 3 +#define ValeurDeplacementBombe 2 + + +//La fonction renvoie 1 si il y a collision +int CheckCollisionEntiteEntite (struct entite entite1, + int L1, + int H1, + struct entite entite2, + int L2, + int H2) +{ + //CheckX + int gauche1 = entite1.posx - L1/2 + ErreurHitbox; + int droite1 = entite1.posx + L1/2 - ErreurHitbox; + int gauche2 = entite2.posx - L2/2 + ErreurHitbox; + int droite2 = entite2.posx + L2/2 - ErreurHitbox; + //Tout les cas possibles de collision + int CheckX = (gauche1 >= gauche2 && gauche1 <= droite2) || + (droite1 >= gauche2 && droite1 <= droite2) || + (gauche1 >= gauche2 && droite1 <= droite2) || + (gauche2 >= gauche1 && droite2 <= droite1); + + //CheckY + int haut1 = entite1.posy - H1/2 + ErreurHitbox; + int bas1 = entite1.posy + H1/2 - ErreurHitbox; + int haut2 = entite2.posy - H2/2 + ErreurHitbox; + int bas2 = entite2.posy + H2/2 - ErreurHitbox; + int CheckY = (haut1 <= bas2 && haut1 >= haut2) || + (bas1 <= bas2 && bas1 >= haut2) || + (haut1 <= haut2 && bas1 >= bas2) || + (haut2 <= haut1 && bas2 >= bas1); + + + return CheckX && CheckY; +} + +//La fonction renvoie l'entite de la Liste1 si il y a collision +struct entite* CheckCollisionListeEntite (struct liste_entite* Liste1, + int L1, + int H1, + struct entite entite2, + int L2, + int H2) +{ + + struct liste_entite *pListe1 = Liste1; + while (pListe1 != NULL) + { + + if(CheckCollisionEntiteEntite (pListe1->entite, + L1, + H1, + entite2, + L2, + H2) == 1) + { + return &pListe1->entite; + } + + pListe1 = pListe1->suivant; + } + return NULL; +} + + + +//La fonction renvoie une liste d'entite avec les deux entites à supprimer +//Seulement si il y a collision +struct liste_entite* CheckCollisionListeListe (struct liste_entite* Liste1, + int L1, + int H1, + struct liste_entite* Liste2, + int L2, + int H2) +{ + + struct liste_entite *pListe2 = Liste2; + while (pListe2 != NULL) + { + + struct entite* collision = CheckCollisionListeEntite (Liste1, + L1, + H1, + pListe2->entite, + L2, + H2); + if (collision == NULL) + { + pListe2 = pListe2->suivant; + } + + else + { + // Création des structures pour les deux entités + struct liste_entite* Entite1 = malloc(sizeof(struct liste_entite)); + struct liste_entite* Entite2 = malloc(sizeof(struct liste_entite)); + + // Remplissage des structure avec les entités correspondantes + Entite1->entite = *collision; + Entite2->entite = pListe2->entite; + + // Relier les structures entre elles + Entite1->suivant = Entite2; + Entite2->suivant = NULL; + + return Entite1; + } + } + + return NULL; +} + +//Tire un missile, il ne peux y en avoir que un à la fois +void Tirer (struct entite joueur, + struct liste_entite** pl) +{ + if (*pl == NULL) + { + ajout_tete(pl, + creer_entite(joueur.posx, + joueur.posy, + -1)); + } +} + + +void DeplacementTire(struct liste_entite** Liste) +{ + struct entite* Entite = &(*Liste)->entite; + if (Entite != NULL) + { + + if (Entite->posy <= 0) + { + afficherLutin(bouillie, + Entite->posx - hitboxbouillieL/2 + ErreurHitbox, + Entite->posy); + SupprimerEntite(Liste, Entite); + } + + else + { + Entite->posy -= ValeurDeplacementTire; + //Je divise ErreurHitbox par 2 car l'erreur du missile + //est plus petite que pour les autres images + afficherLutin(missile, + Entite->posx - hitboxmissileL/2 + ErreurHitbox/2, + Entite->posy - hitboxmissileH/2 + ErreurHitbox/2); + } + } +} + + +//La fonction fait une action soit au joueur +//soit à la Liste des Tires selon la touche préssée +void action(struct entite* joueur, + char c, + struct liste_entite** tires) +{ + switch (c) + { + case 'd': + if (joueur->posx <= TailleX9_10) + { + joueur->posx += ValeurDeplacementJoueur; + } + break; + case 'q': + if (joueur->posx >= TailleX1_10) + { + joueur->posx -= ValeurDeplacementJoueur; + } + break; + case 't': + Tirer(*joueur, + tires); + break; + default: + break; + } +} + +/* +La fonction crée une liste de tout les enemies pouvant drop des bombes +Seulement ceux les plus bas de leur colonne repective +Puis ajoute à la liste bombe, +une bombe provenant d'un des enemies pouvant drop des bombes +Le choix de quel enemie drop la bombe est aléatoire +*/ +void MakeBombeDrop (struct liste_entite* enemies, + struct liste_entite** bombes) +{ + + struct liste_entite* pListe = enemies; + struct liste_entite* Dropable = NULL; + int taille = 0; + + while (pListe != NULL) + { + + if (pListe->entite.dropbombe == 1) + { + ajout_tete(&Dropable,pListe->entite); + taille += 1; + } + + pListe = pListe->suivant; + } + + if(Dropable == NULL) + { + return; + } + /* + On choisit une valeur aléatoire représentant l'enemie qui va drop la bombe + Il ya un warning comme quoi rand() à une limite + Mais on ne la dépassera jamais, taille ne pourra + jamais excédé une vingtaine d'enemies par ligne + */ + int randomIndex = rand() % taille-1; + struct liste_entite* pDropable = Dropable; + + for (int i = 0; i <= randomIndex; i++) + { + pDropable = pDropable->suivant; + } + + ajout_tete(bombes, + creer_entite(pDropable->entite.posx, + pDropable->entite.posy, + -1)); +} + + +void DeplacementBombe(struct liste_entite** Liste) +{ + struct liste_entite* pListe = *Liste; + + while (pListe != NULL) + { + + if (pListe->entite.posy + hitboxbombeH/2 - ErreurHitbox >= Sol) + { + struct entite* a_supprimer = &pListe->entite; + + pListe = pListe->suivant; + SupprimerEntite(Liste,a_supprimer); + } + + else + { + pListe->entite.posy += ValeurDeplacementBombe; + afficherLutin(bombe, + pListe->entite.posx - hitboxbombeL/2 + ErreurHitbox, + pListe->entite.posy - hitboxbombeH/2 + ErreurHitbox); + pListe = pListe->suivant; + } + } +} + +/* +Si un enemie est éliminé et qu'il etait le plus bas de sa colonne +(il pouvait drop des bombes) +Alors si il y en a un, l'enemie au dessus de lui (de la meme colonne) +peut maintenant drop des bombes +*/ +void NouveauDroppeurBombe (struct liste_entite** liste, + struct entite* entite) +{ + + int posx = entite->posx; + int posy = entite->posy; + struct liste_entite* pListe = *liste; + struct entite* entite_basse = NULL; + + // On parcourt la liste et on cherche + //l'entité la plus basse ayant la même position x + while (pListe != NULL) + { + //On ne regarde pas les enemies qui sont sur la meme ligne + if (pListe->entite.posy != posy) + { + //Si meme colonne et qu'il n'y a pas d'entite_basse + if (pListe->entite.posx == posx && + entite_basse == NULL) + { + entite_basse = &pListe->entite; + } + + //Si meme colonne mais qu'il y a deja une entite_basse + //On compare la hauteur de l'entite avec l'entite_basse + else if (pListe->entite.posx == posx && + pListe->entite.posy > entite_basse->posy) + { + entite_basse = &pListe->entite; + } + } + + pListe = pListe->suivant; + } + + // Si aucune entité n'est située plus bas que l'entité en question, + //On ne peut pas dropper la bombe + if (entite_basse == NULL) + { + return; + } + + entite_basse->dropbombe = 1; +} + + + +//Fonction Main qui supprime les entités rentrées en collision de leur liste +int SupprimerEntitesEnCollision (struct liste_entite** Liste1, + int L1, + int H1, + struct liste_entite** Liste2, + int L2, + int H2) +{ + + struct liste_entite* collision = CheckCollisionListeListe(*Liste1, + L1, + H1, + *Liste2, + L2, + H2); + if (collision != NULL) + { + // Récupération des entités impliquées + struct entite* Entite1 = &collision->entite; + struct entite* Entite2 = &collision->suivant->entite; + + if (Entite1->dropbombe == 1) + { + NouveauDroppeurBombe(Liste1,Entite1); + } + + if (Entite2->dropbombe == 1) + { + NouveauDroppeurBombe(Liste2,Entite2); + } + + // Suppression de l'entité 1 de la liste 1 + SupprimerEntite(Liste1, Entite1); + // Suppression de l'entité 2 de la liste 2 + SupprimerEntite(Liste2, Entite2); + + afficherLutin (bouillie, + Entite2->posx - hitboxbouillieL/2 + ErreurHitbox, + Entite2->posy - hitboxbouillieH/2 + ErreurHitbox); + return 1; + } + return 0; +} + + diff --git a/Space Invaders/Envahisseurs/Graphique/src/Interactif/Interactif.h b/Space Invaders/Envahisseurs/Graphique/src/Interactif/Interactif.h new file mode 100644 index 0000000..3b43832 --- /dev/null +++ b/Space Invaders/Envahisseurs/Graphique/src/Interactif/Interactif.h @@ -0,0 +1,44 @@ +int CheckCollisionEntiteEntite (struct entite entite1, + int L1, + int H1, + struct entite entite2, + int L2, + int H2); + +struct entite* CheckCollisionListeEntite (struct liste_entite* Liste1, + int L1, + int H1, + struct entite entite2, + int L2, + int H2); + +struct liste_entite* CheckCollisionListeListe (struct liste_entite* Liste1, + int L1, + int H1, + struct liste_entite* Liste2, + int L2, + int H2); + +void Tirer (struct entite joueur, + struct liste_entite** pl); + +void DeplacementTire(struct liste_entite** Liste); + +void action(struct entite* joueur, + char c, + struct liste_entite** tires); + +void MakeBombeDrop (struct liste_entite* enemies, + struct liste_entite** bombes); + +void DeplacementBombe(struct liste_entite** Liste) ; + +void NouveauDroppeurBombe (struct liste_entite** liste, + struct entite* entite); + +int SupprimerEntitesEnCollision (struct liste_entite** Liste1, + int L1, + int H1, + struct liste_entite** Liste2, + int L2, + int H2); diff --git a/Space Invaders/Envahisseurs/Graphique/src/ListeC/Liste.c b/Space Invaders/Envahisseurs/Graphique/src/ListeC/Liste.c new file mode 100644 index 0000000..cdf57ab --- /dev/null +++ b/Space Invaders/Envahisseurs/Graphique/src/ListeC/Liste.c @@ -0,0 +1,80 @@ +#include +#include +#include + +#include "Liste.h" + +//Crée une entité +struct entite creer_entite (int x, + int y, + int candrop) +{ + struct entite e; + + e.posx = x; + e.posy = y; + e.dropbombe = candrop; + + return e; +} + + +//Ajout en tete une entité dans une liste +void ajout_tete (struct liste_entite** Liste, + struct entite x ) +{ + struct liste_entite *Listetmp=NULL; + + Listetmp = malloc(sizeof(struct liste_entite)); + Listetmp->entite = x; + Listetmp->suivant = *Liste; + + *Liste = Listetmp; +} + + +//Supprime une entite d'une liste +void SupprimerEntite (struct liste_entite** Liste, + struct entite* entite) +{ + struct liste_entite* courant = *Liste; + struct liste_entite* precedent = NULL; + //Ce pointeur precedent va garder en memoire l'entite precedente + //Initialisé à NULL car cela est utile dans le cas ou l'entite est la 1ere + + while (courant != NULL) + { + //Comparaison entre 2 entites + if (memcmp (&courant->entite, + entite, + sizeof(struct entite)) == 0) + { + //Si l'element est le premier + if (precedent == NULL) + { + *Liste = courant->suivant; + } + + else + { + precedent->suivant = courant->suivant; + } + + free(courant); + break; + } + + precedent = courant; + courant = courant->suivant; + } +} + + +//Desallouer une liste entiere +void DesallouerListe (struct liste_entite** Liste) +{ + while(*Liste != NULL) + { + SupprimerEntite(Liste,&((*Liste)->entite)); + } +} diff --git a/Space Invaders/Envahisseurs/Graphique/src/ListeC/Liste.h b/Space Invaders/Envahisseurs/Graphique/src/ListeC/Liste.h new file mode 100644 index 0000000..8d1d688 --- /dev/null +++ b/Space Invaders/Envahisseurs/Graphique/src/ListeC/Liste.h @@ -0,0 +1,29 @@ +//dropbombe concerne les entités enemies +//1 les enemies peuvent drop des bombes, 0 ils ne peuvent pas +//Les entites non concernées vallent ont un dropbombe = -1 +struct entite +{ + int posx; + int posy; + int dropbombe; +}; + + +struct liste_entite +{ + struct entite entite; + struct liste_entite *suivant; +}; + + +struct entite creer_entite (int x, + int y, + int bombe); + +void ajout_tete (struct liste_entite** Liste, + struct entite x ); + +void SupprimerEntite (struct liste_entite** Liste, + struct entite* entite); + +void DesallouerListe (struct liste_entite** Liste); diff --git a/Space Invaders/Envahisseurs/Graphique/src/Main/Makefile b/Space Invaders/Envahisseurs/Graphique/src/Main/Makefile new file mode 100644 index 0000000..a254998 --- /dev/null +++ b/Space Invaders/Envahisseurs/Graphique/src/Main/Makefile @@ -0,0 +1,37 @@ +CC=clang +TARGET=Jeu +CFLAGS=-g -W -Wall -Wextra +LDFLAGS=-I Graphique -l graph -L ../Graphique -l SDL -l SDL_ttf + +default: $(TARGET) + +Liste.o : ../ListeC/Liste.c ../ListeC/Liste.h + clang $(CFLAGS) -c ../ListeC/Liste.c + +Monstre.o : ../Monstre/Monstre.c ../Monstre/Monstre.h + clang $(CFLAGS) -c ../Monstre/Monstre.c + +Interactif.o : ../Interactif/Interactif.c ../Interactif/Interactif.h + clang $(CFLAGS) -c ../Interactif/Interactif.c + +init.o : init.c init.h + clang $(CFLAGS) -c init.c + +main.o : main.c + clang $(CFLAGS) -c main.c + + +$(TARGET): Liste.o main.o Monstre.o Interactif.o init.o + clang main.o Liste.o Monstre.o Interactif.o init.o -o $(TARGET) $(LDFLAGS) + +.PHONY: clean +clean: + rm -f *.o + rm -f $(TARGET) + +tidy : main.c ../ListeC/Liste.c ../Monstre/Monstre.c ../Interactif/Interactif.c init.c + $(CC)-tidy main.c ../ListeC/Liste.c ../Monstre/Monstre.c ../Interactif/Interactif.c init.c --checks="readability-*" -header-filter=.* + +format : + $(CC)-format -style='Microsoft' main.c ../ListeC/Liste.c ../Monstre/Monstre.c ../Interactif/Interactif.c init.c + diff --git a/Space Invaders/Envahisseurs/Graphique/src/Main/init.c b/Space Invaders/Envahisseurs/Graphique/src/Main/init.c new file mode 100644 index 0000000..b08b6d6 --- /dev/null +++ b/Space Invaders/Envahisseurs/Graphique/src/Main/init.c @@ -0,0 +1,244 @@ +#include +#include "../Graphique/libgraph.h" +#include "../ListeC/Liste.h" +#include "../Interactif/Interactif.h" +#include "init.h" + +#define TailleX 500 +#define TailleY 500 +#define Sol 475 +#define ErreurHitbox 2 +#define PositionX_1 (TailleX / 2) +#define PositionY_1 (TailleY / 2) +#define PositionY_2 (TailleY / 4) + +#define JoueurX (TailleX / 2) +#define JoueurY (9 * TailleY / 10) + +#define Nom "Space Invaders" +#define TaillePolice1 (TailleX / 10) +#define TaillePolice2 (TailleX / 20) +#define TailleChaineMax 30 + +//Ces variables sont globales car utilisées dans plusieurs .c +//Toutes les hitbox sont initialisées 1 fois puis sont des constantes +struct entite joueur; + +static const char policeDefaut[]= +"/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf"; + +int canon = 0; +int missile = 0; +int enemie1_1 = 0; +int enemie1_2 = 0; +int bouillie = 0; +int bombe = 0; + +int hitboxcanonL = 0; +int hitboxcanonH = 0; +int hitboxmissileL = 0; +int hitboxmissileH = 0; +int hitboxenemieL = 0; +int hitboxenemieH = 0; +int hitboxbouillieL = 0; +int hitboxbouillieH = 0; +int hitboxbombeL = 0; +int hitboxbombeH = 0; + +//Initialisation des variables globales pour le main +void initialiser() +{ + canon = chargerLutin ("../../Lutins/invader_canon.bmp", + COULEUR_NOIR); + missile = chargerLutin ("../../Lutins/invader_missile.bmp", + COULEUR_NOIR); + enemie1_1 = chargerLutin ("../../Lutins/invader_monstre2_1.bmp", + COULEUR_NOIR); + enemie1_2 = chargerLutin ("../../Lutins/invader_monstre2_2.bmp", + COULEUR_NOIR); + bouillie = chargerLutin ("../../Lutins/invader_monstre_bouillie.bmp", + COULEUR_NOIR); + bombe = chargerLutin ("../../Lutins/invader_bombe.bmp", + COULEUR_NOIR); + + tailleLutin (canon, + &hitboxcanonL, + &hitboxcanonH); + + tailleLutin (missile, + &hitboxmissileL, + &hitboxmissileH); + //La taille des enemmies que j'utilise est la meme dans ces 2 variantes + tailleLutin (enemie1_1, + &hitboxenemieL, + &hitboxenemieH); + + tailleLutin (bouillie, + &hitboxbouillieL, + &hitboxbouillieH); + + tailleLutin (bombe, + &hitboxbombeL, + &hitboxbombeH); + +} + +//Initialisation des coordonnées du joueur pour le main +void initialiserjoueur() +{ + joueur.posx = JoueurX; + joueur.posy = JoueurY; + joueur.dropbombe = -1; +} + +//Page de démarage du jeu +char pagedemarrage() +{ + char input = '\0'; + evenement even = 0; + int Largeur = 0; + int Hauteur = 0; + char jouer[] = "Appuyer sur j pour Jouer"; + char quitter[] = "Appuyer ailleurs pour Quitter"; + + choisirPolice (policeDefaut, TaillePolice2); + int LutinJouer = lutinTexte (jouer, COULEUR_BLANC); + int LutinQuitter = lutinTexte (quitter, COULEUR_BLANC); + + choisirPolice (policeDefaut, TaillePolice1); + int LutinBienvenue = lutinTexte (Nom, COULEUR_VERT); + + rectanglePlein (0, + 0, + TailleX, + TailleY, + COULEUR_NOIR); + + tailleLutin (LutinBienvenue, + &Largeur, + &Hauteur); + afficherLutin (LutinBienvenue, + PositionX_1 - Largeur / 2, + PositionY_2 + Hauteur / 2); + + tailleLutin (LutinJouer, + &Largeur, + &Hauteur); + afficherLutin (LutinJouer, + PositionX_1 - Largeur / 2, + PositionY_1 - Hauteur / 2); + + tailleLutin (LutinQuitter, + &Largeur, + &Hauteur); + afficherLutin (LutinQuitter, + PositionX_1 - Largeur / 2, + PositionY_1 + Hauteur / 2); + + majSurface(); + attendreEvenement (); + + lireEvenement (&even, + &input, + NULL); + while (input == '\0') + { + lireEvenement (&even, + &input, + NULL); + } + return input; +} + +//Page en cas de mort dans le jeu +void pagemort (int nbr_vie) +{ + int Largeur = 0; + int Hauteur = 0; + char mort[] = "Vous etes mort"; + char vie[TailleChaineMax] = "\0"; + sprintf (vie, + "Nombre de vies restantes : %d", + nbr_vie); + /* + sprintf crée un warning mais celui-ci ne peut pas crée d'erreur car + TailleChaineMax ne pourra pas excéder 30 si le nombre de vie reste "normal" + sprintf_s ne fonctionne pas pour mon programme (invalid in C99) + */ + + choisirPolice (policeDefaut, TaillePolice1); + int LutinMort = lutinTexte(mort, COULEUR_ROUGE); + + choisirPolice (policeDefaut, TaillePolice2); + int LutinVie = lutinTexte(vie, COULEUR_BLANC); + + rectanglePlein (0, + 0, + TailleX, + TailleY, + COULEUR_NOIR); + + tailleLutin (LutinMort, + &Largeur, + &Hauteur); + afficherLutin (LutinMort, + PositionX_1 - Largeur / 2, + PositionY_2 + Hauteur / 2); + + tailleLutin (LutinVie, + &Largeur, + &Hauteur); + afficherLutin (LutinVie, + PositionX_1 - Largeur / 2, + PositionY_1 - Hauteur / 2); +} + +//Page de GameOver du jeu +void pageGameOver() +{ + int Largeur = 0; + int Hauteur = 0; + char fin[] = "GAME OVER"; + + choisirPolice(policeDefaut, TaillePolice1); + int LutinFin = lutinTexte(fin, COULEUR_ROUGE); + + rectanglePlein (0, + 0, + TailleX, + TailleY, + COULEUR_NOIR); + + tailleLutin (LutinFin, + &Largeur, + &Hauteur); + afficherLutin (LutinFin, + PositionX_1 - Largeur / 2, + PositionY_1 - Hauteur / 2); + +} + +//Page de Victoire du jeu +void pageVictoire() +{ + int Largeur = 0; + int Hauteur = 0; + char fin[] = "VICTOIRE"; + + choisirPolice(policeDefaut, TaillePolice1); + int LutinFin = lutinTexte(fin, COULEUR_VERT); + + rectanglePlein (0, + 0, + TailleX, + TailleY, + COULEUR_NOIR); + + tailleLutin (LutinFin, + &Largeur, + &Hauteur); + afficherLutin (LutinFin, + PositionX_1 - Largeur / 2, + PositionY_1 - Hauteur / 2); + +} diff --git a/Space Invaders/Envahisseurs/Graphique/src/Main/init.h b/Space Invaders/Envahisseurs/Graphique/src/Main/init.h new file mode 100644 index 0000000..34fd8d5 --- /dev/null +++ b/Space Invaders/Envahisseurs/Graphique/src/Main/init.h @@ -0,0 +1,28 @@ +extern int canon; +extern int missile; +extern int enemie1_1; +extern int enemie1_2; +extern int bouillie; +extern int bombe; + +extern struct entite joueur; +extern char Nom[]; +extern char input; + +extern int hitboxcanonL; +extern int hitboxcanonH; +extern int hitboxmissileL; +extern int hitboxmissileH; +extern int hitboxenemieL; +extern int hitboxenemieH; +extern int hitboxbouillieL; +extern int hitboxbouillieH; +extern int hitboxbombeL; +extern int hitboxbombeH; + +void initialiser(); +void initialiserjoueur(); +char pagedemarrage(); +void pagemort(int nbr_vie); +void pageGameOver(); +void pageVictoire(); diff --git a/Space Invaders/Envahisseurs/Graphique/src/Main/main.c b/Space Invaders/Envahisseurs/Graphique/src/Main/main.c new file mode 100644 index 0000000..6f5e2b5 --- /dev/null +++ b/Space Invaders/Envahisseurs/Graphique/src/Main/main.c @@ -0,0 +1,267 @@ +#include +#include +#include "../Graphique/libgraph.h" +#include "../ListeC/Liste.h" +#include "../Monstre/Monstre.h" +#include "../Interactif/Interactif.h" +#include "init.h" + +#define TailleX 500 +#define TailleY 500 +#define Sol 475 +#define EpaisseurSol 2 +#define ErreurHitbox 2 + +#define Nom "Space Invader" +#define NombreEnemieParLigne 8 +#define NombreLigneEnemies 3 +#define NombreVie 3 + +#define BombeRandomFixe 50 +#define BombeRandomAlea 30 + +//Pour augmenter les deplacements des enemies, vous pouvez: +//Augmenter VitesseDeplacementEnemie +//Tout les VitesseDeplacementEnemie tours de boucle les enemies se déplace +#define VitesseDeplacementEnemie 2 +// Ou augmenter le PasEnemie (Ecart entre la position n et n+1) +#define PasEnemie 5 +#define AffichageImageEnemie 8 + +#define Delai0_2s 200 +#define Delai0_5s 500 +#define Delai2s 2000 + +#define VitesseTourdeBoucle 20 + +int main() +{ + creerSurface(TailleX,TailleY,Nom); + + initialiser(); + initialiserjoueur(); + + struct liste_entite* ListeEnemies = NULL; + struct liste_entite* ListeTires = NULL; + struct liste_entite* ListeBombes = NULL; + + //joueur est dans une liste afin d'utiliser des fonctions deja crée + struct liste_entite* Ljoueur = NULL; + ajout_tete(&Ljoueur,joueur); + + + LigneEnemie(&ListeEnemies, + NombreEnemieParLigne, + NombreLigneEnemies); + int SensVague = 1; + + char input = '\0'; + evenement even = 0; + + int TourdeBoucle = 0; + + int TimeAlea = 0; + int CheckAlea = 0; + + int mort = 0; + int nbr_vie = NombreVie; + int QuelMonstre = 0; + + int coeur = chargerLutin ("../../Lutins/Coeur.bmp", + COULEUR_NOIR); + int hitboxcoeurL = 0; + int hitboxcoeurH = 0; + tailleLutin (coeur, + &hitboxcoeurL, + &hitboxcoeurH); + + if ( pagedemarrage() != 'j') + { + return 0; + } + SDL_Delay(Delai0_5s); + + //Bouble principale + while(input!='m') + { + //Si le joueur est mort + if (mort == 1) + { + nbr_vie-=1; + //Si il lui reste des vies + if (nbr_vie > 0) + { + pagemort(nbr_vie); + majSurface(); + SDL_Delay(Delai2s); + mort = 0; + } + //Si il n'a plus de vie + else + { + pageGameOver(); + majSurface(); + SDL_Delay(Delai2s); + return 0; + } + //On ajoute de nouveau le joueur précedement supprimé à sa liste + ajout_tete(&Ljoueur,joueur); + //Desallocation dynamique des listes + DesallouerListe(&ListeTires); + DesallouerListe(&ListeBombes); + } + + //Affichage Rectangle Noir sur toute la page + rectanglePlein(0, + 0, + TailleX, + TailleY, + COULEUR_NOIR); + + //Affichage des coeurs de vie + for (int i = 1 ; i <= nbr_vie; i++) + { + afficherLutin(coeur, + TailleX - i * hitboxcoeurL, + Sol); + } + + //Affichage du Sol + rectanglePlein(0, + Sol, + TailleX, + EpaisseurSol, + COULEUR_VERT); + + //Affichage du joueur + afficherLutin(canon, + Ljoueur->entite.posx - hitboxcanonL/2 + ErreurHitbox, + Ljoueur->entite.posy); + + //Affichage des ListeEnemies + if (QuelMonstre > 2 * AffichageImageEnemie) + { + QuelMonstre = 0; + } + if (QuelMonstre <= AffichageImageEnemie) + { + AfficherEnemie (ListeEnemies, + enemie1_1, + hitboxenemieL, + hitboxenemieH); + QuelMonstre += 1; + } + else + { + AfficherEnemie (ListeEnemies, + enemie1_2, + hitboxenemieL, + hitboxenemieH); + QuelMonstre += 1; + } + /* + Systeme pour faire drop une bombe dans un temps aléatoire + Mise en place d'un timer + TimeAlea représente le nombre de tour de boucle à éffectuer + */ + if (TimeAlea == 0) + { + //50 tour de boucle minimum + une valeur de 0 à 31 + TimeAlea = rand() % BombeRandomAlea + BombeRandomFixe; + //Il y a un warning car rand() à une valeur limite + } + /* + CheckAlea est incrémenté de 1 à chaque tour de boucle + Lorsque celui ci vaut TimeAlea on peut drop une bombe + On reset à 0 le Timer et le Check aprés avoir Drop une bombe + */ + if (CheckAlea == TimeAlea) + { + MakeBombeDrop(ListeEnemies, + &ListeBombes); + TimeAlea=0; + CheckAlea=0; + } + + //Gestion des evenements clavier + //On ne peut appuyer que sur une seule touche à la fois + lireEvenement (&even, + &input, + NULL); + if (even == toucheBas) + { + action(&Ljoueur->entite, + input, + &ListeTires); + } + + //Deplacement des enemies tout les X tours de boucle + if (TourdeBoucle == VitesseDeplacementEnemie) + { + DeplacementEnemie(ListeEnemies, + &SensVague, + PasEnemie); + TourdeBoucle = 0; + } + + //Deplacement des Tires et Bombes + DeplacementTire(&ListeTires); + DeplacementBombe(&ListeBombes); + + //Supression si collision des Tires et Enemies + SupprimerEntitesEnCollision(&ListeTires, + hitboxmissileL, + hitboxmissileH, + &ListeEnemies, + hitboxenemieL, + hitboxenemieH); + + //Supression si collision des Bombes et Joueur + if (SupprimerEntitesEnCollision(&ListeBombes, + hitboxbombeL, + hitboxbombeH, + &Ljoueur, + hitboxcanonL, + hitboxcanonH) == 1) + { + mort = 1; + majSurface(); + SDL_Delay(Delai0_2s); + } + + //Supression si collision des Enemies et Joueur + if (SupprimerEntitesEnCollision(&ListeEnemies, + hitboxenemieL, + hitboxenemieH, + &Ljoueur, + hitboxcanonL, + hitboxcanonH) == 1) + { + pageGameOver(); + majSurface(); + SDL_Delay(Delai2s); + return 0; + } + + //Si il n'y a plus d'enemies, c'est une victoire !!! + if (ListeEnemies == NULL) + { + majSurface(); + SDL_Delay(Delai0_2s); + pageVictoire(); + majSurface(); + SDL_Delay(Delai2s); + return 0; + } + + + majSurface(); + + TourdeBoucle += 1; + CheckAlea += 1; + + SDL_Delay(VitesseTourdeBoucle); + + } + return 0; +} diff --git a/Space Invaders/Envahisseurs/Graphique/src/Monstre/Monstre.c b/Space Invaders/Envahisseurs/Graphique/src/Monstre/Monstre.c new file mode 100644 index 0000000..336a516 --- /dev/null +++ b/Space Invaders/Envahisseurs/Graphique/src/Monstre/Monstre.c @@ -0,0 +1,103 @@ +#include +#include "../Graphique/libgraph.h" +#include "../ListeC/Liste.h" +#include "Monstre.h" + +#define TailleX 500 +#define TailleY 500 +#define ErreurHitbox 2 + +#define Taille1_10 (TailleX / 10) +#define Taille9_10 (9 * TailleX / 10) +#define TailleJump 30 + +//Sens = 1 -> Va vers la droite +//Sens = 0 -> Va vers la gauche +void DeplacementEnemie(struct liste_entite* Liste, + int* SensDeplacement, + int Pas) +{ + //ind sert à savoir si je dois changer de sens ou non + int ind = 0; + struct liste_entite* pListe = Liste; + + while (pListe != NULL) + { + pListe->entite.posx += (*SensDeplacement == 1) ? Pas : -Pas; + if (pListe->entite.posx >= Taille9_10) + { + ind = 1; + } + + else if (pListe->entite.posx <= Taille1_10) + { + ind = 2; + } + + pListe = pListe->suivant; + } + + if (ind != 0) + { + *SensDeplacement = (ind == 1) ? 0 : 1; + struct liste_entite* p2Liste = Liste; + + while (p2Liste != NULL) + { + p2Liste->entite.posy += TailleJump; + p2Liste = p2Liste->suivant; + } + } +} + +//Création de lignes d'entités enemies dans la liste enemies +void LigneEnemie (struct liste_entite** ListeEnemie, + int nbr_enemies, + int nbr_rangee) +{ + + for (int j = 1; j <= nbr_rangee; j++) + { + int compteurY = j * Taille1_10; + int compteurX = TailleX / (nbr_enemies+1); + + for (int i = 0; i < nbr_enemies; i++) + { + if (j == nbr_rangee) + { + ajout_tete(ListeEnemie, + creer_entite(compteurX, + compteurY, + 1)); + compteurX += 2 * TailleX / (3 * nbr_enemies); + } + + else + { + ajout_tete(ListeEnemie, + creer_entite(compteurX, + compteurY, + 0)); + compteurX += 2 * TailleX / (3 * nbr_enemies); + } + } + } +} + +//Affichage des enemies centrés dans leur hitbox +void AfficherEnemie (struct liste_entite* Liste, + int lutin, + int Largeur, + int Hauteur) +{ + + struct liste_entite* pListe = Liste; + + while (pListe != NULL) + { + afficherLutin(lutin, + pListe->entite.posx - Largeur / 2 + ErreurHitbox, + pListe->entite.posy - Hauteur / 2 + ErreurHitbox); + pListe=pListe->suivant; + } +} diff --git a/Space Invaders/Envahisseurs/Graphique/src/Monstre/Monstre.h b/Space Invaders/Envahisseurs/Graphique/src/Monstre/Monstre.h new file mode 100644 index 0000000..8c13363 --- /dev/null +++ b/Space Invaders/Envahisseurs/Graphique/src/Monstre/Monstre.h @@ -0,0 +1,12 @@ +void DeplacementEnemie(struct liste_entite* Liste, + int* SensDeplacement, + int Pas); + +void LigneEnemie (struct liste_entite** ListeEnemie, + int nbr_enemies, + int nbr_rangee); + +void AfficherEnemie (struct liste_entite* Liste, + int lutin, + int Largeur, + int Hauteur); diff --git a/Space_Invaders/Lutins/Coeur.bmp b/Space_Invaders/Lutins/Coeur.bmp new file mode 100644 index 0000000..823e8a0 Binary files /dev/null and b/Space_Invaders/Lutins/Coeur.bmp differ diff --git a/Space_Invaders/Lutins/invader_bombe.bmp b/Space_Invaders/Lutins/invader_bombe.bmp new file mode 100644 index 0000000..0b3e39b Binary files /dev/null and b/Space_Invaders/Lutins/invader_bombe.bmp differ diff --git a/Space_Invaders/Lutins/invader_bouclier.bmp b/Space_Invaders/Lutins/invader_bouclier.bmp new file mode 100644 index 0000000..f71e3f3 Binary files /dev/null and b/Space_Invaders/Lutins/invader_bouclier.bmp differ diff --git a/Space_Invaders/Lutins/invader_canon.bmp b/Space_Invaders/Lutins/invader_canon.bmp new file mode 100644 index 0000000..2b450dd Binary files /dev/null and b/Space_Invaders/Lutins/invader_canon.bmp differ diff --git a/Space_Invaders/Lutins/invader_canon_ferraille.bmp b/Space_Invaders/Lutins/invader_canon_ferraille.bmp new file mode 100644 index 0000000..575ec72 Binary files /dev/null and b/Space_Invaders/Lutins/invader_canon_ferraille.bmp differ diff --git a/Space_Invaders/Lutins/invader_missile.bmp b/Space_Invaders/Lutins/invader_missile.bmp new file mode 100644 index 0000000..592caa4 Binary files /dev/null and b/Space_Invaders/Lutins/invader_missile.bmp differ diff --git a/Space_Invaders/Lutins/invader_monstre1_1.bmp b/Space_Invaders/Lutins/invader_monstre1_1.bmp new file mode 100644 index 0000000..cf56472 Binary files /dev/null and b/Space_Invaders/Lutins/invader_monstre1_1.bmp differ diff --git a/Space_Invaders/Lutins/invader_monstre1_2.bmp b/Space_Invaders/Lutins/invader_monstre1_2.bmp new file mode 100644 index 0000000..cf56472 Binary files /dev/null and b/Space_Invaders/Lutins/invader_monstre1_2.bmp differ diff --git a/Space_Invaders/Lutins/invader_monstre2_1.bmp b/Space_Invaders/Lutins/invader_monstre2_1.bmp new file mode 100644 index 0000000..40bbf1f Binary files /dev/null and b/Space_Invaders/Lutins/invader_monstre2_1.bmp differ diff --git a/Space_Invaders/Lutins/invader_monstre2_2.bmp b/Space_Invaders/Lutins/invader_monstre2_2.bmp new file mode 100644 index 0000000..f99ec39 Binary files /dev/null and b/Space_Invaders/Lutins/invader_monstre2_2.bmp differ diff --git a/Space_Invaders/Lutins/invader_monstre3_1.bmp b/Space_Invaders/Lutins/invader_monstre3_1.bmp new file mode 100644 index 0000000..a17556a Binary files /dev/null and b/Space_Invaders/Lutins/invader_monstre3_1.bmp differ diff --git a/Space_Invaders/Lutins/invader_monstre3_2.bmp b/Space_Invaders/Lutins/invader_monstre3_2.bmp new file mode 100644 index 0000000..a17556a Binary files /dev/null and b/Space_Invaders/Lutins/invader_monstre3_2.bmp differ diff --git a/Space_Invaders/Lutins/invader_monstre_bouillie.bmp b/Space_Invaders/Lutins/invader_monstre_bouillie.bmp new file mode 100644 index 0000000..fa89282 Binary files /dev/null and b/Space_Invaders/Lutins/invader_monstre_bouillie.bmp differ diff --git a/Space_Invaders/Lutins/invader_ovni.bmp b/Space_Invaders/Lutins/invader_ovni.bmp new file mode 100644 index 0000000..da5fbd8 Binary files /dev/null and b/Space_Invaders/Lutins/invader_ovni.bmp differ diff --git a/Space_Invaders/Lutins/millepatte_champi.bmp b/Space_Invaders/Lutins/millepatte_champi.bmp new file mode 100644 index 0000000..6126777 Binary files /dev/null and b/Space_Invaders/Lutins/millepatte_champi.bmp differ diff --git a/Space_Invaders/Lutins/millepatte_corps_bas.bmp b/Space_Invaders/Lutins/millepatte_corps_bas.bmp new file mode 100644 index 0000000..ed4f660 Binary files /dev/null and b/Space_Invaders/Lutins/millepatte_corps_bas.bmp differ diff --git a/Space_Invaders/Lutins/millepatte_corps_droite.bmp b/Space_Invaders/Lutins/millepatte_corps_droite.bmp new file mode 100644 index 0000000..36b049d Binary files /dev/null and b/Space_Invaders/Lutins/millepatte_corps_droite.bmp differ diff --git a/Space_Invaders/Lutins/millepatte_corps_gauche.bmp b/Space_Invaders/Lutins/millepatte_corps_gauche.bmp new file mode 100644 index 0000000..a67092c Binary files /dev/null and b/Space_Invaders/Lutins/millepatte_corps_gauche.bmp differ diff --git a/Space_Invaders/Lutins/millepatte_corps_haut.bmp b/Space_Invaders/Lutins/millepatte_corps_haut.bmp new file mode 100644 index 0000000..92dd3c7 Binary files /dev/null and b/Space_Invaders/Lutins/millepatte_corps_haut.bmp differ diff --git a/Space_Invaders/Lutins/millepatte_tete_bas.bmp b/Space_Invaders/Lutins/millepatte_tete_bas.bmp new file mode 100644 index 0000000..c582ab3 Binary files /dev/null and b/Space_Invaders/Lutins/millepatte_tete_bas.bmp differ diff --git a/Space_Invaders/Lutins/millepatte_tete_droite.bmp b/Space_Invaders/Lutins/millepatte_tete_droite.bmp new file mode 100644 index 0000000..7bce015 Binary files /dev/null and b/Space_Invaders/Lutins/millepatte_tete_droite.bmp differ diff --git a/Space_Invaders/Lutins/millepatte_tete_gauche.bmp b/Space_Invaders/Lutins/millepatte_tete_gauche.bmp new file mode 100644 index 0000000..f94c70b Binary files /dev/null and b/Space_Invaders/Lutins/millepatte_tete_gauche.bmp differ diff --git a/Space_Invaders/Lutins/millepatte_tete_haut.bmp b/Space_Invaders/Lutins/millepatte_tete_haut.bmp new file mode 100644 index 0000000..c74c0c1 Binary files /dev/null and b/Space_Invaders/Lutins/millepatte_tete_haut.bmp differ diff --git a/Space_Invaders/src/Graphique/Makefile b/Space_Invaders/src/Graphique/Makefile new file mode 100644 index 0000000..5791d72 --- /dev/null +++ b/Space_Invaders/src/Graphique/Makefile @@ -0,0 +1,29 @@ +# +# Makefile pour la bibliotheque graphique +# + +SOURCES = $(wildcard *.c) +OBJETS = $(SOURCES:.c=.o) +CIBLE = libgraph.a + +# +# Nom de la cible principale +# + +all: $(CIBLE) + +# +# Cible de nettoyage +# + +clean: + rm -f core *.o $(CIBLE) + +# +# Dependances pour la bibliotheque +# + +$(CIBLE): $(OBJETS) + $(AR) rs $@ $? + +$(CIBLE:.a=).o: $(CIBLE:.a=).c $(CIBLE:.a=).h diff --git a/Space_Invaders/src/Graphique/libgraph.c b/Space_Invaders/src/Graphique/libgraph.c new file mode 100644 index 0000000..99658e1 --- /dev/null +++ b/Space_Invaders/src/Graphique/libgraph.c @@ -0,0 +1,239 @@ +/**** Bibliotheque graphique ****/ + +/** Fichiers d'inclusion **/ + +#include +#include +#include "libgraph.h" + +/** Types **/ + +typedef struct +{ + int r, v, b; +} couleur; + +/** Constantes **/ + +#define BITS_PAR_PIXEL 32 +#define TAILLE_POLICE 20 + +static const couleur couleurs[] = { { 255, 255, 255 }, { 0, 0, 0 }, { 255, 0, 0 }, + { 0, 255, 0 }, { 0, 0, 255 }, { 255, 105, 180 }, + { 150, 150, 150 }, { -1, -1, -1 } }; + +static const char policeDefaut[]="/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf"; + +/** Variables globales **/ + +static SDL_Surface *surface; +TTF_Font* police; + +/** Fonctions **/ + +void choisirPolice(const char *chemin, int taille){ + police=TTF_OpenFont(chemin, taille); +} + +void initialiserTexte() { + TTF_Init(); + choisirPolice(policeDefaut, TAILLE_POLICE); +} + +/* Initialisation de la surface dessinable */ +unsigned char creerSurface (int largeur, int hauteur, char *titre) +{ + SDL_Init (SDL_INIT_VIDEO); + SDL_WM_SetCaption (titre, titre); + surface = SDL_SetVideoMode (largeur, hauteur, BITS_PAR_PIXEL, SDL_DOUBLEBUF); + initialiserTexte(); + + return (surface != NULL && police != NULL); +} + +/* Fermeture de la surface dessinable */ + +void fermerSurface (void) +{ + if (surface != NULL) SDL_FreeSurface (surface); + if (police != NULL) TTF_CloseFont(police); + TTF_Quit(); + SDL_Quit (); +} + +/* Creation d'une couleur */ + +static int creerCouleur (int ncouleur) +{ + couleur c = couleurs[ncouleur]; + return SDL_MapRGB (surface->format, c.r, c.v, c.b); +} + +/* Dessin d'un rectangle plein */ + +void rectanglePlein (int x, int y, int l, int h, int c) +{ + SDL_Rect rectangle = { x, y, l, h }; + SDL_FillRect (surface, &rectangle, creerCouleur (c)); + // SDL_Flip(surface); +} + +/* Manipulation de lutins */ + +static SDL_Surface *lutins[MAX_LUTINS]; +static int lutins_nb = 0; + +int lutinTexte(char* texte, int couleurTexte) { + couleur c=couleurs[couleurTexte]; + SDL_Color couleur={c.r, c.v, c.b}; + SDL_Surface* lutin=TTF_RenderText_Solid(police, texte, couleur); + if (lutin != NULL) + { + lutins[lutins_nb++] = lutin; + return lutins_nb - 1; + } + return -1; +} + +static void configurerLutin (SDL_Surface *lutin, int ncouleur) +{ + couleur c = couleurs[ncouleur]; + int fond = SDL_MapRGB (lutin->format, c.r, c.v, c.b); + SDL_SetColorKey (lutin, SDL_SRCCOLORKEY | SDL_RLEACCEL, fond); +} + +int chargerLutin (char *fichier, int couleur) +{ + if (lutins_nb >= MAX_LUTINS) return -2; + SDL_Surface *lutin = SDL_LoadBMP (fichier); + if (lutin != NULL) + { + lutins[lutins_nb++] = lutin; + if (couleur >= 0) configurerLutin (lutin, couleur); + return lutins_nb - 1; + } + return -1; +} + +void afficherLutin (int lutin, int x, int y) +{ + SDL_Rect position; + position.x = x; + position.y = y; + SDL_BlitSurface (lutins[lutin], NULL, surface, &position); +} + +int creerLutin (int x, int y, int largeur, int hauteur, int couleur) +{ + if (lutins_nb >= MAX_LUTINS) return -2; + int rmask, gmask, bmask, amask; +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + rmask = 0xff000000; + gmask = 0x00ff0000; + bmask = 0x0000ff00; + amask = 0x000000ff; +#else + rmask = 0x000000ff; + gmask = 0x0000ff00; + bmask = 0x00ff0000; + amask = 0xff000000; +#endif + if (couleur < 0) amask = 0x00000000; + SDL_Surface *lutin = + SDL_CreateRGBSurface (0, largeur, hauteur, BITS_PAR_PIXEL, rmask, gmask, bmask, amask); + SDL_Rect fenetre; + fenetre.x = x; + fenetre.y = y; + fenetre.h = hauteur; + fenetre.w = largeur; + SDL_BlitSurface (surface, &fenetre, lutin, NULL); + lutins[lutins_nb++] = lutin; + if (couleur >= 0) configurerLutin (lutin, couleur); + return lutins_nb - 1; +} + +void tailleLutin (int lutin, int *largeur, int *hauteur) +{ + *largeur = lutins[lutin]->w; + *hauteur = lutins[lutin]->h; +} + +int sauverLutin (int lutin, char *nom) { return SDL_SaveBMP (lutins[lutin], nom); } + +/* Manipulation de copie de surface en BMP */ + +int sauverSurface (char *fichier) { return SDL_SaveBMP (surface, fichier); } + +unsigned char chargerSurface (char *fichier) +{ + SDL_Surface *image = SDL_LoadBMP (fichier); + if (image != NULL) + { + SDL_BlitSurface (image, NULL, surface, NULL); + SDL_Flip (surface); + } + return (image != NULL); +} + +void majSurface (void) { SDL_Flip (surface); } + +/* Trouver la couleur d'un pixel */ + +int couleurPixel (int x, int y) +{ + int bpp = surface->format->BytesPerPixel; + Uint32 *p = (Uint32 *)(surface->pixels + y * surface->pitch + x * bpp); + Uint8 r, v, b; + SDL_GetRGB (*p, surface->format, &r, &v, &b); + int i = 0; + while (1) + { + if (couleurs[i].r < 0) break; + if (r == couleurs[i].r && v == couleurs[i].v && b == couleurs[i].b) break; + i++; + } + if (couleurs[i].r < 0) + return -1; + else + return i; +} + +/* Fonction de traitement des événements */ + +void lireEvenement (evenement *evt, char *touche, void **detail) +{ + static SDL_keysym _detail; + SDL_Event event; + while (SDL_PollEvent (&event)) + { + if (event.type == SDL_QUIT) *evt = quitter; + if (event.type == SDL_KEYDOWN || event.type == SDL_KEYUP) + { + *evt = (event.type == SDL_KEYDOWN) ? toucheBas : toucheHaut; + char *nom = SDL_GetKeyName (event.key.keysym.sym); + if (strlen (nom) == 1 && nom[0] >= 32 && nom[0] < 128) + *touche = nom[0]; + else + *touche = 0; + if (detail != NULL) + { + _detail = event.key.keysym; + *detail = &_detail; + } + break; + } + } +} + +void attendreEvenement (void) +{ + SDL_Event event; + while (SDL_WaitEvent (&event)) switch (event.type) + { + case SDL_QUIT: + exit (0); + case SDL_KEYDOWN: + case SDL_MOUSEBUTTONDOWN: + return; + } +} diff --git a/Space_Invaders/src/Graphique/libgraph.h b/Space_Invaders/src/Graphique/libgraph.h new file mode 100644 index 0000000..f518cff --- /dev/null +++ b/Space_Invaders/src/Graphique/libgraph.h @@ -0,0 +1,156 @@ +/**** Bibliotheque graphique (definitions) ****/ + +/** Constantes **/ + +#define COULEUR_BLANC 0 +#define COULEUR_NOIR 1 +#define COULEUR_ROUGE 2 +#define COULEUR_VERT 3 +#define COULEUR_BLEU 4 +#define COULEUR_ROSE 5 +#define COULEUR_GRIS 6 + +#define MAX_LUTINS 16 + +typedef enum {toucheBas, toucheHaut, quitter} evenement; + +/** Prototypes **/ + +/** + * @brief cree une fenetre 2D + * + * @param largeur en pixels de la fenetre + * @param hauteur en pixels de la fenetre + * @param titre de la fenetre (chaine de caractere) + */ +unsigned char creerSurface (int largeur, int hauteur, char *titre); + +/** + * @brief permet de charger un fichier image au format bmp (bitmap) + * + * @param fichier nom du fichier + */ +unsigned char chargerSurface (char *fichier); + + +/** + * @brief permet de sauvegarder une surface en image (format bmp) + * + * @param fichier nom du fichier + * @return 0 si OK, valeur negative sinon + */ +int sauverSurface (char *fichier); + +/** + * @brief met a jour la surface d'affichage + */ +void majSurface (void); + + +/** + * @brief libere la surface d'affichage + * a faire lors de la fermeture + * du programme + */ +void fermerSurface (void); + +/** + * @brief choisit la police de caractères à utiliser pour afficher du texte + * @param chemin nom du fichier de police (format .ttf, voir /usr/share/fonts/truetype) + * @param taille taille de la police + */ +void choisirPolice(const char *chemin, int taille); + +/** + * @brief dessine un rectange de taille (l,h) aux coordonnêes + * (x,y) et de couleur c + * + * @param x 0 <= x <= l_surface + * @param y 0 <= y <= h_surface + * @param l largeur en pixels + * @param h longueur en pixels + * @param c indice de couleur voir variable couleurs dans le fichier .c + */ +void rectanglePlein (int x, int y, int l, int h, int c); + + +/** + * @brief permet de determiner l'indice du tableau de couleur du + * pixel aux coordonnees (x,y) + * + * @param x 0 <= x <= l_surface + * @param y 0 <= y <= h_surface + * @return indice de couleur voire variable couleurs dans le fichier .c + */ +int couleurPixel (int x, int y); + +/** + * @brief crée un lutin à partir d'un texte + * + * @param texte le texte + * @param couleur indice de couleur du texte + * @return numero de lutin dans le tableau dynamique de lutin (< MAX_LUTINS) + */ +int lutinTexte(char *texte, int couleur); + +/** + * @brief charge un lutin à partir du fichier + * + * @param fichier image bitmap du lutin à charger + * @param couleur indice de couleurs à charger + * @return numero de lutin dans le tableau dynamique de lutin (< MAX_LUTINS) + */ +int chargerLutin (char *fichier, int couleur); + +/** + * @brief afficher un lutin aux coordonnées (x,y) + * + * @param lutin numero du lutin à afficher (< MAX_LUTINS) + * @param x abscisse de départ + * @param y ordonnée de départ + */ +void afficherLutin (int lutin, int x, int y); + +/** + * @brief creer un lutin de taille (l,h) aux coordonnées (x,y) + * + * @param x abscisse de départ + * @param y ordonnée de départ + * @param largeur largeur du lutin + * @param hauteur hauteur du lutin + * @param couleur indice de couleur à partir du tableau _couleurs_ + * @return indice du lutin dans le tableau global (< MAX_LUTINS) + */ +int creerLutin (int x, int y, int largeur, int hauteur, int couleur); + +/** + * @brief sauvegarde un lutin dans un fichier + * + * @param lutin numero de lutin à sauvegarder (< MAX_LUTINS) + * @param nom fichier pour la sauvegarde + * @return 0 si OK valeur négative sinon + */ +int sauverLutin (int lutin, char *nom); + +/** + * @brief calcule la taille (largeur,hauteur) d'un lutin + * + * @param lutin index du lutin (< MAX_LUTINS) + * @param largeur pointeur sur la largeur + * @param hauteur pointeur sur la hauteur + */ +void tailleLutin (int lutin, int *largeur, int *hauteur); + +/** + * @brief lire une touche au clavier + * + * @param evt pointeur sur evenement + * @param touche pointeur sur la touche pressée + * @param detail NULL ou keysim + */ +void lireEvenement (evenement *evt, char *touche, void **detail); + +/** + * @brief attente d'un evenement bouton, souris, fin de programme + */ +void attendreEvenement (void); diff --git a/Space_Invaders/src/Interactif/Interactif.c b/Space_Invaders/src/Interactif/Interactif.c new file mode 100644 index 0000000..0a75322 --- /dev/null +++ b/Space_Invaders/src/Interactif/Interactif.c @@ -0,0 +1,375 @@ +#include +#include + +#include "../Graphique/libgraph.h" +#include "../ListeC/Liste.h" +#include "Interactif.h" +#include "../Main/init.h" + +#define TailleX 500 +#define TailleY 500 +#define Sol 475 +#define ErreurHitbox 2 +#define TailleX9_10 (9 * TailleX / 10) +#define TailleX1_10 (TailleX / 10) + +#define ValeurDeplacementTire 5 +#define ValeurDeplacementJoueur 3 +#define ValeurDeplacementBombe 2 + + +//La fonction renvoie 1 si il y a collision +int CheckCollisionEntiteEntite (struct entite entite1, + int L1, + int H1, + struct entite entite2, + int L2, + int H2) +{ + //CheckX + int gauche1 = entite1.posx - L1/2 + ErreurHitbox; + int droite1 = entite1.posx + L1/2 - ErreurHitbox; + int gauche2 = entite2.posx - L2/2 + ErreurHitbox; + int droite2 = entite2.posx + L2/2 - ErreurHitbox; + //Tout les cas possibles de collision + int CheckX = (gauche1 >= gauche2 && gauche1 <= droite2) || + (droite1 >= gauche2 && droite1 <= droite2) || + (gauche1 >= gauche2 && droite1 <= droite2) || + (gauche2 >= gauche1 && droite2 <= droite1); + + //CheckY + int haut1 = entite1.posy - H1/2 + ErreurHitbox; + int bas1 = entite1.posy + H1/2 - ErreurHitbox; + int haut2 = entite2.posy - H2/2 + ErreurHitbox; + int bas2 = entite2.posy + H2/2 - ErreurHitbox; + int CheckY = (haut1 <= bas2 && haut1 >= haut2) || + (bas1 <= bas2 && bas1 >= haut2) || + (haut1 <= haut2 && bas1 >= bas2) || + (haut2 <= haut1 && bas2 >= bas1); + + + return CheckX && CheckY; +} + +//La fonction renvoie l'entite de la Liste1 si il y a collision +struct entite* CheckCollisionListeEntite (struct liste_entite* Liste1, + int L1, + int H1, + struct entite entite2, + int L2, + int H2) +{ + + struct liste_entite *pListe1 = Liste1; + while (pListe1 != NULL) + { + + if(CheckCollisionEntiteEntite (pListe1->entite, + L1, + H1, + entite2, + L2, + H2) == 1) + { + return &pListe1->entite; + } + + pListe1 = pListe1->suivant; + } + return NULL; +} + + + +//La fonction renvoie une liste d'entite avec les deux entites à supprimer +//Seulement si il y a collision +struct liste_entite* CheckCollisionListeListe (struct liste_entite* Liste1, + int L1, + int H1, + struct liste_entite* Liste2, + int L2, + int H2) +{ + + struct liste_entite *pListe2 = Liste2; + while (pListe2 != NULL) + { + + struct entite* collision = CheckCollisionListeEntite (Liste1, + L1, + H1, + pListe2->entite, + L2, + H2); + if (collision == NULL) + { + pListe2 = pListe2->suivant; + } + + else + { + // Création des structures pour les deux entités + struct liste_entite* Entite1 = malloc(sizeof(struct liste_entite)); + struct liste_entite* Entite2 = malloc(sizeof(struct liste_entite)); + + // Remplissage des structure avec les entités correspondantes + Entite1->entite = *collision; + Entite2->entite = pListe2->entite; + + // Relier les structures entre elles + Entite1->suivant = Entite2; + Entite2->suivant = NULL; + + return Entite1; + } + } + + return NULL; +} + +//Tire un missile, il ne peux y en avoir que un à la fois +void Tirer (struct entite joueur, + struct liste_entite** pl) +{ + if (*pl == NULL) + { + ajout_tete(pl, + creer_entite(joueur.posx, + joueur.posy, + -1)); + } +} + + +void DeplacementTire(struct liste_entite** Liste) +{ + struct entite* Entite = &(*Liste)->entite; + if (Entite != NULL) + { + + if (Entite->posy <= 0) + { + afficherLutin(bouillie, + Entite->posx - hitboxbouillieL/2 + ErreurHitbox, + Entite->posy); + SupprimerEntite(Liste, Entite); + } + + else + { + Entite->posy -= ValeurDeplacementTire; + //Je divise ErreurHitbox par 2 car l'erreur du missile + //est plus petite que pour les autres images + afficherLutin(missile, + Entite->posx - hitboxmissileL/2 + ErreurHitbox/2, + Entite->posy - hitboxmissileH/2 + ErreurHitbox/2); + } + } +} + + +//La fonction fait une action soit au joueur +//soit à la Liste des Tires selon la touche préssée +void action(struct entite* joueur, + char c, + struct liste_entite** tires) +{ + switch (c) + { + case 'd': + if (joueur->posx <= TailleX9_10) + { + joueur->posx += ValeurDeplacementJoueur; + } + break; + case 'q': + if (joueur->posx >= TailleX1_10) + { + joueur->posx -= ValeurDeplacementJoueur; + } + break; + case 't': + Tirer(*joueur, + tires); + break; + default: + break; + } +} + +/* +La fonction crée une liste de tout les enemies pouvant drop des bombes +Seulement ceux les plus bas de leur colonne repective +Puis ajoute à la liste bombe, +une bombe provenant d'un des enemies pouvant drop des bombes +Le choix de quel enemie drop la bombe est aléatoire +*/ +void MakeBombeDrop (struct liste_entite* enemies, + struct liste_entite** bombes) +{ + + struct liste_entite* pListe = enemies; + struct liste_entite* Dropable = NULL; + int taille = 0; + + while (pListe != NULL) + { + + if (pListe->entite.dropbombe == 1) + { + ajout_tete(&Dropable,pListe->entite); + taille += 1; + } + + pListe = pListe->suivant; + } + + if(Dropable == NULL) + { + return; + } + /* + On choisit une valeur aléatoire représentant l'enemie qui va drop la bombe + Il ya un warning comme quoi rand() à une limite + Mais on ne la dépassera jamais, taille ne pourra + jamais excédé une vingtaine d'enemies par ligne + */ + int randomIndex = rand() % taille-1; + struct liste_entite* pDropable = Dropable; + + for (int i = 0; i <= randomIndex; i++) + { + pDropable = pDropable->suivant; + } + + ajout_tete(bombes, + creer_entite(pDropable->entite.posx, + pDropable->entite.posy, + -1)); +} + + +void DeplacementBombe(struct liste_entite** Liste) +{ + struct liste_entite* pListe = *Liste; + + while (pListe != NULL) + { + + if (pListe->entite.posy + hitboxbombeH/2 - ErreurHitbox >= Sol) + { + struct entite* a_supprimer = &pListe->entite; + + pListe = pListe->suivant; + SupprimerEntite(Liste,a_supprimer); + } + + else + { + pListe->entite.posy += ValeurDeplacementBombe; + afficherLutin(bombe, + pListe->entite.posx - hitboxbombeL/2 + ErreurHitbox, + pListe->entite.posy - hitboxbombeH/2 + ErreurHitbox); + pListe = pListe->suivant; + } + } +} + +/* +Si un enemie est éliminé et qu'il etait le plus bas de sa colonne +(il pouvait drop des bombes) +Alors si il y en a un, l'enemie au dessus de lui (de la meme colonne) +peut maintenant drop des bombes +*/ +void NouveauDroppeurBombe (struct liste_entite** liste, + struct entite* entite) +{ + + int posx = entite->posx; + int posy = entite->posy; + struct liste_entite* pListe = *liste; + struct entite* entite_basse = NULL; + + // On parcourt la liste et on cherche + //l'entité la plus basse ayant la même position x + while (pListe != NULL) + { + //On ne regarde pas les enemies qui sont sur la meme ligne + if (pListe->entite.posy != posy) + { + //Si meme colonne et qu'il n'y a pas d'entite_basse + if (pListe->entite.posx == posx && + entite_basse == NULL) + { + entite_basse = &pListe->entite; + } + + //Si meme colonne mais qu'il y a deja une entite_basse + //On compare la hauteur de l'entite avec l'entite_basse + else if (pListe->entite.posx == posx && + pListe->entite.posy > entite_basse->posy) + { + entite_basse = &pListe->entite; + } + } + + pListe = pListe->suivant; + } + + // Si aucune entité n'est située plus bas que l'entité en question, + //On ne peut pas dropper la bombe + if (entite_basse == NULL) + { + return; + } + + entite_basse->dropbombe = 1; +} + + + +//Fonction Main qui supprime les entités rentrées en collision de leur liste +int SupprimerEntitesEnCollision (struct liste_entite** Liste1, + int L1, + int H1, + struct liste_entite** Liste2, + int L2, + int H2) +{ + + struct liste_entite* collision = CheckCollisionListeListe(*Liste1, + L1, + H1, + *Liste2, + L2, + H2); + if (collision != NULL) + { + // Récupération des entités impliquées + struct entite* Entite1 = &collision->entite; + struct entite* Entite2 = &collision->suivant->entite; + + if (Entite1->dropbombe == 1) + { + NouveauDroppeurBombe(Liste1,Entite1); + } + + if (Entite2->dropbombe == 1) + { + NouveauDroppeurBombe(Liste2,Entite2); + } + + // Suppression de l'entité 1 de la liste 1 + SupprimerEntite(Liste1, Entite1); + // Suppression de l'entité 2 de la liste 2 + SupprimerEntite(Liste2, Entite2); + + afficherLutin (bouillie, + Entite2->posx - hitboxbouillieL/2 + ErreurHitbox, + Entite2->posy - hitboxbouillieH/2 + ErreurHitbox); + return 1; + } + return 0; +} + + diff --git a/Space_Invaders/src/Interactif/Interactif.h b/Space_Invaders/src/Interactif/Interactif.h new file mode 100644 index 0000000..3b43832 --- /dev/null +++ b/Space_Invaders/src/Interactif/Interactif.h @@ -0,0 +1,44 @@ +int CheckCollisionEntiteEntite (struct entite entite1, + int L1, + int H1, + struct entite entite2, + int L2, + int H2); + +struct entite* CheckCollisionListeEntite (struct liste_entite* Liste1, + int L1, + int H1, + struct entite entite2, + int L2, + int H2); + +struct liste_entite* CheckCollisionListeListe (struct liste_entite* Liste1, + int L1, + int H1, + struct liste_entite* Liste2, + int L2, + int H2); + +void Tirer (struct entite joueur, + struct liste_entite** pl); + +void DeplacementTire(struct liste_entite** Liste); + +void action(struct entite* joueur, + char c, + struct liste_entite** tires); + +void MakeBombeDrop (struct liste_entite* enemies, + struct liste_entite** bombes); + +void DeplacementBombe(struct liste_entite** Liste) ; + +void NouveauDroppeurBombe (struct liste_entite** liste, + struct entite* entite); + +int SupprimerEntitesEnCollision (struct liste_entite** Liste1, + int L1, + int H1, + struct liste_entite** Liste2, + int L2, + int H2); diff --git a/Space_Invaders/src/ListeC/Liste.c b/Space_Invaders/src/ListeC/Liste.c new file mode 100644 index 0000000..cdf57ab --- /dev/null +++ b/Space_Invaders/src/ListeC/Liste.c @@ -0,0 +1,80 @@ +#include +#include +#include + +#include "Liste.h" + +//Crée une entité +struct entite creer_entite (int x, + int y, + int candrop) +{ + struct entite e; + + e.posx = x; + e.posy = y; + e.dropbombe = candrop; + + return e; +} + + +//Ajout en tete une entité dans une liste +void ajout_tete (struct liste_entite** Liste, + struct entite x ) +{ + struct liste_entite *Listetmp=NULL; + + Listetmp = malloc(sizeof(struct liste_entite)); + Listetmp->entite = x; + Listetmp->suivant = *Liste; + + *Liste = Listetmp; +} + + +//Supprime une entite d'une liste +void SupprimerEntite (struct liste_entite** Liste, + struct entite* entite) +{ + struct liste_entite* courant = *Liste; + struct liste_entite* precedent = NULL; + //Ce pointeur precedent va garder en memoire l'entite precedente + //Initialisé à NULL car cela est utile dans le cas ou l'entite est la 1ere + + while (courant != NULL) + { + //Comparaison entre 2 entites + if (memcmp (&courant->entite, + entite, + sizeof(struct entite)) == 0) + { + //Si l'element est le premier + if (precedent == NULL) + { + *Liste = courant->suivant; + } + + else + { + precedent->suivant = courant->suivant; + } + + free(courant); + break; + } + + precedent = courant; + courant = courant->suivant; + } +} + + +//Desallouer une liste entiere +void DesallouerListe (struct liste_entite** Liste) +{ + while(*Liste != NULL) + { + SupprimerEntite(Liste,&((*Liste)->entite)); + } +} diff --git a/Space_Invaders/src/ListeC/Liste.h b/Space_Invaders/src/ListeC/Liste.h new file mode 100644 index 0000000..8d1d688 --- /dev/null +++ b/Space_Invaders/src/ListeC/Liste.h @@ -0,0 +1,29 @@ +//dropbombe concerne les entités enemies +//1 les enemies peuvent drop des bombes, 0 ils ne peuvent pas +//Les entites non concernées vallent ont un dropbombe = -1 +struct entite +{ + int posx; + int posy; + int dropbombe; +}; + + +struct liste_entite +{ + struct entite entite; + struct liste_entite *suivant; +}; + + +struct entite creer_entite (int x, + int y, + int bombe); + +void ajout_tete (struct liste_entite** Liste, + struct entite x ); + +void SupprimerEntite (struct liste_entite** Liste, + struct entite* entite); + +void DesallouerListe (struct liste_entite** Liste); diff --git a/Space_Invaders/src/Main/Makefile b/Space_Invaders/src/Main/Makefile new file mode 100644 index 0000000..a254998 --- /dev/null +++ b/Space_Invaders/src/Main/Makefile @@ -0,0 +1,37 @@ +CC=clang +TARGET=Jeu +CFLAGS=-g -W -Wall -Wextra +LDFLAGS=-I Graphique -l graph -L ../Graphique -l SDL -l SDL_ttf + +default: $(TARGET) + +Liste.o : ../ListeC/Liste.c ../ListeC/Liste.h + clang $(CFLAGS) -c ../ListeC/Liste.c + +Monstre.o : ../Monstre/Monstre.c ../Monstre/Monstre.h + clang $(CFLAGS) -c ../Monstre/Monstre.c + +Interactif.o : ../Interactif/Interactif.c ../Interactif/Interactif.h + clang $(CFLAGS) -c ../Interactif/Interactif.c + +init.o : init.c init.h + clang $(CFLAGS) -c init.c + +main.o : main.c + clang $(CFLAGS) -c main.c + + +$(TARGET): Liste.o main.o Monstre.o Interactif.o init.o + clang main.o Liste.o Monstre.o Interactif.o init.o -o $(TARGET) $(LDFLAGS) + +.PHONY: clean +clean: + rm -f *.o + rm -f $(TARGET) + +tidy : main.c ../ListeC/Liste.c ../Monstre/Monstre.c ../Interactif/Interactif.c init.c + $(CC)-tidy main.c ../ListeC/Liste.c ../Monstre/Monstre.c ../Interactif/Interactif.c init.c --checks="readability-*" -header-filter=.* + +format : + $(CC)-format -style='Microsoft' main.c ../ListeC/Liste.c ../Monstre/Monstre.c ../Interactif/Interactif.c init.c + diff --git a/Space_Invaders/src/Main/init.c b/Space_Invaders/src/Main/init.c new file mode 100644 index 0000000..b08b6d6 --- /dev/null +++ b/Space_Invaders/src/Main/init.c @@ -0,0 +1,244 @@ +#include +#include "../Graphique/libgraph.h" +#include "../ListeC/Liste.h" +#include "../Interactif/Interactif.h" +#include "init.h" + +#define TailleX 500 +#define TailleY 500 +#define Sol 475 +#define ErreurHitbox 2 +#define PositionX_1 (TailleX / 2) +#define PositionY_1 (TailleY / 2) +#define PositionY_2 (TailleY / 4) + +#define JoueurX (TailleX / 2) +#define JoueurY (9 * TailleY / 10) + +#define Nom "Space Invaders" +#define TaillePolice1 (TailleX / 10) +#define TaillePolice2 (TailleX / 20) +#define TailleChaineMax 30 + +//Ces variables sont globales car utilisées dans plusieurs .c +//Toutes les hitbox sont initialisées 1 fois puis sont des constantes +struct entite joueur; + +static const char policeDefaut[]= +"/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf"; + +int canon = 0; +int missile = 0; +int enemie1_1 = 0; +int enemie1_2 = 0; +int bouillie = 0; +int bombe = 0; + +int hitboxcanonL = 0; +int hitboxcanonH = 0; +int hitboxmissileL = 0; +int hitboxmissileH = 0; +int hitboxenemieL = 0; +int hitboxenemieH = 0; +int hitboxbouillieL = 0; +int hitboxbouillieH = 0; +int hitboxbombeL = 0; +int hitboxbombeH = 0; + +//Initialisation des variables globales pour le main +void initialiser() +{ + canon = chargerLutin ("../../Lutins/invader_canon.bmp", + COULEUR_NOIR); + missile = chargerLutin ("../../Lutins/invader_missile.bmp", + COULEUR_NOIR); + enemie1_1 = chargerLutin ("../../Lutins/invader_monstre2_1.bmp", + COULEUR_NOIR); + enemie1_2 = chargerLutin ("../../Lutins/invader_monstre2_2.bmp", + COULEUR_NOIR); + bouillie = chargerLutin ("../../Lutins/invader_monstre_bouillie.bmp", + COULEUR_NOIR); + bombe = chargerLutin ("../../Lutins/invader_bombe.bmp", + COULEUR_NOIR); + + tailleLutin (canon, + &hitboxcanonL, + &hitboxcanonH); + + tailleLutin (missile, + &hitboxmissileL, + &hitboxmissileH); + //La taille des enemmies que j'utilise est la meme dans ces 2 variantes + tailleLutin (enemie1_1, + &hitboxenemieL, + &hitboxenemieH); + + tailleLutin (bouillie, + &hitboxbouillieL, + &hitboxbouillieH); + + tailleLutin (bombe, + &hitboxbombeL, + &hitboxbombeH); + +} + +//Initialisation des coordonnées du joueur pour le main +void initialiserjoueur() +{ + joueur.posx = JoueurX; + joueur.posy = JoueurY; + joueur.dropbombe = -1; +} + +//Page de démarage du jeu +char pagedemarrage() +{ + char input = '\0'; + evenement even = 0; + int Largeur = 0; + int Hauteur = 0; + char jouer[] = "Appuyer sur j pour Jouer"; + char quitter[] = "Appuyer ailleurs pour Quitter"; + + choisirPolice (policeDefaut, TaillePolice2); + int LutinJouer = lutinTexte (jouer, COULEUR_BLANC); + int LutinQuitter = lutinTexte (quitter, COULEUR_BLANC); + + choisirPolice (policeDefaut, TaillePolice1); + int LutinBienvenue = lutinTexte (Nom, COULEUR_VERT); + + rectanglePlein (0, + 0, + TailleX, + TailleY, + COULEUR_NOIR); + + tailleLutin (LutinBienvenue, + &Largeur, + &Hauteur); + afficherLutin (LutinBienvenue, + PositionX_1 - Largeur / 2, + PositionY_2 + Hauteur / 2); + + tailleLutin (LutinJouer, + &Largeur, + &Hauteur); + afficherLutin (LutinJouer, + PositionX_1 - Largeur / 2, + PositionY_1 - Hauteur / 2); + + tailleLutin (LutinQuitter, + &Largeur, + &Hauteur); + afficherLutin (LutinQuitter, + PositionX_1 - Largeur / 2, + PositionY_1 + Hauteur / 2); + + majSurface(); + attendreEvenement (); + + lireEvenement (&even, + &input, + NULL); + while (input == '\0') + { + lireEvenement (&even, + &input, + NULL); + } + return input; +} + +//Page en cas de mort dans le jeu +void pagemort (int nbr_vie) +{ + int Largeur = 0; + int Hauteur = 0; + char mort[] = "Vous etes mort"; + char vie[TailleChaineMax] = "\0"; + sprintf (vie, + "Nombre de vies restantes : %d", + nbr_vie); + /* + sprintf crée un warning mais celui-ci ne peut pas crée d'erreur car + TailleChaineMax ne pourra pas excéder 30 si le nombre de vie reste "normal" + sprintf_s ne fonctionne pas pour mon programme (invalid in C99) + */ + + choisirPolice (policeDefaut, TaillePolice1); + int LutinMort = lutinTexte(mort, COULEUR_ROUGE); + + choisirPolice (policeDefaut, TaillePolice2); + int LutinVie = lutinTexte(vie, COULEUR_BLANC); + + rectanglePlein (0, + 0, + TailleX, + TailleY, + COULEUR_NOIR); + + tailleLutin (LutinMort, + &Largeur, + &Hauteur); + afficherLutin (LutinMort, + PositionX_1 - Largeur / 2, + PositionY_2 + Hauteur / 2); + + tailleLutin (LutinVie, + &Largeur, + &Hauteur); + afficherLutin (LutinVie, + PositionX_1 - Largeur / 2, + PositionY_1 - Hauteur / 2); +} + +//Page de GameOver du jeu +void pageGameOver() +{ + int Largeur = 0; + int Hauteur = 0; + char fin[] = "GAME OVER"; + + choisirPolice(policeDefaut, TaillePolice1); + int LutinFin = lutinTexte(fin, COULEUR_ROUGE); + + rectanglePlein (0, + 0, + TailleX, + TailleY, + COULEUR_NOIR); + + tailleLutin (LutinFin, + &Largeur, + &Hauteur); + afficherLutin (LutinFin, + PositionX_1 - Largeur / 2, + PositionY_1 - Hauteur / 2); + +} + +//Page de Victoire du jeu +void pageVictoire() +{ + int Largeur = 0; + int Hauteur = 0; + char fin[] = "VICTOIRE"; + + choisirPolice(policeDefaut, TaillePolice1); + int LutinFin = lutinTexte(fin, COULEUR_VERT); + + rectanglePlein (0, + 0, + TailleX, + TailleY, + COULEUR_NOIR); + + tailleLutin (LutinFin, + &Largeur, + &Hauteur); + afficherLutin (LutinFin, + PositionX_1 - Largeur / 2, + PositionY_1 - Hauteur / 2); + +} diff --git a/Space_Invaders/src/Main/init.h b/Space_Invaders/src/Main/init.h new file mode 100644 index 0000000..34fd8d5 --- /dev/null +++ b/Space_Invaders/src/Main/init.h @@ -0,0 +1,28 @@ +extern int canon; +extern int missile; +extern int enemie1_1; +extern int enemie1_2; +extern int bouillie; +extern int bombe; + +extern struct entite joueur; +extern char Nom[]; +extern char input; + +extern int hitboxcanonL; +extern int hitboxcanonH; +extern int hitboxmissileL; +extern int hitboxmissileH; +extern int hitboxenemieL; +extern int hitboxenemieH; +extern int hitboxbouillieL; +extern int hitboxbouillieH; +extern int hitboxbombeL; +extern int hitboxbombeH; + +void initialiser(); +void initialiserjoueur(); +char pagedemarrage(); +void pagemort(int nbr_vie); +void pageGameOver(); +void pageVictoire(); diff --git a/Space_Invaders/src/Main/main.c b/Space_Invaders/src/Main/main.c new file mode 100644 index 0000000..ead9a4a --- /dev/null +++ b/Space_Invaders/src/Main/main.c @@ -0,0 +1,267 @@ +#include +#include +#include "../Graphique/libgraph.h" +#include "../ListeC/Liste.h" +#include "../Monstre/Monstre.h" +#include "../Interactif/Interactif.h" +#include "init.h" + +#define TailleX 500 +#define TailleY 500 +#define Sol 475 +#define EpaisseurSol 2 +#define ErreurHitbox 2 + +#define Nom "Space Invader" +#define NombreEnemieParLigne 8 +#define NombreLigneEnemies 3 +#define NombreVie 3 + +#define BombeRandomFixe 50 +#define BombeRandomAlea 30 + +//Pour augmenter les deplacements des enemies, vous pouvez: +//Augmenter VitesseDeplacementEnemie +//Tout les VitesseDeplacementEnemie tours de boucle les enemies se déplace +#define VitesseDeplacementEnemie 2 +// Ou augmenter le PasEnemie (Ecart entre la position n et n+1) +#define PasEnemie 1 +#define AffichageImageEnemie 8 + +#define Delai0_2s 200 +#define Delai0_5s 500 +#define Delai2s 2000 + +#define VitesseTourdeBoucle 20 + +int main() +{ + creerSurface(TailleX,TailleY,Nom); + + initialiser(); + initialiserjoueur(); + + struct liste_entite* ListeEnemies = NULL; + struct liste_entite* ListeTires = NULL; + struct liste_entite* ListeBombes = NULL; + + //joueur est dans une liste afin d'utiliser des fonctions deja crée + struct liste_entite* Ljoueur = NULL; + ajout_tete(&Ljoueur,joueur); + + + LigneEnemie(&ListeEnemies, + NombreEnemieParLigne, + NombreLigneEnemies); + int SensVague = 1; + + char input = '\0'; + evenement even = 0; + + int TourdeBoucle = 0; + + int TimeAlea = 0; + int CheckAlea = 0; + + int mort = 0; + int nbr_vie = NombreVie; + int QuelMonstre = 0; + + int coeur = chargerLutin ("../../Lutins/Coeur.bmp", + COULEUR_NOIR); + int hitboxcoeurL = 0; + int hitboxcoeurH = 0; + tailleLutin (coeur, + &hitboxcoeurL, + &hitboxcoeurH); + + if ( pagedemarrage() != 'j') + { + return 0; + } + SDL_Delay(Delai0_5s); + + //Bouble principale + while(input!='m') + { + //Si le joueur est mort + if (mort == 1) + { + nbr_vie-=1; + //Si il lui reste des vies + if (nbr_vie > 0) + { + pagemort(nbr_vie); + majSurface(); + SDL_Delay(Delai2s); + mort = 0; + } + //Si il n'a plus de vie + else + { + pageGameOver(); + majSurface(); + SDL_Delay(Delai2s); + return 0; + } + //On ajoute de nouveau le joueur précedement supprimé à sa liste + ajout_tete(&Ljoueur,joueur); + //Desallocation dynamique des listes + DesallouerListe(&ListeTires); + DesallouerListe(&ListeBombes); + } + + //Affichage Rectangle Noir sur toute la page + rectanglePlein(0, + 0, + TailleX, + TailleY, + COULEUR_NOIR); + + //Affichage des coeurs de vie + for (int i = 1 ; i <= nbr_vie; i++) + { + afficherLutin(coeur, + TailleX - i * hitboxcoeurL, + Sol); + } + + //Affichage du Sol + rectanglePlein(0, + Sol, + TailleX, + EpaisseurSol, + COULEUR_VERT); + + //Affichage du joueur + afficherLutin(canon, + Ljoueur->entite.posx - hitboxcanonL/2 + ErreurHitbox, + Ljoueur->entite.posy); + + //Affichage des ListeEnemies + if (QuelMonstre > 2 * AffichageImageEnemie) + { + QuelMonstre = 0; + } + if (QuelMonstre <= AffichageImageEnemie) + { + AfficherEnemie (ListeEnemies, + enemie1_1, + hitboxenemieL, + hitboxenemieH); + QuelMonstre += 1; + } + else + { + AfficherEnemie (ListeEnemies, + enemie1_2, + hitboxenemieL, + hitboxenemieH); + QuelMonstre += 1; + } + /* + Systeme pour faire drop une bombe dans un temps aléatoire + Mise en place d'un timer + TimeAlea représente le nombre de tour de boucle à éffectuer + */ + if (TimeAlea == 0) + { + //50 tour de boucle minimum + une valeur de 0 à 31 + TimeAlea = rand() % BombeRandomAlea + BombeRandomFixe; + //Il y a un warning car rand() à une valeur limite + } + /* + CheckAlea est incrémenté de 1 à chaque tour de boucle + Lorsque celui ci vaut TimeAlea on peut drop une bombe + On reset à 0 le Timer et le Check aprés avoir Drop une bombe + */ + if (CheckAlea == TimeAlea) + { + MakeBombeDrop(ListeEnemies, + &ListeBombes); + TimeAlea=0; + CheckAlea=0; + } + + //Gestion des evenements clavier + //On ne peut appuyer que sur une seule touche à la fois + lireEvenement (&even, + &input, + NULL); + if (even == toucheBas) + { + action(&Ljoueur->entite, + input, + &ListeTires); + } + + //Deplacement des enemies tout les X tours de boucle + if (TourdeBoucle == VitesseDeplacementEnemie) + { + DeplacementEnemie(ListeEnemies, + &SensVague, + PasEnemie); + TourdeBoucle = 0; + } + + //Deplacement des Tires et Bombes + DeplacementTire(&ListeTires); + DeplacementBombe(&ListeBombes); + + //Supression si collision des Tires et Enemies + SupprimerEntitesEnCollision(&ListeTires, + hitboxmissileL, + hitboxmissileH, + &ListeEnemies, + hitboxenemieL, + hitboxenemieH); + + //Supression si collision des Bombes et Joueur + if (SupprimerEntitesEnCollision(&ListeBombes, + hitboxbombeL, + hitboxbombeH, + &Ljoueur, + hitboxcanonL, + hitboxcanonH) == 1) + { + mort = 1; + majSurface(); + SDL_Delay(Delai0_2s); + } + + //Supression si collision des Enemies et Joueur + if (SupprimerEntitesEnCollision(&ListeEnemies, + hitboxenemieL, + hitboxenemieH, + &Ljoueur, + hitboxcanonL, + hitboxcanonH) == 1) + { + pageGameOver(); + majSurface(); + SDL_Delay(Delai2s); + return 0; + } + + //Si il n'y a plus d'enemies, c'est une victoire !!! + if (ListeEnemies == NULL) + { + majSurface(); + SDL_Delay(Delai0_2s); + pageVictoire(); + majSurface(); + SDL_Delay(Delai2s); + return 0; + } + + + majSurface(); + + TourdeBoucle += 1; + CheckAlea += 1; + + SDL_Delay(VitesseTourdeBoucle); + + } + return 0; +} diff --git a/Space_Invaders/src/Monstre/Monstre.c b/Space_Invaders/src/Monstre/Monstre.c new file mode 100644 index 0000000..336a516 --- /dev/null +++ b/Space_Invaders/src/Monstre/Monstre.c @@ -0,0 +1,103 @@ +#include +#include "../Graphique/libgraph.h" +#include "../ListeC/Liste.h" +#include "Monstre.h" + +#define TailleX 500 +#define TailleY 500 +#define ErreurHitbox 2 + +#define Taille1_10 (TailleX / 10) +#define Taille9_10 (9 * TailleX / 10) +#define TailleJump 30 + +//Sens = 1 -> Va vers la droite +//Sens = 0 -> Va vers la gauche +void DeplacementEnemie(struct liste_entite* Liste, + int* SensDeplacement, + int Pas) +{ + //ind sert à savoir si je dois changer de sens ou non + int ind = 0; + struct liste_entite* pListe = Liste; + + while (pListe != NULL) + { + pListe->entite.posx += (*SensDeplacement == 1) ? Pas : -Pas; + if (pListe->entite.posx >= Taille9_10) + { + ind = 1; + } + + else if (pListe->entite.posx <= Taille1_10) + { + ind = 2; + } + + pListe = pListe->suivant; + } + + if (ind != 0) + { + *SensDeplacement = (ind == 1) ? 0 : 1; + struct liste_entite* p2Liste = Liste; + + while (p2Liste != NULL) + { + p2Liste->entite.posy += TailleJump; + p2Liste = p2Liste->suivant; + } + } +} + +//Création de lignes d'entités enemies dans la liste enemies +void LigneEnemie (struct liste_entite** ListeEnemie, + int nbr_enemies, + int nbr_rangee) +{ + + for (int j = 1; j <= nbr_rangee; j++) + { + int compteurY = j * Taille1_10; + int compteurX = TailleX / (nbr_enemies+1); + + for (int i = 0; i < nbr_enemies; i++) + { + if (j == nbr_rangee) + { + ajout_tete(ListeEnemie, + creer_entite(compteurX, + compteurY, + 1)); + compteurX += 2 * TailleX / (3 * nbr_enemies); + } + + else + { + ajout_tete(ListeEnemie, + creer_entite(compteurX, + compteurY, + 0)); + compteurX += 2 * TailleX / (3 * nbr_enemies); + } + } + } +} + +//Affichage des enemies centrés dans leur hitbox +void AfficherEnemie (struct liste_entite* Liste, + int lutin, + int Largeur, + int Hauteur) +{ + + struct liste_entite* pListe = Liste; + + while (pListe != NULL) + { + afficherLutin(lutin, + pListe->entite.posx - Largeur / 2 + ErreurHitbox, + pListe->entite.posy - Hauteur / 2 + ErreurHitbox); + pListe=pListe->suivant; + } +} diff --git a/Space_Invaders/src/Monstre/Monstre.h b/Space_Invaders/src/Monstre/Monstre.h new file mode 100644 index 0000000..8c13363 --- /dev/null +++ b/Space_Invaders/src/Monstre/Monstre.h @@ -0,0 +1,12 @@ +void DeplacementEnemie(struct liste_entite* Liste, + int* SensDeplacement, + int Pas); + +void LigneEnemie (struct liste_entite** ListeEnemie, + int nbr_enemies, + int nbr_rangee); + +void AfficherEnemie (struct liste_entite* Liste, + int lutin, + int Largeur, + int Hauteur); -- libgit2 0.21.2