Bonjour,
Voilà j'essaye de gérer les collisions entre une balle et plusieurs segments pour plus tard mettre en place le jeu pong. Pour cela je représente ma balle par une image toute simple au format bmp. Le problème c'est que l'origine de l'image est située en haut à gauche. Le terrain forme un rectangle, donc lorsqu'il y a un contact en haut ou à gauche tout va bien, en revanche à droite et en bas, la balle disparaît puis revient...
Il doit y avoir une astuce, un jeu de changement de repère pour placer l'origine de la balle au centre ou autre mais je bloque...
Je vous montre mon code :
geometrie.c
geometrie.h
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130 #include <stdio.h> #include <stdlib.h> #include <math.h> #include <SDL/SDL.h> #include "geometrie.h" #include "pong.h" Vecteur creer_vecteur(Point a, Point b) { Vecteur vecteur; vecteur.x = b.x - a.x; vecteur.y = b.y - a.y; return vecteur; } int norme_carre(Vecteur u) { return u.x * u.x + u.y * u.y; } int produit_scalaire(Vecteur u, Vecteur v) { return u.x * v.x + u.y * v.y; } int produit_vectoriel(Vecteur u, Vecteur v) { return u.x * v.y - v.x * u.y; } int intersection_segments(Segment a, Segment b, Point* i) { Vecteur ab; Vecteur ac; Vecteur cd; Vecteur n_ab; Vecteur n_cd; int ps; double t; ab = creer_vecteur(a.a, a.b); ac = creer_vecteur(a.a, b.a); cd = creer_vecteur(b.a, b.b); n_ab.x = - ab.y; n_ab.y = ab.x; n_cd.x = - cd.y; n_cd.y = cd.x; if ((ps = produit_scalaire(n_ab, cd)) == 0) { return 0; } if ((t = (double) - produit_scalaire(n_ab, ac) / ps) < 0 || t > 1) { return 0; } if ((t = (double) - produit_scalaire(n_cd, ac) / ps) < 0 || t > 1) { return 0; } i->x = a.a.x + t * ab.x; i->y = a.a.y + t * ab.y; return 1; } int collision_balle_segment(Balle* balle, Segment s) { Vecteur ab; Vecteur n_ab; Segment s_tmp; Point position_suivante; Point i; int ps; double rapport; ab = creer_vecteur(s.a, s.b); n_ab.x = - ab.y; n_ab.y = ab.x; if ((ps = produit_scalaire(n_ab, balle->vitesse)) > 0) { return 0; } position_suivante.x = balle->position.x + balle->vitesse.x; position_suivante.y = balle->position.y + balle->vitesse.y; s_tmp.a.x = balle->position.x; s_tmp.a.y = balle->position.y; s_tmp.b.x = position_suivante.x; s_tmp.b.y = position_suivante.y; if (intersection_segments(s, s_tmp, &i)) { rapport = (double) - 2 * ps / norme_carre(n_ab); balle->vitesse.x += rapport * n_ab.x; balle->vitesse.y += rapport * n_ab.y; return 1; } return 0; } int collision_balle_segments(Balle* balle, Segment segments[]) { int i; for (i = 0; i < 4; i++) { if (collision_balle_segment(balle, segments[i])) { return 1; } } return 0; }
pong.c
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45 #ifndef GEOMETRIE_H #define GEOMETRIE_H typedef struct vecteur { int x; int y; } Point, Vecteur; typedef struct segment { Point a; Point b; } Segment; typedef struct balle { SDL_Surface* image; SDL_Rect position; Vecteur vitesse; int rayon; } Balle; Vecteur creer_vecteur(Point a, Point b); int norme_carre(Vecteur u); int produit_scalaire(Vecteur u, Vecteur v); int produit_vectoriel(Vecteur u, Vecteur v); int intersection_segments(Segment a, Segment b, Point* i); int intersection_balle_segment(Balle* balle, Segment s); int intersection_balle_segments(Balle* balle, Segment segments[]); #endif
Voilà merci à ceux qui prendront le temps de m'aider ;-).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118 #include <stdio.h> #include <stdlib.h> #include <SDL/SDL.h> #include "geometrie.h" #include "pong.h" #define LARGEUR_FENETRE 640 #define HAUTEUR_FENETRE 480 #define HAUT 0 #define DROITE 1 #define BAS 2 #define GAUCHE 3 void initialiser_balle(SDL_Surface* ecran, Balle* balle) { balle->image = SDL_LoadBMP("balle.bmp"); balle->rayon = 10; balle->position.x = 50; balle->position.y = 50; balle->vitesse.x = 1; balle->vitesse.y = 1; } void initialiser_terrain(Segment terrain[]) { terrain[HAUT].a.x = 0; terrain[HAUT].a.y = 0; terrain[HAUT].b.x = LARGEUR_FENETRE; terrain[HAUT].b.y = 0; terrain[DROITE].a.x = LARGEUR_FENETRE; terrain[DROITE].a.y = 0; terrain[DROITE].b.x = LARGEUR_FENETRE; terrain[DROITE].b.y = HAUTEUR_FENETRE; terrain[BAS].a.x = LARGEUR_FENETRE; terrain[BAS].a.y = HAUTEUR_FENETRE; terrain[BAS].b.x = 0; terrain[BAS].b.y = HAUTEUR_FENETRE; terrain[GAUCHE].a.x = 0; terrain[GAUCHE].a.y = HAUTEUR_FENETRE; terrain[GAUCHE].b.x = 0; terrain[GAUCHE].b.y = 0; } void deplacer_balle(SDL_Surface* ecran, Balle* balle) { balle->position.x += balle->vitesse.x; balle->position.y += balle->vitesse.y; SDL_Delay(30); SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 0, 0, 0)); SDL_BlitSurface(balle->image, NULL, ecran, &(balle->position)); } void gerer_evenement(SDL_Event* evenement, int* continuer) { switch(evenement->type) { case SDL_QUIT: *continuer = 0; } } void jeu(SDL_Surface* ecran) { SDL_Event evenement; Balle balle; Segment segments[4]; int continuer = 1; initialiser_balle(ecran, &balle); initialiser_terrain(segments); SDL_BlitSurface(balle.image, NULL, ecran, &balle.position); SDL_Flip(ecran); while (continuer) { SDL_PollEvent(&evenement); gerer_evenement(&evenement, &continuer); if (!collision_balle_segments(&balle, segments)) { deplacer_balle(ecran, &balle); } SDL_Flip(ecran); } } int main(void) { SDL_Surface* ecran; if (SDL_Init(SDL_INIT_VIDEO) == -1) { fprintf(stderr, "Initialisation de la SDL impossible.\n"); exit(EXIT_FAILURE); } if ((ecran = SDL_SetVideoMode(640, 480, 32, SDL_HWSURFACE)) == NULL) { fprintf(stderr, "Initialisation du mode video impossible.\n"); exit(EXIT_FAILURE); } jeu(ecran); SDL_Quit(); return EXIT_SUCCESS; }
Bye
Partager