テラリウム徹底攻略ガイド(改訂版)
KAnimalクラスで処理しているイベント(1)
泉 祐介+デジタルアドバンテージ
2003/05/10 |
|
KAnimalクラスで処理しているイベント
冒頭にも述べたが、KAnimalクラスには動物としての基本的な行動があらかじめ記述してある。ここまではKAnimalクラスを利用した動物の実装に直接関係のあるメソッドについて解説してきたが、この項では、動物の基本的な行動を実装している部分であるKAnimalクラスのイベント・ハンドラについて説明していく。
LoadEventイベント・ハンドラ
Loadイベントは、各ターンの最初に必ず発生するイベントだ。従って、Loadイベントのイベント・ハンドラであるこのメソッドも、各ターンの最初に必ず呼び出されることになる。
まずは、コードを示すことにしよう。
protected virtual void LoadEvent(object sender, LoadEventArgs e) {
try {
moveCount--;
for(int i = 0 ; i < 10 ; i++) {
UpdateViewState();
}
UpdateTarget();
if(CanReproduce) {
BeginReproduction(null);
}
} catch(Exception exc) {
WriteTrace(exc);
}
}
|
|
KAnimalクラスのLoadEventイベント・ハンドラ |
Brunt、Food、Threatの各プロパティの値を変更するために、KAnimalクラスの内部ではScanメソッドなどによって得られた動物の情報を、適当に更新しながら保持するようにしている。UpdateViewStateはこれらの情報を更新するためのメソッドだ。情報をより確かにするために、forループを使って10回このメソッドを呼び出している。これは、偽装により隠れている動物を、可能な限り発見できるようにするためだ。ただ、tabataのような単純な生物なら、たいていの場合10回呼び出しても処理は1ターンに収まるようである(これはテラリウム・アプリケーションを実行しているマシンの性能による)。しかしUpdateViewState内で呼び出しているScanメソッドは、比較的処理時間を必要とするので、IdelEventなどでより複雑な行動を行うような場合には、この値を小さくする必要があるだろう。次のUpdateTargetは、Brunt、Food、Threatの各プロパティの値を設定するためのメソッドである。
CanReproduceは、生物が生殖できる状態にあるかを調べるAnimalクラスのプロパティである。生殖活動を行うには、生物が成熟している、エネルギー状態が通常の状態以上になっている、前の生殖活動から一定期間がたっている(これは先にも書いたとおり)などの諸条件が満たされる必要があるが、このプロパティを使えば簡単にこれらの条件がそろっているかどうかを調べることができる。続くBeginReproductionはAnimalクラスのメソッドで、実際に生殖活動を始めるメソッドだ。
生物リストを更新するUpdateViewStateメソッド
LoadEventメソッドで呼び出しているUpdateViewStateメソッドについても簡単に解説しておこう。
protected void UpdateViewState() {
ArrayList newfoundCreatures = base.Scan();
foreach(OrganismState oos in foundCreatures) {
bool exist = false;
foreach(OrganismState nos in newfoundCreatures) {
if(oos.ID == nos.ID) {
exist = true;
break;
}
}
if(!exist) {
OrganismState os = LookFor(oos);
if(os != null) {
newfoundCreatures.Add(os);
} else {
if((oos is PlantState && !WithinViewRange(oos)) ||
(oos is AnimalState && oos.IsAlive )) {
newfoundCreatures.Add(oos);
}
}
}
}
foundCreatures = newfoundCreatures;
}
|
|
保持している生物リストを更新するUpdateViewStateメソッド |
ここではまず、Scanメソッドを使って、その時点で動物の視界に含まれている生物リスト(newfoundCreatures)を得る。次に、前ターンで見つかった生物を保持している生物のリスト(foundCreatures)と照らし合わせて、見つからないときはLookForメソッドを使って、その生物に関する新しい情報を獲得しようとする。このメソッドは指定された生物に関する新しい情報を返すもので、Animalクラスで定義されている。ただし、偽装などによって新しい情報を得られない場合や、死んでしまったために生物が消滅した場合などにはnullが返ってくる。このような場合にはさらに生物の状態を確認し、存在するのであればリストに加える。
3つの主要プロパティを更新するUpdateTargetメソッド
UpdateTargetメソッドでは、Brunt、Food、Threatの各プロパティの値を設定する。
protected void UpdateTarget() {
food = null;
threat = null;
brunt = null;
double minDistanceF = Double.MaxValue;
double minDistanceT = Double.MaxValue;
double minDistanceB = Double.MaxValue;
foreach(OrganismState organismState in foundCreatures) {
if(organismState == null || RefreshState(organismState.ID) == null)
continue;
double r = DistanceTo(organismState);
if(r < minDistanceF && IsFood(organismState)) {
minDistanceF = r;
food = organismState;
}
if(r < minDistanceT && IsThreat(organismState)) {
minDistanceT = r;
threat = organismState as AnimalState;
}
if(r < minDistanceB && IsBrunt(organismState)) {
minDistanceB = r;
brunt = organismState as AnimalState;
}
}
}
|
|
Brunt、Food、Threatの各プロパティ値を更新するUpdateTargetメソッド |
このメソッドの処理はいたって単純だ。あらかじめ、Food、Threat、Bruntの各プロパティの値をnullで消去しておく。実際には、それらのプロパティの値を実際に格納しているfood、threat、bruntの各フィールドにnullを格納することになる。次に、先のUpdateViewStateで見つけた生物の一覧に含まれる生物1つ1つをIsFood、IsThreat、IsBruntの各メソッドにかけ、それに当てはまる生物であれば該当するフィールド(food、threat、brunt)にその生物を格納している。また、すでにそのフィールドに何らかの生物が格納されていた場合は、より距離の近い方を格納するようにする(これはFood、Threat、Bruntの各プロパティのところで解説したとおり)。
Insider.NET 記事ランキング
本日
月間