package org.erikaredmark.monkeyshines.tiles; import java.awt.Graphics2D; import org.erikaredmark.monkeyshines.GameConstants; import org.erikaredmark.monkeyshines.resource.WorldResource; /** * * Represents a specific collapsible tile in the level. There is no analog 'Collapsible' class to * store immutable state like the other tiles; the only thing immutable about this is the id for * drawing. Everything else is state dependent. * <p/> * Tiles collapse a bit when {@code collapse} is called. Collapsible tiles have 10 frames of * animation and 20 ticks of collapsibility before they are gone. * <p/> * When not collapsed, they act like thru tiles. When collapsed, they act like scene tiles. * * @author Erika Redmark * */ public final class CollapsibleTile implements TileType { // Only immutable state; id of which collapsing tile this in graphics resource private final int id; // the level of damage the tile has currently taken. Once it hits 20 that effectively // makes it 'dead'. Lower values mean LESS damage. int damage; public CollapsibleTile(final int id) { this.id = id; this.damage = 0; } @Override public int getId() { return id; } /** * * {@inheritDoc} * <p/> * Collapsible tiles take on the characterstics of thrus when not destroyed, but lose that power * when destroyed. * */ @Override public boolean isThru() { return damage < 20; } @Override public boolean isSolid() { return false; } @Override public boolean isLandable() { return isSolid() || isThru(); } @Override public void reset(boolean oddElseEven) { damage = 0; } @Override public void update() { /* Damaging a tile is done per tick IF bonzo is standing on it. We don't have that context here so * update does nothing. Collision logic must check for collapsing tile and call specific methods. */ } @Override public CollapsibleTile copy() { return new CollapsibleTile(this.id); } /** * * Performs 1 tick of collapsing. This is typically called if bonzo is standing on a collapsible tile. * This method can safely be called if the collapsible tile is gone; it just won't do anything. * */ public void collapse() { if (damage < 20) ++damage; } /** * * Paints the given collapsible tile onto the given graphics context, at the given position. * The appearence of this tile if fully controlled by its own state. * */ @Override public void paint(Graphics2D g2d, int drawToX, int drawToY, WorldResource rsrc) { // 10 frames of animation, 20 points of damage. int drawFromX = (damage / 2) * GameConstants.TILE_SIZE_X; // y position is controlled 100% by immutable id int drawFromY = id * GameConstants.TILE_SIZE_Y; g2d.drawImage(rsrc.getCollapsingSheet(), drawToX , drawToY, // Destination 1 (top left) drawToX + GameConstants.TILE_SIZE_X, drawToY + GameConstants.TILE_SIZE_Y, // Destination 2 (bottom right) drawFromX, drawFromY, // Source 1 (top Left) drawFromX + GameConstants.TILE_SIZE_X, drawFromY + GameConstants.TILE_SIZE_Y, // Source 2 (bottom right) null); } @Override public boolean equals(Object o) { if (o == this) return true; if (!(o instanceof CollapsibleTile) ) return false; CollapsibleTile other = (CollapsibleTile) o; return this.id == other.id; } @Override public int hashCode() { int result = 17; result += result * 31 + id; return result; } @Override public String toString() { return "Collapsible Tile of id " + id + " with damange " + damage; } }