Tit   Inh   Ind   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   <<   <   >   >> 

25.5 Animation in Applets



Animation ist in Applets ebenso möglich wie in Applikationen. Alle Techniken, die in Kapitel 24 erklärt wurden, sind grundsätzlich auch auf Applets anwendbar. Aufgrund der Tatsache, daß Applets in einem Browser laufen und über eine Netzwerk-Fernverbindung mit Daten versorgt werden müssen, sollten folgende Besonderheiten beachtet werden:

Wir wollen uns diese Regeln zu eigen machen und in diesem Abschnitt ein einfaches animiertes Applet entwickeln. Das Programm soll die Skyline einer Großstadt bei Nacht darstellen. Dabei gehen in den Wolkenkratzern die Lichter an und aus, auf einigen Dächern gibt es rote Blinklichter, und von Zeit zu Zeit schlägt der Blitz mit Krachen in einen der Wolkenkratzer ein. (Diese Aufgabenstellung erinnert nicht ganz zu Unrecht an einen bekannten Bildschirmschoner.) Abbildung 25.5 zeigt einen Schnappschuß des laufenden Programms.

Abbildung 25.5: Das Wolkenkratzer-Beispielprogramm

Das Programm implementiert zwei Klassen, Skyscraper und SkyscraperApplet. Skyscraper repräsentiert einen Wolkenkratzer, der die Membervariablen x- und y-Position, Höhe, Breite und Anzahl der Fenster in x- und y-Richtung besitzt. Zusätzlich kann ein Skyscraper-Objekt auf Simulations-Events reagieren, die durch den Aufruf der Methode LightEvent ausgelöst werden. In diesem Fall wird das Licht in einem der Fenster an- oder ausgeschaltet oder das rote Blinklicht auf dem Dach getriggert.

Das eigentliche Applet wird durch die Klasse SkyscraperApplet realisiert. In der init-Methode wird zunächst eine Reihe von Skyscraper-Objekten erzeugt und im Vector c abgelegt. Zusätzlich werden die Parameter DELAY, FLASH und THUNDER eingelesen, die zur Steuerung der Animationsverzögerung, der Blitzwahrscheinlichkeit und der Sound-Datei für den Donner dienen. In der Methode start wird ein Thread erzeugt, so daß die eigentliche Animation mit der repaint-Schleife in run abläuft. Um das Bildschirmflackern zu verringern, wird update überlagert, wie in Kapitel 24 erläutert. In paint wird per Zufallszahlengenerator eines der in v gespeicherten Skyscraper-Objekte ausgewählt und dessen LigthEvent-Methode aufgerufen, um ein Beleuchtungsereignis zu simulieren.

Manchmal wird auch noch die Methode Lightning aufgerufen, um einen Blitzeinschlag darzustellen. Ein Blitz wird dabei durch einen Streckenzug vom oberen Bildrand bis zur Dachspitze eines Hochhauses dargestellt. Dieser Streckenzug wird für einen kurzen Augenblick in weißer Farbe auf den Bildschirm gezeichnet und anschließend durch erneutes Zeichnen in schwarzer Farbe wieder entfernt. Um ein realistisches Flackern zu erreichen, wird dieser Vorgang noch einmal wiederholt. Unmittelbar vor der Darstellung des Blitzes wird das zuvor geladene Donnergeräusch abgespielt.

Hier ist der Quellcode des Applets:

001 /* SkyscraperApplet.java */
002 
003 import java.awt.*;
004 import java.util.*;
005 import java.applet.*;
006 
007 class Skyscraper
008 {
009   public int x;
010   public int y;
011   public int width;
012   public int height;
013   int        wndcntx;
014   int        wndcnty;
015   boolean    blinkon = false;
016 
017   Skyscraper(int x, int y)
018   {
019 	this.x = x;
020 	this.y = y;
021 	this.width = (int)(30*(0.5+Math.random()));
022 	this.height = (int)(100*(0.5+Math.random()));
023 	wndcntx = (width-4)/5;
024 	wndcnty = (height-4)/5;
025   }
026 
027   void LightEvent(Graphics g)
028   {
029 	double rnd  = Math.random();
030 	int    xwnd = (int)(Math.random()*wndcntx);
031 	int    ywnd = (int)(Math.random()*wndcnty);
032 	if (blinkon) {
033 	  g.setColor(Color.black);
034 	  g.fillRect(x+width/2,y-height-20,2,2);
035 	  blinkon = false;
036 	}
037 	if (rnd >= 0.9) {
038 	  blinkon = true;
039 	  g.setColor(Color.red);
040 	  g.fillRect(x+width/2,y-height-20,2,2);
041 	} else if (rnd >= 0.7) {
042 	  g.setColor(Color.black);
043 	  g.fillRect(x+2+xwnd*5,y-height+2+ywnd*5,2,2);
044 	} else {
045 	  g.setColor(Color.yellow);
046 	  g.fillRect(x+2+xwnd*5,y-height+2+ywnd*5,2,2);
047 	}
048   }
049 }
050 
051 public class SkyscraperApplet
052 extends Applet
053 implements Runnable
054 {
055   //Membervariablen
056   Thread th;
057   Vector v = new Vector();
058   AudioClip thunder;
059   boolean running;
060 
061    //Parameter
062   int    DELAY;
063   float  FLASH;
064   String THUNDER;
065 
066   public void init()
067   {
068 	Skyscraper house;
069 	int x = 5;
070 
071 	//Häuser erzeugen
072 	while (this.getSize().width-x-1 >= 30) {
073 	  house = new Skyscraper(x,this.getSize().height-10);
074 	  v.addElement(house);
075 	  x += house.width + 5;
076 	}
077 	setBackground(Color.black);
078 
079 	//Parameter einlesen
080 	try {
081 	  DELAY = Integer.parseInt(getParameter("delay"));
082 	} catch (NumberFormatException e) {
083 	  DELAY = 75;
084 	}
085 	try {
086 	  FLASH = (new Float(getParameter("flash"))).floatValue();
087 	} catch (NumberFormatException e) {
088 	  FLASH = 0.01F;
089 	}
090 	THUNDER = getParameter("thunder");
091 	if (THUNDER != null) {
092 	  thunder = getAudioClip(getCodeBase(),THUNDER);
093 	}
094 	System.out.println("DELAY = "+DELAY);
095 	System.out.println("FLASH = "+FLASH);
096 	System.out.println("THUNDER = "+THUNDER);
097   }
098 
099   public void start()
100   {
101 	if (th == null) {
102 	  running = true;
103 	  th = new Thread(this);
104 	  th.start();
105 	}
106   }
107 
108   public void stop()
109   {
110 	if (th != null) {
111 	  running = false;
112 	  th = null;
113 	}
114   }
115 
116   public void run()
117   {
118 	while (running) {
119 	  repaint();
120 	  try {
121 		Thread.sleep(DELAY);
122 	  } catch (InterruptedException e) {
123 		//nothing
124 	  }
125 	}
126   }
127 
128   public void update(Graphics g)
129   {
130 	paint(g);
131   }
132 
133   public void paint(Graphics g)
134   {
135 	int i;
136 	Skyscraper house;
137 
138 	i = (int)Math.floor(Math.random()*v.size());
139 	house = (Skyscraper)v.elementAt(i);
140 	house.LightEvent(g);
141 	if (Math.random() < FLASH) {
142 	  Lightning(g,house.x+10,house.y-house.height);
143 	}
144   }
145 
146   public void Lightning(Graphics g, int x, int y)
147   {
148 	Vector poly = new Vector();
149 	int dx, dy, i, polysize;
150 
151 	thunder.play();
152 	//Blitzpolygon berechnen
153 	poly.addElement(new Point(x,y));
154 	polysize = 1;
155 	while (y > 10) {
156 	  dx = 10 - (int)(Math.floor(Math.random()*20));
157 	  dy = - (int)(Math.floor(Math.random()*20));
158 	  x += dx;
159 	  y += dy;
160 	  poly.addElement(new Point(x,y));
161 	  ++polysize;
162 	}
163 	//Blitzvector in Koordinaten-Arrays umwandeln
164 	int xpoints[] = new int[poly.size()];
165 	int ypoints[] = new int[poly.size()];
166 	for (i = 0; i < polysize; ++i) {
167 	  Point p = (Point)poly.elementAt(i);
168 	  xpoints[i] = p.x;
169 	  ypoints[i] = p.y;
170 	}
171 	//Blitz zeichnen
172 	for (i = 0; i <= 1; ++i) {
173 	  g.setColor(Color.white);
174 	  g.drawPolyline(xpoints, ypoints, polysize);
175 	  try {
176 		Thread.sleep(20);
177 	  } catch (InterruptedException e) {}
178 	  g.setColor(Color.black);
179 	  g.drawPolyline(xpoints, ypoints, polysize);
180 	  try {
181 		Thread.sleep(20);
182 	  } catch (InterruptedException e) {}
183 	}
184   }
185 }
SkyscraperApplet.java
Listing 25.11: Das Wolkenkratzer-Applet

 Beispiel 

Zum Aufruf des Applets kann beispielsweise folgende HTML-Datei verwendet werden:

001 <html>
002 <head>
003 <title>Skyscraper</title>
004 </head>
005 <body>
006 <h1>Skyscraper</h1>
007 <applet code=SkyscraperApplet.class width=500 height=300>
008 <param name="delay"   value=75>
009 <param name="flash"   value=0.01>
010 <param name="thunder" value="thunder.au">
011 Hier steht das Applet Skyscraper.class
012 </applet>
013 </body>
014 </html>
SkyscraperApplet.html
Listing 25.12: Die HTML-Datei zum Aufrufen des Wolkenkratzer-Applets


 Tit   Inh   Ind   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   <<   <   >   >> 
Go To Java 2, Addison Wesley, Version 1.0.2, © 1999 Guido Krüger, http://www.gkrueger.com