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.
216 lines
5.0 KiB
216 lines
5.0 KiB
/** |
|
* Copyright 2022 Jamie Munro, All rights reserved |
|
* CS5041 P1 |
|
* Game 1 |
|
*/ |
|
|
|
public class Boss implements Enemy { |
|
public static final int MINIMUM_DIFFICULTY = 6; |
|
public static final int SCORE = 5000; |
|
public static final int INITIAL_HIT_POINTS = 3; |
|
public static final int SCALE_FACTOR = 50; |
|
public static final int CHANCE_OF_SPAWNING = 2; |
|
public static final int MAX_SPEED = 1; |
|
public static final int ROTATION_SPEED = 3; |
|
|
|
public static final int ANIMATION_INTERVAL = 1000; |
|
private static final int MAX_SPRITE_INDEX = 1; |
|
|
|
public static final int RELOAD_TIME = 3000; |
|
public static final int PROJECTILE_SPEED = 3; |
|
public static final int PROJECTILE_DAMAGE = 1; |
|
public static final int PROJECTILE_RANGE = 200; |
|
|
|
private final PImage[] sprites; |
|
private int spriteIndex; |
|
|
|
private final int tintR; |
|
private final int tintG; |
|
private final int tintB; |
|
|
|
private final Level level; |
|
private final Player player; |
|
|
|
private int x; |
|
private int y; |
|
private int rotation; |
|
private float speed; |
|
|
|
private int hitPoints; |
|
|
|
//animation variables |
|
private long lastChange; |
|
private boolean up; |
|
|
|
//shot variables |
|
private Projectile projectile; |
|
private PImage projectileSprite; |
|
private long lastShot; |
|
|
|
public Boss(int x, int y, PImage[] sprites, PImage projectileSprite, Level level, Player player) { |
|
this.x = x; |
|
this.y = y; |
|
this.rotation = int(random(0,360)); |
|
|
|
this.level = level; |
|
this.player = player; |
|
|
|
this.hitPoints = INITIAL_HIT_POINTS; |
|
|
|
this.sprites = sprites; |
|
this.tintR = int(random(0, 256)); |
|
this.tintG = int(random(0, 256)); |
|
this.tintB = int(random(0, 256)); |
|
|
|
this.speed = MAX_SPEED; |
|
|
|
lastChange = millis(); |
|
up = true; |
|
|
|
this.projectileSprite = projectileSprite; |
|
lastShot = millis(); |
|
|
|
this.spriteIndex = 0; |
|
} |
|
|
|
@Override |
|
public int getX() { |
|
return this.x; |
|
} |
|
|
|
@Override |
|
public int getY(){ |
|
return this.y; |
|
} |
|
|
|
@Override |
|
public int getRotation(){ |
|
return this.rotation; |
|
} |
|
|
|
@Override |
|
public PImage getSprite(){ |
|
return this.sprites[spriteIndex]; |
|
} |
|
|
|
@Override |
|
public int getScaleFactor() { |
|
return SCALE_FACTOR; |
|
} |
|
|
|
@Override |
|
public int getTintR() { |
|
return this.tintR; |
|
} |
|
|
|
@Override |
|
public int getTintG() { |
|
return this.tintG; |
|
} |
|
|
|
@Override |
|
public int getTintB() { |
|
return this.tintB; |
|
} |
|
|
|
@Override |
|
public int getMinimumDifficulty() { |
|
return MINIMUM_DIFFICULTY; |
|
} |
|
|
|
@Override |
|
public int getInitialHitPoints() { |
|
return INITIAL_HIT_POINTS; |
|
} |
|
|
|
@Override |
|
public int getHitPoints(){ |
|
return this.hitPoints; |
|
} |
|
|
|
@Override |
|
public int getScore() { |
|
return SCORE; |
|
} |
|
|
|
@Override |
|
public int getChanceOfSpawning() { |
|
return CHANCE_OF_SPAWNING; |
|
} |
|
|
|
@Override |
|
public void update(){ |
|
//animate |
|
long currentTime = millis(); |
|
if (currentTime - this.lastChange > ANIMATION_INTERVAL) { |
|
this.lastChange = currentTime; |
|
|
|
if (this.up) { |
|
spriteIndex++; |
|
if (spriteIndex == MAX_SPRITE_INDEX) up = false; |
|
} |
|
else { |
|
spriteIndex--; |
|
if (spriteIndex == 0) up = true; |
|
} |
|
} |
|
|
|
//calculate bearing to player |
|
double theta = Math.atan2(player.getX() - this.x, player.getY() - this.y); |
|
if (theta < 0) theta += 2 * PI; |
|
|
|
int degreesToPlayer = int(degrees((float) theta)); |
|
int desiredRotation = 180 - degreesToPlayer; |
|
while (desiredRotation < 0) desiredRotation += 360; |
|
|
|
if (Math.abs(this.rotation - desiredRotation) > ROTATION_SPEED) { |
|
if (desiredRotation > this.rotation) this.rotation += ROTATION_SPEED; |
|
else if (desiredRotation < this.rotation) this.rotation -= ROTATION_SPEED; |
|
} |
|
|
|
int newX = this.getX() + Math.round(this.speed * sin(radians(this.getRotation()))); |
|
int newY = this.getY() + Math.round(this.speed * -cos(radians(this.getRotation()))); |
|
|
|
//bounce off boundaries: https://forum.processing.org/two/discussion/10649/maths-calculate-reflection-angle.html |
|
if ((newX <= 0) || (newX >= level.getCols()-1)) { |
|
//verticle wall |
|
this.rotation = 360 - rotation; |
|
while (this.rotation < 0) this.rotation += 360; |
|
} |
|
else if ((newY <= 0) || (newY >= level.getRows()-1)){ |
|
//horizontal wall |
|
this.rotation = 180 - rotation; |
|
while (this.rotation < 0) this.rotation += 360; |
|
} |
|
else { |
|
this.x = newX; |
|
this.y = newY; |
|
} |
|
|
|
//shoot |
|
if (currentTime - this.lastShot > RELOAD_TIME) { |
|
lastShot = currentTime; |
|
this.projectile = new Projectile(this.x, this.y, this.rotation, this.projectileSprite, PROJECTILE_SPEED, PROJECTILE_DAMAGE, PROJECTILE_RANGE); |
|
} |
|
else { |
|
this.projectile = null; |
|
} |
|
} |
|
|
|
@Override |
|
public boolean hit() { |
|
this.hitPoints--; |
|
if (this.hitPoints <= 0) return true; |
|
return false; |
|
} |
|
|
|
@Override |
|
public List<Enemy> spawnlings() { |
|
return null; |
|
} |
|
|
|
@Override |
|
public Projectile projectile() { |
|
return this.projectile; |
|
} |
|
}
|
|
|