Commit f8b7fad8660ac127311edc6e0ec836f815d21516
1 parent
7563cd89
Version Finale
Showing
72 changed files
with
3286 additions
and
0 deletions
Show diff stats
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
Space Invaders/Envahisseurs/Graphique/Lutins/invader_canon_ferraille.bmp
0 → 100644
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
Space Invaders/Envahisseurs/Graphique/Lutins/invader_monstre_bouillie.bmp
0 → 100644
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
Space Invaders/Envahisseurs/Graphique/Lutins/millepatte_corps_droite.bmp
0 → 100644
No preview for this file type
Space Invaders/Envahisseurs/Graphique/Lutins/millepatte_corps_gauche.bmp
0 → 100644
No preview for this file type
Space Invaders/Envahisseurs/Graphique/Lutins/millepatte_corps_haut.bmp
0 → 100644
No preview for this file type
No preview for this file type
Space Invaders/Envahisseurs/Graphique/Lutins/millepatte_tete_droite.bmp
0 → 100644
No preview for this file type
Space Invaders/Envahisseurs/Graphique/Lutins/millepatte_tete_gauche.bmp
0 → 100644
No preview for this file type
No preview for this file type
Space Invaders/Envahisseurs/Graphique/src/Graphique/Makefile
0 → 100644
... | ... | @@ -0,0 +1,29 @@ |
1 | +# | |
2 | +# Makefile pour la bibliotheque graphique | |
3 | +# | |
4 | + | |
5 | +SOURCES = $(wildcard *.c) | |
6 | +OBJETS = $(SOURCES:.c=.o) | |
7 | +CIBLE = libgraph.a | |
8 | + | |
9 | +# | |
10 | +# Nom de la cible principale | |
11 | +# | |
12 | + | |
13 | +all: $(CIBLE) | |
14 | + | |
15 | +# | |
16 | +# Cible de nettoyage | |
17 | +# | |
18 | + | |
19 | +clean: | |
20 | + rm -f core *.o $(CIBLE) | |
21 | + | |
22 | +# | |
23 | +# Dependances pour la bibliotheque | |
24 | +# | |
25 | + | |
26 | +$(CIBLE): $(OBJETS) | |
27 | + $(AR) rs $@ $? | |
28 | + | |
29 | +$(CIBLE:.a=).o: $(CIBLE:.a=).c $(CIBLE:.a=).h | ... | ... |
Space Invaders/Envahisseurs/Graphique/src/Graphique/libgraph.c
0 → 100644
... | ... | @@ -0,0 +1,239 @@ |
1 | +/**** Bibliotheque graphique ****/ | |
2 | + | |
3 | +/** Fichiers d'inclusion **/ | |
4 | + | |
5 | +#include <SDL/SDL.h> | |
6 | +#include <SDL/SDL_ttf.h> | |
7 | +#include "libgraph.h" | |
8 | + | |
9 | +/** Types **/ | |
10 | + | |
11 | +typedef struct | |
12 | +{ | |
13 | + int r, v, b; | |
14 | +} couleur; | |
15 | + | |
16 | +/** Constantes **/ | |
17 | + | |
18 | +#define BITS_PAR_PIXEL 32 | |
19 | +#define TAILLE_POLICE 20 | |
20 | + | |
21 | +static const couleur couleurs[] = { { 255, 255, 255 }, { 0, 0, 0 }, { 255, 0, 0 }, | |
22 | + { 0, 255, 0 }, { 0, 0, 255 }, { 255, 105, 180 }, | |
23 | + { 150, 150, 150 }, { -1, -1, -1 } }; | |
24 | + | |
25 | +static const char policeDefaut[]="/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf"; | |
26 | + | |
27 | +/** Variables globales **/ | |
28 | + | |
29 | +static SDL_Surface *surface; | |
30 | +TTF_Font* police; | |
31 | + | |
32 | +/** Fonctions **/ | |
33 | + | |
34 | +void choisirPolice(const char *chemin, int taille){ | |
35 | + police=TTF_OpenFont(chemin, taille); | |
36 | +} | |
37 | + | |
38 | +void initialiserTexte() { | |
39 | + TTF_Init(); | |
40 | + choisirPolice(policeDefaut, TAILLE_POLICE); | |
41 | +} | |
42 | + | |
43 | +/* Initialisation de la surface dessinable */ | |
44 | +unsigned char creerSurface (int largeur, int hauteur, char *titre) | |
45 | +{ | |
46 | + SDL_Init (SDL_INIT_VIDEO); | |
47 | + SDL_WM_SetCaption (titre, titre); | |
48 | + surface = SDL_SetVideoMode (largeur, hauteur, BITS_PAR_PIXEL, SDL_DOUBLEBUF); | |
49 | + initialiserTexte(); | |
50 | + | |
51 | + return (surface != NULL && police != NULL); | |
52 | +} | |
53 | + | |
54 | +/* Fermeture de la surface dessinable */ | |
55 | + | |
56 | +void fermerSurface (void) | |
57 | +{ | |
58 | + if (surface != NULL) SDL_FreeSurface (surface); | |
59 | + if (police != NULL) TTF_CloseFont(police); | |
60 | + TTF_Quit(); | |
61 | + SDL_Quit (); | |
62 | +} | |
63 | + | |
64 | +/* Creation d'une couleur */ | |
65 | + | |
66 | +static int creerCouleur (int ncouleur) | |
67 | +{ | |
68 | + couleur c = couleurs[ncouleur]; | |
69 | + return SDL_MapRGB (surface->format, c.r, c.v, c.b); | |
70 | +} | |
71 | + | |
72 | +/* Dessin d'un rectangle plein */ | |
73 | + | |
74 | +void rectanglePlein (int x, int y, int l, int h, int c) | |
75 | +{ | |
76 | + SDL_Rect rectangle = { x, y, l, h }; | |
77 | + SDL_FillRect (surface, &rectangle, creerCouleur (c)); | |
78 | + // SDL_Flip(surface); | |
79 | +} | |
80 | + | |
81 | +/* Manipulation de lutins */ | |
82 | + | |
83 | +static SDL_Surface *lutins[MAX_LUTINS]; | |
84 | +static int lutins_nb = 0; | |
85 | + | |
86 | +int lutinTexte(char* texte, int couleurTexte) { | |
87 | + couleur c=couleurs[couleurTexte]; | |
88 | + SDL_Color couleur={c.r, c.v, c.b}; | |
89 | + SDL_Surface* lutin=TTF_RenderText_Solid(police, texte, couleur); | |
90 | + if (lutin != NULL) | |
91 | + { | |
92 | + lutins[lutins_nb++] = lutin; | |
93 | + return lutins_nb - 1; | |
94 | + } | |
95 | + return -1; | |
96 | +} | |
97 | + | |
98 | +static void configurerLutin (SDL_Surface *lutin, int ncouleur) | |
99 | +{ | |
100 | + couleur c = couleurs[ncouleur]; | |
101 | + int fond = SDL_MapRGB (lutin->format, c.r, c.v, c.b); | |
102 | + SDL_SetColorKey (lutin, SDL_SRCCOLORKEY | SDL_RLEACCEL, fond); | |
103 | +} | |
104 | + | |
105 | +int chargerLutin (char *fichier, int couleur) | |
106 | +{ | |
107 | + if (lutins_nb >= MAX_LUTINS) return -2; | |
108 | + SDL_Surface *lutin = SDL_LoadBMP (fichier); | |
109 | + if (lutin != NULL) | |
110 | + { | |
111 | + lutins[lutins_nb++] = lutin; | |
112 | + if (couleur >= 0) configurerLutin (lutin, couleur); | |
113 | + return lutins_nb - 1; | |
114 | + } | |
115 | + return -1; | |
116 | +} | |
117 | + | |
118 | +void afficherLutin (int lutin, int x, int y) | |
119 | +{ | |
120 | + SDL_Rect position; | |
121 | + position.x = x; | |
122 | + position.y = y; | |
123 | + SDL_BlitSurface (lutins[lutin], NULL, surface, &position); | |
124 | +} | |
125 | + | |
126 | +int creerLutin (int x, int y, int largeur, int hauteur, int couleur) | |
127 | +{ | |
128 | + if (lutins_nb >= MAX_LUTINS) return -2; | |
129 | + int rmask, gmask, bmask, amask; | |
130 | +#if SDL_BYTEORDER == SDL_BIG_ENDIAN | |
131 | + rmask = 0xff000000; | |
132 | + gmask = 0x00ff0000; | |
133 | + bmask = 0x0000ff00; | |
134 | + amask = 0x000000ff; | |
135 | +#else | |
136 | + rmask = 0x000000ff; | |
137 | + gmask = 0x0000ff00; | |
138 | + bmask = 0x00ff0000; | |
139 | + amask = 0xff000000; | |
140 | +#endif | |
141 | + if (couleur < 0) amask = 0x00000000; | |
142 | + SDL_Surface *lutin = | |
143 | + SDL_CreateRGBSurface (0, largeur, hauteur, BITS_PAR_PIXEL, rmask, gmask, bmask, amask); | |
144 | + SDL_Rect fenetre; | |
145 | + fenetre.x = x; | |
146 | + fenetre.y = y; | |
147 | + fenetre.h = hauteur; | |
148 | + fenetre.w = largeur; | |
149 | + SDL_BlitSurface (surface, &fenetre, lutin, NULL); | |
150 | + lutins[lutins_nb++] = lutin; | |
151 | + if (couleur >= 0) configurerLutin (lutin, couleur); | |
152 | + return lutins_nb - 1; | |
153 | +} | |
154 | + | |
155 | +void tailleLutin (int lutin, int *largeur, int *hauteur) | |
156 | +{ | |
157 | + *largeur = lutins[lutin]->w; | |
158 | + *hauteur = lutins[lutin]->h; | |
159 | +} | |
160 | + | |
161 | +int sauverLutin (int lutin, char *nom) { return SDL_SaveBMP (lutins[lutin], nom); } | |
162 | + | |
163 | +/* Manipulation de copie de surface en BMP */ | |
164 | + | |
165 | +int sauverSurface (char *fichier) { return SDL_SaveBMP (surface, fichier); } | |
166 | + | |
167 | +unsigned char chargerSurface (char *fichier) | |
168 | +{ | |
169 | + SDL_Surface *image = SDL_LoadBMP (fichier); | |
170 | + if (image != NULL) | |
171 | + { | |
172 | + SDL_BlitSurface (image, NULL, surface, NULL); | |
173 | + SDL_Flip (surface); | |
174 | + } | |
175 | + return (image != NULL); | |
176 | +} | |
177 | + | |
178 | +void majSurface (void) { SDL_Flip (surface); } | |
179 | + | |
180 | +/* Trouver la couleur d'un pixel */ | |
181 | + | |
182 | +int couleurPixel (int x, int y) | |
183 | +{ | |
184 | + int bpp = surface->format->BytesPerPixel; | |
185 | + Uint32 *p = (Uint32 *)(surface->pixels + y * surface->pitch + x * bpp); | |
186 | + Uint8 r, v, b; | |
187 | + SDL_GetRGB (*p, surface->format, &r, &v, &b); | |
188 | + int i = 0; | |
189 | + while (1) | |
190 | + { | |
191 | + if (couleurs[i].r < 0) break; | |
192 | + if (r == couleurs[i].r && v == couleurs[i].v && b == couleurs[i].b) break; | |
193 | + i++; | |
194 | + } | |
195 | + if (couleurs[i].r < 0) | |
196 | + return -1; | |
197 | + else | |
198 | + return i; | |
199 | +} | |
200 | + | |
201 | +/* Fonction de traitement des événements */ | |
202 | + | |
203 | +void lireEvenement (evenement *evt, char *touche, void **detail) | |
204 | +{ | |
205 | + static SDL_keysym _detail; | |
206 | + SDL_Event event; | |
207 | + while (SDL_PollEvent (&event)) | |
208 | + { | |
209 | + if (event.type == SDL_QUIT) *evt = quitter; | |
210 | + if (event.type == SDL_KEYDOWN || event.type == SDL_KEYUP) | |
211 | + { | |
212 | + *evt = (event.type == SDL_KEYDOWN) ? toucheBas : toucheHaut; | |
213 | + char *nom = SDL_GetKeyName (event.key.keysym.sym); | |
214 | + if (strlen (nom) == 1 && nom[0] >= 32 && nom[0] < 128) | |
215 | + *touche = nom[0]; | |
216 | + else | |
217 | + *touche = 0; | |
218 | + if (detail != NULL) | |
219 | + { | |
220 | + _detail = event.key.keysym; | |
221 | + *detail = &_detail; | |
222 | + } | |
223 | + break; | |
224 | + } | |
225 | + } | |
226 | +} | |
227 | + | |
228 | +void attendreEvenement (void) | |
229 | +{ | |
230 | + SDL_Event event; | |
231 | + while (SDL_WaitEvent (&event)) switch (event.type) | |
232 | + { | |
233 | + case SDL_QUIT: | |
234 | + exit (0); | |
235 | + case SDL_KEYDOWN: | |
236 | + case SDL_MOUSEBUTTONDOWN: | |
237 | + return; | |
238 | + } | |
239 | +} | ... | ... |
Space Invaders/Envahisseurs/Graphique/src/Graphique/libgraph.h
0 → 100644
... | ... | @@ -0,0 +1,156 @@ |
1 | +/**** Bibliotheque graphique (definitions) ****/ | |
2 | + | |
3 | +/** Constantes **/ | |
4 | + | |
5 | +#define COULEUR_BLANC 0 | |
6 | +#define COULEUR_NOIR 1 | |
7 | +#define COULEUR_ROUGE 2 | |
8 | +#define COULEUR_VERT 3 | |
9 | +#define COULEUR_BLEU 4 | |
10 | +#define COULEUR_ROSE 5 | |
11 | +#define COULEUR_GRIS 6 | |
12 | + | |
13 | +#define MAX_LUTINS 16 | |
14 | + | |
15 | +typedef enum {toucheBas, toucheHaut, quitter} evenement; | |
16 | + | |
17 | +/** Prototypes **/ | |
18 | + | |
19 | +/** | |
20 | + * @brief cree une fenetre 2D | |
21 | + * | |
22 | + * @param largeur en pixels de la fenetre | |
23 | + * @param hauteur en pixels de la fenetre | |
24 | + * @param titre de la fenetre (chaine de caractere) | |
25 | + */ | |
26 | +unsigned char creerSurface (int largeur, int hauteur, char *titre); | |
27 | + | |
28 | +/** | |
29 | + * @brief permet de charger un fichier image au format bmp (bitmap) | |
30 | + * | |
31 | + * @param fichier nom du fichier | |
32 | + */ | |
33 | +unsigned char chargerSurface (char *fichier); | |
34 | + | |
35 | + | |
36 | +/** | |
37 | + * @brief permet de sauvegarder une surface en image (format bmp) | |
38 | + * | |
39 | + * @param fichier nom du fichier | |
40 | + * @return 0 si OK, valeur negative sinon | |
41 | + */ | |
42 | +int sauverSurface (char *fichier); | |
43 | + | |
44 | +/** | |
45 | + * @brief met a jour la surface d'affichage | |
46 | + */ | |
47 | +void majSurface (void); | |
48 | + | |
49 | + | |
50 | +/** | |
51 | + * @brief libere la surface d'affichage | |
52 | + * a faire lors de la fermeture | |
53 | + * du programme | |
54 | + */ | |
55 | +void fermerSurface (void); | |
56 | + | |
57 | +/** | |
58 | + * @brief choisit la police de caractères à utiliser pour afficher du texte | |
59 | + * @param chemin nom du fichier de police (format .ttf, voir /usr/share/fonts/truetype) | |
60 | + * @param taille taille de la police | |
61 | + */ | |
62 | +void choisirPolice(const char *chemin, int taille); | |
63 | + | |
64 | +/** | |
65 | + * @brief dessine un rectange de taille (l,h) aux coordonnêes | |
66 | + * (x,y) et de couleur c | |
67 | + * | |
68 | + * @param x 0 <= x <= l_surface | |
69 | + * @param y 0 <= y <= h_surface | |
70 | + * @param l largeur en pixels | |
71 | + * @param h longueur en pixels | |
72 | + * @param c indice de couleur voir variable couleurs dans le fichier .c | |
73 | + */ | |
74 | +void rectanglePlein (int x, int y, int l, int h, int c); | |
75 | + | |
76 | + | |
77 | +/** | |
78 | + * @brief permet de determiner l'indice du tableau de couleur du | |
79 | + * pixel aux coordonnees (x,y) | |
80 | + * | |
81 | + * @param x 0 <= x <= l_surface | |
82 | + * @param y 0 <= y <= h_surface | |
83 | + * @return indice de couleur voire variable couleurs dans le fichier .c | |
84 | + */ | |
85 | +int couleurPixel (int x, int y); | |
86 | + | |
87 | +/** | |
88 | + * @brief crée un lutin à partir d'un texte | |
89 | + * | |
90 | + * @param texte le texte | |
91 | + * @param couleur indice de couleur du texte | |
92 | + * @return numero de lutin dans le tableau dynamique de lutin (< MAX_LUTINS) | |
93 | + */ | |
94 | +int lutinTexte(char *texte, int couleur); | |
95 | + | |
96 | +/** | |
97 | + * @brief charge un lutin à partir du fichier | |
98 | + * | |
99 | + * @param fichier image bitmap du lutin à charger | |
100 | + * @param couleur indice de couleurs à charger | |
101 | + * @return numero de lutin dans le tableau dynamique de lutin (< MAX_LUTINS) | |
102 | + */ | |
103 | +int chargerLutin (char *fichier, int couleur); | |
104 | + | |
105 | +/** | |
106 | + * @brief afficher un lutin aux coordonnées (x,y) | |
107 | + * | |
108 | + * @param lutin numero du lutin à afficher (< MAX_LUTINS) | |
109 | + * @param x abscisse de départ | |
110 | + * @param y ordonnée de départ | |
111 | + */ | |
112 | +void afficherLutin (int lutin, int x, int y); | |
113 | + | |
114 | +/** | |
115 | + * @brief creer un lutin de taille (l,h) aux coordonnées (x,y) | |
116 | + * | |
117 | + * @param x abscisse de départ | |
118 | + * @param y ordonnée de départ | |
119 | + * @param largeur largeur du lutin | |
120 | + * @param hauteur hauteur du lutin | |
121 | + * @param couleur indice de couleur à partir du tableau _couleurs_ | |
122 | + * @return indice du lutin dans le tableau global (< MAX_LUTINS) | |
123 | + */ | |
124 | +int creerLutin (int x, int y, int largeur, int hauteur, int couleur); | |
125 | + | |
126 | +/** | |
127 | + * @brief sauvegarde un lutin dans un fichier | |
128 | + * | |
129 | + * @param lutin numero de lutin à sauvegarder (< MAX_LUTINS) | |
130 | + * @param nom fichier pour la sauvegarde | |
131 | + * @return 0 si OK valeur négative sinon | |
132 | + */ | |
133 | +int sauverLutin (int lutin, char *nom); | |
134 | + | |
135 | +/** | |
136 | + * @brief calcule la taille (largeur,hauteur) d'un lutin | |
137 | + * | |
138 | + * @param lutin index du lutin (< MAX_LUTINS) | |
139 | + * @param largeur pointeur sur la largeur | |
140 | + * @param hauteur pointeur sur la hauteur | |
141 | + */ | |
142 | +void tailleLutin (int lutin, int *largeur, int *hauteur); | |
143 | + | |
144 | +/** | |
145 | + * @brief lire une touche au clavier | |
146 | + * | |
147 | + * @param evt pointeur sur evenement | |
148 | + * @param touche pointeur sur la touche pressée | |
149 | + * @param detail NULL ou keysim | |
150 | + */ | |
151 | +void lireEvenement (evenement *evt, char *touche, void **detail); | |
152 | + | |
153 | +/** | |
154 | + * @brief attente d'un evenement bouton, souris, fin de programme | |
155 | + */ | |
156 | +void attendreEvenement (void); | ... | ... |
Space Invaders/Envahisseurs/Graphique/src/Interactif/Interactif.c
0 → 100644
... | ... | @@ -0,0 +1,375 @@ |
1 | +#include <stdlib.h> | |
2 | +#include <string.h> | |
3 | + | |
4 | +#include "../Graphique/libgraph.h" | |
5 | +#include "../ListeC/Liste.h" | |
6 | +#include "Interactif.h" | |
7 | +#include "../Main/init.h" | |
8 | + | |
9 | +#define TailleX 500 | |
10 | +#define TailleY 500 | |
11 | +#define Sol 475 | |
12 | +#define ErreurHitbox 2 | |
13 | +#define TailleX9_10 (9 * TailleX / 10) | |
14 | +#define TailleX1_10 (TailleX / 10) | |
15 | + | |
16 | +#define ValeurDeplacementTire 5 | |
17 | +#define ValeurDeplacementJoueur 3 | |
18 | +#define ValeurDeplacementBombe 2 | |
19 | + | |
20 | + | |
21 | +//La fonction renvoie 1 si il y a collision | |
22 | +int CheckCollisionEntiteEntite (struct entite entite1, | |
23 | + int L1, | |
24 | + int H1, | |
25 | + struct entite entite2, | |
26 | + int L2, | |
27 | + int H2) | |
28 | +{ | |
29 | + //CheckX | |
30 | + int gauche1 = entite1.posx - L1/2 + ErreurHitbox; | |
31 | + int droite1 = entite1.posx + L1/2 - ErreurHitbox; | |
32 | + int gauche2 = entite2.posx - L2/2 + ErreurHitbox; | |
33 | + int droite2 = entite2.posx + L2/2 - ErreurHitbox; | |
34 | + //Tout les cas possibles de collision | |
35 | + int CheckX = (gauche1 >= gauche2 && gauche1 <= droite2) || | |
36 | + (droite1 >= gauche2 && droite1 <= droite2) || | |
37 | + (gauche1 >= gauche2 && droite1 <= droite2) || | |
38 | + (gauche2 >= gauche1 && droite2 <= droite1); | |
39 | + | |
40 | + //CheckY | |
41 | + int haut1 = entite1.posy - H1/2 + ErreurHitbox; | |
42 | + int bas1 = entite1.posy + H1/2 - ErreurHitbox; | |
43 | + int haut2 = entite2.posy - H2/2 + ErreurHitbox; | |
44 | + int bas2 = entite2.posy + H2/2 - ErreurHitbox; | |
45 | + int CheckY = (haut1 <= bas2 && haut1 >= haut2) || | |
46 | + (bas1 <= bas2 && bas1 >= haut2) || | |
47 | + (haut1 <= haut2 && bas1 >= bas2) || | |
48 | + (haut2 <= haut1 && bas2 >= bas1); | |
49 | + | |
50 | + | |
51 | + return CheckX && CheckY; | |
52 | +} | |
53 | + | |
54 | +//La fonction renvoie l'entite de la Liste1 si il y a collision | |
55 | +struct entite* CheckCollisionListeEntite (struct liste_entite* Liste1, | |
56 | + int L1, | |
57 | + int H1, | |
58 | + struct entite entite2, | |
59 | + int L2, | |
60 | + int H2) | |
61 | +{ | |
62 | + | |
63 | + struct liste_entite *pListe1 = Liste1; | |
64 | + while (pListe1 != NULL) | |
65 | + { | |
66 | + | |
67 | + if(CheckCollisionEntiteEntite (pListe1->entite, | |
68 | + L1, | |
69 | + H1, | |
70 | + entite2, | |
71 | + L2, | |
72 | + H2) == 1) | |
73 | + { | |
74 | + return &pListe1->entite; | |
75 | + } | |
76 | + | |
77 | + pListe1 = pListe1->suivant; | |
78 | + } | |
79 | + return NULL; | |
80 | +} | |
81 | + | |
82 | + | |
83 | + | |
84 | +//La fonction renvoie une liste d'entite avec les deux entites à supprimer | |
85 | +//Seulement si il y a collision | |
86 | +struct liste_entite* CheckCollisionListeListe (struct liste_entite* Liste1, | |
87 | + int L1, | |
88 | + int H1, | |
89 | + struct liste_entite* Liste2, | |
90 | + int L2, | |
91 | + int H2) | |
92 | +{ | |
93 | + | |
94 | + struct liste_entite *pListe2 = Liste2; | |
95 | + while (pListe2 != NULL) | |
96 | + { | |
97 | + | |
98 | + struct entite* collision = CheckCollisionListeEntite (Liste1, | |
99 | + L1, | |
100 | + H1, | |
101 | + pListe2->entite, | |
102 | + L2, | |
103 | + H2); | |
104 | + if (collision == NULL) | |
105 | + { | |
106 | + pListe2 = pListe2->suivant; | |
107 | + } | |
108 | + | |
109 | + else | |
110 | + { | |
111 | + // Création des structures pour les deux entités | |
112 | + struct liste_entite* Entite1 = malloc(sizeof(struct liste_entite)); | |
113 | + struct liste_entite* Entite2 = malloc(sizeof(struct liste_entite)); | |
114 | + | |
115 | + // Remplissage des structure avec les entités correspondantes | |
116 | + Entite1->entite = *collision; | |
117 | + Entite2->entite = pListe2->entite; | |
118 | + | |
119 | + // Relier les structures entre elles | |
120 | + Entite1->suivant = Entite2; | |
121 | + Entite2->suivant = NULL; | |
122 | + | |
123 | + return Entite1; | |
124 | + } | |
125 | + } | |
126 | + | |
127 | + return NULL; | |
128 | +} | |
129 | + | |
130 | +//Tire un missile, il ne peux y en avoir que un à la fois | |
131 | +void Tirer (struct entite joueur, | |
132 | + struct liste_entite** pl) | |
133 | +{ | |
134 | + if (*pl == NULL) | |
135 | + { | |
136 | + ajout_tete(pl, | |
137 | + creer_entite(joueur.posx, | |
138 | + joueur.posy, | |
139 | + -1)); | |
140 | + } | |
141 | +} | |
142 | + | |
143 | + | |
144 | +void DeplacementTire(struct liste_entite** Liste) | |
145 | +{ | |
146 | + struct entite* Entite = &(*Liste)->entite; | |
147 | + if (Entite != NULL) | |
148 | + { | |
149 | + | |
150 | + if (Entite->posy <= 0) | |
151 | + { | |
152 | + afficherLutin(bouillie, | |
153 | + Entite->posx - hitboxbouillieL/2 + ErreurHitbox, | |
154 | + Entite->posy); | |
155 | + SupprimerEntite(Liste, Entite); | |
156 | + } | |
157 | + | |
158 | + else | |
159 | + { | |
160 | + Entite->posy -= ValeurDeplacementTire; | |
161 | + //Je divise ErreurHitbox par 2 car l'erreur du missile | |
162 | + //est plus petite que pour les autres images | |
163 | + afficherLutin(missile, | |
164 | + Entite->posx - hitboxmissileL/2 + ErreurHitbox/2, | |
165 | + Entite->posy - hitboxmissileH/2 + ErreurHitbox/2); | |
166 | + } | |
167 | + } | |
168 | +} | |
169 | + | |
170 | + | |
171 | +//La fonction fait une action soit au joueur | |
172 | +//soit à la Liste des Tires selon la touche préssée | |
173 | +void action(struct entite* joueur, | |
174 | + char c, | |
175 | + struct liste_entite** tires) | |
176 | +{ | |
177 | + switch (c) | |
178 | + { | |
179 | + case 'd': | |
180 | + if (joueur->posx <= TailleX9_10) | |
181 | + { | |
182 | + joueur->posx += ValeurDeplacementJoueur; | |
183 | + } | |
184 | + break; | |
185 | + case 'q': | |
186 | + if (joueur->posx >= TailleX1_10) | |
187 | + { | |
188 | + joueur->posx -= ValeurDeplacementJoueur; | |
189 | + } | |
190 | + break; | |
191 | + case 't': | |
192 | + Tirer(*joueur, | |
193 | + tires); | |
194 | + break; | |
195 | + default: | |
196 | + break; | |
197 | + } | |
198 | +} | |
199 | + | |
200 | +/* | |
201 | +La fonction crée une liste de tout les enemies pouvant drop des bombes | |
202 | +Seulement ceux les plus bas de leur colonne repective | |
203 | +Puis ajoute à la liste bombe, | |
204 | +une bombe provenant d'un des enemies pouvant drop des bombes | |
205 | +Le choix de quel enemie drop la bombe est aléatoire | |
206 | +*/ | |
207 | +void MakeBombeDrop (struct liste_entite* enemies, | |
208 | + struct liste_entite** bombes) | |
209 | +{ | |
210 | + | |
211 | + struct liste_entite* pListe = enemies; | |
212 | + struct liste_entite* Dropable = NULL; | |
213 | + int taille = 0; | |
214 | + | |
215 | + while (pListe != NULL) | |
216 | + { | |
217 | + | |
218 | + if (pListe->entite.dropbombe == 1) | |
219 | + { | |
220 | + ajout_tete(&Dropable,pListe->entite); | |
221 | + taille += 1; | |
222 | + } | |
223 | + | |
224 | + pListe = pListe->suivant; | |
225 | + } | |
226 | + | |
227 | + if(Dropable == NULL) | |
228 | + { | |
229 | + return; | |
230 | + } | |
231 | + /* | |
232 | + On choisit une valeur aléatoire représentant l'enemie qui va drop la bombe | |
233 | + Il ya un warning comme quoi rand() à une limite | |
234 | + Mais on ne la dépassera jamais, taille ne pourra | |
235 | + jamais excédé une vingtaine d'enemies par ligne | |
236 | + */ | |
237 | + int randomIndex = rand() % taille-1; | |
238 | + struct liste_entite* pDropable = Dropable; | |
239 | + | |
240 | + for (int i = 0; i <= randomIndex; i++) | |
241 | + { | |
242 | + pDropable = pDropable->suivant; | |
243 | + } | |
244 | + | |
245 | + ajout_tete(bombes, | |
246 | + creer_entite(pDropable->entite.posx, | |
247 | + pDropable->entite.posy, | |
248 | + -1)); | |
249 | +} | |
250 | + | |
251 | + | |
252 | +void DeplacementBombe(struct liste_entite** Liste) | |
253 | +{ | |
254 | + struct liste_entite* pListe = *Liste; | |
255 | + | |
256 | + while (pListe != NULL) | |
257 | + { | |
258 | + | |
259 | + if (pListe->entite.posy + hitboxbombeH/2 - ErreurHitbox >= Sol) | |
260 | + { | |
261 | + struct entite* a_supprimer = &pListe->entite; | |
262 | + | |
263 | + pListe = pListe->suivant; | |
264 | + SupprimerEntite(Liste,a_supprimer); | |
265 | + } | |
266 | + | |
267 | + else | |
268 | + { | |
269 | + pListe->entite.posy += ValeurDeplacementBombe; | |
270 | + afficherLutin(bombe, | |
271 | + pListe->entite.posx - hitboxbombeL/2 + ErreurHitbox, | |
272 | + pListe->entite.posy - hitboxbombeH/2 + ErreurHitbox); | |
273 | + pListe = pListe->suivant; | |
274 | + } | |
275 | + } | |
276 | +} | |
277 | + | |
278 | +/* | |
279 | +Si un enemie est éliminé et qu'il etait le plus bas de sa colonne | |
280 | +(il pouvait drop des bombes) | |
281 | +Alors si il y en a un, l'enemie au dessus de lui (de la meme colonne) | |
282 | +peut maintenant drop des bombes | |
283 | +*/ | |
284 | +void NouveauDroppeurBombe (struct liste_entite** liste, | |
285 | + struct entite* entite) | |
286 | +{ | |
287 | + | |
288 | + int posx = entite->posx; | |
289 | + int posy = entite->posy; | |
290 | + struct liste_entite* pListe = *liste; | |
291 | + struct entite* entite_basse = NULL; | |
292 | + | |
293 | + // On parcourt la liste et on cherche | |
294 | + //l'entité la plus basse ayant la même position x | |
295 | + while (pListe != NULL) | |
296 | + { | |
297 | + //On ne regarde pas les enemies qui sont sur la meme ligne | |
298 | + if (pListe->entite.posy != posy) | |
299 | + { | |
300 | + //Si meme colonne et qu'il n'y a pas d'entite_basse | |
301 | + if (pListe->entite.posx == posx && | |
302 | + entite_basse == NULL) | |
303 | + { | |
304 | + entite_basse = &pListe->entite; | |
305 | + } | |
306 | + | |
307 | + //Si meme colonne mais qu'il y a deja une entite_basse | |
308 | + //On compare la hauteur de l'entite avec l'entite_basse | |
309 | + else if (pListe->entite.posx == posx && | |
310 | + pListe->entite.posy > entite_basse->posy) | |
311 | + { | |
312 | + entite_basse = &pListe->entite; | |
313 | + } | |
314 | + } | |
315 | + | |
316 | + pListe = pListe->suivant; | |
317 | + } | |
318 | + | |
319 | + // Si aucune entité n'est située plus bas que l'entité en question, | |
320 | + //On ne peut pas dropper la bombe | |
321 | + if (entite_basse == NULL) | |
322 | + { | |
323 | + return; | |
324 | + } | |
325 | + | |
326 | + entite_basse->dropbombe = 1; | |
327 | +} | |
328 | + | |
329 | + | |
330 | + | |
331 | +//Fonction Main qui supprime les entités rentrées en collision de leur liste | |
332 | +int SupprimerEntitesEnCollision (struct liste_entite** Liste1, | |
333 | + int L1, | |
334 | + int H1, | |
335 | + struct liste_entite** Liste2, | |
336 | + int L2, | |
337 | + int H2) | |
338 | +{ | |
339 | + | |
340 | + struct liste_entite* collision = CheckCollisionListeListe(*Liste1, | |
341 | + L1, | |
342 | + H1, | |
343 | + *Liste2, | |
344 | + L2, | |
345 | + H2); | |
346 | + if (collision != NULL) | |
347 | + { | |
348 | + // Récupération des entités impliquées | |
349 | + struct entite* Entite1 = &collision->entite; | |
350 | + struct entite* Entite2 = &collision->suivant->entite; | |
351 | + | |
352 | + if (Entite1->dropbombe == 1) | |
353 | + { | |
354 | + NouveauDroppeurBombe(Liste1,Entite1); | |
355 | + } | |
356 | + | |
357 | + if (Entite2->dropbombe == 1) | |
358 | + { | |
359 | + NouveauDroppeurBombe(Liste2,Entite2); | |
360 | + } | |
361 | + | |
362 | + // Suppression de l'entité 1 de la liste 1 | |
363 | + SupprimerEntite(Liste1, Entite1); | |
364 | + // Suppression de l'entité 2 de la liste 2 | |
365 | + SupprimerEntite(Liste2, Entite2); | |
366 | + | |
367 | + afficherLutin (bouillie, | |
368 | + Entite2->posx - hitboxbouillieL/2 + ErreurHitbox, | |
369 | + Entite2->posy - hitboxbouillieH/2 + ErreurHitbox); | |
370 | + return 1; | |
371 | + } | |
372 | + return 0; | |
373 | +} | |
374 | + | |
375 | + | ... | ... |
Space Invaders/Envahisseurs/Graphique/src/Interactif/Interactif.h
0 → 100644
... | ... | @@ -0,0 +1,44 @@ |
1 | +int CheckCollisionEntiteEntite (struct entite entite1, | |
2 | + int L1, | |
3 | + int H1, | |
4 | + struct entite entite2, | |
5 | + int L2, | |
6 | + int H2); | |
7 | + | |
8 | +struct entite* CheckCollisionListeEntite (struct liste_entite* Liste1, | |
9 | + int L1, | |
10 | + int H1, | |
11 | + struct entite entite2, | |
12 | + int L2, | |
13 | + int H2); | |
14 | + | |
15 | +struct liste_entite* CheckCollisionListeListe (struct liste_entite* Liste1, | |
16 | + int L1, | |
17 | + int H1, | |
18 | + struct liste_entite* Liste2, | |
19 | + int L2, | |
20 | + int H2); | |
21 | + | |
22 | +void Tirer (struct entite joueur, | |
23 | + struct liste_entite** pl); | |
24 | + | |
25 | +void DeplacementTire(struct liste_entite** Liste); | |
26 | + | |
27 | +void action(struct entite* joueur, | |
28 | + char c, | |
29 | + struct liste_entite** tires); | |
30 | + | |
31 | +void MakeBombeDrop (struct liste_entite* enemies, | |
32 | + struct liste_entite** bombes); | |
33 | + | |
34 | +void DeplacementBombe(struct liste_entite** Liste) ; | |
35 | + | |
36 | +void NouveauDroppeurBombe (struct liste_entite** liste, | |
37 | + struct entite* entite); | |
38 | + | |
39 | +int SupprimerEntitesEnCollision (struct liste_entite** Liste1, | |
40 | + int L1, | |
41 | + int H1, | |
42 | + struct liste_entite** Liste2, | |
43 | + int L2, | |
44 | + int H2); | ... | ... |
Space Invaders/Envahisseurs/Graphique/src/ListeC/Liste.c
0 → 100644
... | ... | @@ -0,0 +1,80 @@ |
1 | +#include <stdio.h> | |
2 | +#include <stdlib.h> | |
3 | +#include <string.h> | |
4 | + | |
5 | +#include "Liste.h" | |
6 | + | |
7 | +//Crée une entité | |
8 | +struct entite creer_entite (int x, | |
9 | + int y, | |
10 | + int candrop) | |
11 | +{ | |
12 | + struct entite e; | |
13 | + | |
14 | + e.posx = x; | |
15 | + e.posy = y; | |
16 | + e.dropbombe = candrop; | |
17 | + | |
18 | + return e; | |
19 | +} | |
20 | + | |
21 | + | |
22 | +//Ajout en tete une entité dans une liste | |
23 | +void ajout_tete (struct liste_entite** Liste, | |
24 | + struct entite x ) | |
25 | +{ | |
26 | + struct liste_entite *Listetmp=NULL; | |
27 | + | |
28 | + Listetmp = malloc(sizeof(struct liste_entite)); | |
29 | + Listetmp->entite = x; | |
30 | + Listetmp->suivant = *Liste; | |
31 | + | |
32 | + *Liste = Listetmp; | |
33 | +} | |
34 | + | |
35 | + | |
36 | +//Supprime une entite d'une liste | |
37 | +void SupprimerEntite (struct liste_entite** Liste, | |
38 | + struct entite* entite) | |
39 | +{ | |
40 | + struct liste_entite* courant = *Liste; | |
41 | + struct liste_entite* precedent = NULL; | |
42 | + //Ce pointeur precedent va garder en memoire l'entite precedente | |
43 | + //Initialisé à NULL car cela est utile dans le cas ou l'entite est la 1ere | |
44 | + | |
45 | + while (courant != NULL) | |
46 | + { | |
47 | + //Comparaison entre 2 entites | |
48 | + if (memcmp (&courant->entite, | |
49 | + entite, | |
50 | + sizeof(struct entite)) == 0) | |
51 | + { | |
52 | + //Si l'element est le premier | |
53 | + if (precedent == NULL) | |
54 | + { | |
55 | + *Liste = courant->suivant; | |
56 | + } | |
57 | + | |
58 | + else | |
59 | + { | |
60 | + precedent->suivant = courant->suivant; | |
61 | + } | |
62 | + | |
63 | + free(courant); | |
64 | + break; | |
65 | + } | |
66 | + | |
67 | + precedent = courant; | |
68 | + courant = courant->suivant; | |
69 | + } | |
70 | +} | |
71 | + | |
72 | + | |
73 | +//Desallouer une liste entiere | |
74 | +void DesallouerListe (struct liste_entite** Liste) | |
75 | +{ | |
76 | + while(*Liste != NULL) | |
77 | + { | |
78 | + SupprimerEntite(Liste,&((*Liste)->entite)); | |
79 | + } | |
80 | +} | ... | ... |
Space Invaders/Envahisseurs/Graphique/src/ListeC/Liste.h
0 → 100644
... | ... | @@ -0,0 +1,29 @@ |
1 | +//dropbombe concerne les entités enemies | |
2 | +//1 les enemies peuvent drop des bombes, 0 ils ne peuvent pas | |
3 | +//Les entites non concernées vallent ont un dropbombe = -1 | |
4 | +struct entite | |
5 | +{ | |
6 | + int posx; | |
7 | + int posy; | |
8 | + int dropbombe; | |
9 | +}; | |
10 | + | |
11 | + | |
12 | +struct liste_entite | |
13 | +{ | |
14 | + struct entite entite; | |
15 | + struct liste_entite *suivant; | |
16 | +}; | |
17 | + | |
18 | + | |
19 | +struct entite creer_entite (int x, | |
20 | + int y, | |
21 | + int bombe); | |
22 | + | |
23 | +void ajout_tete (struct liste_entite** Liste, | |
24 | + struct entite x ); | |
25 | + | |
26 | +void SupprimerEntite (struct liste_entite** Liste, | |
27 | + struct entite* entite); | |
28 | + | |
29 | +void DesallouerListe (struct liste_entite** Liste); | ... | ... |
Space Invaders/Envahisseurs/Graphique/src/Main/Makefile
0 → 100644
... | ... | @@ -0,0 +1,37 @@ |
1 | +CC=clang | |
2 | +TARGET=Jeu | |
3 | +CFLAGS=-g -W -Wall -Wextra | |
4 | +LDFLAGS=-I Graphique -l graph -L ../Graphique -l SDL -l SDL_ttf | |
5 | + | |
6 | +default: $(TARGET) | |
7 | + | |
8 | +Liste.o : ../ListeC/Liste.c ../ListeC/Liste.h | |
9 | + clang $(CFLAGS) -c ../ListeC/Liste.c | |
10 | + | |
11 | +Monstre.o : ../Monstre/Monstre.c ../Monstre/Monstre.h | |
12 | + clang $(CFLAGS) -c ../Monstre/Monstre.c | |
13 | + | |
14 | +Interactif.o : ../Interactif/Interactif.c ../Interactif/Interactif.h | |
15 | + clang $(CFLAGS) -c ../Interactif/Interactif.c | |
16 | + | |
17 | +init.o : init.c init.h | |
18 | + clang $(CFLAGS) -c init.c | |
19 | + | |
20 | +main.o : main.c | |
21 | + clang $(CFLAGS) -c main.c | |
22 | + | |
23 | + | |
24 | +$(TARGET): Liste.o main.o Monstre.o Interactif.o init.o | |
25 | + clang main.o Liste.o Monstre.o Interactif.o init.o -o $(TARGET) $(LDFLAGS) | |
26 | + | |
27 | +.PHONY: clean | |
28 | +clean: | |
29 | + rm -f *.o | |
30 | + rm -f $(TARGET) | |
31 | + | |
32 | +tidy : main.c ../ListeC/Liste.c ../Monstre/Monstre.c ../Interactif/Interactif.c init.c | |
33 | + $(CC)-tidy main.c ../ListeC/Liste.c ../Monstre/Monstre.c ../Interactif/Interactif.c init.c --checks="readability-*" -header-filter=.* | |
34 | + | |
35 | +format : | |
36 | + $(CC)-format -style='Microsoft' main.c ../ListeC/Liste.c ../Monstre/Monstre.c ../Interactif/Interactif.c init.c | |
37 | + | ... | ... |
Space Invaders/Envahisseurs/Graphique/src/Main/init.c
0 → 100644
... | ... | @@ -0,0 +1,244 @@ |
1 | +#include <stdio.h> | |
2 | +#include "../Graphique/libgraph.h" | |
3 | +#include "../ListeC/Liste.h" | |
4 | +#include "../Interactif/Interactif.h" | |
5 | +#include "init.h" | |
6 | + | |
7 | +#define TailleX 500 | |
8 | +#define TailleY 500 | |
9 | +#define Sol 475 | |
10 | +#define ErreurHitbox 2 | |
11 | +#define PositionX_1 (TailleX / 2) | |
12 | +#define PositionY_1 (TailleY / 2) | |
13 | +#define PositionY_2 (TailleY / 4) | |
14 | + | |
15 | +#define JoueurX (TailleX / 2) | |
16 | +#define JoueurY (9 * TailleY / 10) | |
17 | + | |
18 | +#define Nom "Space Invaders" | |
19 | +#define TaillePolice1 (TailleX / 10) | |
20 | +#define TaillePolice2 (TailleX / 20) | |
21 | +#define TailleChaineMax 30 | |
22 | + | |
23 | +//Ces variables sont globales car utilisées dans plusieurs .c | |
24 | +//Toutes les hitbox sont initialisées 1 fois puis sont des constantes | |
25 | +struct entite joueur; | |
26 | + | |
27 | +static const char policeDefaut[]= | |
28 | +"/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf"; | |
29 | + | |
30 | +int canon = 0; | |
31 | +int missile = 0; | |
32 | +int enemie1_1 = 0; | |
33 | +int enemie1_2 = 0; | |
34 | +int bouillie = 0; | |
35 | +int bombe = 0; | |
36 | + | |
37 | +int hitboxcanonL = 0; | |
38 | +int hitboxcanonH = 0; | |
39 | +int hitboxmissileL = 0; | |
40 | +int hitboxmissileH = 0; | |
41 | +int hitboxenemieL = 0; | |
42 | +int hitboxenemieH = 0; | |
43 | +int hitboxbouillieL = 0; | |
44 | +int hitboxbouillieH = 0; | |
45 | +int hitboxbombeL = 0; | |
46 | +int hitboxbombeH = 0; | |
47 | + | |
48 | +//Initialisation des variables globales pour le main | |
49 | +void initialiser() | |
50 | +{ | |
51 | + canon = chargerLutin ("../../Lutins/invader_canon.bmp", | |
52 | + COULEUR_NOIR); | |
53 | + missile = chargerLutin ("../../Lutins/invader_missile.bmp", | |
54 | + COULEUR_NOIR); | |
55 | + enemie1_1 = chargerLutin ("../../Lutins/invader_monstre2_1.bmp", | |
56 | + COULEUR_NOIR); | |
57 | + enemie1_2 = chargerLutin ("../../Lutins/invader_monstre2_2.bmp", | |
58 | + COULEUR_NOIR); | |
59 | + bouillie = chargerLutin ("../../Lutins/invader_monstre_bouillie.bmp", | |
60 | + COULEUR_NOIR); | |
61 | + bombe = chargerLutin ("../../Lutins/invader_bombe.bmp", | |
62 | + COULEUR_NOIR); | |
63 | + | |
64 | + tailleLutin (canon, | |
65 | + &hitboxcanonL, | |
66 | + &hitboxcanonH); | |
67 | + | |
68 | + tailleLutin (missile, | |
69 | + &hitboxmissileL, | |
70 | + &hitboxmissileH); | |
71 | + //La taille des enemmies que j'utilise est la meme dans ces 2 variantes | |
72 | + tailleLutin (enemie1_1, | |
73 | + &hitboxenemieL, | |
74 | + &hitboxenemieH); | |
75 | + | |
76 | + tailleLutin (bouillie, | |
77 | + &hitboxbouillieL, | |
78 | + &hitboxbouillieH); | |
79 | + | |
80 | + tailleLutin (bombe, | |
81 | + &hitboxbombeL, | |
82 | + &hitboxbombeH); | |
83 | + | |
84 | +} | |
85 | + | |
86 | +//Initialisation des coordonnées du joueur pour le main | |
87 | +void initialiserjoueur() | |
88 | +{ | |
89 | + joueur.posx = JoueurX; | |
90 | + joueur.posy = JoueurY; | |
91 | + joueur.dropbombe = -1; | |
92 | +} | |
93 | + | |
94 | +//Page de démarage du jeu | |
95 | +char pagedemarrage() | |
96 | +{ | |
97 | + char input = '\0'; | |
98 | + evenement even = 0; | |
99 | + int Largeur = 0; | |
100 | + int Hauteur = 0; | |
101 | + char jouer[] = "Appuyer sur j pour Jouer"; | |
102 | + char quitter[] = "Appuyer ailleurs pour Quitter"; | |
103 | + | |
104 | + choisirPolice (policeDefaut, TaillePolice2); | |
105 | + int LutinJouer = lutinTexte (jouer, COULEUR_BLANC); | |
106 | + int LutinQuitter = lutinTexte (quitter, COULEUR_BLANC); | |
107 | + | |
108 | + choisirPolice (policeDefaut, TaillePolice1); | |
109 | + int LutinBienvenue = lutinTexte (Nom, COULEUR_VERT); | |
110 | + | |
111 | + rectanglePlein (0, | |
112 | + 0, | |
113 | + TailleX, | |
114 | + TailleY, | |
115 | + COULEUR_NOIR); | |
116 | + | |
117 | + tailleLutin (LutinBienvenue, | |
118 | + &Largeur, | |
119 | + &Hauteur); | |
120 | + afficherLutin (LutinBienvenue, | |
121 | + PositionX_1 - Largeur / 2, | |
122 | + PositionY_2 + Hauteur / 2); | |
123 | + | |
124 | + tailleLutin (LutinJouer, | |
125 | + &Largeur, | |
126 | + &Hauteur); | |
127 | + afficherLutin (LutinJouer, | |
128 | + PositionX_1 - Largeur / 2, | |
129 | + PositionY_1 - Hauteur / 2); | |
130 | + | |
131 | + tailleLutin (LutinQuitter, | |
132 | + &Largeur, | |
133 | + &Hauteur); | |
134 | + afficherLutin (LutinQuitter, | |
135 | + PositionX_1 - Largeur / 2, | |
136 | + PositionY_1 + Hauteur / 2); | |
137 | + | |
138 | + majSurface(); | |
139 | + attendreEvenement (); | |
140 | + | |
141 | + lireEvenement (&even, | |
142 | + &input, | |
143 | + NULL); | |
144 | + while (input == '\0') | |
145 | + { | |
146 | + lireEvenement (&even, | |
147 | + &input, | |
148 | + NULL); | |
149 | + } | |
150 | + return input; | |
151 | +} | |
152 | + | |
153 | +//Page en cas de mort dans le jeu | |
154 | +void pagemort (int nbr_vie) | |
155 | +{ | |
156 | + int Largeur = 0; | |
157 | + int Hauteur = 0; | |
158 | + char mort[] = "Vous etes mort"; | |
159 | + char vie[TailleChaineMax] = "\0"; | |
160 | + sprintf (vie, | |
161 | + "Nombre de vies restantes : %d", | |
162 | + nbr_vie); | |
163 | + /* | |
164 | + sprintf crée un warning mais celui-ci ne peut pas crée d'erreur car | |
165 | + TailleChaineMax ne pourra pas excéder 30 si le nombre de vie reste "normal" | |
166 | + sprintf_s ne fonctionne pas pour mon programme (invalid in C99) | |
167 | + */ | |
168 | + | |
169 | + choisirPolice (policeDefaut, TaillePolice1); | |
170 | + int LutinMort = lutinTexte(mort, COULEUR_ROUGE); | |
171 | + | |
172 | + choisirPolice (policeDefaut, TaillePolice2); | |
173 | + int LutinVie = lutinTexte(vie, COULEUR_BLANC); | |
174 | + | |
175 | + rectanglePlein (0, | |
176 | + 0, | |
177 | + TailleX, | |
178 | + TailleY, | |
179 | + COULEUR_NOIR); | |
180 | + | |
181 | + tailleLutin (LutinMort, | |
182 | + &Largeur, | |
183 | + &Hauteur); | |
184 | + afficherLutin (LutinMort, | |
185 | + PositionX_1 - Largeur / 2, | |
186 | + PositionY_2 + Hauteur / 2); | |
187 | + | |
188 | + tailleLutin (LutinVie, | |
189 | + &Largeur, | |
190 | + &Hauteur); | |
191 | + afficherLutin (LutinVie, | |
192 | + PositionX_1 - Largeur / 2, | |
193 | + PositionY_1 - Hauteur / 2); | |
194 | +} | |
195 | + | |
196 | +//Page de GameOver du jeu | |
197 | +void pageGameOver() | |
198 | +{ | |
199 | + int Largeur = 0; | |
200 | + int Hauteur = 0; | |
201 | + char fin[] = "GAME OVER"; | |
202 | + | |
203 | + choisirPolice(policeDefaut, TaillePolice1); | |
204 | + int LutinFin = lutinTexte(fin, COULEUR_ROUGE); | |
205 | + | |
206 | + rectanglePlein (0, | |
207 | + 0, | |
208 | + TailleX, | |
209 | + TailleY, | |
210 | + COULEUR_NOIR); | |
211 | + | |
212 | + tailleLutin (LutinFin, | |
213 | + &Largeur, | |
214 | + &Hauteur); | |
215 | + afficherLutin (LutinFin, | |
216 | + PositionX_1 - Largeur / 2, | |
217 | + PositionY_1 - Hauteur / 2); | |
218 | + | |
219 | +} | |
220 | + | |
221 | +//Page de Victoire du jeu | |
222 | +void pageVictoire() | |
223 | +{ | |
224 | + int Largeur = 0; | |
225 | + int Hauteur = 0; | |
226 | + char fin[] = "VICTOIRE"; | |
227 | + | |
228 | + choisirPolice(policeDefaut, TaillePolice1); | |
229 | + int LutinFin = lutinTexte(fin, COULEUR_VERT); | |
230 | + | |
231 | + rectanglePlein (0, | |
232 | + 0, | |
233 | + TailleX, | |
234 | + TailleY, | |
235 | + COULEUR_NOIR); | |
236 | + | |
237 | + tailleLutin (LutinFin, | |
238 | + &Largeur, | |
239 | + &Hauteur); | |
240 | + afficherLutin (LutinFin, | |
241 | + PositionX_1 - Largeur / 2, | |
242 | + PositionY_1 - Hauteur / 2); | |
243 | + | |
244 | +} | ... | ... |
Space Invaders/Envahisseurs/Graphique/src/Main/init.h
0 → 100644
... | ... | @@ -0,0 +1,28 @@ |
1 | +extern int canon; | |
2 | +extern int missile; | |
3 | +extern int enemie1_1; | |
4 | +extern int enemie1_2; | |
5 | +extern int bouillie; | |
6 | +extern int bombe; | |
7 | + | |
8 | +extern struct entite joueur; | |
9 | +extern char Nom[]; | |
10 | +extern char input; | |
11 | + | |
12 | +extern int hitboxcanonL; | |
13 | +extern int hitboxcanonH; | |
14 | +extern int hitboxmissileL; | |
15 | +extern int hitboxmissileH; | |
16 | +extern int hitboxenemieL; | |
17 | +extern int hitboxenemieH; | |
18 | +extern int hitboxbouillieL; | |
19 | +extern int hitboxbouillieH; | |
20 | +extern int hitboxbombeL; | |
21 | +extern int hitboxbombeH; | |
22 | + | |
23 | +void initialiser(); | |
24 | +void initialiserjoueur(); | |
25 | +char pagedemarrage(); | |
26 | +void pagemort(int nbr_vie); | |
27 | +void pageGameOver(); | |
28 | +void pageVictoire(); | ... | ... |
Space Invaders/Envahisseurs/Graphique/src/Main/main.c
0 → 100644
... | ... | @@ -0,0 +1,267 @@ |
1 | +#include <unistd.h> | |
2 | +#include <SDL/SDL.h> | |
3 | +#include "../Graphique/libgraph.h" | |
4 | +#include "../ListeC/Liste.h" | |
5 | +#include "../Monstre/Monstre.h" | |
6 | +#include "../Interactif/Interactif.h" | |
7 | +#include "init.h" | |
8 | + | |
9 | +#define TailleX 500 | |
10 | +#define TailleY 500 | |
11 | +#define Sol 475 | |
12 | +#define EpaisseurSol 2 | |
13 | +#define ErreurHitbox 2 | |
14 | + | |
15 | +#define Nom "Space Invader" | |
16 | +#define NombreEnemieParLigne 8 | |
17 | +#define NombreLigneEnemies 3 | |
18 | +#define NombreVie 3 | |
19 | + | |
20 | +#define BombeRandomFixe 50 | |
21 | +#define BombeRandomAlea 30 | |
22 | + | |
23 | +//Pour augmenter les deplacements des enemies, vous pouvez: | |
24 | +//Augmenter VitesseDeplacementEnemie | |
25 | +//Tout les VitesseDeplacementEnemie tours de boucle les enemies se déplace | |
26 | +#define VitesseDeplacementEnemie 2 | |
27 | +// Ou augmenter le PasEnemie (Ecart entre la position n et n+1) | |
28 | +#define PasEnemie 5 | |
29 | +#define AffichageImageEnemie 8 | |
30 | + | |
31 | +#define Delai0_2s 200 | |
32 | +#define Delai0_5s 500 | |
33 | +#define Delai2s 2000 | |
34 | + | |
35 | +#define VitesseTourdeBoucle 20 | |
36 | + | |
37 | +int main() | |
38 | +{ | |
39 | + creerSurface(TailleX,TailleY,Nom); | |
40 | + | |
41 | + initialiser(); | |
42 | + initialiserjoueur(); | |
43 | + | |
44 | + struct liste_entite* ListeEnemies = NULL; | |
45 | + struct liste_entite* ListeTires = NULL; | |
46 | + struct liste_entite* ListeBombes = NULL; | |
47 | + | |
48 | + //joueur est dans une liste afin d'utiliser des fonctions deja crée | |
49 | + struct liste_entite* Ljoueur = NULL; | |
50 | + ajout_tete(&Ljoueur,joueur); | |
51 | + | |
52 | + | |
53 | + LigneEnemie(&ListeEnemies, | |
54 | + NombreEnemieParLigne, | |
55 | + NombreLigneEnemies); | |
56 | + int SensVague = 1; | |
57 | + | |
58 | + char input = '\0'; | |
59 | + evenement even = 0; | |
60 | + | |
61 | + int TourdeBoucle = 0; | |
62 | + | |
63 | + int TimeAlea = 0; | |
64 | + int CheckAlea = 0; | |
65 | + | |
66 | + int mort = 0; | |
67 | + int nbr_vie = NombreVie; | |
68 | + int QuelMonstre = 0; | |
69 | + | |
70 | + int coeur = chargerLutin ("../../Lutins/Coeur.bmp", | |
71 | + COULEUR_NOIR); | |
72 | + int hitboxcoeurL = 0; | |
73 | + int hitboxcoeurH = 0; | |
74 | + tailleLutin (coeur, | |
75 | + &hitboxcoeurL, | |
76 | + &hitboxcoeurH); | |
77 | + | |
78 | + if ( pagedemarrage() != 'j') | |
79 | + { | |
80 | + return 0; | |
81 | + } | |
82 | + SDL_Delay(Delai0_5s); | |
83 | + | |
84 | + //Bouble principale | |
85 | + while(input!='m') | |
86 | + { | |
87 | + //Si le joueur est mort | |
88 | + if (mort == 1) | |
89 | + { | |
90 | + nbr_vie-=1; | |
91 | + //Si il lui reste des vies | |
92 | + if (nbr_vie > 0) | |
93 | + { | |
94 | + pagemort(nbr_vie); | |
95 | + majSurface(); | |
96 | + SDL_Delay(Delai2s); | |
97 | + mort = 0; | |
98 | + } | |
99 | + //Si il n'a plus de vie | |
100 | + else | |
101 | + { | |
102 | + pageGameOver(); | |
103 | + majSurface(); | |
104 | + SDL_Delay(Delai2s); | |
105 | + return 0; | |
106 | + } | |
107 | + //On ajoute de nouveau le joueur précedement supprimé à sa liste | |
108 | + ajout_tete(&Ljoueur,joueur); | |
109 | + //Desallocation dynamique des listes | |
110 | + DesallouerListe(&ListeTires); | |
111 | + DesallouerListe(&ListeBombes); | |
112 | + } | |
113 | + | |
114 | + //Affichage Rectangle Noir sur toute la page | |
115 | + rectanglePlein(0, | |
116 | + 0, | |
117 | + TailleX, | |
118 | + TailleY, | |
119 | + COULEUR_NOIR); | |
120 | + | |
121 | + //Affichage des coeurs de vie | |
122 | + for (int i = 1 ; i <= nbr_vie; i++) | |
123 | + { | |
124 | + afficherLutin(coeur, | |
125 | + TailleX - i * hitboxcoeurL, | |
126 | + Sol); | |
127 | + } | |
128 | + | |
129 | + //Affichage du Sol | |
130 | + rectanglePlein(0, | |
131 | + Sol, | |
132 | + TailleX, | |
133 | + EpaisseurSol, | |
134 | + COULEUR_VERT); | |
135 | + | |
136 | + //Affichage du joueur | |
137 | + afficherLutin(canon, | |
138 | + Ljoueur->entite.posx - hitboxcanonL/2 + ErreurHitbox, | |
139 | + Ljoueur->entite.posy); | |
140 | + | |
141 | + //Affichage des ListeEnemies | |
142 | + if (QuelMonstre > 2 * AffichageImageEnemie) | |
143 | + { | |
144 | + QuelMonstre = 0; | |
145 | + } | |
146 | + if (QuelMonstre <= AffichageImageEnemie) | |
147 | + { | |
148 | + AfficherEnemie (ListeEnemies, | |
149 | + enemie1_1, | |
150 | + hitboxenemieL, | |
151 | + hitboxenemieH); | |
152 | + QuelMonstre += 1; | |
153 | + } | |
154 | + else | |
155 | + { | |
156 | + AfficherEnemie (ListeEnemies, | |
157 | + enemie1_2, | |
158 | + hitboxenemieL, | |
159 | + hitboxenemieH); | |
160 | + QuelMonstre += 1; | |
161 | + } | |
162 | + /* | |
163 | + Systeme pour faire drop une bombe dans un temps aléatoire | |
164 | + Mise en place d'un timer | |
165 | + TimeAlea représente le nombre de tour de boucle à éffectuer | |
166 | + */ | |
167 | + if (TimeAlea == 0) | |
168 | + { | |
169 | + //50 tour de boucle minimum + une valeur de 0 à 31 | |
170 | + TimeAlea = rand() % BombeRandomAlea + BombeRandomFixe; | |
171 | + //Il y a un warning car rand() à une valeur limite | |
172 | + } | |
173 | + /* | |
174 | + CheckAlea est incrémenté de 1 à chaque tour de boucle | |
175 | + Lorsque celui ci vaut TimeAlea on peut drop une bombe | |
176 | + On reset à 0 le Timer et le Check aprés avoir Drop une bombe | |
177 | + */ | |
178 | + if (CheckAlea == TimeAlea) | |
179 | + { | |
180 | + MakeBombeDrop(ListeEnemies, | |
181 | + &ListeBombes); | |
182 | + TimeAlea=0; | |
183 | + CheckAlea=0; | |
184 | + } | |
185 | + | |
186 | + //Gestion des evenements clavier | |
187 | + //On ne peut appuyer que sur une seule touche à la fois | |
188 | + lireEvenement (&even, | |
189 | + &input, | |
190 | + NULL); | |
191 | + if (even == toucheBas) | |
192 | + { | |
193 | + action(&Ljoueur->entite, | |
194 | + input, | |
195 | + &ListeTires); | |
196 | + } | |
197 | + | |
198 | + //Deplacement des enemies tout les X tours de boucle | |
199 | + if (TourdeBoucle == VitesseDeplacementEnemie) | |
200 | + { | |
201 | + DeplacementEnemie(ListeEnemies, | |
202 | + &SensVague, | |
203 | + PasEnemie); | |
204 | + TourdeBoucle = 0; | |
205 | + } | |
206 | + | |
207 | + //Deplacement des Tires et Bombes | |
208 | + DeplacementTire(&ListeTires); | |
209 | + DeplacementBombe(&ListeBombes); | |
210 | + | |
211 | + //Supression si collision des Tires et Enemies | |
212 | + SupprimerEntitesEnCollision(&ListeTires, | |
213 | + hitboxmissileL, | |
214 | + hitboxmissileH, | |
215 | + &ListeEnemies, | |
216 | + hitboxenemieL, | |
217 | + hitboxenemieH); | |
218 | + | |
219 | + //Supression si collision des Bombes et Joueur | |
220 | + if (SupprimerEntitesEnCollision(&ListeBombes, | |
221 | + hitboxbombeL, | |
222 | + hitboxbombeH, | |
223 | + &Ljoueur, | |
224 | + hitboxcanonL, | |
225 | + hitboxcanonH) == 1) | |
226 | + { | |
227 | + mort = 1; | |
228 | + majSurface(); | |
229 | + SDL_Delay(Delai0_2s); | |
230 | + } | |
231 | + | |
232 | + //Supression si collision des Enemies et Joueur | |
233 | + if (SupprimerEntitesEnCollision(&ListeEnemies, | |
234 | + hitboxenemieL, | |
235 | + hitboxenemieH, | |
236 | + &Ljoueur, | |
237 | + hitboxcanonL, | |
238 | + hitboxcanonH) == 1) | |
239 | + { | |
240 | + pageGameOver(); | |
241 | + majSurface(); | |
242 | + SDL_Delay(Delai2s); | |
243 | + return 0; | |
244 | + } | |
245 | + | |
246 | + //Si il n'y a plus d'enemies, c'est une victoire !!! | |
247 | + if (ListeEnemies == NULL) | |
248 | + { | |
249 | + majSurface(); | |
250 | + SDL_Delay(Delai0_2s); | |
251 | + pageVictoire(); | |
252 | + majSurface(); | |
253 | + SDL_Delay(Delai2s); | |
254 | + return 0; | |
255 | + } | |
256 | + | |
257 | + | |
258 | + majSurface(); | |
259 | + | |
260 | + TourdeBoucle += 1; | |
261 | + CheckAlea += 1; | |
262 | + | |
263 | + SDL_Delay(VitesseTourdeBoucle); | |
264 | + | |
265 | + } | |
266 | + return 0; | |
267 | +} | ... | ... |
Space Invaders/Envahisseurs/Graphique/src/Monstre/Monstre.c
0 → 100644
... | ... | @@ -0,0 +1,103 @@ |
1 | +#include <stdlib.h> | |
2 | +#include "../Graphique/libgraph.h" | |
3 | +#include "../ListeC/Liste.h" | |
4 | +#include "Monstre.h" | |
5 | + | |
6 | +#define TailleX 500 | |
7 | +#define TailleY 500 | |
8 | +#define ErreurHitbox 2 | |
9 | + | |
10 | +#define Taille1_10 (TailleX / 10) | |
11 | +#define Taille9_10 (9 * TailleX / 10) | |
12 | +#define TailleJump 30 | |
13 | + | |
14 | +//Sens = 1 -> Va vers la droite | |
15 | +//Sens = 0 -> Va vers la gauche | |
16 | +void DeplacementEnemie(struct liste_entite* Liste, | |
17 | + int* SensDeplacement, | |
18 | + int Pas) | |
19 | +{ | |
20 | + //ind sert à savoir si je dois changer de sens ou non | |
21 | + int ind = 0; | |
22 | + struct liste_entite* pListe = Liste; | |
23 | + | |
24 | + while (pListe != NULL) | |
25 | + { | |
26 | + pListe->entite.posx += (*SensDeplacement == 1) ? Pas : -Pas; | |
27 | + if (pListe->entite.posx >= Taille9_10) | |
28 | + { | |
29 | + ind = 1; | |
30 | + } | |
31 | + | |
32 | + else if (pListe->entite.posx <= Taille1_10) | |
33 | + { | |
34 | + ind = 2; | |
35 | + } | |
36 | + | |
37 | + pListe = pListe->suivant; | |
38 | + } | |
39 | + | |
40 | + if (ind != 0) | |
41 | + { | |
42 | + *SensDeplacement = (ind == 1) ? 0 : 1; | |
43 | + struct liste_entite* p2Liste = Liste; | |
44 | + | |
45 | + while (p2Liste != NULL) | |
46 | + { | |
47 | + p2Liste->entite.posy += TailleJump; | |
48 | + p2Liste = p2Liste->suivant; | |
49 | + } | |
50 | + } | |
51 | +} | |
52 | + | |
53 | +//Création de lignes d'entités enemies dans la liste enemies | |
54 | +void LigneEnemie (struct liste_entite** ListeEnemie, | |
55 | + int nbr_enemies, | |
56 | + int nbr_rangee) | |
57 | +{ | |
58 | + | |
59 | + for (int j = 1; j <= nbr_rangee; j++) | |
60 | + { | |
61 | + int compteurY = j * Taille1_10; | |
62 | + int compteurX = TailleX / (nbr_enemies+1); | |
63 | + | |
64 | + for (int i = 0; i < nbr_enemies; i++) | |
65 | + { | |
66 | + if (j == nbr_rangee) | |
67 | + { | |
68 | + ajout_tete(ListeEnemie, | |
69 | + creer_entite(compteurX, | |
70 | + compteurY, | |
71 | + 1)); | |
72 | + compteurX += 2 * TailleX / (3 * nbr_enemies); | |
73 | + } | |
74 | + | |
75 | + else | |
76 | + { | |
77 | + ajout_tete(ListeEnemie, | |
78 | + creer_entite(compteurX, | |
79 | + compteurY, | |
80 | + 0)); | |
81 | + compteurX += 2 * TailleX / (3 * nbr_enemies); | |
82 | + } | |
83 | + } | |
84 | + } | |
85 | +} | |
86 | + | |
87 | +//Affichage des enemies centrés dans leur hitbox | |
88 | +void AfficherEnemie (struct liste_entite* Liste, | |
89 | + int lutin, | |
90 | + int Largeur, | |
91 | + int Hauteur) | |
92 | +{ | |
93 | + | |
94 | + struct liste_entite* pListe = Liste; | |
95 | + | |
96 | + while (pListe != NULL) | |
97 | + { | |
98 | + afficherLutin(lutin, | |
99 | + pListe->entite.posx - Largeur / 2 + ErreurHitbox, | |
100 | + pListe->entite.posy - Hauteur / 2 + ErreurHitbox); | |
101 | + pListe=pListe->suivant; | |
102 | + } | |
103 | +} | ... | ... |
Space Invaders/Envahisseurs/Graphique/src/Monstre/Monstre.h
0 → 100644
... | ... | @@ -0,0 +1,12 @@ |
1 | +void DeplacementEnemie(struct liste_entite* Liste, | |
2 | + int* SensDeplacement, | |
3 | + int Pas); | |
4 | + | |
5 | +void LigneEnemie (struct liste_entite** ListeEnemie, | |
6 | + int nbr_enemies, | |
7 | + int nbr_rangee); | |
8 | + | |
9 | +void AfficherEnemie (struct liste_entite* Liste, | |
10 | + int lutin, | |
11 | + int Largeur, | |
12 | + int Hauteur); | ... | ... |
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
No preview for this file type
... | ... | @@ -0,0 +1,29 @@ |
1 | +# | |
2 | +# Makefile pour la bibliotheque graphique | |
3 | +# | |
4 | + | |
5 | +SOURCES = $(wildcard *.c) | |
6 | +OBJETS = $(SOURCES:.c=.o) | |
7 | +CIBLE = libgraph.a | |
8 | + | |
9 | +# | |
10 | +# Nom de la cible principale | |
11 | +# | |
12 | + | |
13 | +all: $(CIBLE) | |
14 | + | |
15 | +# | |
16 | +# Cible de nettoyage | |
17 | +# | |
18 | + | |
19 | +clean: | |
20 | + rm -f core *.o $(CIBLE) | |
21 | + | |
22 | +# | |
23 | +# Dependances pour la bibliotheque | |
24 | +# | |
25 | + | |
26 | +$(CIBLE): $(OBJETS) | |
27 | + $(AR) rs $@ $? | |
28 | + | |
29 | +$(CIBLE:.a=).o: $(CIBLE:.a=).c $(CIBLE:.a=).h | ... | ... |
... | ... | @@ -0,0 +1,239 @@ |
1 | +/**** Bibliotheque graphique ****/ | |
2 | + | |
3 | +/** Fichiers d'inclusion **/ | |
4 | + | |
5 | +#include <SDL/SDL.h> | |
6 | +#include <SDL/SDL_ttf.h> | |
7 | +#include "libgraph.h" | |
8 | + | |
9 | +/** Types **/ | |
10 | + | |
11 | +typedef struct | |
12 | +{ | |
13 | + int r, v, b; | |
14 | +} couleur; | |
15 | + | |
16 | +/** Constantes **/ | |
17 | + | |
18 | +#define BITS_PAR_PIXEL 32 | |
19 | +#define TAILLE_POLICE 20 | |
20 | + | |
21 | +static const couleur couleurs[] = { { 255, 255, 255 }, { 0, 0, 0 }, { 255, 0, 0 }, | |
22 | + { 0, 255, 0 }, { 0, 0, 255 }, { 255, 105, 180 }, | |
23 | + { 150, 150, 150 }, { -1, -1, -1 } }; | |
24 | + | |
25 | +static const char policeDefaut[]="/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf"; | |
26 | + | |
27 | +/** Variables globales **/ | |
28 | + | |
29 | +static SDL_Surface *surface; | |
30 | +TTF_Font* police; | |
31 | + | |
32 | +/** Fonctions **/ | |
33 | + | |
34 | +void choisirPolice(const char *chemin, int taille){ | |
35 | + police=TTF_OpenFont(chemin, taille); | |
36 | +} | |
37 | + | |
38 | +void initialiserTexte() { | |
39 | + TTF_Init(); | |
40 | + choisirPolice(policeDefaut, TAILLE_POLICE); | |
41 | +} | |
42 | + | |
43 | +/* Initialisation de la surface dessinable */ | |
44 | +unsigned char creerSurface (int largeur, int hauteur, char *titre) | |
45 | +{ | |
46 | + SDL_Init (SDL_INIT_VIDEO); | |
47 | + SDL_WM_SetCaption (titre, titre); | |
48 | + surface = SDL_SetVideoMode (largeur, hauteur, BITS_PAR_PIXEL, SDL_DOUBLEBUF); | |
49 | + initialiserTexte(); | |
50 | + | |
51 | + return (surface != NULL && police != NULL); | |
52 | +} | |
53 | + | |
54 | +/* Fermeture de la surface dessinable */ | |
55 | + | |
56 | +void fermerSurface (void) | |
57 | +{ | |
58 | + if (surface != NULL) SDL_FreeSurface (surface); | |
59 | + if (police != NULL) TTF_CloseFont(police); | |
60 | + TTF_Quit(); | |
61 | + SDL_Quit (); | |
62 | +} | |
63 | + | |
64 | +/* Creation d'une couleur */ | |
65 | + | |
66 | +static int creerCouleur (int ncouleur) | |
67 | +{ | |
68 | + couleur c = couleurs[ncouleur]; | |
69 | + return SDL_MapRGB (surface->format, c.r, c.v, c.b); | |
70 | +} | |
71 | + | |
72 | +/* Dessin d'un rectangle plein */ | |
73 | + | |
74 | +void rectanglePlein (int x, int y, int l, int h, int c) | |
75 | +{ | |
76 | + SDL_Rect rectangle = { x, y, l, h }; | |
77 | + SDL_FillRect (surface, &rectangle, creerCouleur (c)); | |
78 | + // SDL_Flip(surface); | |
79 | +} | |
80 | + | |
81 | +/* Manipulation de lutins */ | |
82 | + | |
83 | +static SDL_Surface *lutins[MAX_LUTINS]; | |
84 | +static int lutins_nb = 0; | |
85 | + | |
86 | +int lutinTexte(char* texte, int couleurTexte) { | |
87 | + couleur c=couleurs[couleurTexte]; | |
88 | + SDL_Color couleur={c.r, c.v, c.b}; | |
89 | + SDL_Surface* lutin=TTF_RenderText_Solid(police, texte, couleur); | |
90 | + if (lutin != NULL) | |
91 | + { | |
92 | + lutins[lutins_nb++] = lutin; | |
93 | + return lutins_nb - 1; | |
94 | + } | |
95 | + return -1; | |
96 | +} | |
97 | + | |
98 | +static void configurerLutin (SDL_Surface *lutin, int ncouleur) | |
99 | +{ | |
100 | + couleur c = couleurs[ncouleur]; | |
101 | + int fond = SDL_MapRGB (lutin->format, c.r, c.v, c.b); | |
102 | + SDL_SetColorKey (lutin, SDL_SRCCOLORKEY | SDL_RLEACCEL, fond); | |
103 | +} | |
104 | + | |
105 | +int chargerLutin (char *fichier, int couleur) | |
106 | +{ | |
107 | + if (lutins_nb >= MAX_LUTINS) return -2; | |
108 | + SDL_Surface *lutin = SDL_LoadBMP (fichier); | |
109 | + if (lutin != NULL) | |
110 | + { | |
111 | + lutins[lutins_nb++] = lutin; | |
112 | + if (couleur >= 0) configurerLutin (lutin, couleur); | |
113 | + return lutins_nb - 1; | |
114 | + } | |
115 | + return -1; | |
116 | +} | |
117 | + | |
118 | +void afficherLutin (int lutin, int x, int y) | |
119 | +{ | |
120 | + SDL_Rect position; | |
121 | + position.x = x; | |
122 | + position.y = y; | |
123 | + SDL_BlitSurface (lutins[lutin], NULL, surface, &position); | |
124 | +} | |
125 | + | |
126 | +int creerLutin (int x, int y, int largeur, int hauteur, int couleur) | |
127 | +{ | |
128 | + if (lutins_nb >= MAX_LUTINS) return -2; | |
129 | + int rmask, gmask, bmask, amask; | |
130 | +#if SDL_BYTEORDER == SDL_BIG_ENDIAN | |
131 | + rmask = 0xff000000; | |
132 | + gmask = 0x00ff0000; | |
133 | + bmask = 0x0000ff00; | |
134 | + amask = 0x000000ff; | |
135 | +#else | |
136 | + rmask = 0x000000ff; | |
137 | + gmask = 0x0000ff00; | |
138 | + bmask = 0x00ff0000; | |
139 | + amask = 0xff000000; | |
140 | +#endif | |
141 | + if (couleur < 0) amask = 0x00000000; | |
142 | + SDL_Surface *lutin = | |
143 | + SDL_CreateRGBSurface (0, largeur, hauteur, BITS_PAR_PIXEL, rmask, gmask, bmask, amask); | |
144 | + SDL_Rect fenetre; | |
145 | + fenetre.x = x; | |
146 | + fenetre.y = y; | |
147 | + fenetre.h = hauteur; | |
148 | + fenetre.w = largeur; | |
149 | + SDL_BlitSurface (surface, &fenetre, lutin, NULL); | |
150 | + lutins[lutins_nb++] = lutin; | |
151 | + if (couleur >= 0) configurerLutin (lutin, couleur); | |
152 | + return lutins_nb - 1; | |
153 | +} | |
154 | + | |
155 | +void tailleLutin (int lutin, int *largeur, int *hauteur) | |
156 | +{ | |
157 | + *largeur = lutins[lutin]->w; | |
158 | + *hauteur = lutins[lutin]->h; | |
159 | +} | |
160 | + | |
161 | +int sauverLutin (int lutin, char *nom) { return SDL_SaveBMP (lutins[lutin], nom); } | |
162 | + | |
163 | +/* Manipulation de copie de surface en BMP */ | |
164 | + | |
165 | +int sauverSurface (char *fichier) { return SDL_SaveBMP (surface, fichier); } | |
166 | + | |
167 | +unsigned char chargerSurface (char *fichier) | |
168 | +{ | |
169 | + SDL_Surface *image = SDL_LoadBMP (fichier); | |
170 | + if (image != NULL) | |
171 | + { | |
172 | + SDL_BlitSurface (image, NULL, surface, NULL); | |
173 | + SDL_Flip (surface); | |
174 | + } | |
175 | + return (image != NULL); | |
176 | +} | |
177 | + | |
178 | +void majSurface (void) { SDL_Flip (surface); } | |
179 | + | |
180 | +/* Trouver la couleur d'un pixel */ | |
181 | + | |
182 | +int couleurPixel (int x, int y) | |
183 | +{ | |
184 | + int bpp = surface->format->BytesPerPixel; | |
185 | + Uint32 *p = (Uint32 *)(surface->pixels + y * surface->pitch + x * bpp); | |
186 | + Uint8 r, v, b; | |
187 | + SDL_GetRGB (*p, surface->format, &r, &v, &b); | |
188 | + int i = 0; | |
189 | + while (1) | |
190 | + { | |
191 | + if (couleurs[i].r < 0) break; | |
192 | + if (r == couleurs[i].r && v == couleurs[i].v && b == couleurs[i].b) break; | |
193 | + i++; | |
194 | + } | |
195 | + if (couleurs[i].r < 0) | |
196 | + return -1; | |
197 | + else | |
198 | + return i; | |
199 | +} | |
200 | + | |
201 | +/* Fonction de traitement des événements */ | |
202 | + | |
203 | +void lireEvenement (evenement *evt, char *touche, void **detail) | |
204 | +{ | |
205 | + static SDL_keysym _detail; | |
206 | + SDL_Event event; | |
207 | + while (SDL_PollEvent (&event)) | |
208 | + { | |
209 | + if (event.type == SDL_QUIT) *evt = quitter; | |
210 | + if (event.type == SDL_KEYDOWN || event.type == SDL_KEYUP) | |
211 | + { | |
212 | + *evt = (event.type == SDL_KEYDOWN) ? toucheBas : toucheHaut; | |
213 | + char *nom = SDL_GetKeyName (event.key.keysym.sym); | |
214 | + if (strlen (nom) == 1 && nom[0] >= 32 && nom[0] < 128) | |
215 | + *touche = nom[0]; | |
216 | + else | |
217 | + *touche = 0; | |
218 | + if (detail != NULL) | |
219 | + { | |
220 | + _detail = event.key.keysym; | |
221 | + *detail = &_detail; | |
222 | + } | |
223 | + break; | |
224 | + } | |
225 | + } | |
226 | +} | |
227 | + | |
228 | +void attendreEvenement (void) | |
229 | +{ | |
230 | + SDL_Event event; | |
231 | + while (SDL_WaitEvent (&event)) switch (event.type) | |
232 | + { | |
233 | + case SDL_QUIT: | |
234 | + exit (0); | |
235 | + case SDL_KEYDOWN: | |
236 | + case SDL_MOUSEBUTTONDOWN: | |
237 | + return; | |
238 | + } | |
239 | +} | ... | ... |
... | ... | @@ -0,0 +1,156 @@ |
1 | +/**** Bibliotheque graphique (definitions) ****/ | |
2 | + | |
3 | +/** Constantes **/ | |
4 | + | |
5 | +#define COULEUR_BLANC 0 | |
6 | +#define COULEUR_NOIR 1 | |
7 | +#define COULEUR_ROUGE 2 | |
8 | +#define COULEUR_VERT 3 | |
9 | +#define COULEUR_BLEU 4 | |
10 | +#define COULEUR_ROSE 5 | |
11 | +#define COULEUR_GRIS 6 | |
12 | + | |
13 | +#define MAX_LUTINS 16 | |
14 | + | |
15 | +typedef enum {toucheBas, toucheHaut, quitter} evenement; | |
16 | + | |
17 | +/** Prototypes **/ | |
18 | + | |
19 | +/** | |
20 | + * @brief cree une fenetre 2D | |
21 | + * | |
22 | + * @param largeur en pixels de la fenetre | |
23 | + * @param hauteur en pixels de la fenetre | |
24 | + * @param titre de la fenetre (chaine de caractere) | |
25 | + */ | |
26 | +unsigned char creerSurface (int largeur, int hauteur, char *titre); | |
27 | + | |
28 | +/** | |
29 | + * @brief permet de charger un fichier image au format bmp (bitmap) | |
30 | + * | |
31 | + * @param fichier nom du fichier | |
32 | + */ | |
33 | +unsigned char chargerSurface (char *fichier); | |
34 | + | |
35 | + | |
36 | +/** | |
37 | + * @brief permet de sauvegarder une surface en image (format bmp) | |
38 | + * | |
39 | + * @param fichier nom du fichier | |
40 | + * @return 0 si OK, valeur negative sinon | |
41 | + */ | |
42 | +int sauverSurface (char *fichier); | |
43 | + | |
44 | +/** | |
45 | + * @brief met a jour la surface d'affichage | |
46 | + */ | |
47 | +void majSurface (void); | |
48 | + | |
49 | + | |
50 | +/** | |
51 | + * @brief libere la surface d'affichage | |
52 | + * a faire lors de la fermeture | |
53 | + * du programme | |
54 | + */ | |
55 | +void fermerSurface (void); | |
56 | + | |
57 | +/** | |
58 | + * @brief choisit la police de caractères à utiliser pour afficher du texte | |
59 | + * @param chemin nom du fichier de police (format .ttf, voir /usr/share/fonts/truetype) | |
60 | + * @param taille taille de la police | |
61 | + */ | |
62 | +void choisirPolice(const char *chemin, int taille); | |
63 | + | |
64 | +/** | |
65 | + * @brief dessine un rectange de taille (l,h) aux coordonnêes | |
66 | + * (x,y) et de couleur c | |
67 | + * | |
68 | + * @param x 0 <= x <= l_surface | |
69 | + * @param y 0 <= y <= h_surface | |
70 | + * @param l largeur en pixels | |
71 | + * @param h longueur en pixels | |
72 | + * @param c indice de couleur voir variable couleurs dans le fichier .c | |
73 | + */ | |
74 | +void rectanglePlein (int x, int y, int l, int h, int c); | |
75 | + | |
76 | + | |
77 | +/** | |
78 | + * @brief permet de determiner l'indice du tableau de couleur du | |
79 | + * pixel aux coordonnees (x,y) | |
80 | + * | |
81 | + * @param x 0 <= x <= l_surface | |
82 | + * @param y 0 <= y <= h_surface | |
83 | + * @return indice de couleur voire variable couleurs dans le fichier .c | |
84 | + */ | |
85 | +int couleurPixel (int x, int y); | |
86 | + | |
87 | +/** | |
88 | + * @brief crée un lutin à partir d'un texte | |
89 | + * | |
90 | + * @param texte le texte | |
91 | + * @param couleur indice de couleur du texte | |
92 | + * @return numero de lutin dans le tableau dynamique de lutin (< MAX_LUTINS) | |
93 | + */ | |
94 | +int lutinTexte(char *texte, int couleur); | |
95 | + | |
96 | +/** | |
97 | + * @brief charge un lutin à partir du fichier | |
98 | + * | |
99 | + * @param fichier image bitmap du lutin à charger | |
100 | + * @param couleur indice de couleurs à charger | |
101 | + * @return numero de lutin dans le tableau dynamique de lutin (< MAX_LUTINS) | |
102 | + */ | |
103 | +int chargerLutin (char *fichier, int couleur); | |
104 | + | |
105 | +/** | |
106 | + * @brief afficher un lutin aux coordonnées (x,y) | |
107 | + * | |
108 | + * @param lutin numero du lutin à afficher (< MAX_LUTINS) | |
109 | + * @param x abscisse de départ | |
110 | + * @param y ordonnée de départ | |
111 | + */ | |
112 | +void afficherLutin (int lutin, int x, int y); | |
113 | + | |
114 | +/** | |
115 | + * @brief creer un lutin de taille (l,h) aux coordonnées (x,y) | |
116 | + * | |
117 | + * @param x abscisse de départ | |
118 | + * @param y ordonnée de départ | |
119 | + * @param largeur largeur du lutin | |
120 | + * @param hauteur hauteur du lutin | |
121 | + * @param couleur indice de couleur à partir du tableau _couleurs_ | |
122 | + * @return indice du lutin dans le tableau global (< MAX_LUTINS) | |
123 | + */ | |
124 | +int creerLutin (int x, int y, int largeur, int hauteur, int couleur); | |
125 | + | |
126 | +/** | |
127 | + * @brief sauvegarde un lutin dans un fichier | |
128 | + * | |
129 | + * @param lutin numero de lutin à sauvegarder (< MAX_LUTINS) | |
130 | + * @param nom fichier pour la sauvegarde | |
131 | + * @return 0 si OK valeur négative sinon | |
132 | + */ | |
133 | +int sauverLutin (int lutin, char *nom); | |
134 | + | |
135 | +/** | |
136 | + * @brief calcule la taille (largeur,hauteur) d'un lutin | |
137 | + * | |
138 | + * @param lutin index du lutin (< MAX_LUTINS) | |
139 | + * @param largeur pointeur sur la largeur | |
140 | + * @param hauteur pointeur sur la hauteur | |
141 | + */ | |
142 | +void tailleLutin (int lutin, int *largeur, int *hauteur); | |
143 | + | |
144 | +/** | |
145 | + * @brief lire une touche au clavier | |
146 | + * | |
147 | + * @param evt pointeur sur evenement | |
148 | + * @param touche pointeur sur la touche pressée | |
149 | + * @param detail NULL ou keysim | |
150 | + */ | |
151 | +void lireEvenement (evenement *evt, char *touche, void **detail); | |
152 | + | |
153 | +/** | |
154 | + * @brief attente d'un evenement bouton, souris, fin de programme | |
155 | + */ | |
156 | +void attendreEvenement (void); | ... | ... |
... | ... | @@ -0,0 +1,375 @@ |
1 | +#include <stdlib.h> | |
2 | +#include <string.h> | |
3 | + | |
4 | +#include "../Graphique/libgraph.h" | |
5 | +#include "../ListeC/Liste.h" | |
6 | +#include "Interactif.h" | |
7 | +#include "../Main/init.h" | |
8 | + | |
9 | +#define TailleX 500 | |
10 | +#define TailleY 500 | |
11 | +#define Sol 475 | |
12 | +#define ErreurHitbox 2 | |
13 | +#define TailleX9_10 (9 * TailleX / 10) | |
14 | +#define TailleX1_10 (TailleX / 10) | |
15 | + | |
16 | +#define ValeurDeplacementTire 5 | |
17 | +#define ValeurDeplacementJoueur 3 | |
18 | +#define ValeurDeplacementBombe 2 | |
19 | + | |
20 | + | |
21 | +//La fonction renvoie 1 si il y a collision | |
22 | +int CheckCollisionEntiteEntite (struct entite entite1, | |
23 | + int L1, | |
24 | + int H1, | |
25 | + struct entite entite2, | |
26 | + int L2, | |
27 | + int H2) | |
28 | +{ | |
29 | + //CheckX | |
30 | + int gauche1 = entite1.posx - L1/2 + ErreurHitbox; | |
31 | + int droite1 = entite1.posx + L1/2 - ErreurHitbox; | |
32 | + int gauche2 = entite2.posx - L2/2 + ErreurHitbox; | |
33 | + int droite2 = entite2.posx + L2/2 - ErreurHitbox; | |
34 | + //Tout les cas possibles de collision | |
35 | + int CheckX = (gauche1 >= gauche2 && gauche1 <= droite2) || | |
36 | + (droite1 >= gauche2 && droite1 <= droite2) || | |
37 | + (gauche1 >= gauche2 && droite1 <= droite2) || | |
38 | + (gauche2 >= gauche1 && droite2 <= droite1); | |
39 | + | |
40 | + //CheckY | |
41 | + int haut1 = entite1.posy - H1/2 + ErreurHitbox; | |
42 | + int bas1 = entite1.posy + H1/2 - ErreurHitbox; | |
43 | + int haut2 = entite2.posy - H2/2 + ErreurHitbox; | |
44 | + int bas2 = entite2.posy + H2/2 - ErreurHitbox; | |
45 | + int CheckY = (haut1 <= bas2 && haut1 >= haut2) || | |
46 | + (bas1 <= bas2 && bas1 >= haut2) || | |
47 | + (haut1 <= haut2 && bas1 >= bas2) || | |
48 | + (haut2 <= haut1 && bas2 >= bas1); | |
49 | + | |
50 | + | |
51 | + return CheckX && CheckY; | |
52 | +} | |
53 | + | |
54 | +//La fonction renvoie l'entite de la Liste1 si il y a collision | |
55 | +struct entite* CheckCollisionListeEntite (struct liste_entite* Liste1, | |
56 | + int L1, | |
57 | + int H1, | |
58 | + struct entite entite2, | |
59 | + int L2, | |
60 | + int H2) | |
61 | +{ | |
62 | + | |
63 | + struct liste_entite *pListe1 = Liste1; | |
64 | + while (pListe1 != NULL) | |
65 | + { | |
66 | + | |
67 | + if(CheckCollisionEntiteEntite (pListe1->entite, | |
68 | + L1, | |
69 | + H1, | |
70 | + entite2, | |
71 | + L2, | |
72 | + H2) == 1) | |
73 | + { | |
74 | + return &pListe1->entite; | |
75 | + } | |
76 | + | |
77 | + pListe1 = pListe1->suivant; | |
78 | + } | |
79 | + return NULL; | |
80 | +} | |
81 | + | |
82 | + | |
83 | + | |
84 | +//La fonction renvoie une liste d'entite avec les deux entites à supprimer | |
85 | +//Seulement si il y a collision | |
86 | +struct liste_entite* CheckCollisionListeListe (struct liste_entite* Liste1, | |
87 | + int L1, | |
88 | + int H1, | |
89 | + struct liste_entite* Liste2, | |
90 | + int L2, | |
91 | + int H2) | |
92 | +{ | |
93 | + | |
94 | + struct liste_entite *pListe2 = Liste2; | |
95 | + while (pListe2 != NULL) | |
96 | + { | |
97 | + | |
98 | + struct entite* collision = CheckCollisionListeEntite (Liste1, | |
99 | + L1, | |
100 | + H1, | |
101 | + pListe2->entite, | |
102 | + L2, | |
103 | + H2); | |
104 | + if (collision == NULL) | |
105 | + { | |
106 | + pListe2 = pListe2->suivant; | |
107 | + } | |
108 | + | |
109 | + else | |
110 | + { | |
111 | + // Création des structures pour les deux entités | |
112 | + struct liste_entite* Entite1 = malloc(sizeof(struct liste_entite)); | |
113 | + struct liste_entite* Entite2 = malloc(sizeof(struct liste_entite)); | |
114 | + | |
115 | + // Remplissage des structure avec les entités correspondantes | |
116 | + Entite1->entite = *collision; | |
117 | + Entite2->entite = pListe2->entite; | |
118 | + | |
119 | + // Relier les structures entre elles | |
120 | + Entite1->suivant = Entite2; | |
121 | + Entite2->suivant = NULL; | |
122 | + | |
123 | + return Entite1; | |
124 | + } | |
125 | + } | |
126 | + | |
127 | + return NULL; | |
128 | +} | |
129 | + | |
130 | +//Tire un missile, il ne peux y en avoir que un à la fois | |
131 | +void Tirer (struct entite joueur, | |
132 | + struct liste_entite** pl) | |
133 | +{ | |
134 | + if (*pl == NULL) | |
135 | + { | |
136 | + ajout_tete(pl, | |
137 | + creer_entite(joueur.posx, | |
138 | + joueur.posy, | |
139 | + -1)); | |
140 | + } | |
141 | +} | |
142 | + | |
143 | + | |
144 | +void DeplacementTire(struct liste_entite** Liste) | |
145 | +{ | |
146 | + struct entite* Entite = &(*Liste)->entite; | |
147 | + if (Entite != NULL) | |
148 | + { | |
149 | + | |
150 | + if (Entite->posy <= 0) | |
151 | + { | |
152 | + afficherLutin(bouillie, | |
153 | + Entite->posx - hitboxbouillieL/2 + ErreurHitbox, | |
154 | + Entite->posy); | |
155 | + SupprimerEntite(Liste, Entite); | |
156 | + } | |
157 | + | |
158 | + else | |
159 | + { | |
160 | + Entite->posy -= ValeurDeplacementTire; | |
161 | + //Je divise ErreurHitbox par 2 car l'erreur du missile | |
162 | + //est plus petite que pour les autres images | |
163 | + afficherLutin(missile, | |
164 | + Entite->posx - hitboxmissileL/2 + ErreurHitbox/2, | |
165 | + Entite->posy - hitboxmissileH/2 + ErreurHitbox/2); | |
166 | + } | |
167 | + } | |
168 | +} | |
169 | + | |
170 | + | |
171 | +//La fonction fait une action soit au joueur | |
172 | +//soit à la Liste des Tires selon la touche préssée | |
173 | +void action(struct entite* joueur, | |
174 | + char c, | |
175 | + struct liste_entite** tires) | |
176 | +{ | |
177 | + switch (c) | |
178 | + { | |
179 | + case 'd': | |
180 | + if (joueur->posx <= TailleX9_10) | |
181 | + { | |
182 | + joueur->posx += ValeurDeplacementJoueur; | |
183 | + } | |
184 | + break; | |
185 | + case 'q': | |
186 | + if (joueur->posx >= TailleX1_10) | |
187 | + { | |
188 | + joueur->posx -= ValeurDeplacementJoueur; | |
189 | + } | |
190 | + break; | |
191 | + case 't': | |
192 | + Tirer(*joueur, | |
193 | + tires); | |
194 | + break; | |
195 | + default: | |
196 | + break; | |
197 | + } | |
198 | +} | |
199 | + | |
200 | +/* | |
201 | +La fonction crée une liste de tout les enemies pouvant drop des bombes | |
202 | +Seulement ceux les plus bas de leur colonne repective | |
203 | +Puis ajoute à la liste bombe, | |
204 | +une bombe provenant d'un des enemies pouvant drop des bombes | |
205 | +Le choix de quel enemie drop la bombe est aléatoire | |
206 | +*/ | |
207 | +void MakeBombeDrop (struct liste_entite* enemies, | |
208 | + struct liste_entite** bombes) | |
209 | +{ | |
210 | + | |
211 | + struct liste_entite* pListe = enemies; | |
212 | + struct liste_entite* Dropable = NULL; | |
213 | + int taille = 0; | |
214 | + | |
215 | + while (pListe != NULL) | |
216 | + { | |
217 | + | |
218 | + if (pListe->entite.dropbombe == 1) | |
219 | + { | |
220 | + ajout_tete(&Dropable,pListe->entite); | |
221 | + taille += 1; | |
222 | + } | |
223 | + | |
224 | + pListe = pListe->suivant; | |
225 | + } | |
226 | + | |
227 | + if(Dropable == NULL) | |
228 | + { | |
229 | + return; | |
230 | + } | |
231 | + /* | |
232 | + On choisit une valeur aléatoire représentant l'enemie qui va drop la bombe | |
233 | + Il ya un warning comme quoi rand() à une limite | |
234 | + Mais on ne la dépassera jamais, taille ne pourra | |
235 | + jamais excédé une vingtaine d'enemies par ligne | |
236 | + */ | |
237 | + int randomIndex = rand() % taille-1; | |
238 | + struct liste_entite* pDropable = Dropable; | |
239 | + | |
240 | + for (int i = 0; i <= randomIndex; i++) | |
241 | + { | |
242 | + pDropable = pDropable->suivant; | |
243 | + } | |
244 | + | |
245 | + ajout_tete(bombes, | |
246 | + creer_entite(pDropable->entite.posx, | |
247 | + pDropable->entite.posy, | |
248 | + -1)); | |
249 | +} | |
250 | + | |
251 | + | |
252 | +void DeplacementBombe(struct liste_entite** Liste) | |
253 | +{ | |
254 | + struct liste_entite* pListe = *Liste; | |
255 | + | |
256 | + while (pListe != NULL) | |
257 | + { | |
258 | + | |
259 | + if (pListe->entite.posy + hitboxbombeH/2 - ErreurHitbox >= Sol) | |
260 | + { | |
261 | + struct entite* a_supprimer = &pListe->entite; | |
262 | + | |
263 | + pListe = pListe->suivant; | |
264 | + SupprimerEntite(Liste,a_supprimer); | |
265 | + } | |
266 | + | |
267 | + else | |
268 | + { | |
269 | + pListe->entite.posy += ValeurDeplacementBombe; | |
270 | + afficherLutin(bombe, | |
271 | + pListe->entite.posx - hitboxbombeL/2 + ErreurHitbox, | |
272 | + pListe->entite.posy - hitboxbombeH/2 + ErreurHitbox); | |
273 | + pListe = pListe->suivant; | |
274 | + } | |
275 | + } | |
276 | +} | |
277 | + | |
278 | +/* | |
279 | +Si un enemie est éliminé et qu'il etait le plus bas de sa colonne | |
280 | +(il pouvait drop des bombes) | |
281 | +Alors si il y en a un, l'enemie au dessus de lui (de la meme colonne) | |
282 | +peut maintenant drop des bombes | |
283 | +*/ | |
284 | +void NouveauDroppeurBombe (struct liste_entite** liste, | |
285 | + struct entite* entite) | |
286 | +{ | |
287 | + | |
288 | + int posx = entite->posx; | |
289 | + int posy = entite->posy; | |
290 | + struct liste_entite* pListe = *liste; | |
291 | + struct entite* entite_basse = NULL; | |
292 | + | |
293 | + // On parcourt la liste et on cherche | |
294 | + //l'entité la plus basse ayant la même position x | |
295 | + while (pListe != NULL) | |
296 | + { | |
297 | + //On ne regarde pas les enemies qui sont sur la meme ligne | |
298 | + if (pListe->entite.posy != posy) | |
299 | + { | |
300 | + //Si meme colonne et qu'il n'y a pas d'entite_basse | |
301 | + if (pListe->entite.posx == posx && | |
302 | + entite_basse == NULL) | |
303 | + { | |
304 | + entite_basse = &pListe->entite; | |
305 | + } | |
306 | + | |
307 | + //Si meme colonne mais qu'il y a deja une entite_basse | |
308 | + //On compare la hauteur de l'entite avec l'entite_basse | |
309 | + else if (pListe->entite.posx == posx && | |
310 | + pListe->entite.posy > entite_basse->posy) | |
311 | + { | |
312 | + entite_basse = &pListe->entite; | |
313 | + } | |
314 | + } | |
315 | + | |
316 | + pListe = pListe->suivant; | |
317 | + } | |
318 | + | |
319 | + // Si aucune entité n'est située plus bas que l'entité en question, | |
320 | + //On ne peut pas dropper la bombe | |
321 | + if (entite_basse == NULL) | |
322 | + { | |
323 | + return; | |
324 | + } | |
325 | + | |
326 | + entite_basse->dropbombe = 1; | |
327 | +} | |
328 | + | |
329 | + | |
330 | + | |
331 | +//Fonction Main qui supprime les entités rentrées en collision de leur liste | |
332 | +int SupprimerEntitesEnCollision (struct liste_entite** Liste1, | |
333 | + int L1, | |
334 | + int H1, | |
335 | + struct liste_entite** Liste2, | |
336 | + int L2, | |
337 | + int H2) | |
338 | +{ | |
339 | + | |
340 | + struct liste_entite* collision = CheckCollisionListeListe(*Liste1, | |
341 | + L1, | |
342 | + H1, | |
343 | + *Liste2, | |
344 | + L2, | |
345 | + H2); | |
346 | + if (collision != NULL) | |
347 | + { | |
348 | + // Récupération des entités impliquées | |
349 | + struct entite* Entite1 = &collision->entite; | |
350 | + struct entite* Entite2 = &collision->suivant->entite; | |
351 | + | |
352 | + if (Entite1->dropbombe == 1) | |
353 | + { | |
354 | + NouveauDroppeurBombe(Liste1,Entite1); | |
355 | + } | |
356 | + | |
357 | + if (Entite2->dropbombe == 1) | |
358 | + { | |
359 | + NouveauDroppeurBombe(Liste2,Entite2); | |
360 | + } | |
361 | + | |
362 | + // Suppression de l'entité 1 de la liste 1 | |
363 | + SupprimerEntite(Liste1, Entite1); | |
364 | + // Suppression de l'entité 2 de la liste 2 | |
365 | + SupprimerEntite(Liste2, Entite2); | |
366 | + | |
367 | + afficherLutin (bouillie, | |
368 | + Entite2->posx - hitboxbouillieL/2 + ErreurHitbox, | |
369 | + Entite2->posy - hitboxbouillieH/2 + ErreurHitbox); | |
370 | + return 1; | |
371 | + } | |
372 | + return 0; | |
373 | +} | |
374 | + | |
375 | + | ... | ... |
... | ... | @@ -0,0 +1,44 @@ |
1 | +int CheckCollisionEntiteEntite (struct entite entite1, | |
2 | + int L1, | |
3 | + int H1, | |
4 | + struct entite entite2, | |
5 | + int L2, | |
6 | + int H2); | |
7 | + | |
8 | +struct entite* CheckCollisionListeEntite (struct liste_entite* Liste1, | |
9 | + int L1, | |
10 | + int H1, | |
11 | + struct entite entite2, | |
12 | + int L2, | |
13 | + int H2); | |
14 | + | |
15 | +struct liste_entite* CheckCollisionListeListe (struct liste_entite* Liste1, | |
16 | + int L1, | |
17 | + int H1, | |
18 | + struct liste_entite* Liste2, | |
19 | + int L2, | |
20 | + int H2); | |
21 | + | |
22 | +void Tirer (struct entite joueur, | |
23 | + struct liste_entite** pl); | |
24 | + | |
25 | +void DeplacementTire(struct liste_entite** Liste); | |
26 | + | |
27 | +void action(struct entite* joueur, | |
28 | + char c, | |
29 | + struct liste_entite** tires); | |
30 | + | |
31 | +void MakeBombeDrop (struct liste_entite* enemies, | |
32 | + struct liste_entite** bombes); | |
33 | + | |
34 | +void DeplacementBombe(struct liste_entite** Liste) ; | |
35 | + | |
36 | +void NouveauDroppeurBombe (struct liste_entite** liste, | |
37 | + struct entite* entite); | |
38 | + | |
39 | +int SupprimerEntitesEnCollision (struct liste_entite** Liste1, | |
40 | + int L1, | |
41 | + int H1, | |
42 | + struct liste_entite** Liste2, | |
43 | + int L2, | |
44 | + int H2); | ... | ... |
... | ... | @@ -0,0 +1,80 @@ |
1 | +#include <stdio.h> | |
2 | +#include <stdlib.h> | |
3 | +#include <string.h> | |
4 | + | |
5 | +#include "Liste.h" | |
6 | + | |
7 | +//Crée une entité | |
8 | +struct entite creer_entite (int x, | |
9 | + int y, | |
10 | + int candrop) | |
11 | +{ | |
12 | + struct entite e; | |
13 | + | |
14 | + e.posx = x; | |
15 | + e.posy = y; | |
16 | + e.dropbombe = candrop; | |
17 | + | |
18 | + return e; | |
19 | +} | |
20 | + | |
21 | + | |
22 | +//Ajout en tete une entité dans une liste | |
23 | +void ajout_tete (struct liste_entite** Liste, | |
24 | + struct entite x ) | |
25 | +{ | |
26 | + struct liste_entite *Listetmp=NULL; | |
27 | + | |
28 | + Listetmp = malloc(sizeof(struct liste_entite)); | |
29 | + Listetmp->entite = x; | |
30 | + Listetmp->suivant = *Liste; | |
31 | + | |
32 | + *Liste = Listetmp; | |
33 | +} | |
34 | + | |
35 | + | |
36 | +//Supprime une entite d'une liste | |
37 | +void SupprimerEntite (struct liste_entite** Liste, | |
38 | + struct entite* entite) | |
39 | +{ | |
40 | + struct liste_entite* courant = *Liste; | |
41 | + struct liste_entite* precedent = NULL; | |
42 | + //Ce pointeur precedent va garder en memoire l'entite precedente | |
43 | + //Initialisé à NULL car cela est utile dans le cas ou l'entite est la 1ere | |
44 | + | |
45 | + while (courant != NULL) | |
46 | + { | |
47 | + //Comparaison entre 2 entites | |
48 | + if (memcmp (&courant->entite, | |
49 | + entite, | |
50 | + sizeof(struct entite)) == 0) | |
51 | + { | |
52 | + //Si l'element est le premier | |
53 | + if (precedent == NULL) | |
54 | + { | |
55 | + *Liste = courant->suivant; | |
56 | + } | |
57 | + | |
58 | + else | |
59 | + { | |
60 | + precedent->suivant = courant->suivant; | |
61 | + } | |
62 | + | |
63 | + free(courant); | |
64 | + break; | |
65 | + } | |
66 | + | |
67 | + precedent = courant; | |
68 | + courant = courant->suivant; | |
69 | + } | |
70 | +} | |
71 | + | |
72 | + | |
73 | +//Desallouer une liste entiere | |
74 | +void DesallouerListe (struct liste_entite** Liste) | |
75 | +{ | |
76 | + while(*Liste != NULL) | |
77 | + { | |
78 | + SupprimerEntite(Liste,&((*Liste)->entite)); | |
79 | + } | |
80 | +} | ... | ... |
... | ... | @@ -0,0 +1,29 @@ |
1 | +//dropbombe concerne les entités enemies | |
2 | +//1 les enemies peuvent drop des bombes, 0 ils ne peuvent pas | |
3 | +//Les entites non concernées vallent ont un dropbombe = -1 | |
4 | +struct entite | |
5 | +{ | |
6 | + int posx; | |
7 | + int posy; | |
8 | + int dropbombe; | |
9 | +}; | |
10 | + | |
11 | + | |
12 | +struct liste_entite | |
13 | +{ | |
14 | + struct entite entite; | |
15 | + struct liste_entite *suivant; | |
16 | +}; | |
17 | + | |
18 | + | |
19 | +struct entite creer_entite (int x, | |
20 | + int y, | |
21 | + int bombe); | |
22 | + | |
23 | +void ajout_tete (struct liste_entite** Liste, | |
24 | + struct entite x ); | |
25 | + | |
26 | +void SupprimerEntite (struct liste_entite** Liste, | |
27 | + struct entite* entite); | |
28 | + | |
29 | +void DesallouerListe (struct liste_entite** Liste); | ... | ... |
... | ... | @@ -0,0 +1,37 @@ |
1 | +CC=clang | |
2 | +TARGET=Jeu | |
3 | +CFLAGS=-g -W -Wall -Wextra | |
4 | +LDFLAGS=-I Graphique -l graph -L ../Graphique -l SDL -l SDL_ttf | |
5 | + | |
6 | +default: $(TARGET) | |
7 | + | |
8 | +Liste.o : ../ListeC/Liste.c ../ListeC/Liste.h | |
9 | + clang $(CFLAGS) -c ../ListeC/Liste.c | |
10 | + | |
11 | +Monstre.o : ../Monstre/Monstre.c ../Monstre/Monstre.h | |
12 | + clang $(CFLAGS) -c ../Monstre/Monstre.c | |
13 | + | |
14 | +Interactif.o : ../Interactif/Interactif.c ../Interactif/Interactif.h | |
15 | + clang $(CFLAGS) -c ../Interactif/Interactif.c | |
16 | + | |
17 | +init.o : init.c init.h | |
18 | + clang $(CFLAGS) -c init.c | |
19 | + | |
20 | +main.o : main.c | |
21 | + clang $(CFLAGS) -c main.c | |
22 | + | |
23 | + | |
24 | +$(TARGET): Liste.o main.o Monstre.o Interactif.o init.o | |
25 | + clang main.o Liste.o Monstre.o Interactif.o init.o -o $(TARGET) $(LDFLAGS) | |
26 | + | |
27 | +.PHONY: clean | |
28 | +clean: | |
29 | + rm -f *.o | |
30 | + rm -f $(TARGET) | |
31 | + | |
32 | +tidy : main.c ../ListeC/Liste.c ../Monstre/Monstre.c ../Interactif/Interactif.c init.c | |
33 | + $(CC)-tidy main.c ../ListeC/Liste.c ../Monstre/Monstre.c ../Interactif/Interactif.c init.c --checks="readability-*" -header-filter=.* | |
34 | + | |
35 | +format : | |
36 | + $(CC)-format -style='Microsoft' main.c ../ListeC/Liste.c ../Monstre/Monstre.c ../Interactif/Interactif.c init.c | |
37 | + | ... | ... |
... | ... | @@ -0,0 +1,244 @@ |
1 | +#include <stdio.h> | |
2 | +#include "../Graphique/libgraph.h" | |
3 | +#include "../ListeC/Liste.h" | |
4 | +#include "../Interactif/Interactif.h" | |
5 | +#include "init.h" | |
6 | + | |
7 | +#define TailleX 500 | |
8 | +#define TailleY 500 | |
9 | +#define Sol 475 | |
10 | +#define ErreurHitbox 2 | |
11 | +#define PositionX_1 (TailleX / 2) | |
12 | +#define PositionY_1 (TailleY / 2) | |
13 | +#define PositionY_2 (TailleY / 4) | |
14 | + | |
15 | +#define JoueurX (TailleX / 2) | |
16 | +#define JoueurY (9 * TailleY / 10) | |
17 | + | |
18 | +#define Nom "Space Invaders" | |
19 | +#define TaillePolice1 (TailleX / 10) | |
20 | +#define TaillePolice2 (TailleX / 20) | |
21 | +#define TailleChaineMax 30 | |
22 | + | |
23 | +//Ces variables sont globales car utilisées dans plusieurs .c | |
24 | +//Toutes les hitbox sont initialisées 1 fois puis sont des constantes | |
25 | +struct entite joueur; | |
26 | + | |
27 | +static const char policeDefaut[]= | |
28 | +"/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf"; | |
29 | + | |
30 | +int canon = 0; | |
31 | +int missile = 0; | |
32 | +int enemie1_1 = 0; | |
33 | +int enemie1_2 = 0; | |
34 | +int bouillie = 0; | |
35 | +int bombe = 0; | |
36 | + | |
37 | +int hitboxcanonL = 0; | |
38 | +int hitboxcanonH = 0; | |
39 | +int hitboxmissileL = 0; | |
40 | +int hitboxmissileH = 0; | |
41 | +int hitboxenemieL = 0; | |
42 | +int hitboxenemieH = 0; | |
43 | +int hitboxbouillieL = 0; | |
44 | +int hitboxbouillieH = 0; | |
45 | +int hitboxbombeL = 0; | |
46 | +int hitboxbombeH = 0; | |
47 | + | |
48 | +//Initialisation des variables globales pour le main | |
49 | +void initialiser() | |
50 | +{ | |
51 | + canon = chargerLutin ("../../Lutins/invader_canon.bmp", | |
52 | + COULEUR_NOIR); | |
53 | + missile = chargerLutin ("../../Lutins/invader_missile.bmp", | |
54 | + COULEUR_NOIR); | |
55 | + enemie1_1 = chargerLutin ("../../Lutins/invader_monstre2_1.bmp", | |
56 | + COULEUR_NOIR); | |
57 | + enemie1_2 = chargerLutin ("../../Lutins/invader_monstre2_2.bmp", | |
58 | + COULEUR_NOIR); | |
59 | + bouillie = chargerLutin ("../../Lutins/invader_monstre_bouillie.bmp", | |
60 | + COULEUR_NOIR); | |
61 | + bombe = chargerLutin ("../../Lutins/invader_bombe.bmp", | |
62 | + COULEUR_NOIR); | |
63 | + | |
64 | + tailleLutin (canon, | |
65 | + &hitboxcanonL, | |
66 | + &hitboxcanonH); | |
67 | + | |
68 | + tailleLutin (missile, | |
69 | + &hitboxmissileL, | |
70 | + &hitboxmissileH); | |
71 | + //La taille des enemmies que j'utilise est la meme dans ces 2 variantes | |
72 | + tailleLutin (enemie1_1, | |
73 | + &hitboxenemieL, | |
74 | + &hitboxenemieH); | |
75 | + | |
76 | + tailleLutin (bouillie, | |
77 | + &hitboxbouillieL, | |
78 | + &hitboxbouillieH); | |
79 | + | |
80 | + tailleLutin (bombe, | |
81 | + &hitboxbombeL, | |
82 | + &hitboxbombeH); | |
83 | + | |
84 | +} | |
85 | + | |
86 | +//Initialisation des coordonnées du joueur pour le main | |
87 | +void initialiserjoueur() | |
88 | +{ | |
89 | + joueur.posx = JoueurX; | |
90 | + joueur.posy = JoueurY; | |
91 | + joueur.dropbombe = -1; | |
92 | +} | |
93 | + | |
94 | +//Page de démarage du jeu | |
95 | +char pagedemarrage() | |
96 | +{ | |
97 | + char input = '\0'; | |
98 | + evenement even = 0; | |
99 | + int Largeur = 0; | |
100 | + int Hauteur = 0; | |
101 | + char jouer[] = "Appuyer sur j pour Jouer"; | |
102 | + char quitter[] = "Appuyer ailleurs pour Quitter"; | |
103 | + | |
104 | + choisirPolice (policeDefaut, TaillePolice2); | |
105 | + int LutinJouer = lutinTexte (jouer, COULEUR_BLANC); | |
106 | + int LutinQuitter = lutinTexte (quitter, COULEUR_BLANC); | |
107 | + | |
108 | + choisirPolice (policeDefaut, TaillePolice1); | |
109 | + int LutinBienvenue = lutinTexte (Nom, COULEUR_VERT); | |
110 | + | |
111 | + rectanglePlein (0, | |
112 | + 0, | |
113 | + TailleX, | |
114 | + TailleY, | |
115 | + COULEUR_NOIR); | |
116 | + | |
117 | + tailleLutin (LutinBienvenue, | |
118 | + &Largeur, | |
119 | + &Hauteur); | |
120 | + afficherLutin (LutinBienvenue, | |
121 | + PositionX_1 - Largeur / 2, | |
122 | + PositionY_2 + Hauteur / 2); | |
123 | + | |
124 | + tailleLutin (LutinJouer, | |
125 | + &Largeur, | |
126 | + &Hauteur); | |
127 | + afficherLutin (LutinJouer, | |
128 | + PositionX_1 - Largeur / 2, | |
129 | + PositionY_1 - Hauteur / 2); | |
130 | + | |
131 | + tailleLutin (LutinQuitter, | |
132 | + &Largeur, | |
133 | + &Hauteur); | |
134 | + afficherLutin (LutinQuitter, | |
135 | + PositionX_1 - Largeur / 2, | |
136 | + PositionY_1 + Hauteur / 2); | |
137 | + | |
138 | + majSurface(); | |
139 | + attendreEvenement (); | |
140 | + | |
141 | + lireEvenement (&even, | |
142 | + &input, | |
143 | + NULL); | |
144 | + while (input == '\0') | |
145 | + { | |
146 | + lireEvenement (&even, | |
147 | + &input, | |
148 | + NULL); | |
149 | + } | |
150 | + return input; | |
151 | +} | |
152 | + | |
153 | +//Page en cas de mort dans le jeu | |
154 | +void pagemort (int nbr_vie) | |
155 | +{ | |
156 | + int Largeur = 0; | |
157 | + int Hauteur = 0; | |
158 | + char mort[] = "Vous etes mort"; | |
159 | + char vie[TailleChaineMax] = "\0"; | |
160 | + sprintf (vie, | |
161 | + "Nombre de vies restantes : %d", | |
162 | + nbr_vie); | |
163 | + /* | |
164 | + sprintf crée un warning mais celui-ci ne peut pas crée d'erreur car | |
165 | + TailleChaineMax ne pourra pas excéder 30 si le nombre de vie reste "normal" | |
166 | + sprintf_s ne fonctionne pas pour mon programme (invalid in C99) | |
167 | + */ | |
168 | + | |
169 | + choisirPolice (policeDefaut, TaillePolice1); | |
170 | + int LutinMort = lutinTexte(mort, COULEUR_ROUGE); | |
171 | + | |
172 | + choisirPolice (policeDefaut, TaillePolice2); | |
173 | + int LutinVie = lutinTexte(vie, COULEUR_BLANC); | |
174 | + | |
175 | + rectanglePlein (0, | |
176 | + 0, | |
177 | + TailleX, | |
178 | + TailleY, | |
179 | + COULEUR_NOIR); | |
180 | + | |
181 | + tailleLutin (LutinMort, | |
182 | + &Largeur, | |
183 | + &Hauteur); | |
184 | + afficherLutin (LutinMort, | |
185 | + PositionX_1 - Largeur / 2, | |
186 | + PositionY_2 + Hauteur / 2); | |
187 | + | |
188 | + tailleLutin (LutinVie, | |
189 | + &Largeur, | |
190 | + &Hauteur); | |
191 | + afficherLutin (LutinVie, | |
192 | + PositionX_1 - Largeur / 2, | |
193 | + PositionY_1 - Hauteur / 2); | |
194 | +} | |
195 | + | |
196 | +//Page de GameOver du jeu | |
197 | +void pageGameOver() | |
198 | +{ | |
199 | + int Largeur = 0; | |
200 | + int Hauteur = 0; | |
201 | + char fin[] = "GAME OVER"; | |
202 | + | |
203 | + choisirPolice(policeDefaut, TaillePolice1); | |
204 | + int LutinFin = lutinTexte(fin, COULEUR_ROUGE); | |
205 | + | |
206 | + rectanglePlein (0, | |
207 | + 0, | |
208 | + TailleX, | |
209 | + TailleY, | |
210 | + COULEUR_NOIR); | |
211 | + | |
212 | + tailleLutin (LutinFin, | |
213 | + &Largeur, | |
214 | + &Hauteur); | |
215 | + afficherLutin (LutinFin, | |
216 | + PositionX_1 - Largeur / 2, | |
217 | + PositionY_1 - Hauteur / 2); | |
218 | + | |
219 | +} | |
220 | + | |
221 | +//Page de Victoire du jeu | |
222 | +void pageVictoire() | |
223 | +{ | |
224 | + int Largeur = 0; | |
225 | + int Hauteur = 0; | |
226 | + char fin[] = "VICTOIRE"; | |
227 | + | |
228 | + choisirPolice(policeDefaut, TaillePolice1); | |
229 | + int LutinFin = lutinTexte(fin, COULEUR_VERT); | |
230 | + | |
231 | + rectanglePlein (0, | |
232 | + 0, | |
233 | + TailleX, | |
234 | + TailleY, | |
235 | + COULEUR_NOIR); | |
236 | + | |
237 | + tailleLutin (LutinFin, | |
238 | + &Largeur, | |
239 | + &Hauteur); | |
240 | + afficherLutin (LutinFin, | |
241 | + PositionX_1 - Largeur / 2, | |
242 | + PositionY_1 - Hauteur / 2); | |
243 | + | |
244 | +} | ... | ... |
... | ... | @@ -0,0 +1,28 @@ |
1 | +extern int canon; | |
2 | +extern int missile; | |
3 | +extern int enemie1_1; | |
4 | +extern int enemie1_2; | |
5 | +extern int bouillie; | |
6 | +extern int bombe; | |
7 | + | |
8 | +extern struct entite joueur; | |
9 | +extern char Nom[]; | |
10 | +extern char input; | |
11 | + | |
12 | +extern int hitboxcanonL; | |
13 | +extern int hitboxcanonH; | |
14 | +extern int hitboxmissileL; | |
15 | +extern int hitboxmissileH; | |
16 | +extern int hitboxenemieL; | |
17 | +extern int hitboxenemieH; | |
18 | +extern int hitboxbouillieL; | |
19 | +extern int hitboxbouillieH; | |
20 | +extern int hitboxbombeL; | |
21 | +extern int hitboxbombeH; | |
22 | + | |
23 | +void initialiser(); | |
24 | +void initialiserjoueur(); | |
25 | +char pagedemarrage(); | |
26 | +void pagemort(int nbr_vie); | |
27 | +void pageGameOver(); | |
28 | +void pageVictoire(); | ... | ... |
... | ... | @@ -0,0 +1,267 @@ |
1 | +#include <unistd.h> | |
2 | +#include <SDL/SDL.h> | |
3 | +#include "../Graphique/libgraph.h" | |
4 | +#include "../ListeC/Liste.h" | |
5 | +#include "../Monstre/Monstre.h" | |
6 | +#include "../Interactif/Interactif.h" | |
7 | +#include "init.h" | |
8 | + | |
9 | +#define TailleX 500 | |
10 | +#define TailleY 500 | |
11 | +#define Sol 475 | |
12 | +#define EpaisseurSol 2 | |
13 | +#define ErreurHitbox 2 | |
14 | + | |
15 | +#define Nom "Space Invader" | |
16 | +#define NombreEnemieParLigne 8 | |
17 | +#define NombreLigneEnemies 3 | |
18 | +#define NombreVie 3 | |
19 | + | |
20 | +#define BombeRandomFixe 50 | |
21 | +#define BombeRandomAlea 30 | |
22 | + | |
23 | +//Pour augmenter les deplacements des enemies, vous pouvez: | |
24 | +//Augmenter VitesseDeplacementEnemie | |
25 | +//Tout les VitesseDeplacementEnemie tours de boucle les enemies se déplace | |
26 | +#define VitesseDeplacementEnemie 2 | |
27 | +// Ou augmenter le PasEnemie (Ecart entre la position n et n+1) | |
28 | +#define PasEnemie 1 | |
29 | +#define AffichageImageEnemie 8 | |
30 | + | |
31 | +#define Delai0_2s 200 | |
32 | +#define Delai0_5s 500 | |
33 | +#define Delai2s 2000 | |
34 | + | |
35 | +#define VitesseTourdeBoucle 20 | |
36 | + | |
37 | +int main() | |
38 | +{ | |
39 | + creerSurface(TailleX,TailleY,Nom); | |
40 | + | |
41 | + initialiser(); | |
42 | + initialiserjoueur(); | |
43 | + | |
44 | + struct liste_entite* ListeEnemies = NULL; | |
45 | + struct liste_entite* ListeTires = NULL; | |
46 | + struct liste_entite* ListeBombes = NULL; | |
47 | + | |
48 | + //joueur est dans une liste afin d'utiliser des fonctions deja crée | |
49 | + struct liste_entite* Ljoueur = NULL; | |
50 | + ajout_tete(&Ljoueur,joueur); | |
51 | + | |
52 | + | |
53 | + LigneEnemie(&ListeEnemies, | |
54 | + NombreEnemieParLigne, | |
55 | + NombreLigneEnemies); | |
56 | + int SensVague = 1; | |
57 | + | |
58 | + char input = '\0'; | |
59 | + evenement even = 0; | |
60 | + | |
61 | + int TourdeBoucle = 0; | |
62 | + | |
63 | + int TimeAlea = 0; | |
64 | + int CheckAlea = 0; | |
65 | + | |
66 | + int mort = 0; | |
67 | + int nbr_vie = NombreVie; | |
68 | + int QuelMonstre = 0; | |
69 | + | |
70 | + int coeur = chargerLutin ("../../Lutins/Coeur.bmp", | |
71 | + COULEUR_NOIR); | |
72 | + int hitboxcoeurL = 0; | |
73 | + int hitboxcoeurH = 0; | |
74 | + tailleLutin (coeur, | |
75 | + &hitboxcoeurL, | |
76 | + &hitboxcoeurH); | |
77 | + | |
78 | + if ( pagedemarrage() != 'j') | |
79 | + { | |
80 | + return 0; | |
81 | + } | |
82 | + SDL_Delay(Delai0_5s); | |
83 | + | |
84 | + //Bouble principale | |
85 | + while(input!='m') | |
86 | + { | |
87 | + //Si le joueur est mort | |
88 | + if (mort == 1) | |
89 | + { | |
90 | + nbr_vie-=1; | |
91 | + //Si il lui reste des vies | |
92 | + if (nbr_vie > 0) | |
93 | + { | |
94 | + pagemort(nbr_vie); | |
95 | + majSurface(); | |
96 | + SDL_Delay(Delai2s); | |
97 | + mort = 0; | |
98 | + } | |
99 | + //Si il n'a plus de vie | |
100 | + else | |
101 | + { | |
102 | + pageGameOver(); | |
103 | + majSurface(); | |
104 | + SDL_Delay(Delai2s); | |
105 | + return 0; | |
106 | + } | |
107 | + //On ajoute de nouveau le joueur précedement supprimé à sa liste | |
108 | + ajout_tete(&Ljoueur,joueur); | |
109 | + //Desallocation dynamique des listes | |
110 | + DesallouerListe(&ListeTires); | |
111 | + DesallouerListe(&ListeBombes); | |
112 | + } | |
113 | + | |
114 | + //Affichage Rectangle Noir sur toute la page | |
115 | + rectanglePlein(0, | |
116 | + 0, | |
117 | + TailleX, | |
118 | + TailleY, | |
119 | + COULEUR_NOIR); | |
120 | + | |
121 | + //Affichage des coeurs de vie | |
122 | + for (int i = 1 ; i <= nbr_vie; i++) | |
123 | + { | |
124 | + afficherLutin(coeur, | |
125 | + TailleX - i * hitboxcoeurL, | |
126 | + Sol); | |
127 | + } | |
128 | + | |
129 | + //Affichage du Sol | |
130 | + rectanglePlein(0, | |
131 | + Sol, | |
132 | + TailleX, | |
133 | + EpaisseurSol, | |
134 | + COULEUR_VERT); | |
135 | + | |
136 | + //Affichage du joueur | |
137 | + afficherLutin(canon, | |
138 | + Ljoueur->entite.posx - hitboxcanonL/2 + ErreurHitbox, | |
139 | + Ljoueur->entite.posy); | |
140 | + | |
141 | + //Affichage des ListeEnemies | |
142 | + if (QuelMonstre > 2 * AffichageImageEnemie) | |
143 | + { | |
144 | + QuelMonstre = 0; | |
145 | + } | |
146 | + if (QuelMonstre <= AffichageImageEnemie) | |
147 | + { | |
148 | + AfficherEnemie (ListeEnemies, | |
149 | + enemie1_1, | |
150 | + hitboxenemieL, | |
151 | + hitboxenemieH); | |
152 | + QuelMonstre += 1; | |
153 | + } | |
154 | + else | |
155 | + { | |
156 | + AfficherEnemie (ListeEnemies, | |
157 | + enemie1_2, | |
158 | + hitboxenemieL, | |
159 | + hitboxenemieH); | |
160 | + QuelMonstre += 1; | |
161 | + } | |
162 | + /* | |
163 | + Systeme pour faire drop une bombe dans un temps aléatoire | |
164 | + Mise en place d'un timer | |
165 | + TimeAlea représente le nombre de tour de boucle à éffectuer | |
166 | + */ | |
167 | + if (TimeAlea == 0) | |
168 | + { | |
169 | + //50 tour de boucle minimum + une valeur de 0 à 31 | |
170 | + TimeAlea = rand() % BombeRandomAlea + BombeRandomFixe; | |
171 | + //Il y a un warning car rand() à une valeur limite | |
172 | + } | |
173 | + /* | |
174 | + CheckAlea est incrémenté de 1 à chaque tour de boucle | |
175 | + Lorsque celui ci vaut TimeAlea on peut drop une bombe | |
176 | + On reset à 0 le Timer et le Check aprés avoir Drop une bombe | |
177 | + */ | |
178 | + if (CheckAlea == TimeAlea) | |
179 | + { | |
180 | + MakeBombeDrop(ListeEnemies, | |
181 | + &ListeBombes); | |
182 | + TimeAlea=0; | |
183 | + CheckAlea=0; | |
184 | + } | |
185 | + | |
186 | + //Gestion des evenements clavier | |
187 | + //On ne peut appuyer que sur une seule touche à la fois | |
188 | + lireEvenement (&even, | |
189 | + &input, | |
190 | + NULL); | |
191 | + if (even == toucheBas) | |
192 | + { | |
193 | + action(&Ljoueur->entite, | |
194 | + input, | |
195 | + &ListeTires); | |
196 | + } | |
197 | + | |
198 | + //Deplacement des enemies tout les X tours de boucle | |
199 | + if (TourdeBoucle == VitesseDeplacementEnemie) | |
200 | + { | |
201 | + DeplacementEnemie(ListeEnemies, | |
202 | + &SensVague, | |
203 | + PasEnemie); | |
204 | + TourdeBoucle = 0; | |
205 | + } | |
206 | + | |
207 | + //Deplacement des Tires et Bombes | |
208 | + DeplacementTire(&ListeTires); | |
209 | + DeplacementBombe(&ListeBombes); | |
210 | + | |
211 | + //Supression si collision des Tires et Enemies | |
212 | + SupprimerEntitesEnCollision(&ListeTires, | |
213 | + hitboxmissileL, | |
214 | + hitboxmissileH, | |
215 | + &ListeEnemies, | |
216 | + hitboxenemieL, | |
217 | + hitboxenemieH); | |
218 | + | |
219 | + //Supression si collision des Bombes et Joueur | |
220 | + if (SupprimerEntitesEnCollision(&ListeBombes, | |
221 | + hitboxbombeL, | |
222 | + hitboxbombeH, | |
223 | + &Ljoueur, | |
224 | + hitboxcanonL, | |
225 | + hitboxcanonH) == 1) | |
226 | + { | |
227 | + mort = 1; | |
228 | + majSurface(); | |
229 | + SDL_Delay(Delai0_2s); | |
230 | + } | |
231 | + | |
232 | + //Supression si collision des Enemies et Joueur | |
233 | + if (SupprimerEntitesEnCollision(&ListeEnemies, | |
234 | + hitboxenemieL, | |
235 | + hitboxenemieH, | |
236 | + &Ljoueur, | |
237 | + hitboxcanonL, | |
238 | + hitboxcanonH) == 1) | |
239 | + { | |
240 | + pageGameOver(); | |
241 | + majSurface(); | |
242 | + SDL_Delay(Delai2s); | |
243 | + return 0; | |
244 | + } | |
245 | + | |
246 | + //Si il n'y a plus d'enemies, c'est une victoire !!! | |
247 | + if (ListeEnemies == NULL) | |
248 | + { | |
249 | + majSurface(); | |
250 | + SDL_Delay(Delai0_2s); | |
251 | + pageVictoire(); | |
252 | + majSurface(); | |
253 | + SDL_Delay(Delai2s); | |
254 | + return 0; | |
255 | + } | |
256 | + | |
257 | + | |
258 | + majSurface(); | |
259 | + | |
260 | + TourdeBoucle += 1; | |
261 | + CheckAlea += 1; | |
262 | + | |
263 | + SDL_Delay(VitesseTourdeBoucle); | |
264 | + | |
265 | + } | |
266 | + return 0; | |
267 | +} | ... | ... |
... | ... | @@ -0,0 +1,103 @@ |
1 | +#include <stdlib.h> | |
2 | +#include "../Graphique/libgraph.h" | |
3 | +#include "../ListeC/Liste.h" | |
4 | +#include "Monstre.h" | |
5 | + | |
6 | +#define TailleX 500 | |
7 | +#define TailleY 500 | |
8 | +#define ErreurHitbox 2 | |
9 | + | |
10 | +#define Taille1_10 (TailleX / 10) | |
11 | +#define Taille9_10 (9 * TailleX / 10) | |
12 | +#define TailleJump 30 | |
13 | + | |
14 | +//Sens = 1 -> Va vers la droite | |
15 | +//Sens = 0 -> Va vers la gauche | |
16 | +void DeplacementEnemie(struct liste_entite* Liste, | |
17 | + int* SensDeplacement, | |
18 | + int Pas) | |
19 | +{ | |
20 | + //ind sert à savoir si je dois changer de sens ou non | |
21 | + int ind = 0; | |
22 | + struct liste_entite* pListe = Liste; | |
23 | + | |
24 | + while (pListe != NULL) | |
25 | + { | |
26 | + pListe->entite.posx += (*SensDeplacement == 1) ? Pas : -Pas; | |
27 | + if (pListe->entite.posx >= Taille9_10) | |
28 | + { | |
29 | + ind = 1; | |
30 | + } | |
31 | + | |
32 | + else if (pListe->entite.posx <= Taille1_10) | |
33 | + { | |
34 | + ind = 2; | |
35 | + } | |
36 | + | |
37 | + pListe = pListe->suivant; | |
38 | + } | |
39 | + | |
40 | + if (ind != 0) | |
41 | + { | |
42 | + *SensDeplacement = (ind == 1) ? 0 : 1; | |
43 | + struct liste_entite* p2Liste = Liste; | |
44 | + | |
45 | + while (p2Liste != NULL) | |
46 | + { | |
47 | + p2Liste->entite.posy += TailleJump; | |
48 | + p2Liste = p2Liste->suivant; | |
49 | + } | |
50 | + } | |
51 | +} | |
52 | + | |
53 | +//Création de lignes d'entités enemies dans la liste enemies | |
54 | +void LigneEnemie (struct liste_entite** ListeEnemie, | |
55 | + int nbr_enemies, | |
56 | + int nbr_rangee) | |
57 | +{ | |
58 | + | |
59 | + for (int j = 1; j <= nbr_rangee; j++) | |
60 | + { | |
61 | + int compteurY = j * Taille1_10; | |
62 | + int compteurX = TailleX / (nbr_enemies+1); | |
63 | + | |
64 | + for (int i = 0; i < nbr_enemies; i++) | |
65 | + { | |
66 | + if (j == nbr_rangee) | |
67 | + { | |
68 | + ajout_tete(ListeEnemie, | |
69 | + creer_entite(compteurX, | |
70 | + compteurY, | |
71 | + 1)); | |
72 | + compteurX += 2 * TailleX / (3 * nbr_enemies); | |
73 | + } | |
74 | + | |
75 | + else | |
76 | + { | |
77 | + ajout_tete(ListeEnemie, | |
78 | + creer_entite(compteurX, | |
79 | + compteurY, | |
80 | + 0)); | |
81 | + compteurX += 2 * TailleX / (3 * nbr_enemies); | |
82 | + } | |
83 | + } | |
84 | + } | |
85 | +} | |
86 | + | |
87 | +//Affichage des enemies centrés dans leur hitbox | |
88 | +void AfficherEnemie (struct liste_entite* Liste, | |
89 | + int lutin, | |
90 | + int Largeur, | |
91 | + int Hauteur) | |
92 | +{ | |
93 | + | |
94 | + struct liste_entite* pListe = Liste; | |
95 | + | |
96 | + while (pListe != NULL) | |
97 | + { | |
98 | + afficherLutin(lutin, | |
99 | + pListe->entite.posx - Largeur / 2 + ErreurHitbox, | |
100 | + pListe->entite.posy - Hauteur / 2 + ErreurHitbox); | |
101 | + pListe=pListe->suivant; | |
102 | + } | |
103 | +} | ... | ... |
... | ... | @@ -0,0 +1,12 @@ |
1 | +void DeplacementEnemie(struct liste_entite* Liste, | |
2 | + int* SensDeplacement, | |
3 | + int Pas); | |
4 | + | |
5 | +void LigneEnemie (struct liste_entite** ListeEnemie, | |
6 | + int nbr_enemies, | |
7 | + int nbr_rangee); | |
8 | + | |
9 | +void AfficherEnemie (struct liste_entite* Liste, | |
10 | + int lutin, | |
11 | + int Largeur, | |
12 | + int Hauteur); | ... | ... |