module es.enemy;

private import opengl;
private import std.math;
private import es.basis;
private import es.gamemanager;
private import es.screen;
private import es.field;
private import es.shape;
private import es.moving;

public enum{
	BULLET, MISSILE, BOUND, THREEWAY, FOURWAY, SCATTER, PLANE, NIGHTWING, ICEBERG, SWINE
}

public abstract class Enemy {
  public Shape shape;
  public Enemy parent;
  public Moving moving;
  public real fx ,fy ,fz;
  public real x ,y ,z;
  public real vx ,vy;
  public real sx ,sy ,sz;
  public real largeness;
  public real power;
  public real maxhp;
  public real hp;
  public int attackTerm;
  public int reloadTerm;
  public int vanishTerm;
  public bool start;
  private int attackCnt;
  private int reloadCnt;
  private int attackTimes;
  private real dam;
  private bool exist;
  public bool destroyed;
  private bool attacking;
  private bool vanished;
  private int vanCnt;
  public int cnt;
  public this(Enemy parent ,Moving moving,real hp ,real fx ,real fy ,real fz ,real vx ,real vy){
    this.parent = parent;
    this.moving = moving;
    this.fx = fx;
    this.fy = fy;
    this.fz = fz;
    this.vx = vx;
    this.vy = vy;
    this.maxhp = hp;
    this.hp = maxhp;
    if(maxhp < 5)largeness = 15;
    else largeness = sqrt(maxhp - 4) * 5 + 15;
    x = field.transX(fx ,fy ,fz);
    y = field.transY(fx ,fy ,fz);
    z = field.transZ(fx ,fy ,fz);
	sx = 0;
	sy = 0;
	sz = 0;
    exist =true;
    destroyed = false;
    vanished = false;
    start = true;
    attacking = true;
    
    attackCnt = 0;
    reloadCnt = 0;
    attackTimes = 0;
    dam = 0;
    cnt = 0;
    vanCnt = 0;
  }
  public void move(){
  	
    if(0 < vanishTerm && vanishTerm <= cnt)vanish();
   if(vanished){
     if(30 < vanCnt)setExist(false);
      vanCnt ++; 
   }else if(start){
     real fr = dist(fx ,fy ,field.x ,field.y );
     if(field.radius < fr){
       fx = fx * 0.99;
       fy = fy * 0.99;
     }else if(5 < abs(fz)){
       fz -= fz /abs(fz) * 5;
     }else {
       fz = 0;
       start = false;
     }
   }else {
   	
     if(attacking){
       
       attackCnt ++;
       attack(attackTimes ,attackCnt);
       if(attackTerm < attackCnt){
        attacking = false;
        attackCnt = 0;
        attackTimes ++;
       }
       
      } else{
      reloadCnt ++;
      if(reloadTerm < reloadCnt){
        if(0 < attackTerm)attacking = true;
        reloadCnt = 0;
       } 
     }
	 
     moving.update(attacking);
	 
     real fr = dist(fx ,fy ,field.x ,field.y );
     if(field.radius < fr){
       bonk(fr);
     }
     if(dist(ship.x ,ship.y ,ship.z ,x ,y ,z) < largeness){
        ship.damage(power);
     }
	 
	  sx = dam * rand.nextFloat(5.0f);
    sy = dam * rand.nextFloat(5.0f);
    sz = dam * rand.nextFloat(5.0f);
	
	 
   }
   if(dam > 0)dam -= 1.0f;
    else dam = 0;
    
	
	
	
	
	cnt ++;
  }
   public void draw(){
  
   	glPushMatrix();
	
    x = field.transX(fx ,fy ,fz);
    y  = field.transY(fx ,fy ,fz);
    z = field.transZ(fx ,fy ,fz);
    real[] ax = shape.x;
    real[] ay = shape.y;
    real[] az = shape.z;
    
	
	
    glTranslated(x + sx, y + sy, z + sz);
    roll();
	real sc;
    if(start)glColor3d(0.5,0.5,0.5);
    else if(vanished){
      if(destroyed){
        glColor3d(0.5,0.5,0.5);
		sc = 1 + (900.0 - (30 - cast(real)vanCnt) * (30 - cast(real)vanCnt)) / 100.0;
        glScaled(sc, sc, sc);
      }else{
        glColor3d(0.5,0.5,0.5);
		sc = 1.0 - (900.0 - (30 - cast(real)vanCnt) * (30 - cast(real)vanCnt)) / 900.0;
        glScaled(sc, sc, sc);
      }
    }
    else glColor3d(1,1,1);
    if(parent is null)glLineWidth(2);
    else glLineWidth(1);
    glBegin(GL_LINE_LOOP);
    for(int i = 0; i < ax.length ;i ++){
      glVertex3d(ax[i] ,ay[i] ,az[i]);
    }
    glEnd();
    glLineWidth(1);
    
	glPopMatrix();
  }
  public  void setExist(bool e){
    exist = e;
  }
  public void destroy(){
    real rec;
    if(parent is null){
      stage.wait -= cast(real)maxhp * stage.rank / 2;
      rec = log(maxhp + 1);
    }else rec = log(maxhp + 1) / 10;
    ship.recPlus(rec);
    destroyed = true;
    vanished = true;
  }
  public void vanish(){
    destroyed = false;
    vanished = true;
  }
   public bool isExist(){
    return exist;
  }
  public real damage(real power){
    real h;
    if(start || destroyed)h = 0;
    else{
      h =  hp;
      hp -= power;
      dam = power;
      if(hp <= 0)destroy();
    }
    return h;
  }
  public real aim(){
    return atan2(vy ,vx);
  }
  public abstract void attack(int attackTerm ,int attackCnt);
  public abstract void bonk(real fr);
  public abstract void roll();
}

Shape BULLET_SHAPE;
class Bullet:Enemy{
  public this(Enemy parent ,Moving moving ,real hp ,real fx ,real fy ,real fz ,real vx ,real vy){
    super(parent ,moving ,hp ,fx ,fy ,fz ,vx ,vy);
    reloadTerm = 0;
    attackTerm = 0;
    vanishTerm = -1;
    power = 5.0;
    if(BULLET_SHAPE is null){
      real[] a = [-2.2 ,-0.8 ,0.0 ,0.8 ,1.0];
      real[] b = [0.0  ,0.6 ,1.0 ,0.6 ,0.0];
      BULLET_SHAPE = new Pole(a ,b ,6);
    }
    shape = cast(Shape)BULLET_SHAPE.clone();
    shape.multi(largeness);
  }
  public void attack(int attackTerm ,int attackCnt){}
  public void bonk(real fr){
    vanish();
  }
  public void roll(){
    glRotated(aim()*180.0/PI, 0,0,1);
    glRotated(360.0 * cast(real)(cnt % 60) / 60 ,1,0,0);
  }
}
Shape MISSILE_SHAPE;
class Missile:Enemy {
  public this(Enemy parent ,Moving moving ,real hp ,real fx ,real fy, real fz ,real vx ,real vy){
    super(parent ,moving ,hp ,fx ,fy ,fz ,vx ,vy);
    power = 10.0;
    reloadTerm = 0;
    attackTerm = 0;
    vanishTerm = 300;
    if(MISSILE_SHAPE is null){
      real[] a = [-1.0 ,-1.5  ,-1.0   ,-0.5 ,0.0 ,2.0   ,2.5];
      real[] b = [0.0  ,1.0     ,0.7  ,0.3  ,1.0 ,0.7 ,0.0];
      MISSILE_SHAPE = new Pole(a ,b ,6);
    }
    shape = cast(Shape)MISSILE_SHAPE.clone();
    shape.multi(largeness);
  }
  public void attack(int attackTerm ,int attackCnt){}
  public void bonk(real fr){
  }
  public void roll(){
    glRotated(aim()*180.0/PI, 0,0,1);
    glRotated(360.0 * cast(real)(cnt % 60) / 60 ,1,0,0);
  }
}
Shape BOUND_SHAPE;
class Bound:Enemy {
  public this(Enemy parent ,Moving moving ,real hp ,real fx ,real fy, real fz ,real vx ,real vy){
    super(parent ,moving ,hp ,fx ,fy ,fz ,vx ,vy);
    power = 5.0;
    reloadTerm = 0;
    attackTerm = 0;
    vanishTerm = 600;
    if(BOUND_SHAPE is null){
      real[] a = [-1 ,0 ,1];
      real[] b = [0 ,1 ,0];
      BOUND_SHAPE = new Pole(a ,b ,6);
    }
    shape = cast(Shape)BOUND_SHAPE.clone();
    shape.multi(largeness);
  }
  public void attack(int attackTerm ,int attackCnt){}
  public void bonk(real fr){
    real vr = dist(0 ,0 ,vx ,vy);
    real theta = atan2(fy ,fx);
    real rad = atan2(vy ,vx);
    vx = - vr * cos(2 * theta -rad);
    vy = - vr * sin(2 * theta - rad);
    
    fx = fx / fr * field.radius;
    fy = fy / fr * field.radius;
  }
  public void roll(){
    glRotated(90.0, 0, 1, 0);
    glRotated(360.0 * cast(real)(cnt % 60) / 60, 1, 0, 0);
  }
}
Shape THREEWAY_SHAPE;
public class Threeway:Enemy {
	
  public this(Enemy parent ,Moving moving ,real hp ,real fx ,real fy, real fz ,real vx ,real vy){
	
    super(parent ,moving ,hp ,fx ,fy ,fz ,vx ,vy);
	
    power = 10.0;
    reloadTerm = 60;
    attackTerm = 30;
    vanishTerm = 600;
    if(THREEWAY_SHAPE is null){
      real[] a = [-1.2 ,-1.0  ,-0.6   ,0.0  ,0.6 ,1.0   ,1.2];
      real[] b = [0.0  ,0.5     ,0.8  ,1.0 ,0.8  ,0.5 ,0.0];
      THREEWAY_SHAPE = new Pole(a ,b ,6);
    }
    shape = cast(Shape)THREEWAY_SHAPE.clone();
    shape.multi(largeness);
	
  }
  public void attack(int attackTerm ,int attackCnt){
  
    if(attackCnt % 30 == 1){
      real aim = atan2(ship.fy - fy ,ship.fx -fx);
	  
      ep.addEnemy(this ,BULLET ,new Straight() ,30 ,fx ,fy ,fz ,cos(aim) * 5.0,sin(aim) * 5.0);
      ep.addEnemy(this ,MISSILE ,new Homing(2.0*PI / 360) ,10 ,fx ,fy ,fz ,cos(aim + PI / 3) * 3.0 ,sin(aim + PI / 3) * 3.0);
      ep.addEnemy(this ,MISSILE ,new Homing(2.0*PI / 360) ,10 ,fx ,fy ,fz ,cos(aim - PI / 3) * 3.0 ,sin(aim - PI / 3) * 3.0);
	  
    }
	
  }
  public void bonk(real fr){
  }
  public void roll(){
    glRotated(90.0, 0, 1, 0);
    glRotated(360.0 * cast(real)(cnt % 60) / 60, 1, 0, 0);
  }
}
Shape FOURWAY_SHAPE;
public class Fourway:Enemy {
  public this(Enemy parent ,Moving moving ,real hp ,real fx ,real fy, real fz ,real vx ,real vy){
    super(parent ,moving ,hp ,fx ,fy ,fz ,vx ,vy);
    power = 10.0;
    reloadTerm = 60;
    attackTerm = 30;
    vanishTerm = 600;
    if(FOURWAY_SHAPE is null){
      real[][] a = [
        [-1.2 ,-0.6 ,0.0   ,0.6 ,1.2],
        [-0.4 ,-0.4 ,-0.4  ,0.4 ,0.4]
      ];
      real[][] b =[
        [0.0    ,0.6  ,1.2 ,0.6 ,0.0],
        [0.4  ,0.4  ,0.4   ,0.4  ,0.4]
      ];
      FOURWAY_SHAPE = new Pole(a ,b ,8);
    }
    shape = cast(Shape)FOURWAY_SHAPE.clone();
    shape.multi(largeness * 1.5);
  }
  public void attack(int attackTerm ,int attackCnt){
    if(attackCnt % 30 == 1){
      real aim = 2.0 * PI * cast(real)(cnt % 180) / 180.0;
	  
      ep.addEnemy(this ,BOUND ,new Straight() ,10 ,fx ,fy ,fz ,cos(aim) * 5.0,sin(aim) * 5.0);
      ep.addEnemy(this ,BOUND ,new Straight() ,10 ,fx ,fy ,fz ,cos(aim + PI / 2) * 5.0 ,sin(aim + PI / 3) * 5.0);
      ep.addEnemy(this ,BOUND ,new Straight() ,10 ,fx ,fy ,fz ,cos(aim + PI) * 5.0 ,sin(aim + PI / 3) * 5.0);
      ep.addEnemy(this ,BOUND ,new Straight() ,10 ,fx ,fy ,fz ,cos(aim - PI / 2) * 5.0 ,sin(aim - PI / 3) * 5.0);
	  
    }
  }
  public void bonk(real fr){
  }
  public void roll(){
    glRotated(90.0 ,0,1,0);
    glRotated(360.0 * cast(real)(cnt % 180) / 180,1,0,0);
  }
}
Shape SCATTER_SHAPE;
class Scatter:Enemy {
  public this(Enemy parent ,Moving moving ,real hp ,real fx ,real fy, real fz ,real vx ,real vy){
    super(parent ,moving ,hp ,fx ,fy ,fz ,vx ,vy);
    power = 10.0;
    reloadTerm = 60;
    attackTerm = 30;
    vanishTerm = 600;
    if(SCATTER_SHAPE is null){
      real[][] a = [
        [-0.6 ,-1 ,-0.6  ,1.0 ,0.4],
        [-0.6 ,0.0  ,0.0     ,0.0  ,0.4]
      ];
      real[][] b =[
       [0.0 ,0.5  ,1.0 ,0.4 ,0.0],
       [0.0 ,0.6  ,0.6  ,0.6,0.0]
     ];
      SCATTER_SHAPE = new Pole(a ,b ,6);
    }
    shape = cast(Shape)SCATTER_SHAPE.clone();
    shape.multi(largeness);
  }
  public void attack(int attackTerm ,int attackCnt){
    if(attackCnt % 10 == 0){
      real drad = PI / 30.0;
      real aim = atan2(vy ,vx);
      real si ,co;
      real dsi ,dco;
      real temp;
      si = sin(aim - PI / 3.0);
      co = cos(aim - PI / 3.0);
      dsi = sin(drad);
      dco = cos(drad);
      for(real i = -PI /3.0;i <= PI / 3.0;i += drad){
        temp = co;
        co = co * dco - si * dsi;
        si = temp * dsi + si * dco;
        ep.addEnemy(this ,BULLET ,new Straight() ,1 ,fx ,fy ,fz ,co * 3.0,si * 3.0);
      }
    }
  }
  public void bonk(real fr){
  }
  public void roll(){
    
    glRotated(aim()*180.0/PI, 0, 0, 1);
    glRotated(360.0 * cast(real)(cnt % 60) / 60,1,0,0);
  }
}
Shape PLANE_SHAPE;
class Plane:Enemy {
  public this(Enemy parent ,Moving moving ,real hp ,real fx ,real fy, real fz ,real vx ,real vy){
    super(parent ,moving ,hp ,fx ,fy ,fz ,vx ,vy);
    power = 10.0;
    reloadTerm = 60;
    attackTerm = 30;
    vanishTerm = 600;
    if(PLANE_SHAPE is null){
      real[][] a = [
        [-1.0 ,-0.8 ,-0.6 ,0.2 ,1.4],
        [-1.0 ,-1.0 ,-0.6 ,0.2 ,0.2]
      ];
      real[][] b =[
       [0.0 ,0.8  ,1.2 ,0.6 ,0.0],
       [0.2 ,0.2  ,0.4 ,0.2 ,0.2]
     ];
      PLANE_SHAPE = new Pole(a ,b ,4);
    }
    shape = cast(Shape)PLANE_SHAPE.clone();
    shape.multi(largeness);
  }
  public void attack(int attackTerm ,int attackCnt){
    if(attackCnt % 5 == 0 && 15 < attackCnt ){
      real vr = dist(0 ,0 ,vx ,vy);
      ep.addEnemy(this ,BULLET ,new Straight() ,5 ,fx ,fy ,fz ,vx / vr * 6.0 ,vy / vr *6.0);
    }
  }
  public void bonk(real fr){
  }
  public void roll(){
    glRotated(aim()*180.0/PI ,0,0,1);
  }
}
Shape NIGHTWING_SHAPE;
class Nightwing:Enemy {
  public this(Enemy parent ,Moving moving ,real hp ,real fx ,real fy, real fz ,real vx ,real vy){
    super(parent ,moving ,hp ,fx ,fy ,fz ,vx ,vy);
    power = 10.0;
    reloadTerm = 60;
    attackTerm = 60;
    vanishTerm = 600;
    if(NIGHTWING_SHAPE is null){
      real[][] a = [
        [0.0 ,0.2 ,0.0   ,-1.0 ,0.8 ,1.0 ,0.9 ,0.7],
        [0.0 ,0.2 ,0.2 ,0.2  ,0.5 ,0.5 ,0.5 ,0.0]
      ];
      real[][] b =[
       [0.0  ,0.4 ,0.8 ,1.2  ,1.0 ,0.6 ,0.2 ,0.0],
       [0.0  ,0.3  ,0.5 ,0.6 ,0.5 ,0.5 ,0.3 ,0.0]
     ];
      NIGHTWING_SHAPE = new Pole(a ,b ,8);
    }
    shape = cast(Shape)NIGHTWING_SHAPE.clone();
    shape.multi(largeness);
  }
  public void attack(int attackTerm ,int attackCnt){
    if(20 < attackCnt){
      if(attackCnt < 40){
        if(attackCnt % 3 == 0){
          real vr = dist(0 ,0 ,vx ,vy);
          ep.addEnemy(this ,BULLET ,new Straight() ,5 ,fx ,fy ,fz ,vx / vr * 8.0 ,vy / vr * 8.0);
        }
      }else if(attackCnt == 55){
        real vr = dist(0 ,0 ,vx ,vy);
        ep.addEnemy(this ,MISSILE ,new Homing(2.0*PI / 180.0) ,20 ,fx ,fy ,fz ,- vx / vr * 5.0 ,- vy / vr * 5.0);
      }
    }
  }
  public void bonk(real fr){
  }
  public void roll(){
    glRotated(aim()*180.0/PI ,0,0,1);
    glRotated(- 90.0 * fmax((1 - cast(real)(fmax(cnt - 80,0)) / 30.0) ,0),0,1,0);
    glRotated(360.0 * cast(real)(cnt % 60) / 60 ,1,0,0);
    
  }
}
Shape ICEBERG_SHAPE;
class Iceberg:Enemy {
  public this(Enemy parent ,Moving moving ,real hp ,real fx ,real fy, real fz ,real vx ,real vy){
    super(parent ,moving ,hp ,fx ,fy ,fz ,vx ,vy);
    power = 10.0;
    reloadTerm = 60;
    attackTerm = 30;
    vanishTerm = 600;
    if(ICEBERG_SHAPE is null){
      real[][] a = [
        [0.0 ,-0.5 ,0.0 ,1.0 ,0.0],
        [0.0]
      ];
      real[][] b =[
       [0.0  ,0.5 ,1.0 ,0.5 ,0.0],
       [0.5]
     ];
      ICEBERG_SHAPE = new Pole(a ,b ,8);
    }
    shape = cast(Shape)ICEBERG_SHAPE.clone();
    shape.multi(largeness);
  }
  void attack(int attackTerm ,int attackCnt){
    if(attackCnt % 10 == 0){
      real fr = dist(fx ,fy ,ship.fx ,ship.fy);
      ep.addEnemy(this ,BOUND ,new Straight() ,5 ,fx ,fy ,fz , (ship.fx -fx) / fr * 5.0 ,(ship.fy -fy) / fr * 5.0);
    }
  }
  void bonk(real fr){
  }
  void roll(){
    glRotated(-90.0 ,0,1,0);
    glRotated(360 * cast(real)(cnt % 60) / 60 ,1,0,0);
    
  }
}
Shape SWINE_SHAPE;
class Swine:Enemy {
  public this(Enemy parent ,Moving moving ,real hp ,real fx ,real fy, real fz ,real vx ,real vy){
    super(parent ,moving ,hp ,fx ,fy ,fz ,vx ,vy);
    power = 10.0;
    reloadTerm = 45;
    attackTerm = 20;
    vanishTerm = 600;
    if(SWINE_SHAPE is null){
      real[][] a = [
        [-1.0 ,-0.8 ,-0.6 ,0.2 ,1.2 ,0.2],
        [-1.0 ,-0.8 ,-0.6 ,0.2 ,0.4 ,0.4]
      ];
      real[][] b =[
       [0.0 ,0.8  ,1.2 ,0.6 ,0.3 ,0.0],
       [0.0 ,0.4  ,0.6 ,0.4 ,0.4 ,0.2]
     ];
      SWINE_SHAPE = new Pole(a ,b ,4);
    }
    shape = cast(Shape)SWINE_SHAPE.clone();
    shape.multi(largeness);
  }
  public void attack(int attackTerm ,int attackCnt){
  }
  public void bonk(real fr){
  }
  public void roll(){
     glRotated(aim()*180.0/PI ,0,0,1);
    glRotated(360 * cast(real)(cnt % 60) / 60 ,1,0,0);
    
  }
}

public class EnemyPool{
	public:
	Enemy[] enemy;
	protected:
  	int enemyIdx = 0;
	const int maxEnemy;
	public this() {
		maxEnemy = 16;
		enemy.length = maxEnemy;
		enemyIdx = 0;
	}

  public this(int n) {
		maxEnemy = n;
		enemy.length = maxEnemy;
		enemyIdx = 0;
  }
  public void clear(){
    foreach(inout Enemy e;enemy){
		if(e !is null){
			e.setExist(false);
		}
    }
	enemyIdx = 0;
  }

	public void addEnemy(Enemy parent ,int type ,Moving moving ,real hp ,real x ,real y ,real z ,real vx ,real vy){
    Enemy e;
    switch(type){
      case BULLET:   e =new Bullet(parent ,moving ,hp ,x ,y ,z ,vx ,vy);break;
      case MISSILE:  e =new Missile(parent ,moving ,hp ,x ,y ,z ,vx ,vy);break;
      case BOUND:    e =new Bound(parent ,moving ,hp ,x ,y ,z ,vx ,vy);break;
      case THREEWAY: e =new Threeway(parent ,moving ,hp ,x ,y ,z ,vx ,vy);break;
      case FOURWAY:  e =new Fourway(parent ,moving ,hp ,x ,y ,z ,vx ,vy);break;
      case SCATTER:  e =new Scatter(parent ,moving ,hp ,x ,y ,z ,vx ,vy);break;
      case PLANE:    e =new Plane(parent ,moving ,hp ,x ,y ,z ,vx ,vy);break;
      case NIGHTWING:e =new Nightwing(parent ,moving ,hp ,x ,y ,z ,vx ,vy);break;
      case ICEBERG:  e =new Iceberg(parent ,moving ,hp ,x ,y ,z ,vx ,vy);break;
      case SWINE:    e =new Swine(parent ,moving ,hp ,x ,y ,z ,vx ,vy);break;
      default:
      e =null;break;
    }
    moving.set(e);
		
		for(int i = 0;i < enemy.length;i ++){
			if(enemy[enemyIdx] is null || !enemy[enemyIdx].isExist()){
				enemy[enemyIdx] = e;
				return true;
			}
			enemyIdx ++;
			if(enemy.length <= enemyIdx)enemyIdx = 0;
		}
		return false;
	}
	public void move() {
		for (int i = 0;i < enemy.length;i ++){
			Enemy e = enemy[i];
    		if (e !is null && e.isExist){
				
        		e.move();
				if(e.isExist() == false)e = null;
      		}else{
	    }
    }
  }


  public void draw() {
		
    for (int i = 0;i < enemy.length;i ++){
		Enemy e = enemy[i];
      	if (e !is null && e.isExist()){
			glPushMatrix();
   	  		e.draw();
			glPopMatrix();
      }
    }
		
  }

  public void allDamage(real power){
	foreach(inout Enemy e;enemy){
		if(e !is null && e.isExist()){
			e.damage(power);
		}
	}
   	//parts.length = 0;
    enemyIdx = 0;
  }

}
/*
public class EnemyPool {
  private ArrayList enemies;
  EnemyPool(){
    init();
  }
  void init(){
    if(enemies != null){
      enemies.clear();
    }else enemies = new ArrayList();
  }
  void addEnemy(Enemy parent ,int type ,Moving moving ,real hp ,real x ,real y ,real z ,real vx ,real vy){
    Enemy e;
    switch(type){
      case BULLET:   e =new Bullet(parent ,moving ,hp ,x ,y ,z ,vx ,vy);break;
      case MISSILE:  e =new Missile(parent ,moving ,hp ,x ,y ,z ,vx ,vy);break;
      case BOUND:    e =new Bound(parent ,moving ,hp ,x ,y ,z ,vx ,vy);break;
      case THREEWAY: e =new Threeway(parent ,moving ,hp ,x ,y ,z ,vx ,vy);break;
      case FOURWAY:  e =new Fourway(parent ,moving ,hp ,x ,y ,z ,vx ,vy);break;
      case SCATTER:  e =new Scatter(parent ,moving ,hp ,x ,y ,z ,vx ,vy);break;
      case PLANE:    e =new Plane(parent ,moving ,hp ,x ,y ,z ,vx ,vy);break;
      case NIGHTWING:e =new Nightwing(parent ,moving ,hp ,x ,y ,z ,vx ,vy);break;
      case ICEBERG:  e =new Iceberg(parent ,moving ,hp ,x ,y ,z ,vx ,vy);break;
      case SWINE:    e =new Swine(parent ,moving ,hp ,x ,y ,z ,vx ,vy);break;
      default:
      e =null;break;
    }
    moving.set(e);
    enemies.add(e);
  }
  void update(){
    int i = enemies.size() - 1;
      while(0 <=i){
        Enemy e = (Enemy)enemies.get(i);
        popMatrix();
        pushMatrix();
        e.update();
        if(e.isExist() == false){
          enemies.remove(i);
        }
        i--;
      }
    }
    void allDamage(real power){
      int i = enemies.size() - 1;
      while(0 <=i){
        Enemy e = (Enemy)enemies.get(i);
        e.damage(power);
        i--;
      }
    }
}
*/