Benutzer-Werkzeuge

Webseiten-Werkzeuge


flyingbullets

Showcase: "Fliegende Kugeln"

Im Folgenden ist die Implementierung „fliegender Kugeln“ aufgeführt. Dabei wird eine Menge von Kugeln mit konstanter Geschwindigkeit bewegt. Kollidiert eine Kugel mit dem Fensterrand oder einer anderen Kugel, so prallt diese im Einfallswinkel der Kollision vom getroffenen Objekt ab. Die Lösung umfasst die zwei Klassen Bullet (Kugel) und BulletsMover.

Zugegeben, die physikalische Modellierung der Kollision ist verbesserungswürdig ;-)

Klasse Bullet

Bullet.java
import java.awt.Point;
import java.util.ArrayList;
 
import geofasc.swing.Circle;
import geofasc.swing.tool.Calculator;
import geofasc.swing.tool.Canvas;
 
/**
 * Eine <code>Bullet</code> kann sich mit einer Geschwindigkeit von 5 Pixeln
 * in eine bestimmbare Richtung bewegen. Sie ist ein {@link Circle} und 
 * wird auf einer {@link Canvas} visualisiert.
 * 
 */
public class Bullet extends Circle {
 
   private static final int sVelocity = 5; // Konstante Geschwindigkeit aller Bullets in Pixeln
 
   private Canvas mCanvas;
   private ArrayList<Bullet> mNeighbours;  // Liste benachbarter Bullets
 
 
   /**
    * Erzeugt eine neue <code>Bullet</code> bullet.
    * 
    * @param x die x-Koordinate von bullet bez. der canvas
    * @param y die y-Koordinate von bullet bez. der canvas
    * @param diameter der Radius des Kreises zur Visualisierung von bullet
    * @param direction die initiale Richtung von bullet
    * @param canvas die Zeichenflaeche, die bullet visualisiert
    */
   public Bullet(int x, int y, int diameter, double direction, Canvas canvas) {
      super(x, y, diameter);
      setFigureDirection(direction);
      mCanvas = canvas;
      mCanvas.add(this);
      mNeighbours = new ArrayList<Bullet>();
   }
 
   /**
    * Bewegt diese bullet um 5 Pixel abhängig
    * von ihrer Bewegungsrichtung.
    */
   public void move() {
 
      int x = getFigureLocationX();
      int y = getFigureLocationY();
      double dir = getFigureDirection();
 
      if (y <= 0 || (y + getFigureHeight()) >= mCanvas.getHeight())
         setFigureDirection(360 - dir);
      if (x <= 0 || (x + getFigureWidth()) >= mCanvas.getWidth())
         setFigureDirection(180 - dir);
 
      for (Bullet b : mNeighbours) {
         if (hits(b)) {
            setFigureDirection(dir - 180);
         }
      }
 
      moveFigureLocationBy(sVelocity);
 
   }
 
 
   /**
    * Fuegt die Nachbarbullet b der Liste von Nachbarbullets dieser
    * bullet hinzu.
    * 
    * @param b die Nachbarbullet
    */
   public void addNeighbour(Bullet b) {
      if (b != null && !mNeighbours.contains(b))
         mNeighbours.add(b);
   }
 
   /**
    * Gibt den Mittelpunkt des dieser bullet visualisierenden
    * Kreises wieder. 
    */
   public Point getCenter() {
      return new Point(getFigureLocationX() + getRadius(),
            getFigureLocationY() + getRadius());
   }
 
   /**
    * Prueft fuer diese bullet, ob sie mit der <code>Bullet</code> b
    * kollidiert.
    * 
    * @param b die Nachbarbullet
    * @return true oder false
    */
   public boolean hits(Bullet b) {
 
      if (b == null)
         return false;
 
      else {
         Point m1 = getCenter();
         Point m2 = b.getCenter();
 
         Calculator c = new Calculator();
         return (c.sqrt(c.square(m1.x - m2.x) + c.square(m1.y - m2.y)) <= (getRadius() + b
               .getRadius()));
 
      }
 
   }
 
   /**
    * Entfernt die Nachbarbullet b aus der Liste von Nachbarbullets dieser
    * bullet.
    * 
    * @param b die Nachbarbullet
    */
   public void removeNeighbour(Bullet b) {
      mNeighbours.remove(b);
   }
 
}

Klasse BulletsMover

BulletsMover.java
import geofasc.swing.tool.Calculator;
import geofasc.swing.tool.Canvas;
import geofasc.swing.tool.Frame;
 
import javax.swing.SwingUtilities;
 
/**
 * Ein <code>BulletsMover</code> stellt ein Hauptprogramm dar,
 * in dem mehrere {@link Bullet}s erzeugt, bewegt und dargestellt
 * werden.
 *
 */
public class BulletsMover {
 
   private Bullet[] mBullets;
   private Thread mMovingThread; // Thread fuer die nebenlaeufige Bewegung aller Bullets
   private Frame mFrame;
 
   /**
    * Erzeugt einen neuen <code>BulletsMover</code>.   
    */
   public BulletsMover() {
      mBullets = new Bullet[20];
      mFrame = new Frame("Bullets");
      mMovingThread = null;
      init();
      mFrame.setCenterLocation();
      mFrame.setVisible(true);
   }
 
   /**
    * Fuehrt diverse initiale Operationen aus.   
    */
   private void init() {
      Canvas canvas = mFrame.getCanvas();
 
      double direction = 13;
      int x, y, diameter;
      Calculator calc = new Calculator();
 
      for (int i = 0; i < mBullets.length; i++, direction += 11) {
         x = calc.randomInt(10, 620);
         y = calc.randomInt(20, 460);
         diameter = calc.randomInt(5, 20);
 
         mBullets[i] = new Bullet(x, y, diameter, direction, canvas);
      }
 
      for (int i = 0; i < mBullets.length; i++) {
         for (int j = 0; j < mBullets.length; j++) {
            if (i != j)
               mBullets[i].addNeighbour(mBullets[j]);
         }
      }
   }
 
   /**
    * Erzeugt einen Thread, in dem alle Bullets nebenlaeufig bewegt werden.
    */
   public void move() {
      if (mMovingThread == null) {
         mMovingThread = new Thread() {
 
            @Override
            public void run() {
               try {
                  while (true) {
                     if (isInterrupted())
                        break;
 
                     for (Bullet bullet : mBullets) {
                        bullet.move();
                     }
                     sleep(50);
                  }
               }// try
               catch (Exception e) {
               }
            }
         };
 
         mMovingThread.start();
      }
   }
 
   /**
    * Stoppt die nebenlaeufige Bewegung der Bullets.
    */
   public void stop() {
      if (mMovingThread != null) {
         mMovingThread.interrupt();
         mMovingThread = null;
      }
   }
 
   /**
    *    Hauptmethode zum Ausfuehren des Programms.
    */
   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
 
         @Override
         public void run() {
            BulletsMover bm = new BulletsMover();
            bm.move();
         }
      });
 
   }
 
}
flyingbullets.txt · Zuletzt geändert: 2014/03/06 17:12 von admin