5 static final Scanner input = new Scanner(System.in);
6 static final Random random = new Random();
8 /* Note : les coordonnées réelles vont de -100 à +100 en abscisse, et
9 * de -10 à +140 en ordonnée
11 static final double rXMin = -100.0;
12 static final double rXMax = 100.0;
13 static final double rYMin = -10.0;
14 static final double rYMax = 140.0;
15 static final double hauteurMin = 10;
16 static final double hauteurMax = 130;
17 static final double largeurMin = 40;
18 static final double largeurMax = 150;
19 static final double ventMax = 30;
20 static final double largeurChateau = 8.5;
21 static final double hauteurChateau = 7;
22 static final double positionChateau1 = -85.0;
23 static final double positionChateau2 = 85.0;
24 static final double g = 9.81;
25 static final double k = 0.005;
26 static final double dt = 0.05;
27 static int nbJoueurs = 2;
28 static int score1 = 0;
29 static int score2 = 0;
30 static double largeurMont;
31 static double hauteurMont;
34 /* Retourne un nombre pseudo-aléatoire compris entre le paramètre
35 * 'min' (inclus) et le paramètre 'max' (exclus)
37 static double frand(double min, double max)
39 return min + (max - min)* (random.nextDouble());
42 // conversion coordonnées réelles -> coordonnées fenêtre
43 static int rtowX(DrawingWindow w, double rx)
45 return (int)Math.round((w.width - 1) * (rx - rXMin) / (rXMax - rXMin));
48 static int rtowY(DrawingWindow w, double ry)
50 return (int )Math.round((w.height - 1) * (rYMax - ry) / (rYMax - rYMin));
53 // conversion coordonnées fenêtre -> coordonnées réelles
54 static double wtorX(DrawingWindow w, int wx)
56 return (rXMax - rXMin) * wx / (w.width - 1) + rXMin;
59 static double wtorY(DrawingWindow w, int wy)
61 return -(rYMax - rYMin) * wy / (w.height - 1) + rYMax;
64 static double hauteurMontagne(double largeur, double hauteur, double x)
66 double rx = 2.0 * x / largeur;
67 return hauteur * (1.0 - rx * rx);
70 static void dessineTerrain(DrawingWindow w, double largeur, double hauteur)
72 int y0 = rtowY(w, 0) + 1;
73 int xmin = rtowX(w, -largeur / 2.0) - 1;
74 int xmax = rtowX(w, largeur / 2.0) + 1;
75 w.setColor("forestgreen");
76 for (int x = xmin; x <= xmax; x++) {
77 double rx = wtorX(w, x);
78 double ry = hauteurMontagne(largeur, hauteur, rx);
81 w.drawLine(x, y0, x, y);
84 w.fillRect(0, y0 + 1, w.width - 1, w.height - 1);
87 static void dessineChateau(DrawingWindow w, double position)
90 w.setColor("darkslategray");
91 int y1 = rtowY(w, 0) + 1;
94 for (int i = 0; i < 7; i++) {
95 int h = i % 2 != 0 ? h0 : h1;
96 int x1 = rtowX(w, position + i - 3.5);
97 int x2 = rtowX(w, position + i - 2.5) - 1;
98 w.fillRect(x1, y1, x2, h);
100 w.setColor("dimgray");
103 for (int i = 0; i < 5; i++) {
104 int h = i % 2 != 0 ? h0 : h1;
105 int x1 = rtowX(w, position + i - 8.5);
106 int x2 = rtowX(w, position + i - 7.5) - 1;
107 w.fillRect(x1, y1, x2, h);
108 x1 = rtowX(w, position + i + 3.5);
109 x2 = rtowX(w, position + i + 4.5) - 1;
110 w.fillRect(x1, y1, x2, h);
114 static void dessineVent(DrawingWindow w, double vitesse)
116 int lg = rtowX(w, vitesse) - rtowX(w, 0);
117 int dir = lg > 0 ? 1 : -1;
121 w.drawCircle(w.width / 2, y, 4);
123 int x1 = (w.width - lg) / 2;
124 int x2 = (w.width + lg) / 2;
125 w.drawLine(x1 - dir, y - 1, x2 - dir, y - 1);
126 w.drawLine(x1, y, x2, y);
127 w.drawLine(x1 - dir, y + 1, x2 - dir, y + 1);
128 for (int i = 0; i < 3; i++) {
129 w.drawLine(x2 - i * dir, y, x2 - (6 + i) * dir, y - 4);
130 w.drawLine(x2 - i * dir, y, x2 - (6 + i) * dir, y + 4);
135 static void dessineExplosion(DrawingWindow w, double rx, double ry)
137 final int maxray = rtowX(w, 2.5) - rtowX(w, 0);
138 // 1/2 rouge -> rouge -> jaune
139 final int x = rtowX(w, rx);
140 final int y = rtowY(w, ry);
142 for (i = 0; i <= maxray / 3; i++) {
143 w.setColor(0.5f + 3.0f * i / (2.0f * maxray), 0.0f, 0.0f);
144 w.drawCircle(x, y, i);
147 for (/* i */; i < maxray; i++) {
148 w.setColor(1.0f, 1.5f * i / maxray - 0.5f, 0.0f);
149 w.drawCircle(x, y, i);
152 w.setColor("skyblue");
153 for (i = 0; i < maxray; i++) {
154 w.drawCircle(x, y, i);
157 // w.fillCircle(x, y, maxray - 1);
160 static void dessineFlammes(DrawingWindow w, double x0, double y0)
162 for (int i = 0; i < 70; i++) {
164 double vx = frand(-2.5, 2.5);
165 double vy = frand(5, 17);
168 float red = (float)frand(0.5, 1);
169 float green = (float)frand(0, red);
171 w.setColor(red, green, blue);
173 w.drawPoint(rtowX(w, x), rtowY(w, y));
182 static void initialise(DrawingWindow w)
184 largeurMont = frand(largeurMin, largeurMax);
185 hauteurMont = frand(hauteurMin, hauteurMax);
186 wnd = frand(-ventMax, ventMax);
187 w.setBgColor("skyblue");
189 dessineTerrain(w, largeurMont, hauteurMont);
191 dessineChateau(w, positionChateau1);
192 dessineChateau(w, positionChateau2);
194 w.drawText(rtowX(w, positionChateau1 - largeurChateau), rtowY(w, 0) + 20,
196 w.drawText(rtowX(w, positionChateau2 - largeurChateau), rtowY(w, 0) + 20,
198 w.drawText(rtowX(w, 0) - 15, rtowY(w, 0) + 20, score1 + " / " + score2);
201 /* Retour : numéro du perdant, 0 sinon
202 x et y contiennent les coordonnées de la collision
204 static class ResTir {
209 static ResTir tir(DrawingWindow w,
210 double x0, double y0, double v0, double alpha) {
211 double vx = v0 * Math.cos(alpha);
212 double vy = v0 * Math.sin(alpha);
217 int wx = rtowX(w, x);
218 int wy = rtowY(w, y);
220 w.fillCircle(wx, wy, 2);
221 double vxr = vx - wnd;
222 double kvr = -k * Math.sqrt(vxr * vxr + vy * vy);
223 double ax = kvr * vxr;
224 double ay = kvr * vy - g;
232 w.setColor("skyblue");
233 w.fillCircle(wx, wy, 2);
234 // w.setColor("black");
235 // w.drawPoint(wx, wy);
238 } else if (y < hauteurChateau) {
239 if (positionChateau1 - largeurChateau <= x
240 && positionChateau1 + largeurChateau >= x)
242 else if (positionChateau2 - largeurChateau <= x
243 && positionChateau2 + largeurChateau >= x)
246 if (collision == 0) {
247 double h = hauteurMontagne(largeurMont, hauteurMont, x);
251 } while (collision == 0);
252 ResTir res = new ResTir();
255 res.perdant = collision == 3 ? 0 : collision;
259 static int jeu1(DrawingWindow w)
268 System.out.println("-=| Joueur " + joueur + " |=-");
271 if (joueur <= nbJoueurs) {
272 System.out.print("\nangle ? ");
273 alpha = input.nextDouble();
274 System.out.print("vitesse initiale ? ");
275 v0 = input.nextDouble();
277 alpha = frand(10, 90);
279 System.out.println(" [ " + (int )alpha + "° ; " + (int )v0 + " ]");
281 alpha = Math.toRadians(alpha);
284 x0 = positionChateau1 + 0.8 * largeurChateau;
286 x0 = positionChateau2 - 0.8 * largeurChateau;
287 alpha = Math.PI - alpha;
289 double y0 = hauteurChateau + 1;
291 ResTir r = tir(w, x0, y0, v0, alpha);
296 dessineExplosion(w, x, y);
298 } while (perdant == 0);
299 dessineFlammes(w, x, y);
300 String msg = " Joueur " + perdant;
301 if (perdant == joueur)
302 msg += " s'est suicidé ! ";
304 msg += " a perdu ! ";
305 w.setColor("darkred");
306 w.setBgColor("white");
307 w.drawText(w.width / 2, w.height / 3, msg);
309 System.out.println(msg);
313 public static void main(String[] args) {
314 DrawingWindow w = new DrawingWindow("Chateaux", 640, 480);
317 nbJoueurs = Integer.parseInt(args[0]);
319 boolean rejouer = true;
321 int perdant = jeu1(w);
324 else if (perdant == 2)
326 System.out.println("### SCORE : " + score1 + " / " + score2 + " ###");
332 System.out.println("Recommencer (o/n) ? ");
333 r = input.next().charAt(0);
334 } while (r != 'o' && r != 'n');