1 #include <QApplication>
2 #include <DrawingWindow.h>
8 /* Note : les coordonnées réelles vont de -100 à +100 en abscisse, et
9 * de -10 à +140 en ordonnée
12 const float PI = 4.0 * atan(1.0);
14 const float rXMin = -100.0;
15 const float rXMax = 100.0;
16 const float rYMin = -10.0;
17 const float rYMax = 140.0;
19 const float hauteurMin = 10;
20 const float hauteurMax = 130;
21 const float largeurMin = 40;
22 const float largeurMax = 150;
24 const float largeurChateau = 8.5;
25 const float hauteurChateau = 7;
27 const float positionChateau1 = -85.0;
28 const float positionChateau2 = 85.0;
31 const float k = 0.005;
32 const float dt = 0.05;
40 /* Retourne un nombre pseudo-aléatoire compris entre 0 et le paramètre
43 float frand(float min, float max)
45 static bool first = true;
50 return min + (max - min)* (rand() / (RAND_MAX + 1.0));
53 float deg2rad(float deg)
55 return deg * PI / 180.0;
58 // conversion coordonnées réelles -> coordonnées fenêtre
59 int rtowX(const DrawingWindow& w, float rx)
61 return (int )roundf(w.width * (rx - rXMin) / (rXMax - rXMin + 1.0));
64 int rtowY(const DrawingWindow& w, float ry)
66 return (int )roundf(w.height * (rYMax - ry) / (rYMax - rYMin + 1.0));
69 // conversion coordonnées réelles -> coordonnées fenêtre
70 float wtorX(const DrawingWindow& w, int wx)
72 return (rXMax - rXMin + 1.0) * wx / w.width + rXMin;
75 float wtorY(const DrawingWindow& w, int wy)
77 return -(rYMax - rYMin + 1.0) * wy / w.height - rYMax;
80 float hauteurMontagne(float largeur, float hauteur, float x)
82 float rx = 2.0 * x / largeur;
83 return hauteur * (1.0 - rx * rx);
86 void dessineTerrain(DrawingWindow& w, float largeur, float hauteur)
88 int y0 = rtowY(w, 0) + 1;
89 int xmin = rtowX(w, -largeur / 2.0) - 1;
90 int xmax = rtowX(w, largeur / 2.0) + 1;
91 w.setColor("forestgreen");
92 for (int x = xmin; x <= xmax; x++) {
93 float rx = wtorX(w, x);
94 float ry = hauteurMontagne(largeur, hauteur, rx);
97 w.drawLine(x, y0, x, y);
100 w.fillRect(0, y0 + 1, w.width - 1, w.height - 1);
103 void dessineChateau(DrawingWindow& w, float position)
106 w.setColor("darkslategray");
107 int y1 = rtowY(w, 0);
108 int h0 = rtowY(w, 3);
109 int h1 = rtowY(w, 4);
110 for (int i = 0; i < 7; i++) {
111 int h = i % 2 ? h0 : h1;
112 int x1 = rtowX(w, position + i - 3.5);
113 int x2 = rtowX(w, position + i - 2.5) - 1;
114 w.fillRect(x1, y1, x2, h);
116 w.setColor("dimgray");
119 for (int i = 0; i < 5; i++) {
120 int h = i % 2 ? h0 : h1;
121 int x1 = rtowX(w, position + i - 8.5);
122 int x2 = rtowX(w, position + i - 7.5) - 1;
123 w.fillRect(x1, y1, x2, h);
124 x1 = rtowX(w, position + i + 3.5);
125 x2 = rtowX(w, position + i + 4.5) - 1;
126 w.fillRect(x1, y1, x2, h);
130 void dessineVent(DrawingWindow &w, float vitesse)
132 int lg = rtowX(w, vitesse) - rtowX(w, 0);
133 int dir = lg > 0 ? 1 : -1;
137 w.drawCircle(w.width / 2, y, 4);
139 int x1 = (w.width - lg) / 2;
140 int x2 = (w.width + lg) / 2;
141 w.drawLine(x1 - dir, y - 1, x2 - dir, y - 1);
142 w.drawLine(x1, y, x2, y);
143 w.drawLine(x1 - dir, y + 1, x2 - dir, y + 1);
144 for (int i = 0; i < 3; i++) {
145 w.drawLine(x2 - i * dir, y, x2 - (6 + i) * dir, y - 4);
146 w.drawLine(x2 - i * dir, y, x2 - (6 + i) * dir, y + 4);
151 void dessineExplosion(DrawingWindow& w, float rx, float ry)
153 const int maxray = rtowX(w, 2.5) - rtowX(w, 0);
154 // 1/2 rouge -> rouge -> jaune
155 const int x = rtowX(w, rx);
156 const int y = rtowY(w, ry);
158 for (i = 0; i <= maxray / 3; i++) {
159 w.setColor(0.5 + 3.0 * i / (2.0 * maxray), 0.0, 0.0);
160 w.drawCircle(x, y, i);
163 for (/* i */; i < maxray; i++) {
164 w.setColor(1.0, 1.5 * i / maxray - 0.5, 0.0);
165 w.drawCircle(x, y, i);
169 for (i = 0; i < maxray; i++) {
170 w.drawCircle(x, y, i);
173 w.fillCircle(x, y, maxray - 1);
176 void dessineFlammes(DrawingWindow& w, float x0, float y0)
178 for (int i = 0; i < 70; i++) {
180 float vx = frand(-2.5, 2.5);
181 float vy = frand(5, 17);
184 float red = frand(0.5, 1);
185 float green = frand(0, red);
187 w.setColor(red, green, blue);
189 w.drawPoint(rtowX(w, x), rtowY(w, y));
198 void initialise(DrawingWindow& w)
200 largeurMont = frand(largeurMin, largeurMax);
201 hauteurMont = frand(hauteurMin, hauteurMax);
202 wnd = frand(-30, 30);
204 dessineTerrain(w, largeurMont, hauteurMont);
205 dessineChateau(w, positionChateau1);
206 dessineChateau(w, positionChateau2);
210 /* Retour : numéro du perdant, 0 sinon
211 x et y contiennent les coordonnées de la collision
213 int tir(DrawingWindow& w,
214 float x0, float y0, float v0, float alpha, float& x, float &y)
216 float vx = v0 * cos(alpha);
217 float vy = v0 * sin(alpha);
222 int wx = rtowX(w, x);
223 int wy = rtowY(w, y);
225 w.fillCircle(wx, wy, 2);
227 float vxr = vx - wnd;
228 float kvr = -k * sqrt(vxr * vxr + vy * vy);
229 float ax = kvr * vxr;
230 float ay = kvr * vy - g;
238 w.fillCircle(wx, wy, 2);
239 // w.setColor("black");
240 // w.drawPoint(wx, wy);
244 } else if (y < hauteurChateau) {
245 if (positionChateau1 - largeurChateau <= x
246 && positionChateau1 + largeurChateau >= x)
248 else if (positionChateau2 - largeurChateau <= x
249 && positionChateau2 + largeurChateau >= x)
253 float h = hauteurMontagne(largeurMont, hauteurMont, x);
257 } while (!collision);
258 return collision == 3 ? 0 : collision;
261 void jeu1(DrawingWindow& w)
270 std::cout << "-=| Joueur " << joueur << " |=-\n";
274 if (joueur <= nbJoueurs) {
275 std::cout << "angle ? ";
277 std::cout << "vitesse initiale ? ";
280 alpha = frand(10, 90);
282 std::cout << "[ " << alpha << " ; " << v0 << " ]\n";
285 alpha = deg2rad(alpha);
288 x0 = positionChateau1 + 8;
290 x0 = positionChateau2 - 8;
294 perdant = tir(w, x0, y0, v0, alpha, x, y);
295 dessineExplosion(w, x, y);
298 dessineFlammes(w, x, y);
299 std::cout << "Joueur " << perdant;
300 if (perdant == joueur)
301 std::cout << " s'est suicidé";
303 std::cout << " a perdu";
307 void jeu(DrawingWindow& w)
315 int main(int argc, char *argv[])
317 QApplication application(argc, argv);
320 nbJoueurs = atoi(argv[1]);
322 DrawingWindow window(jeu, 640, 480);
324 return application.exec();