Titel   Inhalt   Suchen   Index   DOC  Handbuch der Java-Programmierung, 7. Auflage
 <<    <     >    >>   API  Kapitel 40 - Applets I

40.4 Animation in Applets



Animation ist in Applets ebenso möglich wie in Applikationen. Alle Techniken, die in Abschnitt 34.2 erklärt wurden, sind grundsätzlich auch auf Applets anwendbar. Aufgrund der Tatsache, dass 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 40.4 zeigt einen Schnappschuss des laufenden Programms.

Abbildung 40.4: 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 dass die eigentliche Animation mit der repaint-Schleife in run abläuft. Um das Bildschirmflackern zu verringern, wird update überlagert, wie in Kapitel 34 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<Skyscraper> v = new Vector<Skyscraper>();
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 = 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<Point> poly = new Vector<Point>();
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 = 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 40.9: Das Wolkenkratzer-Applet

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 40.10: Die HTML-Datei zum Aufrufen des Wolkenkratzer-Applets


 Titel   Inhalt   Suchen   Index   DOC  Handbuch der Java-Programmierung, 7. Auflage, Addison Wesley, Version 7.0
 <<    <     >    >>   API  © 1998, 2011 Guido Krüger & Heiko Hansen, http://www.javabuch.de