Android Open Source - Gloomy-Dungeons-3D Monster






From Project

Back to project page Gloomy-Dungeons-3D.

License

The source code is released under:

MIT License

If you think the Android project Gloomy-Dungeons-3D listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package zame.game.engine;
//from  w  ww .j a va 2  s  .  c o m
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import zame.game.Common;
import zame.game.SoundManager;

public class Monster implements Externalizable
{
  private static final long serialVersionUID = 0L;

  public int index;
  public int cellX;
  public int cellY;
  public float x;
  public float y;
  public int texture;
  public int dir;      // 0 - right, 1 - up, 2 - left, 3 - down
  public int maxStep;
  public int health;
  public int hits;
  public float visibleDistSq;
  public float attackDistSq;
  public int shootSoundIdx;
  public int ammoType;

  public int step;
  public int prevX;
  public int prevY;
  public int hitTimeout;    // hero hits monster
  public int attackTimeout;  // monster hits hero
  public int removeTimeout;
  public long dieTime;
  public int aroundReqDir;
  public boolean inverseRotation;
  public int prevAroundX;
  public int prevAroundY;
  public int shootAngle;
  public int hitHeroTimeout;
  public int hitHeroHits;
  public boolean chaseMode;
  public boolean waitForDoor;

  public boolean isInAttackState;
  public boolean isAimedOnHero;

  public void init()
  {
    step = 0;
    maxStep = 50;
    hitTimeout = 0;
    attackTimeout = 0;
    removeTimeout = 5000;
    dieTime = 0;
    aroundReqDir = -1;
    inverseRotation = false;
    prevAroundX = -1;
    prevAroundY = -1;
    visibleDistSq = 15.0f * 15.0f;
    hitHeroTimeout = 0;
    chaseMode = false;
    waitForDoor = false;
  }

  public void writeExternal(ObjectOutput os) throws IOException
  {
    os.writeInt(cellX);
    os.writeInt(cellY);
    os.writeFloat(x);
    os.writeFloat(y);
    os.writeInt(texture);
    os.writeInt(dir);
    os.writeInt(maxStep);
    os.writeInt(health);
    os.writeInt(hits);
    os.writeFloat(visibleDistSq);
    os.writeFloat(attackDistSq);
    os.writeInt(shootSoundIdx);
    os.writeInt(ammoType);

    os.writeInt(step);
    os.writeInt(prevX);
    os.writeInt(prevY);
    os.writeInt(hitTimeout);
    os.writeInt(attackTimeout);
    os.writeInt(removeTimeout);
    os.writeInt(aroundReqDir);
    os.writeBoolean(inverseRotation);
    os.writeInt(prevAroundX);
    os.writeInt(prevAroundY);
    os.writeInt(shootAngle);
    os.writeInt(hitHeroTimeout);
    os.writeInt(hitHeroHits);
    os.writeBoolean(chaseMode);
    os.writeBoolean(waitForDoor);
  }

  public void readExternal(ObjectInput is) throws IOException
  {
    cellX = is.readInt();
    cellY = is.readInt();
    x = is.readFloat();
    y = is.readFloat();
    texture = is.readInt();
    dir = is.readInt();
    maxStep = is.readInt();
    health = is.readInt();
    hits = is.readInt();
    visibleDistSq = is.readFloat();
    attackDistSq = is.readFloat();
    shootSoundIdx = is.readInt();
    ammoType = is.readInt();

    step = is.readInt();
    prevX = is.readInt();
    prevY = is.readInt();
    hitTimeout = is.readInt();
    attackTimeout = is.readInt();
    removeTimeout = is.readInt();
    aroundReqDir = is.readInt();
    inverseRotation = is.readBoolean();
    prevAroundX = is.readInt();
    prevAroundY = is.readInt();
    shootAngle = is.readInt();
    hitHeroTimeout = is.readInt();
    hitHeroHits = is.readInt();
    chaseMode = is.readBoolean();
    waitForDoor = is.readBoolean();

    isInAttackState = false;
    isAimedOnHero = false;
    dieTime = (health <= 0 ? -1 : 0);
  }

  public void setAttackDist(boolean longAttackDist)
  {
    attackDistSq = (longAttackDist ? (10.0f * 10.0f) : (1.8f * 1.8f));
  }

  public void copyFrom(Monster mon)
  {
    cellX = mon.cellX;
    cellY = mon.cellY;
    x = mon.x;
    y = mon.y;
    texture = mon.texture;
    dir = mon.dir;
    maxStep = mon.maxStep;
    health = mon.health;
    hits = mon.hits;
    visibleDistSq = mon.visibleDistSq;
    attackDistSq = mon.attackDistSq;
    shootSoundIdx = mon.shootSoundIdx;
    ammoType = mon.ammoType;

    step = mon.step;
    prevX = mon.prevX;
    prevY = mon.prevY;
    hitTimeout = mon.hitTimeout;
    attackTimeout = mon.attackTimeout;
    removeTimeout = mon.removeTimeout;
    dieTime = mon.dieTime;
    aroundReqDir = mon.aroundReqDir;
    inverseRotation = mon.inverseRotation;
    prevAroundX = mon.prevAroundX;
    prevAroundY = mon.prevAroundY;
    shootAngle = mon.shootAngle;
    hitHeroTimeout = mon.hitHeroTimeout;
    hitHeroHits = mon.hitHeroHits;
    chaseMode = mon.chaseMode;

    isInAttackState = mon.isInAttackState;
    isAimedOnHero = mon.isAimedOnHero;
  }

  public void hit(int amt, int hitTm)
  {
    hitTimeout = hitTm;
    health -= amt;
    aroundReqDir = -1;

    if (health <= 0)
    {
      SoundManager.playSound(SoundManager.SOUND_DETH_MON);
      State.passableMap[cellY][cellX] &= ~Level.PASSABLE_IS_MONSTER;
      State.passableMap[cellY][cellX] |= Level.PASSABLE_IS_DEAD_CORPSE;

      if (ammoType > 0)
      {
        if ((State.passableMap[cellY][cellX] & Level.PASSABLE_MASK_OBJECT_DROP) == 0)
        {
          State.objectsMap[cellY][cellX] = ammoType;
          State.passableMap[cellY][cellX] |= Level.PASSABLE_IS_OBJECT;
        }
        else
        {
          outer:
          for (int dy = -1; dy <= 1; dy++)
          {
            for (int dx = -1; dx <= 1; dx++)
            {
              if (((dy != 0) || (dx != 0)) && ((State.passableMap[cellY + dy][cellX + dx] & Level.PASSABLE_MASK_OBJECT_DROP) == 0))
              {
                State.objectsMap[cellY + dy][cellX + dx] = ammoType;
                State.passableMap[cellY + dy][cellX + dx] |= Level.PASSABLE_IS_OBJECT;
                break outer;
              }
            }
          }
        }
      }

      State.killedMonsters++;
    }
  }

  public void remove()
  {
    State.passableMap[cellY][cellX] &= ~Level.PASSABLE_IS_DEAD_CORPSE;
    State.monstersCount--;

    for (int i = index; i < State.monstersCount; i++)
    {
      State.monsters[i].copyFrom(State.monsters[i + 1]);

      if (State.monsters[i].health <= 0) {
        State.passableMap[State.monsters[i].cellY][State.monsters[i].cellX] |= Level.PASSABLE_IS_DEAD_CORPSE;
      }
    }
  }

  public void update()
  {
    if (health <= 0)
    {
      // removeTimeout--;  // do not remove dead corpses
      return;
    }

    if (hitHeroTimeout > 0)
    {
      hitHeroTimeout--;

      if (hitHeroTimeout <= 0) {
        Game.hitHero(hitHeroHits, shootSoundIdx, this);
      }
    }

    if (step == 0)
    {
      boolean tryAround = false;

      isInAttackState = false;
      isAimedOnHero = false;
      prevX = cellX;
      prevY = cellY;

      float dx = State.heroX - ((float)cellX + 0.5f);
      float dy = State.heroY - ((float)cellY + 0.5f);
      float distSq = dx*dx + dy*dy;

      if (aroundReqDir >= 0)
      {
        if (!waitForDoor) {
          dir = (dir + (inverseRotation ? 3 : 1)) % 4;
        }
      }
      else if (distSq <= visibleDistSq)
      {
        if (Math.abs(dy) <= 1.0f) {
          dir = (dx < 0 ? 2 : 0);
        } else {
          dir = (dy < 0 ? 1 : 3);
        }

        tryAround = true;
      }

      State.passableMap[cellY][cellX] &= ~Level.PASSABLE_IS_MONSTER;
      boolean vis = false;

      if ((distSq <= visibleDistSq) && Common.traceLine((float)cellX + 0.5f, (float)cellY + 0.5f, State.heroX, State.heroY, Level.PASSABLE_MASK_SHOOT_WM))
      {
        chaseMode = true;
        vis = true;
      }

      if (vis && (distSq <= attackDistSq))
      {
        int angleToHero = (int)(PortalTracer.getAngle(dx, dy) * Common.RAD2G_F);
        int angleDiff = angleToHero - shootAngle;

        if (angleDiff > 180) {
          angleDiff -= 360;
        } else if (angleDiff < -180) {
          angleDiff += 360;
        }

        angleDiff = (angleDiff < 0 ? -angleDiff : angleDiff);
        shootAngle = angleToHero;
        float dist = (float)Math.sqrt(distSq);

        int minAngle = Math.max(1, 15 - (int)(dist * 3.0f));

        if (angleDiff <= minAngle)
        {
          isAimedOnHero = true;
          hitHeroHits = Common.getRealHits(hits, dist);
          hitHeroTimeout = 2;
          attackTimeout = 15;
          step = 50;
        }
        else
        {
          step = 8 + angleDiff / 5;
        }

        isInAttackState = true;
        dir = ((shootAngle + 45) % 360) / 90;
        aroundReqDir = -1;
      }
      else
      {
        waitForDoor = false;

        for (int i = 0; i < 4; i++)
        {
          switch (dir)
          {
            case 0:
              cellX++;
              break;

            case 1:
              cellY--;
              break;

            case 2:
              cellX--;
              break;

            case 3:
              cellY++;
              break;
          }

          if ((State.passableMap[cellY][cellX] & Level.PASSABLE_MASK_MONSTER) == 0)
          {
            if (dir == aroundReqDir) {
              aroundReqDir = -1;
            }

            step = maxStep;
            break;
          }

          if (chaseMode &&
            ((State.passableMap[cellY][cellX] & Level.PASSABLE_IS_DOOR) != 0) &&
            ((State.passableMap[cellY][cellX] & Level.PASSABLE_IS_DOOR_OPENED_BY_HERO) != 0)
          ) {
            Door door = Level.doorsMap[cellY][cellX];

            if (!door.sticked)
            {
              door.open();

              waitForDoor = true;
              cellX = prevX;
              cellY = prevY;
              step = 10;
              break;
            }
          }

          cellX = prevX;
          cellY = prevY;

          if (tryAround)
          {
            if ((prevAroundX == cellX) && (prevAroundY == cellY)) {
              inverseRotation = !inverseRotation;
            }

            aroundReqDir = dir;
            prevAroundX = cellX;
            prevAroundY = cellY;
            tryAround = false;
          }

          dir = (dir + (inverseRotation ? 1 : 3)) % 4;
        }

        if (step == 0) {
          step = maxStep / 2;
        }

        shootAngle = dir * 90;
      }

      State.passableMap[cellY][cellX] |= Level.PASSABLE_IS_MONSTER;
    }

    x = (float)cellX + ((float)(prevX - cellX) * (float)step / (float)maxStep) + 0.5f;
    y = (float)cellY + ((float)(prevY - cellY) * (float)step / (float)maxStep) + 0.5f;

    if (attackTimeout > 0) {
      attackTimeout--;
    }

    if (hitTimeout > 0) {
      hitTimeout--;
    } else if (step > 0) {
      step--;
    }
  }
}




Java Source Code List

zame.game.AppConfig.java
zame.game.AppConfig.java
zame.game.Common.java
zame.game.ConfigZeemote.java
zame.game.ConfigZeemote.java
zame.game.Config.java
zame.game.GameActivityZeemoteHelper.java
zame.game.GameActivityZeemoteHelper.java
zame.game.GameActivity.java
zame.game.GamePreferencesActivity.java
zame.game.GamePreferencesActivity.java
zame.game.MenuActivityHelper.java
zame.game.MenuActivityHelper.java
zame.game.MenuActivity.java
zame.game.Renderer.java
zame.game.SoundManager.java
zame.game.ZameApplicationAnalyticsHelper.java
zame.game.ZameApplicationAnalyticsHelper.java
zame.game.ZameApplication.java
zame.game.ZameGame.java
zame.game.ZameJniRenderer.java
zame.game.engine.Action.java
zame.game.engine.AutoWall.java
zame.game.engine.Controls.java
zame.game.engine.Door.java
zame.game.engine.GameHelper.java
zame.game.engine.GameHelper.java
zame.game.engine.Game.java
zame.game.engine.Labels.java
zame.game.engine.LevelConfig.java
zame.game.engine.LevelRenderer.java
zame.game.engine.Level.java
zame.game.engine.Mark.java
zame.game.engine.Monster.java
zame.game.engine.Overlay.java
zame.game.engine.PortalTracer.java
zame.game.engine.State.java
zame.game.engine.Stats.java
zame.game.engine.TextureLoader.java
zame.game.engine.Weapons.java
zame.game.views.EndLevelView.java
zame.game.views.GameOverView.java
zame.game.views.GameView.java
zame.game.views.IZameView.java
zame.game.views.MenuViewHelper.java
zame.game.views.MenuViewHelper.java
zame.game.views.MenuView.java
zame.game.views.PreLevelView.java
zame.game.views.ZameGameView.java
zame.libs.FrameLayout.java
zame.libs.GLSurfaceView21.java
zame.libs.Grid.java
zame.libs.KeyMapPreference.java
zame.libs.LabelMaker.java
zame.libs.ListPreference.java
zame.libs.NumericSprite.java
zame.libs.SeekBarPreference.java
zame.promo.PromoView.java