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