@ -0,0 +1,216 @@ |
||||
/** |
||||
* 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; |
||||
} |
||||
} |
Before Width: | Height: | Size: 207 B After Width: | Height: | Size: 4.8 KiB |
Before Width: | Height: | Size: 219 B After Width: | Height: | Size: 4.8 KiB |
After Width: | Height: | Size: 121 B |
Before Width: | Height: | Size: 125 B After Width: | Height: | Size: 120 B |
Before Width: | Height: | Size: 129 B After Width: | Height: | Size: 120 B |
Before Width: | Height: | Size: 197 B After Width: | Height: | Size: 192 B |
Before Width: | Height: | Size: 195 B After Width: | Height: | Size: 164 B |
Before Width: | Height: | Size: 203 B After Width: | Height: | Size: 165 B |
Before Width: | Height: | Size: 210 B After Width: | Height: | Size: 166 B |
Before Width: | Height: | Size: 198 B After Width: | Height: | Size: 157 B |
Before Width: | Height: | Size: 188 B After Width: | Height: | Size: 165 B |
Before Width: | Height: | Size: 192 B After Width: | Height: | Size: 167 B |
Before Width: | Height: | Size: 204 B After Width: | Height: | Size: 161 B |
Before Width: | Height: | Size: 206 B After Width: | Height: | Size: 167 B |
Before Width: | Height: | Size: 212 B After Width: | Height: | Size: 163 B |
Before Width: | Height: | Size: 182 B After Width: | Height: | Size: 166 B |
Before Width: | Height: | Size: 213 B After Width: | Height: | Size: 167 B |
Before Width: | Height: | Size: 192 B After Width: | Height: | Size: 161 B |
Before Width: | Height: | Size: 201 B After Width: | Height: | Size: 167 B |
Before Width: | Height: | Size: 192 B After Width: | Height: | Size: 164 B |
Before Width: | Height: | Size: 189 B After Width: | Height: | Size: 156 B |
Before Width: | Height: | Size: 194 B After Width: | Height: | Size: 158 B |
Before Width: | Height: | Size: 196 B After Width: | Height: | Size: 170 B |
Before Width: | Height: | Size: 197 B After Width: | Height: | Size: 158 B |
Before Width: | Height: | Size: 178 B After Width: | Height: | Size: 169 B |
Before Width: | Height: | Size: 172 B After Width: | Height: | Size: 162 B |
Before Width: | Height: | Size: 184 B After Width: | Height: | Size: 159 B |