package core;
import interfaces.Collidable;
import interfaces.Drawable;
import java.awt.Image;
import java.awt.geom.Area;
import java.awt.image.ColorModel;
import java.awt.image.PixelGrabber;
import tiles.WallAbove;
import tiles.WallAboveLeft;
import tiles.WallAboveRight;
import tiles.WallBelow;
import tiles.WallLeft;
import tiles.WallBelowLeft;
import tiles.WallRight;
import tiles.WallBelowRight;
import entities.Coin;
import entities.Enemy;
import entities.Finish;
import entities.Player;
/**
* Die Sprite-Klasse zur Verwaltung der Grafiken für die Animationen,
* dem Kollisionsbereich der Sprites
* und der Kollisionsüberprüfung
*
* @author Sven Lennartz
*
*/
public abstract class Sprite implements Drawable, Collidable {
// Rechteck für den Kollisionsbereich
private Hitbox hitbox;
// Aktuelles Bild (von Bedeutung speziell bei späterer Animation)
private Image currentImage;
// Ist dieses Objekt geblockt?
private boolean blocked;
// Gespiegelt?
private boolean flipped;
/**
* Konstruktor zur erzeugung eines neues Sprites
*
* @param image das Bild oder die Bilder für den Sprite bzw die Animationen
* @param hitboxWidth Breite für die Hitbox, über die Kollisionen geprüft werden
* @param hitboxHeight Höhe für die Hitbox, über die Kollisionen geprüft werden
*/
public Sprite(Image image, int hitboxWidth, int hitboxHeight, boolean blocked) {
this.currentImage = image;
setHitbox(hitboxWidth, hitboxHeight);
this.blocked = blocked;
} //ende Konstruktor
/**
* Getter für das blocked-Flag
*
* @return Blockiert dieses Objekt? true/false
*/
public boolean isBlocked() {
return blocked;
} //ende isBlocked()
/**
* Setter für das blocked-Flag
*
* @param blocked Soll dieses Objekt blockieren?
*/
public void setBlocked(boolean blocked) {
this.blocked = blocked;
}
/**
* Getter für das flipped-Flag
*
* @return Ist das Bild auf Y gespiegeln? true/false
*/
public boolean isFlipped() {
return flipped;
} //ende isFlipped()
/**
* Setter für das flipped-Flag
*
* @param flipped Soll das Bild auf Y gespiegelt werden?
*/
public void setFlipped(boolean flipped) {
this.flipped = flipped;
} //ende setFlipped()
/**
* Getter für die Hitbox, die den
* Bereich definiert, in dem ein Sprite kollidieren kann
*
* @return Rechteck zur Kollisionsabfrage
*/
public Hitbox getHitbox() {
return hitbox;
} //ende getHitbox()
/**
* Setter für die Hitbox, Aufruf im Konstruktor des Sprites
*
* @param width Breite der Hitbox
* @param height Höhe der Hitbox
*/
private void setHitbox(int width, int height) {
hitbox = new Hitbox(0, 0, width, height);
} //ende setHitbox()
/**
* Setter für das aktuelle Bild
*
* @param image Als aktuelles Bild zu verwendendes Bild des Sprites
*/
public void setCurrentImage(Image image) {
this.currentImage = image;
} //ende setCurrentImage()
/**
* Getter für das aktuelle Bild des Sprites
*
* @return Das aktuelle Bild des Sprites
*/
public Image getCurrentImage() {
return currentImage;
} //ende getCurrentImage()
/* (non-Javadoc)
* @see Drawable#draw()
*/
public void draw() {
Renderer.getInstance().draw(this);
} //ende draw()
/**
* Überprüft ob dieser Sprite mit einem anderen kollidiert
*
* @param other das andere Objekt, mit dem potenziell kollidiert wird
* @param pixelAccurate Pixelgenaue Kollision?
* @return kollidiert das Objekt?
*/
public boolean isCollidingWith(Collidable other, boolean pixelAccurate) {
if (other.isBlocked() && this.blocked && hitbox.intersects(other.getHitbox())) {
if (!pixelAccurate)
return true;
else {
// Pixel genaue Überprüfung
Area thisArea = new Area(hitbox);
Area otherArea = new Area(other.getHitbox());
// Kollisionsbereich berechnen
thisArea.intersect(otherArea);
int width = thisArea.getBounds().width;
int height = thisArea.getBounds().height;
try {
// Pixel Arrays
int[] thisPixels = new int[width * height];
int[] otherPixels = new int[width * height];
// Pixel die im Kollisionsbereich liegen in die Arrays laden
PixelGrabber grabber = new PixelGrabber(currentImage,
Math.abs(hitbox.x - thisArea.getBounds().x), Math.abs(hitbox.y - thisArea.getBounds().y),
width, height, thisPixels, 0, width);
grabber.grabPixels();
grabber = new PixelGrabber(((Sprite)other).getCurrentImage(),
Math.abs(other.getHitbox().x - thisArea.getBounds().x), Math.abs(other.getHitbox().y - thisArea.getBounds().y),
width, height, otherPixels, 0, width);
grabber.grabPixels();
ColorModel cm = grabber.getColorModel();
// Prüfen ob in den Pixeln der jeweilig gleichen Position etwas ist
for (int i = 0; i < thisPixels.length; i++)
{
if (cm.getAlpha(thisPixels[i]) != 0 && cm.getAlpha(otherPixels[i]) != 0)
return true;
}
} catch(Exception e)
{
e.printStackTrace();
}
}
}
return false;
} //ende isCollidingWith
/* (non-Javadoc)
* @see interfaces.Collidable#handleCollisionWith(entities.Enemy)
*/
public void handleCollisionWith(Enemy other) {
}
/* (non-Javadoc)
* @see interfaces.Collidable#handleCollisionWith(entities.Player)
*/
public void handleCollisionWith(Player other) {
}
/* (non-Javadoc)
* @see interfaces.Collidable#handleCollisionWith(entities.Coin)
*/
public void handleCollisionWith(Coin other) {
}
/* (non-Javadoc)
* @see interfaces.Collidable#handleCollisionWith(entities.Finish)
*/
public void handleCollisionWith(Finish other) {
}
/* (non-Javadoc)
* @see interfaces.Collidable#handleCollisionWith(tiles.WallAboveLeft)
*/
public void handleCollisionWith(WallAboveLeft other) {
}
/* (non-Javadoc)
* @see interfaces.Collidable#handleCollisionWith(tiles.WallAbove)
*/
public void handleCollisionWith(WallAbove other) {
}
/* (non-Javadoc)
* @see interfaces.Collidable#handleCollisionWith(tiles.WallAboveRight)
*/
public void handleCollisionWith(WallAboveRight other) {
}
/* (non-Javadoc)
* @see interfaces.Collidable#handleCollisionWith(tiles.WallLeft)
*/
public void handleCollisionWith(WallLeft other) {
}
/* (non-Javadoc)
* @see interfaces.Collidable#handleCollisionWith(tiles.WallRight)
*/
public void handleCollisionWith(WallRight other) {
}
/* (non-Javadoc)
* @see interfaces.Collidable#handleCollisionWith(tiles.WallLeftBelow)
*/
public void handleCollisionWith(WallBelowLeft other) {
}
/* (non-Javadoc)
* @see interfaces.Collidable#handleCollisionWith(tiles.WallBelow)
*/
public void handleCollisionWith(WallBelow other) {
}
/* (non-Javadoc)
* @see interfaces.Collidable#handleCollisionWith(tiles.WallRightBelow)
*/
public void handleCollisionWith(WallBelowRight other) {
}
}