package code.kalter.longflight.game; import code.kalter.longflight.game.bullet.Collisionable; import code.kalter.longflight.game.bullet.Gun; import code.kalter.longflight.game.explosion.Detonator; import code.kalter.longflight.game.ship.Ship; import code.kalter.longflight.game.ship.ShipEnemy; import java.io.IOException; import java.util.Random; import java.util.Timer; import java.util.TimerTask; import javax.microedition.lcdui.Graphics; /** * Враги и всё связанное с ними * * @author KalterFive */ public class Enemy implements Collisionable { private static final int COUNT = 28; // специальное обозначение для несуществующего врага private static final int NULL = 666; private final int screenW; private final int screenH; private final Gamer gamer; private final Detonator detonator; private final ShipEnemy ship; private final Gun gun; private final Random random; private Timer createEnemy; // enemy... private final int[] x; private final int[] y; private final int[] type; private final int[] life; private final long[] lastFire; private int score; private int numKill; private int boom; // индекс врага, в которого попала пуля public Enemy(int screenW, int screenH, Gun gun, Detonator detonator, Gamer gamer) throws IOException { this.screenW = screenW; this.screenH = screenH; this.gun = gun; this.detonator = detonator; this.gamer = gamer; ship = ShipEnemy.getInstance(); random = new Random(); x = new int[COUNT]; y = new int[COUNT]; type = new int[COUNT]; life = new int[COUNT]; lastFire = new long[COUNT]; } // очистка всех врагов public void setNull() { for (int i = 0; i < COUNT; i++) { type[i] = NULL; } numKill = score = 0; } public void update() { for (int i = 0; i < COUNT; i++) { if (type[i] == NULL) { continue; } switch (type[i]) { case Ship.LAX: aiLax(i); break; case Ship.POWERFUL: aiPowerful(i); break; case Ship.UNIVERSAL: aiUniversal(i); break; case Ship.STRONG: aiStrong(i); break; } } } public void paint(Graphics graphics) { for (int i = 0; i < COUNT; i++) { if (type[i] == NULL) { continue; } graphics.drawImage(ship.getImage(type[i]), x[i], y[i], 0); } } // override public boolean isCollisionOfBullet(int bx, int by) { for (int i = 0; i < COUNT; i++) { if (type[i] == NULL) { continue; } if ((bx > x[i]) && (bx < x[i] + Ship.SIZE) && (by > y[i]) && (by < y[i] + Ship.SIZE)) { boom = i; return true; } } return false; } // override public void boomOfBullet() { if (--life[boom] <= 0) { numKill++; score += (((type[boom] + 1) * 2) - 1); type[boom] = NULL; detonator.activate(x[boom], y[boom]); } } // override public int getType() { return Gun.ENEMY; } public void activateCreator() { createEnemy = new Timer(); createEnemy.schedule(new TimerTask() { // override public void run() { for (int i = 0; i < COUNT; i++) { if (type[i] != NULL) { continue; } int type = random.nextInt(numKill / 30 + 1); Enemy.this.type[i] = type >= Ship.COUNT ? Ship.COUNT - 1 : type < 0 ? 0 : type; life[i] = ship.getLife(Enemy.this.type[i]); lastFire[i] = System.currentTimeMillis(); x[i] = random.nextInt(screenW - Ship.SIZE); y[i] = -Ship.SIZE; break; } } }, 2500, 2500); } public void deactivateCreator() { createEnemy.cancel(); } public int getScore() { return score; } private void aiLax(int i) { y[i] += ship.getSpeed(type[i]); if (y[i] > screenH) { type[i] = NULL; } if (y[i] > gamer.getY()) { return; } fire(i); if (x[i] > gamer.getX()) { x[i] -= ship.getSpeed(type[i]) / 2; } if (x[i] < gamer.getX()) { x[i] += ship.getSpeed(type[i]) / 2; } } private void aiPowerful(int i) { y[i] += ship.getSpeed(type[i]); if (y[i] > screenH) { type[i] = NULL; } if (y[i] > gamer.getY()) { return; } fire(i); } private void aiUniversal(int i) { if (y[i] < screenH / 3) { y[i] += ship.getSpeed(type[i]); } fire(i); if (x[i] > gamer.getX()) { x[i] -= ship.getSpeed(type[i]) / 2; } if (x[i] < gamer.getX()) { x[i] += ship.getSpeed(type[i]) / 2; } } private void aiStrong(int i) { y[i] += ship.getSpeed(type[i]); if (y[i] > screenH) { type[i] = NULL; } if (y[i] > gamer.getY()) { return; } if (x[i] > gamer.getX()) { x[i] -= ship.getSpeed(type[i]); } if (x[i] < gamer.getX()) { x[i] += ship.getSpeed(type[i]); } final int deltaX = Math.abs(x[i] - gamer.getX()); if (deltaX < Ship.SIZE * 2) { fire(i); } } private void fire(int i) { if (System.currentTimeMillis() - lastFire[i] > ship.getDeltaFire(type[i])) { gun.fire(Gun.ENEMY, x[i] + 4, y[i] + 38); gun.fire(Gun.ENEMY, x[i] + 30, y[i] + 38); lastFire[i] = System.currentTimeMillis(); } } }