Logo Search packages:      
Sourcecode: val-and-rick version File versions  Download package

bulletactor.d

/*
 * $Id: bulletactor.d,v 1.1.1.1 2005/03/13 16:15:04 kenta Exp $
 *
 * Copyright 2005 Kenta Cho. Some rights reserved.
 */
module abagames.vr.bulletactor;

private import std.math;
private import std.c.stdarg;
private import opengl;
private import bulletml;
private import abagames.util.actor;
private import abagames.util.vector;
private import abagames.util.bulletml.bullet;
private import abagames.vr.bulletimpl;
private import abagames.vr.bullettarget;
private import abagames.vr.bulletactorpool;
private import abagames.vr.field;
private import abagames.vr.ship;
private import abagames.vr.screen;
private import abagames.vr.shape;
private import abagames.vr.enemy;
private import abagames.vr.shot;
private import abagames.vr.crystal;
private import abagames.vr.particle;

/**
 * Actor of an bullet controlled by BulletML.
 */
00030 public class BulletActor: Actor {
 public:
  static float totalBulletsSpeed;
  BulletImpl bullet;
  float rootRank;
  bool isActive;
 private:
  static const float BASE_SIZE = 0.8f;
  static const int DISAP_CNT = 45;
  static int nextId = 0;
  static BitmapShape[] shape;
  Field field;
  Ship ship;
  CrystalPool crystals;
  ParticlePool particles;
  Vector ppos;
  int cnt;
  bool isSimple;
  bool isTop;
  bool isAimTop;
  bool isVisible;
  bool shouldBeRemoved;
  bool isWait;
  int postWait;  // Waiting count before a top(root) bullet rewinds the action.
  int waitCnt;
  bool isMorphSeed;  // Bullet marked as morph seed disappears after it morphs.
  int disapCnt;
  bool onBlock;
  
  public static void init() {
    BitmapShape bs;
    bs = new BitmapShape(BitmapShape.bullets, 0, BASE_SIZE);
    shape ~= bs;
    bs = new BitmapShape(BitmapShape.bullets, 1, BASE_SIZE);
    shape ~= bs;
  }

  public static void close() {
    foreach (BitmapShape bs; shape)
      bs.close();
  }

  public static void resetTotalBulletsSpeed() {
    totalBulletsSpeed = 0;
  }

  public override void init(Object[] args) {
    field = cast(Field) args[0];
    ship = cast(Ship) args[1];
    crystals = cast(CrystalPool) args[2];
    particles = cast(ParticlePool) args[3];
    bullet = new BulletImpl(nextId);
    nextId++;
    ppos = new Vector;
  }

  public void set(BulletMLRunner* runner,
                  float x, float y, float deg, float speed) {
    bullet.set(runner, x, y, deg, speed, 0);
    isSimple = false;
    start();
  }

  public void set(float x, float y, float deg, float speed) {
    bullet.set(x, y, deg, speed, 0);
    isSimple = true;
    start();
  }

  private void start() {
    isTop = isAimTop = false;
    isWait = false;
    isVisible = true;
    isMorphSeed = false;
    ppos.x = bullet.pos.x;
    ppos.y = bullet.pos.y;
    cnt = 0;
    rootRank = 1;
    shouldBeRemoved = false;
    disapCnt = 0;
    isActive = true;
    if (field.getBlock(bullet.pos) >= 0)
      onBlock = true;
    else
      onBlock = false;
    exists = true;
  }

  public void setInvisible() {
    isVisible = false;
  }

  public void setTop() {
    isTop = isAimTop = true;
    setInvisible();
  }

  public void unsetTop() {
    isTop = isAimTop = false;
  }

  public void unsetAimTop() {
    isAimTop = false;
  }

  public void setWait(int prvw, int pstw) {
    isWait = true;
    waitCnt = prvw;
    postWait = pstw;
  }

  public void setMorphSeed() {
    isMorphSeed = true;
  }

  public void rewind() {
    bullet.remove();
    bullet.resetParser();
    BulletMLRunner *runner = BulletMLRunner_new_parser(bullet.getParser());
    BulletActorPool.registFunctions(runner);
    bullet.setRunner(runner);
  }

  public void remove() {
    shouldBeRemoved = true;
  }

  public void removeForced() {
    if (!isSimple)
      bullet.remove();
    exists = false;
  }

  public void startDisappear() {
    if (isVisible && disapCnt <= 0)
      disapCnt = 1;
  }

  public void changeToCrystal() {
    if (isVisible && disapCnt <= 0) {
      Crystal cs = crystals.getInstance();
      if (cs)
        cs.set(bullet.pos);
      Particle pt;
      float mx =
        (sin(bullet.deg) * bullet.speed + bullet.acc.x) *
          bullet.getSpeedRank() * bullet.xReverse;
      float my =
        (cos(bullet.deg) * bullet.speed - bullet.acc.y) *
          bullet.getSpeedRank() * bullet.yReverse;
      pt = particles.getInstanceForced();
      pt.set(bullet.pos, mx * 2, my * 2, 0.3f, 0.6f, 1, 16);
      pt = particles.getInstanceForced();
      pt.set(bullet.pos, mx * 3, my * 3, 0.3f, 0.6f, 1, 16);
      pt = particles.getInstanceForced();
      pt.set(bullet.pos, mx * 4, my * 4, 0.3f, 0.6f, 1, 16);
      exists = false;
    }
  }

  public void increasePostWait() {
    postWait++;
  }

  public override void move() {
    Vector tpos = bullet.target.getTargetPos();
    Bullet.target.x = tpos.x;
    Bullet.target.y = tpos.y;
    ppos.x = bullet.pos.x;
    ppos.y = bullet.pos.y;
    if (isAimTop)
      bullet.deg = (atan2(tpos.x - bullet.pos.x, tpos.y - bullet.pos.y) * bullet.xReverse
                    + PI / 2) * bullet.yReverse - PI / 2;
    if (isWait && waitCnt > 0) {
      waitCnt--;
      if (shouldBeRemoved)
        removeForced();
      return;
    }
    if (!isSimple) {
      bullet.move();
      if (bullet.isEnd()) {
        if (isTop) {
          rewind();
          if (isWait) {
            waitCnt = postWait;
            return;
          }
        } else if (isMorphSeed) {
          removeForced();
          return;
        }
      }
    }
    if (shouldBeRemoved) {
      removeForced();
      return;
    }
    float mx =
      (sin(bullet.deg) * bullet.speed + bullet.acc.x) *
        bullet.getSpeedRank() * bullet.xReverse;
    float my =
      (cos(bullet.deg) * bullet.speed - bullet.acc.y) *
        bullet.getSpeedRank() * bullet.yReverse;
    if (disapCnt > 0) {
      float vr = 1 - cast(float)disapCnt / DISAP_CNT * 3;
      if (vr < 0)
        vr = 0;
      mx *= vr;
      my *= vr;
    }
    bullet.pos.x += mx;
    bullet.pos.y += my;
    if (!ship.airMode)
      bullet.pos.y -= field.lastScrollY;

    if (isVisible && disapCnt <= 0) {
      if (ship.checkBulletHit(bullet.pos, ppos) || !field.checkInOuterField(bullet.pos))
        removeForced();
      totalBulletsSpeed += bullet.speed * bullet.getSpeedRank();
    }
    cnt++;
    if (disapCnt > 0) {
      disapCnt++;
      if (disapCnt > DISAP_CNT)
        removeForced();
    } else {
      if (cnt > 600)
        startDisappear();
    }
    if (!ship.airMode && field.getBlock(bullet.pos) >= 0) {
      if (!onBlock)
        startDisappear();
    } else {
      if (onBlock)
        onBlock = false;
    }
  }

  public override void draw() {
    if (!isVisible)
      return;
    //float d = (bullet.deg * bullet.xReverse + PI / 2) * bullet.yReverse - PI / 2;
    glPushMatrix();
    Screen.glTranslate(bullet.pos);
    glRotatef(cnt * 6, 0, 0, 1);
    int si = bullet.shape;
    if (disapCnt <= 0) {
      shape[si].draw();
    } else {
      float s = 1 - cast(float) disapCnt / DISAP_CNT;
      glScalef(s, s, s);
      shape[si].drawAlpha(s);
    }
    glPopMatrix();
  }
}

Generated by  Doxygen 1.6.0   Back to index