package com.lucasdnd.ags.gameplay;
import org.newdawn.slick.Animation;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.SpriteSheet;
import org.newdawn.slick.state.StateBasedGame;
import com.lucasdnd.ags.map.OffsetUtil;
import com.lucasdnd.ags.system.GameSystem;
import com.lucasdnd.ags.ui.components.Clickable;
public abstract class Entity implements Clickable {
private int id; // Entity Identifier
/** Position and movement */
protected float xPos; // Current x position
protected float yPos; // Current y position
protected float xOffset; // Current x offset
protected float yOffset; // Current y offset
protected int xTile; // Current x tile
protected int yTile; // Current y tile
protected int xSize; // The size of the Entity, in Tiles
protected int ySize; // The size of the Entity, in Tiles
protected int topmostXTile; // The topmost tile this Entity occupies, relative to the viewer
protected int topmostYTile; // The topmost tile this Entity occupies, relative to the viewer
protected boolean blocksMap; // Indicates if the Entity blocks a Tile in the Map or not
protected int depth; // The result of xTile + yTile. Used to correctly render objects that appear in front of the others
protected boolean alreadyRendered; // If it already rendered in this render loop
/** Sprite */
protected SpriteSheet spriteSheet; // The Sprite Sheet
protected Animation[] animation; // The 4 Animations (down_left, down_right, up_left, up_right)
protected Image[] image; // All the Sprites in the Animation
protected boolean isAnimating; // Indicates if the Entity is animating or not
protected int frameDuration; // The duration of each Image in the Animation
protected float scale; // Scale of the sprite
protected int spriteWidth; // The width of the sprites
protected int spriteHeight; // The height of the sprites
protected int facingDirection; // The direction which this unit is facing
protected boolean visible; // Visible or not
public static final int DOWN_RIGHT = 0;
public static final int DOWN_LEFT = 1;
public static final int UP_LEFT = 2;
public static final int UP_RIGHT = 3;
protected boolean canBeDisposed; // Indicates if this Entity can be deleted in the next Update loop
public Entity(int id) {
this.id = id;
visible = true;
}
protected Entity(int id, SpriteSheet spriteSheet) throws SlickException {
this(id);
// Create the SpriteSheet
this.spriteSheet = spriteSheet;
// Create and load the Standing Still Images
image = new Image[4];
for(int i = 0; i < image.length; i++) {
image[i] = spriteSheet.getSprite(0, i);
image[i].setFilter(Image.FILTER_NEAREST);
}
// Create the Animations
frameDuration = 150;
animation = new Animation[4];
animation[DOWN_RIGHT] = new Animation(new Image[] {image[DOWN_RIGHT], spriteSheet.getSprite(1, 0), spriteSheet.getSprite(2, 0), spriteSheet.getSprite(1, 0)}, frameDuration);
animation[DOWN_LEFT] = new Animation(new Image[] {image[DOWN_LEFT], spriteSheet.getSprite(1, 1), spriteSheet.getSprite(2, 1), spriteSheet.getSprite(1, 1)}, frameDuration);
animation[UP_LEFT] = new Animation(new Image[] {image[UP_LEFT], spriteSheet.getSprite(1, 2), spriteSheet.getSprite(2, 2), spriteSheet.getSprite(1, 2)}, frameDuration);
animation[UP_RIGHT] = new Animation(new Image[] {image[UP_RIGHT], spriteSheet.getSprite(1, 3), spriteSheet.getSprite(2, 3), spriteSheet.getSprite(1, 3)}, frameDuration);
for(int i = 0; i < animation.length; i++) {
animation[i].setAutoUpdate(true);
animation[i].setPingPong(false);
}
// Some basic Sprite parameters
spriteWidth = image[0].getWidth();
spriteHeight = image[0].getHeight();
facingDirection = DOWN_RIGHT;
scale = 1f;
}
public boolean gotLeftClicked(boolean leftMouseClicked, int mouseX, int mouseY) {
if((leftMouseClicked) &&
(mouseX >= (xPos + xOffset) * GameSystem.globalScale && mouseX <= (xPos + xOffset) * GameSystem.globalScale + spriteWidth * GameSystem.globalScale &&
mouseY >= (yPos + yOffset) * GameSystem.globalScale && mouseY <= (yPos + yOffset) * GameSystem.globalScale + spriteHeight * GameSystem.globalScale)
)
return true;
return false;
}
public boolean gotRightClicked(boolean rightMouseClicked, int mouseX, int mouseY) {
if((rightMouseClicked) &&
(mouseX >= (xPos + xOffset) * GameSystem.globalScale && mouseX <= (xPos + xOffset) * GameSystem.globalScale + spriteWidth * GameSystem.globalScale &&
mouseY >= (yPos + yOffset) * GameSystem.globalScale && mouseY <= (yPos + yOffset) * GameSystem.globalScale + spriteHeight * GameSystem.globalScale)
)
return true;
return false;
}
/**
* Renders the Entity to the Screen
* @param container
* @param game
* @param g
* @throws SlickException
*/
public void render(GameContainer container, StateBasedGame game, Graphics g) throws SlickException {
// Draw only the first Sprite
animation[facingDirection].getImage(0).draw(xPos + OffsetUtil.getPreciseOffset(xOffset), yPos + OffsetUtil.getPreciseOffset(yOffset));
}
public Image getImage(int index) {
return image[index];
}
public Image[] getImage() {
return image;
}
public void setImage(Image[] image) {
this.image = image;
}
public int getSpriteWidth() {
return spriteWidth;
}
public void setSpriteWidth(int spriteWidth) {
this.spriteWidth = spriteWidth;
}
public int getSpriteHeight() {
return spriteHeight;
}
public void setSpriteHeight(int spriteHeight) {
this.spriteHeight = spriteHeight;
}
public int getFacingDirection() {
return facingDirection;
}
public void setFacingDirection(int facingDirection) {
this.facingDirection = facingDirection;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public float getXPos() {
return xPos;
}
public void setXPos(float xPos) {
this.xPos = xPos;
}
public float getYPos() {
return yPos;
}
public void setYPos(float yPos) {
this.yPos = yPos;
}
public int getXTile() {
return xTile;
}
public void setXTile(int xTile) {
this.xTile = xTile;
}
public int getYTile() {
return yTile;
}
public void setYTile(int yTile) {
this.yTile = yTile;
}
public float getxOffset() {
return xOffset;
}
public void setxOffset(float xOffset) {
this.xOffset = xOffset;
}
public float getyOffset() {
return yOffset;
}
public void setyOffset(float yOffset) {
this.yOffset = yOffset;
}
public boolean blocksMap() {
return blocksMap;
}
public void setBlocksMap(boolean blocksMap) {
this.blocksMap = blocksMap;
}
public int getDepth() {
return depth;
}
public void setDepth(int depth) {
this.depth = depth;
}
public int getxSize() {
return xSize;
}
public void setxSize(int xSize) {
this.xSize = xSize;
}
public int getySize() {
return ySize;
}
public void setySize(int ySize) {
this.ySize = ySize;
}
public int getTopmostXTile() {
return topmostXTile;
}
public void setTopmostXTile(int topmostXTile) {
this.topmostXTile = topmostXTile;
}
public int getTopmostYTile() {
return topmostYTile;
}
public void setTopmostYTile(int topmostYTile) {
this.topmostYTile = topmostYTile;
}
public boolean isVisible() {
return visible;
}
public void setVisible(boolean visible) {
this.visible = visible;
}
public boolean canBeDisposed() {
return canBeDisposed;
}
public void setCanBeDisposed(boolean canBeDisposed) {
this.canBeDisposed = canBeDisposed;
}
public boolean isAlreadyRendered() {
return alreadyRendered;
}
public void setAlreadyRendered(boolean alreadyRendered) {
this.alreadyRendered = alreadyRendered;
}
}