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

gamemanager.d

/*
 * $Id: gamemanager.d,v 1.2 2005/03/14 13:37:40 kenta Exp $
 *
 * Copyright 2005 Kenta Cho. Some rights reserved.
 */
module abagames.vr.gamemanager;

private import std.math;
private import opengl;
private import SDL;
private import bulletml;
private import abagames.util.vector;
private import abagames.util.rand;
private import abagames.util.bulletml.bullet;
private import abagames.util.sdl.gamemanager;
private import abagames.util.sdl.texture;
private import abagames.util.sdl.pad;
private import abagames.vr.prefmanager;
private import abagames.vr.screen;
private import abagames.vr.ship;
private import abagames.vr.field;
private import abagames.vr.bulletactor;
private import abagames.vr.bulletactorpool;
private import abagames.vr.barrage;
private import abagames.vr.enemy;
private import abagames.vr.stagemanager;
private import abagames.vr.shape;
private import abagames.vr.particle;
private import abagames.vr.letter;
private import abagames.vr.shot;
private import abagames.vr.title;
private import abagames.vr.soundmanager;
private import abagames.vr.replay;
private import abagames.vr.crystal;
private import abagames.vr.explosion;

/**
 * Manage the game state and actor pools.
 */
00040 public class GameManager: abagames.util.sdl.gamemanager.GameManager {
 public:
  bool nowait = false;
 private:
  static const float SLOWDOWN_START_BULLETS_SPEED = 6;
  float interval;
  Pad pad;
  PrefManager prefManager;
  Screen screen;
  Field field;
  Ship ship;
  ShotPool shots;
  BulletActorPool bullets;
  EnemyPool enemies;
  ParticlePool particles;
  CrystalPool crystals;
  ExplosionPool explosions;
  StageManager stageManager;
  TitleManager titleManager;
  Rand rand;
  GameState state;
  TitleState titleState;
  InGameState inGameState;
  bool escPressed;

  public override void init() {
    BarrageManager.load();
    BitmapShape.init();
    Letter.init();
    Shot.init();
    BulletActor.init();
    EnemyBit.init();
    Crystal.init();
    Explosion.init();
    pad = cast(Pad) input;
    prefManager = cast(PrefManager) abstPrefManager;
    screen = cast(Screen) abstScreen;
    field = new Field;
    ship = new Ship(pad, field, screen);
    Object[] pargs;
    pargs ~= field;
    particles = new ParticlePool(1024, pargs);
    Object[] cargs;
    cargs ~= field;
    cargs ~= ship;
    crystals = new CrystalPool(360, cargs);
    Object[] epargs;
    epargs ~= field;
    explosions = new ExplosionPool(16, epargs);
    Object[] bargs;
    bargs ~= field;
    bargs ~= ship;
    bargs ~= crystals;
    bargs ~= particles;
    bullets = new BulletActorPool(360, bargs);
    Object[] eargs;
    eargs ~= field;
    eargs ~= screen;
    eargs ~= bullets;
    eargs ~= ship;
    eargs ~= particles;
    eargs ~= crystals;
    eargs ~= explosions;
    enemies = new EnemyPool(36, eargs);
    Object[] sargs;
    sargs ~= field;
    sargs ~= enemies;
    sargs ~= bullets;
    sargs ~= particles;
    sargs ~= ship;
    shots = new ShotPool(64, sargs);
    ship.setParticles(particles);
    ship.setExplosions(explosions);
    ship.setShots(shots);
    ship.setEnemies(enemies);
    stageManager = new StageManager(field, enemies, ship, bullets);
    ship.setStageManager(stageManager);
    field.setStageManager(stageManager);
    field.setShip(ship);
    SoundManager.loadSounds();
    titleManager = new TitleManager(prefManager, pad, field, this);
    rand = new Rand;
    inGameState = new InGameState(screen, pad,
                                  field, ship, shots, bullets, enemies,
                                  particles, crystals, explosions, stageManager,
                                  prefManager, this);
    titleState = new TitleState(screen, pad,
                                field, ship, shots, bullets, enemies,
                                particles, crystals, explosions, stageManager,
                                titleManager, inGameState);
    ship.setGameState(inGameState);
  }

  public override void start() {
    loadLastReplay();
    startTitle();
  }

  public void startTitle(bool fromGameover = false) {
    if (fromGameover)
      saveLastReplay();
    titleState.setReplayData(inGameState.replayData);
    state = titleState;
    startState();
  }

  public void startInGame(bool showRank = false) {
    stageManager.showRank = showRank;
    state = inGameState;
    startState();
  }

  private void startState() {
    state.seed = rand.nextInt32();
    interval = mainLoop.INTERVAL_BASE;
    state.start();
  }

  public override void close() {
    BulletActor.close();
    EnemyBit.close();
    Crystal.close();
    Explosion.close();
    stageManager.close();
    titleState.close();
    BitmapShape.closeAll();
    Letter.close();
    BarrageManager.unload();
  }

  public void saveErrorReplay() {
    if (state == inGameState)
      inGameState.saveReplay("error.rpl");
  }

  private void saveLastReplay() {
    try {
      inGameState.saveReplay("last.rpl");
    } catch (Object o) {}
  }

  private void loadLastReplay() {
    try {
      inGameState.loadReplay("last.rpl");
    } catch (Object o) {
      inGameState.resetReplay();
    }
  }

  public override void move() {
    if (pad.keys[SDLK_ESCAPE] == SDL_PRESSED) {
      if (!escPressed) {
        escPressed = true;
        if (state == inGameState) {
          startTitle();
        } else {
          mainLoop.breakLoop();
        }
        return;
      }
    } else {
      escPressed = false;
    }
    BulletActor.resetTotalBulletsSpeed();
    state.move();
    if (!nowait) {
      // Intentional slowdown when the total speed of bullets is over SLOWDOWN_START_BULLETS_SPEED
      if (BulletActor.totalBulletsSpeed > SLOWDOWN_START_BULLETS_SPEED) {
        float sm = BulletActor.totalBulletsSpeed / SLOWDOWN_START_BULLETS_SPEED;
        if (sm > 1.75)
          sm = 1.75;
        interval += (sm * mainLoop.INTERVAL_BASE - interval) * 0.1;
      } else {
        interval += (mainLoop.INTERVAL_BASE - interval) * 0.08;
      }
      mainLoop.interval = cast(int) interval;
    }
  }

  public override void draw() {
    SDL_Event e = mainLoop.event;
    if (e.type == SDL_VIDEORESIZE) {
      SDL_ResizeEvent re = e.resize;
      if (re.w > 150 && re.h > 100)
        screen.resized(re.w, re.h);
    }
    if (screen.startRenderToLuminousScreen()) {
      glPushMatrix();
      screen.setEyepos();
      state.drawLuminous();
      glPopMatrix();
      screen.endRenderToLuminousScreen();
    }
    screen.clear();
    glPushMatrix();
    screen.setEyepos();
    state.draw();
    glPopMatrix();
    screen.drawLuminous();
    glPushMatrix();
    screen.setEyepos();
    field.drawSideWalls();
    glPopMatrix();
    /*screen.viewOrthoFixed();
    state.drawFront();
    screen.viewPerspective();*/
  }
}

/**
 * Manage the game state.
 * (e.g. title, in game, gameover, pause, ...)
 */
00253 public class GameState {
 protected:
  Screen screen;
  Field field;
  Ship ship;
  ShotPool shots;
  BulletActorPool bullets;
  EnemyPool enemies;
  ParticlePool particles;
  CrystalPool crystals;
  ExplosionPool explosions;
  StageManager stageManager;
  Pad pad;
  long _seed;

  public this(Screen screen, Pad pad,
              Field field, Ship ship, ShotPool shots, BulletActorPool bullets,
              EnemyPool enemies, ParticlePool particles, CrystalPool crystals, ExplosionPool explosions,
              StageManager stageManager) {
    this.screen = screen;
    this.pad = pad;
    this.field = field;
    this.ship = ship;
    this.shots = shots;
    this.bullets = bullets;
    this.enemies = enemies;
    this.particles = particles;
    this.crystals = crystals;
    this.explosions = explosions;
    this.stageManager = stageManager;
  }

  public abstract void start();
  public abstract void move();
  public abstract void draw();
  public abstract void drawLuminous();

  protected void clearAll() {
    shots.clear();
    bullets.clear();
    enemies.clear();
    particles.clear();
    crystals.clear();
    explosions.clear();
  }

  public long seed(long v) {
    return _seed = v;
  }
}

public class InGameState: GameState {
 public:
  bool isGameOver;
 private:
  PrefManager prefManager;
  GameManager gameManager;
  float distance;
  int left;
  int startBgmCnt;
  int gameOverCnt;
  bool btnPressed;
  int pauseCnt;
  bool pausePressed;
  ReplayData _replayData;

  public this(Screen screen, Pad pad,
              Field field, Ship ship, ShotPool shots, BulletActorPool bullets,
              EnemyPool enemies, ParticlePool particles, CrystalPool crystals,  ExplosionPool explosions,
              StageManager stageManager,
              PrefManager prefManager, GameManager gameManager) {
    super(screen, pad, field, ship, shots, bullets, enemies, particles, crystals, explosions, stageManager);
    this.prefManager = prefManager;
    this.gameManager = gameManager;
    _replayData = null;
    distance = 0;
  }

  public override void start() {
    Ship.replayMode = false;
    clearAll();
    RecordablePad rp = cast(RecordablePad) pad;
    rp.startRecord();
    _replayData = new ReplayData;
    _replayData.inputRecord = rp.inputRecord;
    _replayData.seed = _seed;
    field.setRandSeed(_seed);
    Bullet.setRandSeed(_seed);
    Enemy.setRandSeed(_seed);
    EnemySpec.setRandSeed(_seed);
    Particle.setRandSeed(_seed);
    Shot.setRandSeed(_seed);
    Ship.setRandSeed(_seed);
    Screen.setRandSeed(_seed);
    stageManager.start(_seed);
    field.start();
    ship.start();
    initGameState();
    screen.setScreenShake(0, 0);
    gameOverCnt = 0;
    pauseCnt = 0;
    isGameOver = false;
    SoundManager.enableBgm();
    SoundManager.enableSe();
    SoundManager.playBgm("ground.ogg");
  }

  public void initGameState() {
    distance = 0;
    left = 2;
  }

  public override void move() {
    if (pad.keys[SDLK_p] == SDL_PRESSED) {
      if (!pausePressed) {
        if (pauseCnt <= 0 && !isGameOver)
          pauseCnt = 1;
        else
          pauseCnt = 0;
      }
      pausePressed = true;
    } else {
      pausePressed = false;
    }
    if (pauseCnt > 0) {
      pauseCnt++;
      return;
    }
    ship.move();
    stageManager.move();
    enemies.move();
    shots.move();
    bullets.move();
    crystals.move();
    explosions.move();
    particles.move();
    screen.move();
    if (isGameOver) {
      gameOverCnt++;
      PadState input = (cast(RecordablePad) pad).getState(false);
      if (input.button & PadState.Button.A) {
        if (gameOverCnt > 60 && !btnPressed)
          gameManager.startTitle(true);
        btnPressed = true;
      } else {
        btnPressed = false;
      }
      if (gameOverCnt > 1200)
        gameManager.startTitle(true);
    }
  }

  public override void draw() {
    field.draw();
    glDisable(GL_TEXTURE_2D);
    particles.draw();
    glEnable(GL_TEXTURE_2D);
    explosions.draw();
    crystals.draw();
    enemies.draw();
    ship.draw();
    bullets.draw();
    shots.draw();
    ship.drawState();
    stageManager.draw();
    drawState();
  }

  private void drawState() {
    drawDistance();
    for (int i = 0; i < left; i++)
      Letter.drawString("^", -9f + i * 0.5f, 8.4f, 1);
    if (isGameOver)
      Letter.drawString("GAME OVER", -2.5f, 0, 1);
    if (pauseCnt > 0 && (pauseCnt % 64) < 32)
      Letter.drawString("PAUSE", -1, 0, 1);
  }

  public void drawDistance() {
    Letter.drawNum(cast(int) distance, -4.6f, 9.2f, 1);
    Letter.drawString("DIST", -9f, 9.8f, 1, Letter.Direction.TO_RIGHT, 1);
    float hd = prefManager.prefData.hiDistance();
    if (distance > hd)
      hd = distance;
    Letter.drawNum(cast(int) hd, 8.4f, 9.2f, 1);
    Letter.drawString("TOP", 3.6f, 9.8f, 1, Letter.Direction.TO_RIGHT, 1);
  }

  public override void drawLuminous() {
    glDisable(GL_TEXTURE_2D);
    particles.drawLuminous();
    glEnable(GL_TEXTURE_2D);
  }

  public void shipDestroyed() {
    clearVisibleBullets();
    left--;
    if (left < 0) {
      isGameOver = true;
      btnPressed = true;
      SoundManager.fadeBgm();
      SoundManager.disableSe();
      prefManager.prefData.recordResult(distance);
    }
  }

  public void clearVisibleBullets() {
    bullets.clearVisible();
  }

  public void addDistance(float dist) {
    if (isGameOver)
      return;
    distance += dist;
  }

  public void saveReplay(char[] fileName) {
    _replayData.save(fileName);
  }

  public void loadReplay(char[] fileName) {
    _replayData = new ReplayData;
    _replayData.load(fileName);
  }

  public void resetReplay() {
    _replayData = null;
  }

  public ReplayData replayData() {
    return _replayData;
  }
}

public class TitleState: GameState {
 private:
  TitleManager titleManager;
  InGameState inGameState;
  ReplayData replayData;
  int gameOverCnt;

  public this(Screen screen, Pad pad,
              Field field, Ship ship, ShotPool shots, BulletActorPool bullets,
              EnemyPool enemies, ParticlePool particles, CrystalPool crystals,  ExplosionPool explosions,
              StageManager stageManager,
              TitleManager titleManager, InGameState inGameState) {
    super(screen, pad, field, ship, shots, bullets, enemies, particles, crystals, explosions, stageManager);
    this.titleManager = titleManager;
    this.inGameState = inGameState;
  }

  public void close() {
    titleManager.close();
  }

  public void setReplayData(ReplayData rd) {
    replayData = rd;
  }

  public override void start() {
    SoundManager.haltBgm();
    SoundManager.disableBgm();
    SoundManager.disableSe();
    titleManager.start();
    clearAll();
    if (replayData)
      startReplay();
  }

  private void startReplay() {
    Ship.replayMode = true;
    RecordablePad rp = cast(RecordablePad) pad;
    rp.startReplay(replayData.inputRecord);
    _seed = replayData.seed;
    field.setRandSeed(_seed);
    Bullet.setRandSeed(_seed);
    Enemy.setRandSeed(_seed);
    EnemySpec.setRandSeed(_seed);
    Particle.setRandSeed(_seed);
    Shot.setRandSeed(_seed);
    Ship.setRandSeed(_seed);
    Screen.setRandSeed(_seed);
    stageManager.start(_seed);
    field.start();
    ship.start();
    inGameState.initGameState();
    screen.setScreenShake(0, 0);
    gameOverCnt = 0;
    inGameState.isGameOver = false;
  }

  public override void move() {
    if (replayData) {
      if (inGameState.isGameOver) {
        gameOverCnt++;
        if (gameOverCnt > 120) {
          clearAll();
          startReplay();
        }
      }
      ship.move();
      stageManager.move();
      enemies.move();
      shots.move();
      bullets.move();
      crystals.move();
      explosions.move();
      particles.move();
      screen.move();
      titleManager.move(true);
    } else {
      titleManager.move(false);
    }
  }

  public override void draw() {
    if (replayData) {
      field.draw();
      glDisable(GL_TEXTURE_2D);
      particles.draw();
      glEnable(GL_TEXTURE_2D);
      explosions.draw();
      crystals.draw();
      enemies.draw();
      ship.draw();
      bullets.draw();
      shots.draw();
      ship.drawState();
      stageManager.draw();
    } else {
      field.draw();
    }
    titleManager.draw();
    inGameState.drawDistance();
  }

  public override void drawLuminous() {
    glDisable(GL_TEXTURE_2D);
    particles.drawLuminous();
    glEnable(GL_TEXTURE_2D);
  }
}

Generated by  Doxygen 1.6.0   Back to index