テラリウム徹底攻略ガイド

KAnimalクラスで処理しているイベント(2)

泉 祐介+デジタルアドバンテージ
2002/05/25

MoveCompletedEventイベント・ハンドラ

 このイベント・ハンドラが呼び出される元となるMoveComplatedイベントは、BeginMovingメソッドで指定した目的地への移動が終わったときと、障害物などにぶつかって移動が止まってしまったときの両方で発生する。

 このイベントについても先にコードを見てもらうことにしよう。

protected virtual void MoveCompletedEvent
  (object sender, MoveCompletedEventArgs e) {
  try {
    moveCount = 0;
    if(e.Reason == ReasonForStop.Blocked) {
      OrganismState os = e.BlockingOrganism;
      if(os != null) {
        if(IsBrunt(os) && CanAttack(os as AnimalState) &&
           WithinAttackingRange(os as AnimalState)) {
          Brunt = os as AnimalState;
          BeginAttacking(os as AnimalState);
          return;
        }
        if(IsFood(os) && WithinEatingRange(os)) {
          Food = os;
          if(WannaEat(os)) {
            BeginEating(os);
          }
          return;
        }
      }
      BeginMoving
        (GetBypass(os),e.MoveToAction.MovementVector.Speed);
      moveCount = 80 / e.MoveToAction.MovementVector.Speed;
    } else if(chase != null) {
      chase = LookFor(chase) as AnimalState;
      if(WithinAttackingRange(chase)) {
        chase = null;
      } else {
        BeginChase(chase);
      }
    }
  } catch(Exception exc) {
    WriteTrace(exc);
  }
}
KAnimalクラスのMoveCompletedEventイベント・ハンドラ

 イベント引数のReasonプロパティは、このイベントが発生した原因を表していて、ReasonForStop.DestinationReachedかReasonForStop.Blockedのいずれかをとる。前者が目的地に無事到達した場合、後者が目的地に到達できなかった場合だ。

 最初の方にあるif節を見れば分かるのだが、目的地に到達できなかった場合の記述がほとんどである。まず、移動をブロックした生物が何なのかを調べる。もし、その生物が攻撃をしかけるような動物であれば、その動物に対して攻撃を開始する。また、ブロックした生物が食料であれば、その食料を食べ始める。攻撃を仕掛けるような動物か、あるいは食料か、といった判定は、IsBruntメソッドやIsFoodメソッドを呼び出して判断している。

 いずれでもない場合は、単なる障害物と見なして、その障害物を回避して移動する。GetBypassは障害物を回避するために移動すべき場所(経由点)を求めるメソッドで、KAnimalの内部で定義している。このメソッドに関する詳細は、次回以降に解説する。

AttackedEventイベント・ハンドラ

 Attackedイベントは、ほかの動物から攻撃を受けたときに発生するイベントだ。

protected virtual void AttackedEvent
  (object sender, AttackedEventArgs e) {
  try {
    AnimalState target = LookFor(e.Attacker) as AnimalState;
    if(target == null) {
      return;
    }
    if(target.IsAlive) {
      BeginDefending(target);
      if(IsBrunt(target)){
        BeginAttacking(target);
      } else {
        RunAway(target);
      }
    }
  } catch(Exception exc) {
    WriteTrace(exc);
  }
}
KAnimalクラスのAttackedEventイベント・ハンドラ

 イベント引数のAttackerプロパティ(e.Attacker)は、こちらに攻撃を仕掛けてきた動物である。この動物に対して防御体制をとったあと、敵が強くない場合は反撃を行い、そうでなければその動物から逃げる。

 コードを見れば分かるが、動物が強いか弱いかはIsBruntメソッドを使って判断している。いい換えれば、こちらが攻撃をしかけるような動物が攻撃してきたのであれば反撃、そうでなければ逃亡という行動をとるようになっている。

AttackCompletedEventイベント・ハンドラ

 AttackedCompletedイベントは、ほかの動物への攻撃を終えたときに発生するイベントで、BeginAttackingメソッドを呼び出した次のターンで発生する。先のAttackedEventとは発生する状況がまったく逆(AttackedEventは攻撃「された」とき、AttackCompletedEventは攻撃を「した」とき)なので、混乱しないでほしい。

protected virtual void AttackCompletedEvent
  (object sender, AttackCompletedEventArgs e) {
  try {
    AnimalState target =
      LookFor(e.AttackAction.TargetAnimal) as AnimalState;
    if(target == null) {
      return;
    }
    if(e.Killed && IsFood(target)) {
      if(!WithinEatingRange(target)) {
        BeginMoving(target);
      } else if(WannaEat(target)) {
        BeginEating(target);
      }
    }
    if(!e.Killed && IsBrunt(target)) {
      if(e.Escaped) {
        BeginChase(target);
      } else {
        BeginAttacking(target);
      }
    }
  } catch(Exception exc) {
    WriteTrace(exc);
  }
}
KAnimalクラスのAttackCompletedEventイベント・ハンドラ

 攻撃をした動物を殺した場合、その殺した動物が食料になるのであればそれを摂食する。このとき、必要であれば摂食のために動物に近づく。イベント引数のAttackAction.TargetAnimalプロパティは、こちらが攻撃をした動物を示している。また、同じくイベント引数のKilledは、攻撃した動物を殺したかどうかを表すプロパティで、動物を殺すとtrueになる。

 一方、攻撃をした動物がまだ死なないのであれば、その動物に対して攻撃を続ける。このとき、攻撃した動物が逃げたら、その動物を追いかけるようにする。イベント引数のEscapedは、こちらが攻撃した動物が逃げた場合にtrueになるプロパティだ。また、BeginChaseは指定した動物を追いかけるためのメソッドで、このメソッドはKAnimalクラスの内部で定義したものであるが、具体的な内容については、次回で解説する。

DefendCompletedEventとEatCompletedEvent

 DefendCompletedイベントは、ほかの動物からの攻撃に対する防御がなされたとき(正確には、その防御行動が終わったとき)に発生するイベントである。また、EatCompletedは生物に対する摂食(より正確には、1回食いつく行動)が終わったときに発生するイベントだ。それぞれ、BeginDefendingメソッド、BeginEatingメソッドを呼び出した次のターンで発生する。これらのイベントの処理は簡単なことしか行っていないので、まとめて解説する。

protected virtual void DefendCompletedEvent
  (object sender, DefendCompletedEventArgs e) {
  try {
    AnimalState target =
     LookFor(e.DefendAction.TargetAnimal) as AnimalState;
    if(target != null) {
      return;
    }
    if(target.IsAlive) {
      BeginDefending(target);
    }
  } catch(Exception exc) {
    WriteTrace(exc.ToString());
  }
}

protected virtual void EatCompletedEvent
  (object sender, EatCompletedEventArgs e) {
  try {
    OrganismState target = LookFor(e.EatAction.TargetOrganism);
    if(target == null) {
      return;
    }
    if(WannaEat(target)) {
      BeginEating(target);
    }
  } catch(Exception exc) {
    WriteTrace(exc);
  }
}
KAnimalクラスのDefendCompletedEventとEatCompletedEvent

 DefendCompletedEventでは、その動物がまだ生存していれば、防御を継続して行う。イベント引数のDefendAction.TargetAnimalプロパティが攻撃をしてきた動物の情報を表している。

 EatCompletedEventの方も、単にWannaEatメソッドがtrueを返す間は摂食を続けるだけだ。イベント引数のEatAction.TargetOrganismプロパティが食料となっている生物を表す。満腹になったときの処理などはBeginEatingメソッドの中で行っているため、ここでは行っていない。

 さて、肝心の草食動物Tabataの実力であるが、これについてはEcosystemのランキングで見ていただくとしよう。コンテスト開催当初ならまだしも、現在のEcosystemにおいては、この程度の標準的なコーディングではもはや入賞も難しそうだ。さらなるパワーアップを目指す前に、取りあえず次回はKAnimalクラスを利用した肉食動物に挑戦してみる。End of Article

 

 INDEX
  [連載]テラリウム徹底攻略ガイド
  第4回 KAnimalクラスを使った草食動物の作成
     KAnimalクラスとは
     草食動物を作成する(1)
     草食動物を作成する(2)
     草食動物を作成する(3)
     KAnimalクラスのプロパティとメソッド
     KAnimalクラスで処理しているイベント(1)
   KAnimalクラスで処理しているイベント(2)
 
更新履歴
【2002/05/24】 掲載したプログラム(kanimal.cs、kanimal.vb)と、このプログラムを引用している本ページ内のコードの一部に誤りがありました。お詫びして訂正させていただきます。

インデックス・ページヘ  「連載  テラリウム徹底攻略ガイド」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間