src/actors/HeroShip.java
package actors;
import collision.CollisionDetection;
import events.EventResolution;
import events.commands.HeroShipShoot;
import utilities.*;
import game.Game;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.awt.geom.Rectangle2D;
import java.util.Arrays;
public class HeroShip implements GraphicalShape, CollisionalShape, DynamicElement {
public static final int WIDTH = 100;
public static final int HEIGHT = 80;
public static final double DRAWING_SCALE = 0.5;
private static final int DELTA_X = 5;
private static final int SHOOT_COOLDOWN_UPDATE_TIME = 30;
private final EventResolution eventResolution;
private final Area currentShape;
private long timeUntilShootingAvailable = 0;
public HeroShip(EventResolution eventResolution) {
Point location = new Point((int)(Game.CANVAS_WIDTH/2 - (WIDTH/2 * DRAWING_SCALE)), Game.CANVAS_HEIGHT - HEIGHT);
this.eventResolution = eventResolution;
this.currentShape = generateShape(location);
}
public void MoveLeft(){
AffineTransform transform = new AffineTransform();
if(CollisionDetection.IsShapeAtEdge_Left(this))
transform.translate(1 - this.currentShape.getBounds2D().getMinX(), 0);
else
transform.translate(- DELTA_X, 0);
currentShape.transform(transform);
}
public void MoveRight(){
AffineTransform transform = new AffineTransform();
if(CollisionDetection.IsShapeAtEdge_Right(this))
transform.translate(Game.CANVAS_WIDTH - this.currentShape.getBounds2D().getMaxX() - 1, 0);
else
transform.translate(DELTA_X, 0);
currentShape.transform(transform);
}
public void Shoot(){
if(timeUntilShootingAvailable <= 0){
Rectangle2D shipBounds = this.currentShape.getBounds2D();
Point projectileLocation = new Point((int)(shipBounds.getMinX()), (int)shipBounds.getMinY());
eventResolution.Push(new HeroShipShoot(projectileLocation));
timeUntilShootingAvailable = SHOOT_COOLDOWN_UPDATE_TIME;
}
}
@Override
public void Update(){
timeUntilShootingAvailable = timeUntilShootingAvailable - 1;
}
@Override
public void Paint(Graphics2D graphics){
graphics.setColor(Color.white);
Area heroShipDrawingShape = GetCollisionArea();
graphics.fill(heroShipDrawingShape);
}
@Override
public Area GetCollisionArea() {
return currentShape;
}
private static Area generateShape(Point location){
Area area = new Area(new Rectangle(
location.x, location.y,
(int)(WIDTH*DRAWING_SCALE),(int)(HEIGHT*DRAWING_SCALE)));
Arrays.stream(new Area[]{
getSingleShapePeace(location, 40, 0, 20, 10),
getSingleShapePeace(location, 0, 0, 20, 20),
getSingleShapePeace(location, (WIDTH - 20), 0, 20, 20),
getSingleShapePeace(location, 0, 6, 25, 2),
getSingleShapePeace(location, (WIDTH - 25), 6, 25, 2),
getSingleShapePeace(location, 0, 10, 25, 2),
getSingleShapePeace(location, (WIDTH - 25), 10, 25, 2),
getSingleShapePeace(location, 0, 14, 25, 2),
getSingleShapePeace(location, (WIDTH - 25), 14, 25, 2),
getSingleShapePeace(location, 0, 20, 30, 20),
getSingleShapePeace(location, (WIDTH - 30), 20, 30, 20),
getSingleShapePeace(location, 0, 40, 20, 10),
getSingleShapePeace(location, (WIDTH - 20), 40, 20, 10),
getSingleShapePeace(location, 0, 50, 10, 10),
getSingleShapePeace(location, (WIDTH - 10), 50, 10, 10),
getSingleShapePeace(location, 0, 76, 16, 5),
getSingleShapePeace(location, (WIDTH - 16), 76, 16, 5),
getSingleShapePeace(location, 40, 76, 20, 8),
}).forEach(area::subtract);
return area;
}
private static Area getSingleShapePeace(Point location, int xPosition, int yPosition, int width, int height){
return new Area(new Rectangle(
(int)(xPosition*DRAWING_SCALE) + location.x, (int)(yPosition*DRAWING_SCALE) + location.y,
(int)(width*DRAWING_SCALE), (int)(height*DRAWING_SCALE)));
}
}