You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

377 lines
10 KiB

package gameobjects;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.util.LinkedList;
import java.lang.reflect.*;
import rendering.*;
import collider.Collider;
import controller.ObjectController;
import playground.Playground;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
/**
* The class {@link GameObject} represents a (possibly animated) object appearing in a level of the
* game. It is therefore attached to an instance of the class {@link Playground}. A GameObject has
* at least the following properties:
* <ul>
* <li>2D screen position
* <li>2D speed
* <li>a name that is unique within a certain {@link Playground}<br>
* <li>a reference to the {@link Playground} object it belongs to<br>
* <li>a reference to an instance of {@link controller.ObjectController} that handles the movement
* logic of the object<br>
* <li>a (circular) radius for simple collision checking. This may be handled differently in
* subclasses<br>
* </ul>
* The main task of GameObject, or its subclasses, is to draw the object on the screen, which is
* handles by the {@link #draw(Graphics2D)} method. It is this method that must be redefined if a
* new appearance should be realized. For introducing new behavior, it is sufficient to supply a
* different {@link controller.ObjectController} instance when constructing a GameObject.
*/
public abstract class GameObject {
public static final int RADIUS = 0;
public static final int RECTANGLE = 1;
public static final int MASK = 2;
protected Artist artist = null;
public String id = null;
protected double x = 0;
protected double vx = 0;
protected double y = 0;
protected double vy = 0;
protected BufferedImage mask = null; // UNDONE implement usage of mask
protected boolean active = true;
// public int collisionMode = GameObject.RADIUS;
protected Playground playground = null;
private ObjectController controller = null;
public LinkedList<Collider> scol;
private static Logger logger = LogManager.getLogger(GameObject.class);
/**
* Constructor to initialize a GameObject, respectively set the current {@link Playground}
* instance this GameObject belongs to.
*
* @param id unique ID for this GameObject (should not be null or empty String)
* @param playground the Playground the GameObject belongs to (should not be null)
* @param x initial screen position in direction horizontal (positive value including zero)
* @param y initial screen position in direction vertical (positive value including zero)
* @param vx initial speed (velocity) in direction horizontal (can be negative, zero, positive)
* @param vy initial speed (velocity) in direction horizontal (can be negative, zero, positive)
*/
public GameObject(String id, Playground playground, double x, double y, double vx, double vy) {
setX(x);
setY(y);
setVX(vx);
setVY(vy);
this.id = id;
this.controller = null;
this.scol = new LinkedList<Collider>();
this.setPlayground(playground);
}
/**
* Constructor to initialize a GameObject, respectively set the current Playground instance this
* GameObject belongs to.
*
* @param id unique ID for this GameObject (should not be null or empty String)
* @param playground the Playground the GameObject belongs to (should not be null)
* @param controller controller instance to be used for this GameObject (can be null)
* @param x initial screen position in direction horizontal (positive value including zero)
* @param y initial screen position in direction vertical (positive value including zero)
* @param vx initial speed (velocity) in direction horizontal (can be negative, zero, positive)
* @param vy initial speed (velocity) in direction horizontal (can be negative, zero, positive)
*/
public GameObject(String id, Playground playground, ObjectController controller, double x,
double y, double vx, double vy) {
this(id, playground, x, y, vx, vy);
this.controller = controller;
if (this.controller != null) {
this.controller.setObject(this);
this.controller.setPlayground(playground);
}
}
/**
* sets colliders.
*
* @param l LinkedList of Colliders.
*/
public void setColliders(LinkedList<Collider> l) {
this.scol = l;
}
/**
* generates and sets collider(s) for this GameObject. This implementation does nothing. Intended
* to be overridden by subclasses.
*
* @return instance of this GameObject (this).
*/
public GameObject generateColliders() {
return this;
}
/**
* Sets the controller to use for this GameObject's logical behavior.
*
* @param c instance to be used.
* @return the current instance (this).
*/
public GameObject addController(ObjectController c) {
this.controller = c;
this.controller.setObject(this);
this.controller.setPlayground(playground);
return this;
}
/**
* Sets the artist to be used for drawing the object onto visible canvas area.
*
* @param a instance to be used for calling {@link rendering.Artist#draw(Graphics2D)}.
* @return the current instance (this).
*/
public GameObject addArtist(Artist a) {
this.artist = a;
return this;
}
/**
* saves the collider in the internal list of Colliders to be used for this GameObject.
*
* @param c instance to be added to internal list
*/
public void addCollider(Collider c) {
if (this.scol == null) {
this.scol = new LinkedList<Collider>();
}
this.scol.add(c);
}
public Playground getPlayground() {
return playground;
}
public void setPlayground(Playground playground) {
this.playground = playground;
}
/**
* calls via reflection a method of a component if this GameObjects instance and provides the
* given value as String parameter.
*
* @param comp class name of GameObject component. Currently only "controller" is supported,
* otherwise nothing happens.
* @param property method name of the component to call.
* @param value argument to pass to the method as String parameter.
*/
public void setComponentProperty(String comp, String property, Object value) {
if (comp.equals("controller")) {
Class<? extends Object> clO = this.controller.getClass();
for (Method m : clO.getMethods()) {
if (m.getName().indexOf(property) != -1) {
logger.debug("Method " + property + " found!!");
try {
m.invoke(this.getObjectController(), value);
} catch (Exception e) {
}
}
}
}
}
public void setObjectFlag(String flag, Object value) {
this.playground.setLevelFlag(this.id + "/" + flag, value);
}
public Object getObjectFlag(String flag) {
return this.playground.getLevelFlag(this.id + "/" + flag);
}
public Object getOrCreateObjectFlag(String flag, Object createValue) {
return this.playground.getOrCreateLevelFlag(this.id + "/" + flag, createValue);
}
public boolean isActive() {
return active;
}
public GameObject setActive(boolean flag) {
this.active = flag;
return this;
}
/**
* return the unique object ID.
*
* @return unique object ID
*/
public String getId() {
return id;
}
/**
* gets the screen X position.
*
* @return screen x position
*/
public double getX() {
return x;
}
/**
* gets the screen Y position.
*
* @return screen Y position
*/
public double getY() {
return y;
}
/**
* gets the screen X speed in pixels per frame.
*
* @return screen x speed
*/
public double getVX() {
return vx;
}
/**
* gets the screen Y speed in pixels per frame.
*
* @return screen y speed
*/
public double getVY() {
return vy;
}
/**
* set screen x position.
*
* @param x new position
*/
public void setX(double x) {
if (this.active == true) {
this.x = x;
}
}
/**
* set screen y position.
*
* @param y new position
*/
public void setY(double y) {
if (this.active == true) {
this.y = y;
}
}
/**
* set screen x speed in pixel per frame
*
* @param vx new x speed
*/
public void setVX(double vx) {
if (this.active == true) {
this.vx = vx;
}
}
/**
* set screen y speed in pixel per frame.
*
* @param vy new y speed.
*/
public void setVY(double vy) {
if (this.active == true) {
this.vy = vy;
}
}
/**
* Sets a new object controller (replaces any former one).
*
* @param controller An instance of {@link controller.ObjectController} or one of its subclasses.
*/
public void setObjectController(ObjectController controller) {
this.controller = controller;
}
/**
* Access to object controller.
*
* @return the controller for this object.
*/
public ObjectController getObjectController() {
return this.controller;
}
public double getGameTime() {
return this.playground.getGameTime();
}
/**
* Collision detection implemented by iteration through the own list of {@link collider.Collider}
* and calling their {@link collider.Collider#collidesWith(Collider)} method to check collision
* with the given parameter instance of other {@link GameObject}.
*
* @param other instance of the other GameObject to check collision with
* @return true if collision is detected, false otherwise
*/
public boolean collisionDetection(GameObject other) {
if (this.scol == null) {
return false;
}
for (Collider c : this.scol) {
logger.trace(other.id);
for (Collider o : other.scol) {
if (c.collidesWith(o)) {
logger.trace(c.id + " " + o.id);
return true;
}
}
}
return false;
}
/**
* triggers this GameObjects own controller (if set) to update the object.
*
* @see GameObject#controller
*/
public void updateObject() {
if (this.controller != null) {
controller.updateObject();
}
}
/**
* Draws the object in its current state. Is called by the game engine, should NOT be called
* otherwise.
*
* @param g object that has all the necessary drawing functionalities
*/
public void draw(Graphics2D g) {
if (this.artist != null) {
this.artist.draw(g);
}
}
}