In einem kleinen Demo-Programm bewegen sich Autos und Motorräder von links nach rechts über das Fenster. Zusätzlich fliegen Sterne in Parabelbahnen.
Es bietet sich an, Klassen Stern
, Auto
und Motorrad
für die bewegten Objekte zu erstellen sowie eine zusätzliche Klasse AnimationStarter
, in der
public class Stern { private Sprite sprite; private double vx, vy, ay; public Stern(double x, double y) { this.vx = Math.random() * 6 - 3; this.vy = Math.random() * (-15) - 5; this.ay = 0.3; sprite = new Sprite("/vererbung/star.png", x, y); sprite.strecken(0.2); } public void zeitschritt(){ vy += ay; if(sprite != null) { sprite.verschieben(vx, vy); } } public boolean istAußerhalbDesFensters(){ return sprite.istAußerhalbDesFensters(); } public void vernichten(){ sprite.vernichten(); } }
public class Auto { private Sprite sprite; private double vx, vy, ay; public Auto(double x, double y) { this.vx = Math.random() * 3 + 1; this.vy = 0; this.ay = 0; sprite = new Sprite("/vererbung/car2.png", x, y); sprite.strecken(0.2); } public void zeitschritt(){ vy += ay; if(sprite != null) { sprite.verschieben(vx, vy); } } public boolean istAußerhalbDesFensters(){ return sprite.istAußerhalbDesFensters(); } public void vernichten(){ sprite.vernichten(); } }
public class Motorrad { private Sprite sprite; private double vx, vy, ay; public Motorrad(double x, double y) { this.vx = Math.random() * 6 + 2; this.vy = 0; this.ay = 0; sprite = new Sprite("/vererbung/motorbike.png", x, y); sprite.strecken(0.2); } public void zeitschritt(){ vy += ay; if(sprite != null) { sprite.verschieben(vx, vy); } } public boolean istAußerhalbDesFensters(){ return sprite.istAußerhalbDesFensters(); } public void vernichten(){ sprite.vernichten(); } }
public class AnimationStarter implements TimerListener { private ArrayList<Stern> sterne = new ArrayList<>(); private ArrayList<Auto> autos = new ArrayList<>(); private ArrayList<Motorrad> motorräder = new ArrayList<>(); int i = 0; public static void main(String[] args) { new AnimationStarter().start(); } private void start() { Fenster f = new Fenster(800, 750); Timer timer = new Timer(this, 20); timer.start(); } @Override public void timerSignalVerarbeiten() { i++; if(i % 10 == 0){ sterne.add(new Stern(300, 600)); autos.add(new Auto(0, Math.random() * 600)); motorräder.add(new Motorrad(0, Math.random() * 600)); } for(int i = 0; i < autos.size(); i++){ Auto a = autos.get(i); if(a.istAußerhalbDesFensters()){ autos.remove(a); a.vernichten(); } a.zeitschritt(); } for(int i = 0; i < sterne.size(); i++){ Stern s = sterne.get(i); if(s.istAußerhalbDesFensters()){ sterne.remove(s); s.vernichten(); } s.zeitschritt(); } for(int i = 0; i < motorräder.size(); i++){ Motorrad m = motorräder.get(i); if(m.istAußerhalbDesFensters()){ motorräder.remove(m); m.vernichten(); } m.zeitschritt(); } } }
Die Implementierung hat folgende Nachteile:
Stern
, Auto
und Motorrad
sind identisch.AnimationStarter
müssen für Autos, Sterne und Motorräder jeweils extra Listen geführt werden. Dies hat zur Folge, dass sich in der Methode timerSignalVerarbeiten
große Teile des Codes wiederholen.
Die gemeinsamen Methoden und Attribute der Klassen Stern
, Auto
und Motorrad
packen wir in eine Basisklasse BewegteFigur
. Die Klassen Stern
, Auto
und Motorrad
leiten wir dann von BewegteFigur
ab, d.h. sie erben alle Attribute und Methoden der Basisklasse.
public class BewegteFigur { private Sprite sprite; private double vx, vy, ay; public BewegteFigur(String dateiname, double x, double y, double vx, double vy, double ay) { this.vx = vx; this.vy = vy; this.ay = ay; sprite = new Sprite(dateiname, x, y); sprite.strecken(0.2); } public void zeitschritt(){ vy += ay; if(sprite != null) { sprite.verschieben(vx, vy); } } public boolean istAußerhalbDesFensters(){ return sprite.istAußerhalbDesFensters(); } public void vernichten(){ sprite.vernichten(); } }
public class SternNeu extends BewegteFigur { public SternNeu(double x, double y){ // Aufruf des Konstruktors der Basisklasse BewegteFigur: super("/vererbung/star.png", x, y, Math.random() * 6 - 3, Math.random() * (-15) - 5, 0.3); } }
public class AutoNeu extends BewegteFigur { public AutoNeu(double x, double y){ super("/vererbung/car2.png", x, y, Math.random() * 3 + 1, 0,0); } }
public class MotorradNeu extends BewegteFigur { public MotorradNeu(double x, double y){ super("/vererbung/motorbike.png", x, y, Math.random() * 6 + 2, 0,0); } }
public class AnimationStarterNeu implements TimerListener { private ArrayList<BewegteFigur> figuren = new ArrayList<>(); int i = 0; public static void main(String[] args) { new AnimationStarterNeu().start(); } private void start() { Fenster f = new Fenster(800, 750); Timer timer = new Timer(this, 20); timer.start(); } @Override public void timerSignalVerarbeiten() { i++; if(i % 10 == 0){ figuren.add(new SternNeu(300, 600)); figuren.add(new AutoNeu(0, Math.random() * 600)); figuren.add(new MotorradNeu(0, Math.random() * 600)); } for(int i = 0; i < figuren.size(); i++){ BewegteFigur f = figuren.get(i); if(f.istAußerhalbDesFensters()){ figuren.remove(f); f.vernichten(); } f.zeitschritt(); } } }