Guido Krüger - JAVA 1.1 lernen - Kapitel 25

Previous Page Previous Page TOC TOC Index Next Page Previous Page



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:

Beispiel

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.

Undisplayed Graphic

Abbildung 25.5: Das Beispielprogramm Example2505

Das Programm implementiert zwei Klassen, Skyscraper und Example2505. Skyscraper repräsentiert einen Wolkenkratzer, der die Instanzmerkmale 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 Example2505 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 im vorigen Kapitel 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 geladenene Donnergeräusch abgespielt.

Hier ist der Quellcode des Applets:

import java.awt.*;
import java.util.*;
import java.applet.*;

class Skyscraper {
   public int x;
   public int y;
   public int width;
   public int height;
   int        wndcntx;
   int        wndcnty;
   boolean    blinkon = false;

   Skyscraper(int x, int y)
   {
      this.x = x;
      this.y = y;
      this.width = (int)(30*(0.5+Math.random()));
      this.height = (int)(100*(0.5+Math.random()));
      wndcntx = (width-4)/5;
      wndcnty = (height-4)/5;
   }

   void LightEvent(Graphics g)
   {
      double rnd  = Math.random();
      int    xwnd = (int)(Math.random()*wndcntx);
      int    ywnd = (int)(Math.random()*wndcnty);
      if (blinkon) {
         g.setColor(Color.black);
         g.fillRect(x+width/2,y-height-20,2,2);
         blinkon = false;
      }
      if (rnd >= 0.9) {
         blinkon = true;
         g.setColor(Color.red);
         g.fillRect(x+width/2,y-height-20,2,2);
      } else if (rnd >= 0.7) {
         g.setColor(Color.black);
         g.fillRect(x+2+xwnd*5,y-height+2+ywnd*5,2,2);
      } else {
         g.setColor(Color.yellow);
         g.fillRect(x+2+xwnd*5,y-height+2+ywnd*5,2,2);
      }
   }
}

public class Example2505
extends Applet
implements Runnable
{
   //Instanzmerkmale
   Thread th;
   Vector v = new Vector();
   AudioClip thunder;

   //Parameter
   int    DELAY;
   float  FLASH;
   String THUNDER;

   public void init()
   {
      Skyscraper house;
      int x = 5;

      //Häuser erzeugen
      while (this.getSize().width-x-1 >= 30) {
         house = new Skyscraper(x,this.getSize().height-10);
         v.addElement(house);
         x += house.width + 5;
      }
      setBackground(Color.black);

      //Parameter einlesen
      try {
         DELAY = Integer.parseInt(getParameter("delay"));
      } catch (NumberFormatException e) {
         DELAY = 75;
      }
      try {
         FLASH = (new Float(getParameter("flash"))).floatValue();
      } catch (NumberFormatException e) {
         FLASH = 0.01F;
      }
      THUNDER = getParameter("thunder");
      if (THUNDER != null) {
         thunder = getAudioClip(getCodeBase(),THUNDER);
      }
      System.out.println("DELAY = "+DELAY);
      System.out.println("FLASH = "+FLASH);
      System.out.println("THUNDER = "+THUNDER);
   }

   public void start()
   {
      if (th == null) {
         th = new Thread(this);
         th.start();
      }
   }

   public void stop()
   {
      if (th != null) {
         th.stop();
         th = null;
      }
   }

   public void run()
   {
      while (true) {
         repaint();
         try {
            Thread.sleep(DELAY);
         } catch (InterruptedException e) {
            //nothing
         }
      }
   }

   public void update(Graphics g)
   {
      paint(g);
   }

   public void paint(Graphics g)
   {
      int i;
      Skyscraper house;

      i = (int)Math.floor(Math.random()*v.size());
      house = (Skyscraper)v.elementAt(i);
      house.LightEvent(g);
      if (Math.random() < FLASH) {
         Lightning(g,house.x+10,house.y-house.height);
      }
   }

   public void Lightning(Graphics g, int x, int y)
   {
      Vector poly = new Vector();
      int dx, dy, i, polysize;

      thunder.play();
      //Blitzpolygon berechnen
      poly.addElement(new Point(x,y));
      polysize = 1;
      while (y > 10) {
         dx = 10 - (int)(Math.floor(Math.random()*20));
         dy = - (int)(Math.floor(Math.random()*20));
         x += dx;
         y += dy;
         poly.addElement(new Point(x,y));
         ++polysize;
      }
      //Blitzvector in Koordinaten-Arrays umwandeln
      int xpoints[] = new int[poly.size()];
      int ypoints[] = new int[poly.size()];
      for (i = 0; i < polysize; ++i) {
         Point p = (Point)poly.elementAt(i);
         xpoints[i] = p.x;
         ypoints[i] = p.y;
      }
      //Blitz zeichnen
      for (i = 0; i <= 1; ++i) {
         g.setColor(Color.white);
         g.drawPolyline(xpoints, ypoints, polysize);
         try {
            Thread.sleep(20);
         } catch (InterruptedException e) {}
         g.setColor(Color.black);
         g.drawPolyline(xpoints, ypoints, polysize);
         try {
            Thread.sleep(20);
         } catch (InterruptedException e) {}
      }
   }
}

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

<html>
<head>
<title>Example2505</title>
</head>
<body>
<h1>Example2505</h1>
<applet code=Example2505.class width=500 height=300>
<param name="delay"   value=75>
<param name="flash"   value=0.01>
<param name="thunder" value="thunder.au">
Hier steht das Applet Example2505.class
</applet>
</body>
</html>


Previous Page Previous Page Page Top TOC Index Next Page Previous Page

(C) 1997 Guido Krueger, "Java 1.1 lernen", Addison-Wesley, Bonn, 1997