summaryrefslogtreecommitdiff
path: root/ws2015
diff options
context:
space:
mode:
Diffstat (limited to 'ws2015')
-rw-r--r--ws2015/eip/blaetter/10/1/de/lmu/ifi/tcs/Ball.java79
-rw-r--r--ws2015/eip/blaetter/10/1/de/lmu/ifi/tcs/GraphicsWindow.java421
-rw-r--r--ws2015/eip/blaetter/10/1/de/lmu/ifi/tcs/HuepfendeBaelle.java129
3 files changed, 629 insertions, 0 deletions
diff --git a/ws2015/eip/blaetter/10/1/de/lmu/ifi/tcs/Ball.java b/ws2015/eip/blaetter/10/1/de/lmu/ifi/tcs/Ball.java
new file mode 100644
index 0000000..83628a9
--- /dev/null
+++ b/ws2015/eip/blaetter/10/1/de/lmu/ifi/tcs/Ball.java
@@ -0,0 +1,79 @@
1package de.lmu.ifi.tcs;
2
3import java.awt.Color;
4import java.awt.Point;
5
6
7public class Ball {
8
9 private Point randpunkt;
10 private double pos_x;
11 private double pos_y;
12 private double dx;
13 private double dy;
14 private long letztesupdate;
15 private Color farbe = Color.BLACK;
16
17 public Ball(Point randpunkt, Point startpunkt, double dx, double dy, Color farbe) {
18 this.randpunkt = randpunkt;
19 this.pos_x = startpunkt.getX();
20 this.pos_y = startpunkt.getY();
21 this.dx = dx;
22 this.dy = dy;
23 this.letztesupdate = System.currentTimeMillis();
24 this.farbe = farbe;
25 }
26
27 public Ball(Point randpunkt, Point startpunkt, double dx, double dy) {
28 this(randpunkt, startpunkt, dx, dy, Color.BLACK);
29 }
30
31 /**
32 * Aktualisiert die Position des Balls gemäß der vestrichenen Zeit.
33 */
34 public void updatePosition() {
35 long aktuellezeit = System.currentTimeMillis();
36 long verstrichen = aktuellezeit - letztesupdate;
37 pos_x += dx * verstrichen / 1000;
38 pos_y += dy * verstrichen / 1000;
39 letztesupdate = aktuellezeit;
40 if (pos_x<0 || pos_x>randpunkt.x) {
41 dx *= -1;
42 pos_x = (2*randpunkt.x - pos_x) % randpunkt.x;
43 }
44 if (pos_y<0 || pos_y>randpunkt.y) {
45 dy *= -1;
46 pos_y = (2*randpunkt.y - pos_y) % randpunkt.y;
47 }
48 }
49
50 /**
51 * @return letzte Position des Balles
52 */
53 public Point holePosition() {
54 return new Point((int) Math.round(pos_x), (int) Math.round(pos_y));
55 }
56
57 /**
58 * @return aktuelle Farbe des Balls
59 */
60 public Color getFarbe() {
61 return farbe;
62 }
63
64 /**
65 * Wechselt die Farbe des Balls
66 */
67 public void wechsleFarbe() {
68 if (this.farbe.equals(Color.RED)) {
69 this.farbe = Color.GREEN;
70 } else if (this.farbe.equals(Color.GREEN)) {
71 this.farbe = Color.BLUE;
72 } else if (this.farbe.equals(Color.BLUE)) {
73 this.farbe = Color.ORANGE;
74 } else {
75 this.farbe = Color.RED;
76 }
77
78 }
79}
diff --git a/ws2015/eip/blaetter/10/1/de/lmu/ifi/tcs/GraphicsWindow.java b/ws2015/eip/blaetter/10/1/de/lmu/ifi/tcs/GraphicsWindow.java
new file mode 100644
index 0000000..925005a
--- /dev/null
+++ b/ws2015/eip/blaetter/10/1/de/lmu/ifi/tcs/GraphicsWindow.java
@@ -0,0 +1,421 @@
1package de.lmu.ifi.tcs;
2
3import java.awt.*;
4import java.util.ArrayList;
5import javax.swing.JFrame;
6import javax.swing.JPanel;
7import javax.swing.Timer;
8
9import java.awt.event.ActionEvent;
10import java.awt.event.ActionListener;
11import java.awt.event.MouseAdapter;
12import java.awt.event.WindowAdapter;
13import java.awt.event.WindowEvent;
14import java.awt.event.MouseEvent;
15import java.awt.geom.RectangularShape;
16import java.awt.geom.GeneralPath;
17
18/**
19 Eine Klasse zu pädagogischen Zwecken.
20 Erlaubt die Eingabe von Punktkoordinaten
21 mittels Mausklicks, das Zeichnen einfacher
22 2D Objekte (java.awt.Shape), sowie die
23 Ausgabe von Texten in einer Statuszeile.
24 @version 3.043
25 @author Martin Hofmann und die EiP-Teams verschiedener Jahre
26 */
27
28public class GraphicsWindow {
29
30 private int width;
31 private int height;
32 private JFrame dasFenster;
33 private static int fensterZahl;
34 private static int fensterNr;
35 private Label label;
36 private GraphicsWindowPanel panel;
37 private Point mousePos;
38 private Color activeColor = Color.BLACK;
39 final private Color backColor = Color.WHITE;
40 MyMouseAdapter mouseListener;
41
42 /**
43 Erzeugt ein Fenster der Größe 640 auf 480 mit Textausgabe, Mauseingabe und Grafikausgabe.
44 */
45 public GraphicsWindow() {
46 this(640, 480);
47 }
48
49 /**
50 Erzeugt ein Fenster in vorgegebener Größe mit Textausgabe, Mauseingabe und Grafikausgabe.
51 @param width Breite des Fensters
52 @param height Höhe des Fensters
53 */
54 public GraphicsWindow(int width, int height) {
55 this.width = width;
56 this.height = height;
57 dasFenster = new JFrame();
58 dasFenster.setTitle("Grafikfenster " + ++fensterNr);
59 fensterZahl++;
60 dasFenster.setLocationByPlatform(true);
61 dasFenster.setSize(width,height+50);
62 dasFenster.getContentPane().setPreferredSize(new Dimension(width, height+50));
63 dasFenster.pack();
64 dasFenster.addWindowListener(new WindowAdapter(){
65 public void windowClosing(WindowEvent e) {
66 dasFenster.dispose(); // nicht gleich alle Fenster abschiessen
67 if (--fensterZahl<1) System.exit(0);
68 }
69 });
70
71 label = new Label("Statuszeile...");
72 label.setFont(new Font("Helvetica", Font.PLAIN, 12));
73 dasFenster.getContentPane().add(label,"North" );
74 panel = new GraphicsWindowPanel();
75 //panel.setBackground(Color.cyan);
76 panel.addCommand(new SetColor(activeColor));
77 dasFenster.getContentPane().add(panel,"Center");
78 mousePos = new Point();
79 mouseListener = new MyMouseAdapter();
80 panel.addMouseListener(mouseListener);
81 clear();
82 dasFenster.setVisible(true);
83 }
84
85 /**
86 Gibt eine Zeichenkette oben im Fenster aus.
87 @param text diese Zeichenkette
88 */
89 public void setText(String text) {
90 label.setText(text);
91 }
92 /**
93 Liest den oben im Fenster angezeigten Text aus.
94 @return den Text
95 */
96 public String getText() {
97 return label.getText();
98 }
99 /**
100 Wartet auf einen Mausklick. Die Methode blockiert das
101 aufrufende Programm solange bis der Mausklick erfolgt ist.
102 @return die Koordinaten des angeklickten Punkts
103 */
104
105 public Point mouseClick() {
106 try{
107 synchronized(mouseListener){mouseListener.wait();}
108 }
109 catch(InterruptedException e){
110 e.printStackTrace();
111 }
112 return mousePos;
113 }
114
115 class MyMouseAdapter extends MouseAdapter {
116
117 /**
118 Beendet das Warten auf den Mausklick und verwertet die Koordinaten.
119 Diese Methode ist nicht für den Anwender bestimmt.
120 */
121
122 synchronized public void mouseClicked(MouseEvent e){
123 mousePos = e.getPoint();
124 notifyAll();
125 }
126 }
127
128
129 /**
130 Schaltet die Zeichenfarbe auf die Hintergrundfarbe um. Dies ist
131 das Mittel, um gezeichnete Linien wieder zu löschen.
132 */
133 public void switchToBackgroundColor(){
134 activeColor = backColor;
135 panel.addCommand(new SwitchToBackgroundColor(activeColor));
136 panel.repaint();
137 }
138
139 /**
140 Schaltet die Zeichenfarbe auf Schwarz um.
141 */
142 public void switchToForegroundColor(){
143 activeColor = Color.BLACK;
144 panel.addCommand(new SetColor(activeColor));
145 panel.repaint();
146 }
147
148
149 /** Liefert die aktuelle Zeichenfarbe.
150 @return die aktuelle Zeichenfarbe des GraphicsWindow. */
151 public Color getColor() {
152 // return panel.getGraphics().getColor(); // getGraphics() has unpleasant side-effects. :(
153 /* Fixed by adding another instance variable activeColor for now. */
154 return activeColor;
155 }
156
157 /**
158 Zeichnet eine Linie in der aktuellen Zeichenfarbe.
159 @param x Anfangspunkt
160 @param y Endpunkt
161 */
162 public void drawLine(Point x, Point y){
163 // Odering points reduces the amount of graphical artifacts in rendering the same object in different ways
164 Point x1 = x;
165 Point y1 = y;
166 if ((x.x > y.x) || ((x.x == y.x) && (x.y > y.y))) {
167 x1 = y;
168 y1 = x;
169 }
170 panel.addCommand(new DrawLine(x1,y1));
171 panel.repaint();
172 }
173
174 /**
175 Zeichnet einen Punkt in der aktuellen Zeichenfarbe.
176 @param p Punkt
177 */
178 public void drawPoint(Point p){
179 drawLine(p, p);
180 }
181
182 /**
183 Zeichnet einen Punkt in der aktuellen Zeichenfarbe.
184 @param p Punkt
185 */
186 public void drawStringAt(String s, Point p){
187 Command c = new DrawString(s,p);
188 panel.addCommand(c);
189 panel.repaint();
190 }
191
192 /**
193 * Zeichnet ein Polygon, gegeben durch ein geordnetes Array von Punkten
194 * @param poly Array von Punkten, welche 2D Polygon beschreiben.
195 */
196 public void drawPoly(Point[] poly) {
197 Point previous = poly[poly.length-1];
198 for (Point next : poly) {
199 drawLine(previous,next);
200 previous = next;
201 }
202 }
203
204 /**
205 * Zeichnet und füllt ein Polygon, gegeben durch ein geornetes Array von Punkten
206 * @param poly Array von Punkten, welche 2D Polygon beschreiben.
207 */
208 public void fillPoly(Point[] poly) {
209 int[] xpoints = new int[poly.length];
210 int[] ypoints = new int[poly.length];
211 for (int i = 0; i<poly.length; i++) {
212 xpoints[i] = poly[i].x;
213 ypoints[i] = poly[i].y;
214 }
215 Polygon polygon = new Polygon(xpoints,ypoints,poly.length);
216 fill(polygon);
217 }
218
219
220 /**
221 Zeichnet ein geometrisches Objekt.
222 */
223 public void draw(Shape s) {
224 panel.addCommand(new Draw(s));
225 panel.repaint();
226 }
227
228 /**
229 Füllt ein geometrisches Objekt aus.
230 */
231 public void fill(Shape s) {
232 panel.addCommand(new Fill(s));
233 panel.repaint();
234 }
235
236 /** Das aufrufende Programm wird für ein gegebene Zeitspanne blockiert.
237 @param millis Die Zeitspanne in Millisekunden*/
238 public void sleep(long millis) {
239 try {Thread.sleep(millis);} catch (Exception e){}
240 }
241
242 /** Setzt die Zeichenfarbe. */
243 public void setColor(Color d) {
244 activeColor = d;
245 panel.addCommand(new SetColor(activeColor));
246 panel.repaint();
247 }
248
249 /**
250 Setzt die Zeichenfarbe auf einen Grauwert
251 @param shade Grauwert zwischen 0(schwarz) und 255(weiß)
252 */
253 public void setGrayColor(int shade) {
254 setColor(new Color(shade, shade, shade));
255 }
256
257 /**
258 Setzt die Zeichenfarbe für die Mandelbrot-Aufgabe
259 @param n Anzahl der Iterationen, die durch die Farbe symboliziert werdem soll
260 */
261 public void setMandelColor(int n) {
262 float r = (float) Math.min(1.0,((double) n / 9.0) );
263 float g = (float) Math.min(1.0,((double) n / 99.0) );
264 float b = (float) Math.min(1.0,((double) n / 999.0) );
265 setColor(new Color(r, g, b));
266 }
267
268 /** Löscht das Bild */
269 public void clear() {
270// Color oldActive = activeColor;
271 panel.clearAll();
272// this.switchToBackgroundColor();
273// fill(new Rectangle(0,0,width,height));
274// setColor(oldActive);
275 }
276
277 public void killIn(int secs) {
278 Timer t = new Timer(1000*secs, new ActionListener(){
279 @Override
280 public void actionPerformed(ActionEvent e) {dasFenster.dispose();}
281 }
282 );
283 t.setRepeats(false);
284 t.start();
285 }
286}
287
288
289class GraphicsWindowPanel extends JPanel
290{
291 private static final long serialVersionUID = 1L;
292 private ArrayList<Command> cl = new ArrayList<Command>();
293
294 public void paintComponent(Graphics g)
295 {
296 super.paintComponent(g);
297 Graphics2D g2D = (Graphics2D)g;
298
299 ArrayList<Command> cl = this.cl; // Kopie wegen Nebenläufigkeit von Swing
300 int size = cl.size();
301 for (int i=0; i<size; i++) {
302 Command c = cl.get(i);
303 if (c != null) c.execute(g2D);
304 }
305 }
306
307 void addCommand(Command c)
308 {
309 cl.add(c);
310 }
311
312 void clearAll()
313 {
314// try {
315// SwingUtilities.invokeAndWait(new Runnable() {
316// @Override
317// public void run() {
318 cl = new ArrayList<Command>();
319// }
320// });
321// } catch (InterruptedException e) {
322// // TODO Auto-generated catch block
323// e.printStackTrace();
324// } catch (InvocationTargetException e) {
325// // TODO Auto-generated catch block
326// e.printStackTrace();
327// }
328 }
329}
330
331
332abstract class Command //implements Serializable
333{
334 abstract void execute(Graphics2D g2D);
335
336 /** Clone a shape. This method is needed because Shape
337 * does not define clone(), although many shape classes do.
338 * Kopiert aus jsky-2.6 auf ftp.eso.org */
339 static Shape cloneShape(Shape s) {
340 // FIXME Add more specific shapes
341 if (s instanceof RectangularShape) {
342 return (RectangularShape) ((RectangularShape) s).clone();
343 } else {
344 return new GeneralPath(s);
345 }
346 }
347
348}
349
350class DrawLine extends Command {
351 Point von;
352 Point bis;
353 DrawLine(Point von, Point bis) {
354 /* Clonen der Punkte essentiell um Aliasingeffekte beim Redraw zu verhindern */
355 this.von = new Point(von);
356 this.bis = new Point(bis);
357 }
358 void execute(Graphics2D g2D)
359 {
360 g2D.drawLine(this.von.x,this.von.y,this.bis.x,this.bis.y);
361 }
362}
363
364class SwitchToForegroundColor extends Command {
365 SwitchToForegroundColor() {}
366 void execute(Graphics2D g2D) {
367 g2D.setColor(Color.black);
368 }
369}
370
371class SwitchToBackgroundColor extends Command {
372 Color backcolor;
373 SwitchToBackgroundColor(Color backcolor) {this.backcolor = backcolor;}
374 void execute(Graphics2D g2D) {
375 g2D.setColor(backcolor);
376 }
377}
378
379class SetColor extends Command {
380 Color color;
381 SetColor(Color color) {this.color = color;}
382 void execute(Graphics2D g2D) {
383 g2D.setColor(this.color);
384 }
385}
386
387
388class Draw extends Command {
389 Shape shape;
390 Draw(Shape shape) {this.shape = cloneShape(shape);}
391 void execute(Graphics2D g2D) {
392 g2D.draw(this.shape);
393 }
394}
395
396class Fill extends Command {
397 Shape shape;
398 Fill(Shape shape) {this.shape = cloneShape(shape);}
399 void execute(Graphics2D g2D) {
400 g2D.fill(this.shape);
401 }
402}
403
404class DrawString extends Command {
405 String string;
406 Point position;
407 DrawString(String string, Point position) {this.string = string; this.position = position;}
408 @Override
409 void execute(Graphics2D g2D) {
410 g2D.drawString(string, position.x, position.y);
411 }
412}
413
414
415
416
417
418
419
420
421
diff --git a/ws2015/eip/blaetter/10/1/de/lmu/ifi/tcs/HuepfendeBaelle.java b/ws2015/eip/blaetter/10/1/de/lmu/ifi/tcs/HuepfendeBaelle.java
new file mode 100644
index 0000000..f6e1eef
--- /dev/null
+++ b/ws2015/eip/blaetter/10/1/de/lmu/ifi/tcs/HuepfendeBaelle.java
@@ -0,0 +1,129 @@
1package de.lmu.ifi.tcs;
2
3import java.awt.Color;
4import java.awt.Point;
5import java.awt.Rectangle;
6import java.awt.Shape;
7import java.awt.geom.Ellipse2D;
8import java.util.ArrayList;
9import java.util.Random;
10
11
12public class HuepfendeBaelle {
13
14 private ArrayList<Ball> baelle;
15 private GraphicsWindow gw;
16
17 // Parameter
18 private final static int max_x = 640;
19 private final static int max_y = 480;
20 private final static int ballgroesse = 20;
21 private final static int knopfgroesse = 40;
22 /**
23 * @param args
24 * @throws InterruptedException
25 */
26 public static void main(String[] args) throws InterruptedException {
27
28 Point randpunkt = new Point(max_x-ballgroesse,max_y-ballgroesse);
29 ArrayList<Ball> baelle = new ArrayList<Ball>();
30
31 Ball b = new Ball(randpunkt, new Point(50,60), 100,90, Color.MAGENTA);
32 baelle.add(b);
33 b = new Ball(randpunkt, new Point(200,100), -5,20, Color.ORANGE);
34 baelle.add(b);
35 b = new Ball(randpunkt, new Point(323,243), 10,-30, Color.GREEN);
36 baelle.add(b);
37 b = new Ball(randpunkt, new Point(23,43), -199,-200);
38
39 GraphicsWindow gw = new GraphicsWindow(max_x,max_y);
40 gw.setText("Bälle anklicken; blaue Leiste zum Beenden anklicken.");
41
42 HuepfendeBaelle hb = new HuepfendeBaelle(baelle, gw);
43
44
45 //while( true ) {
46 for (Ball ball : baelle) {
47 ball.updatePosition();
48 }
49 hb.zeichneAlleBaelle();
50 //}
51
52 // Vearbeitung der Mouse-clicks.
53 Point click = gw.mouseClick();
54 Random zufall = new Random();
55 while (click.x >= 0 && click.x <= max_x && click.y >= knopfgroesse && click.y <= max_y) {
56 if (hb.treffer(click)) {
57 gw.setText("Treffer! ("+ click.x + "," + click.y +")");
58 } else {
59 gw.setText("Daneben! ("+ click.x + "," + click.y +")");
60 b = new Ball(randpunkt, click, (zufall.nextDouble()-0.5)*200, (zufall.nextDouble()-0.5)*200);
61 hb.plusBall(b);
62 }
63 for (Ball ball : baelle) {
64 ball.updatePosition();
65 }
66 hb.zeichneAlleBaelle();
67 click = gw.mouseClick(); // Warten auf Mausklick
68 }
69 gw.setText("Auf Wiedersehen!");
70 gw.sleep(8000);
71
72 System.exit(0);
73 }
74
75 /**
76 * @param baelle
77 * @param gw
78 */
79 public HuepfendeBaelle(ArrayList<Ball> baelle, GraphicsWindow gw) {
80 this.baelle = baelle;
81 this.gw = gw;
82 }
83
84
85 /* Zeichnet alle Baelle ins GraphicsWindow ein */
86 public void zeichneAlleBaelle() {
87 gw.clear();
88 zeichneEnde();
89 for (Ball ball : baelle) {
90 gw.setColor(ball.getFarbe());
91 zeichneBallBei(ball.holePosition());
92 }
93 }
94
95 /* Zeichnet einen Ball bei einer speziellen Position */
96 public void zeichneBallBei(Point p) {
97 Shape ball = new Ellipse2D.Double(p.getX(), p.getY(), ballgroesse, ballgroesse);
98 gw.fill(ball);
99 }
100
101 /* Fügt einen weiteren Ball hinzu */
102 public void plusBall(Ball b) {
103 this.baelle.add(b);
104 }
105
106 /* Prüft ab, ob sich an einer gegebenen Position ein Ball befindet
107 * und wechselt ggf. dessen Farbe.
108 */
109 public boolean treffer(Point schuss) {
110 for (Ball ball : baelle) {
111 Point bpos = ball.holePosition();
112 bpos.translate(ballgroesse/2, ballgroesse/2);
113 if (schuss.distance(bpos) <= ballgroesse+5) {
114 ball.wechsleFarbe();
115 return true;
116 }
117 }
118 return false;
119 }
120
121 /*
122 * Zeichnet einfach nur einen blauen Balken am oberen Fensterrand.
123 */
124 public void zeichneEnde() {
125 Rectangle ende = new Rectangle(0,0,max_x, knopfgroesse);
126 gw.setColor(Color.BLUE);
127 gw.fill(ende);
128 }
129}