/* * Engine Alpha ist eine anfängerorientierte 2D-Gaming Engine. * * Copyright (c) 2011 - 2014 Michael Andonie and contributors. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package ea; import ea.internal.collision.Collider; import ea.internal.collision.ColliderGroup; import ea.internal.gra.Listung; import java.awt.*; /** * Ein Objekt, das aus n primitiven Geometrischen Formen - <b>Dreiecken</b> - besteht * * @author Michael Andonie */ public abstract class Geometrie extends Raum implements Leuchtend, Listung { /** * Die Dimension des Objektes; zur schnellen Ausgabe */ protected BoundingRechteck dimension; /** * Die einzelnen, grafisch darstellbaren Formen, aus denen dieses Geometrie-Objekt besteht. */ private Dreieck[] formen; /** * Gibt an, ob dieses Geometrie-Objekt gerade leuchtet */ private boolean leuchtet = false; /** * Der Leuchtzaehler fuer die Leucht-Animationen */ private int leuchtzaehler = 0; /** * Die Farbe, die sich das Objekt merkt, wenn es zu leuchten anfaengt, um wieder die alte * herstellen zu koennen. */ private Color alte = Color.white; /** * Konstruktor. * * @param x * bestimmende x-Koordinate * @param y * bestimmende y-Koordinate */ public Geometrie (float x, float y) { position = new Punkt(x, y); dimension = new BoundingRechteck(x, y, 0, 0); super.leuchterAnmelden(this); } /** * Zeichnet das Objekt.<br /> heisst in diesem Fall das saemtliche Unterdreiecke gezeichnet * werden. */ public void zeichnen (Graphics2D g, BoundingRechteck r) { super.beforeRender(g, r); for (int i = 0; i < formen.length; i++) { formen[i].zeichnen(g, r); } super.afterRender(g, r); } public BoundingRechteck dimension () { return dimension.klon(); } /** * Verschiebt das Objekt. * * @param v * Der Vektor, der die Verschiebung des Objekts angibt. * * @see Vektor */ @Override public void verschieben (Vektor v) { super.verschieben(v); for (int i = 0; i < formen.length; i++) { formen[i].verschieben(v); } dimension = dimension.verschobeneInstanz(v); } /** * {@inheritDoc} Collider ist eine Gruppierung aus den Collidern der Dreiecke, die dieses Objekt * ausmachen. */ @Override public Collider erzeugeCollider () { ColliderGroup group = new ColliderGroup(); for (Dreieck d : formen) { group.addCollider(d.erzeugeCollider()); } return group; } /** * Berechnet exakter alle Rechteckigen Flaechen, auf denen dieses Objekt liegt.<br /> Diese * Methode wird von komplexeren Gebilden, wie geometrischen oder Listen ueberschrieben. * * @return Alle Rechtecksflaechen, auf denen dieses Objekt liegt. Ist standartisiert ein Array * der Groesse 1 mit der <code>dimension()</code> als Inhalt. */ @Override public BoundingRechteck[] flaechen () { BoundingRechteck[] ret = new BoundingRechteck[formen.length]; for (int i = 0; i < formen.length; i++) { ret[i] = formen[i].dimension(); } return ret; } /** * Diese Methode loescht alle eventuell vorhandenen Referenzen innerhalb der Engine auf dieses * Objekt, damit es problemlos geloescht werden kann.<br /> <b>Achtung:</b> zwar werden * hierdurch alle Referenzen geloescht, die <b>nur innerhalb</b> der Engine liegen (dies * betrifft vor allem Animationen etc), jedoch nicht die innerhalb eines * <code>Knoten</code>-Objektes!!!!!!!!!<br /> Das heisst, wenn das Objekt an einem Knoten liegt * (was <b>immer der Fall ist, wenn es auch gezeichnet wird (siehe die Wurzel des * Fensters)</b>), muss es trotzdem selbst geloescht werden, <b>dies erledigt diese Methode * nicht!!</b>.<br /> Diese Klasse ueberschreibt die Methode wegen des Leuchtens. */ @Override public void loeschen () { super.leuchterAbmelden(this); super.loeschen(); } /** * Setzt ganzheitlich die Farbe der gesamten geometrischen Figur auf eine Farbe. * * @param f * Die Farbe, die das Objekt haben soll. * * @see Farbe */ public void farbeSetzen (Farbe f) { farbeSetzen(f.wert()); } /** * Setzt ganzheitlich die Farbe aller Formen auf eine bestimmte Farbe.<br /> Dadurch faerbt sich * im Endeffekt das ganze Objekt neu ein. * * @param c * Die neue Farbe */ public void farbeSetzen (Color c) { alte = c; if (formen == null) { formen = neuBerechnen(); } for (int i = 0; i < formen.length; i++) { formen[i].setColor(c); } } /** * In dieser Methode werden saemtliche Dreiecke neu berechnet und die Referenz bei Aufruf in der * Superklasse hierauf gesetzt * * @return Ein Dreieck-Array mit allen, die Figur beschreibenden Dreiecken als Inhalt. */ public abstract Dreieck[] neuBerechnen (); /** * Setzt, ob dieses Geometrie-Objekt leuchten soll.<br /> Ist dies der Fall, so werden immer * wieder schnell dessen Farben geaendert; so entsteht ein Leuchteffekt. * * @param leuchtet * Ob dieses Objekt nun leuchten soll oder nicht (mehr). */ @Override public void leuchtetSetzen (boolean leuchtet) { if (this.leuchtet == leuchtet) { return; } this.leuchtet = leuchtet; if (leuchtet) { alte = formen[0].getColor(); } else { this.farbeSetzen(alte); } } /** * Fuehrt einen Leuchtschritt aus.<br /> Dies heisst, dass in dieser Methode die Farbe einfach * gewechselt wird. Da diese Methode schnell und oft hintereinander ausgefuehrt wird, soll so * der Leuchteffekt entstehen.<br /> <b>Diese Methode sollte nur innerhalb der Engine * ausgefuehrt werden! Also nicht fuer den Entwickler gedacht.</b> */ @Override public void leuchtSchritt () { for (int i = 0; i < formen.length; i++) { leuchtzaehler++; leuchtzaehler %= farbzyklus.length; formen[i].setColor(farbzyklus[leuchtzaehler]); } } /** * Gibt wieder, ob das Leuchtet-Objekt gerade leuchtet oder nicht. * * @return <code>true</code>, wenn das Objekt gerade leuchtet, wenn nicht, dann ist die * Rueckgabe <code>false</code> */ @Override public boolean leuchtet () { return this.leuchtet; } /** * aktualisisert die Dreiecke, aus denen die Figur besteht UND weisst sie ein. Diese Methode * MUSS am Ende eines jeden Konstruktors einer Klasse stehen, die sich hieraus ableitet<br /> * Zugrunde liegt eine neue Wertzuweisung des Arrays, es wird <code>neuBerechnen()</code> * aufgerufen. */ protected void aktualisierenFirst () { aktualisieren(); farbeSetzen("Weiss"); } /** * aktualisisert die Dreiecke, aus denen die Figur besteht.<br /> Zugrunde liegt eine neue * Wertzuweisung des Arrays, es wird <code>neuBerechnen()</code> aufgerufen. */ protected void aktualisieren () { formen = neuBerechnen(); for (int i = 0; i < formen.length; i++) { formen[i].setColor(alte); } dimension = ausDreiecken(formen); } /** * Setzt ganzheitlich die Farbe aller Formen auf eine bestimmte Farbe.<br /> Dadurch faerbt sich * im Endeffekt das ganze Objekt neu ein. * * @param farbe * Der String-Wert der Farbe. Zu der Zuordnung siehe <b>Handbuch</b> */ public void farbeSetzen (String farbe) { farbeSetzen(zuFarbeKonvertieren(farbe)); } /** * Berechnet ein neues BoundingRechteck fuer ein Array aus Dreiecken */ public static BoundingRechteck ausDreiecken (Dreieck[] ecke) { BoundingRechteck r = ecke[0].dimension(); for (int i = 1; i < ecke.length; i++) { r = r.summe(ecke[i].dimension()); } return r; } /** * Gibt alle Unterdreiecke dieser Geometrie-Figur wieder.<br /> * * @return Ein Array mit allen Dreiecken dieser Figur. */ public Dreieck[] formen () { return this.formen; } }