Vorgegeben war ein Animations-Applet, das einen Kreis in einem Rechteck bewegt. Diese Applet sollte so erweitert werden, daß als Parameter des Applets die Anzahl der darzustellenden Kreise angegeben werden kann.
Dafür sind im Quellcode folgende Veränderungen vorzunehmen:
//animnew.java
import java.applet.*;
import java.awt.*;
// Einfache Animation mit Double-Buffering
public class animnew extends Applet implements Runnable
{
//eine innere Klasse fuer Kreise
class kreis
{
final int r; //Radius
final Color f; //Farbe
public int x, y; //Position
public int dx, dy; //Richtung
public kreis ()
{
//Radius
r = (int) (Math.random()*50+1);
//Farbe
f = new Color((float)Math.random(),(float)Math.random(),(float)Math.random());
//Anfangspunkt
x = (int) (Math.random() * animnew.this.size.width)/2 + r;
y = (int) (Math.random() * animnew.this.size.height)/2 + r;
//Anfangsrichtung
dx = (int) (Math.random() * animnew.this.size.width)/50 + 3;
dy = (int) (Math.random() * animnew.this.size.height)/50 + 3;
}
}
//hier sind einige Attribute weggefallen, die jetzt in der Klasse Kreis enthalten sind
Dimension size; // Größe des Applets
Image offscreen; // Off-sceen Bild
Graphics offgraphics; // Grafik-Object dafür
Thread animator; // Thread für die Animation
boolean stop; // Zum Anhalten der Animation
//neue Attribute
int kreis_anz; // Anzahl zu animierender Kreise
kreis kreise[]; // Array für die Kreise
public void init()
{ String rs; //zum Einlesen des Parameters
// Initialisierung der Off-Screen-Grafik
size = this.size();
//Parameter einlesen
rs = getParameter("kreise");
if (rs == null) // keine Angabe
rs="1"; // -> ein Kreis
kreis_anz = Integer.parseInt(rs);
//Initialisierung der Kreisdaten
kreise = new kreis[kreis_anz];
for (int i = 0; i < kreis_anz; i++)
kreise[i] = new kreis();
offscreen = this.createImage(size.width, size.height);
offgraphics = offscreen.getGraphics();
}
public void paint(Graphics g)
{ // Zeichne in den Off-Screen-Puffer
offgraphics.setColor(this.getBackground()); // Hintergrundfarbe
offgraphics.fillRect(0, 0, size.width, size.height); // l÷schen
//zeichne alle Kreise
for (int j = 0; j < kreis_anz; j++)
{
offgraphics.setColor(kreise[j].f);
offgraphics.fillOval(kreise[j].x-kreise[j].r, kreise[j].y-kreise[j].r, kreise[j].r*2, kreise[j].r*2);
}
// Kopiere die Zeichnung in die Anzeige
g.drawImage(offscreen, 0, 0, this);
}
public void update(Graphics g)
{ // Sofort zeichnen ohne zu l÷schen
paint(g);
}
public void run()
{ // Der Rumpf des Animations-Threads
while (!stop)
{ // Bewegen, neuzeichnen, schlafen
for (int i = 0; i < kreis_anz; i++)
{
int oldx = kreise[i].x, oldy = kreise[i].y; // alte Position merken
newposition(i); // neue Position berechnen
// alte Position neuzeichnen
repaint(oldx-kreise[i].r, oldy-kreise[i].r, 2*kreise[i].r, 2*kreise[i].r);
// neue Position neuzeichnen
repaint(kreise[i].x-kreise[i].r, kreise[i].y-kreise[i].r, 2*kreise[i].r, 2*kreise[i].r);
// die beiden repaints werden zu einem paint-aufruf verschmolzen
}
sleep(20);
}
animator = null;
}
public void newposition(int i)
{ // neue Position des Kreises
kreise[i].x += kreise[i].dx;
kreise[i].y += kreise[i].dy;
// mal sehen, wo wir sind
if (kreise[i].x - kreise[i].r < 0 || kreise[i].x + kreise[i].r > size.width)
kreise[i].dx = -kreise[i].dx;
if (kreise[i].y - kreise[i].r < 0 || kreise[i].y + kreise[i].r > size.height)
kreise[i].dy = -kreise[i].dy;
}
public void sleep(int milliseconds)
{ // kleine Pause
try
{
Thread.sleep(milliseconds);
}
catch (InterruptedException e) {}
}
public void start()
{ // Start des Animations-Threads
if (animator == null)
{
stop = false;
animator = new Thread(this);
animator.start(); // loslaufen
}
}
public void stop()
{ // Anhalten des Animations-Threads
stop = true;
}
// Starten und stoppen per Maus-Klick
public boolean mouseDown(Event e, int x, int y)
{
if (animator != null)
stop = true;
else start();
return true;
}
}
Gestartet mit dem Parameter 9 sieht das Ganze dann so aus: