エンカント判定の実装
ランダムエンカウント判定のアルゴリズムについては語り尽くされていると思います。
大別すると都度判定するか、先に歩数を決定する方式かです。
先日までは、サンプルプログラムでは歩数方式を採用していましたが、あのゲームのアルゴリズムに寄せるため都度方式を実装してみます。
あのゲームのエンカウントの解説にはDQ1,2(SFC)エンカウント判定に関する解析結果を参考にしました。
つまり
乱数 < 閾値 ならエンカウントです。混乱しないように強調しておくと『閾値の値が大きいほど敵と遭遇しやすい』ということです。
閾値は地形と歩数から導きます。
地形の取得
地形の取得には、マップデータのチップ番号から地形番号への変換テーブルを用意します。
サンプル用は以下の通りです。
Topography = {
Alpine: 0,
Sea: 1,
PoisonedMarsh: 2,
Field: 3,
Ice: 4,
Forest: 5,
Mountain: 6,
Desert: 7,
Town: 8,
Cave: 9,
Bridge: 10,
Other: 11
};
//チップ番号から地形番号を得る
chipToTopography[3, 0, 1, 5, 6, 8, ...];
//地形の取得
var t = chipToTopography[map.data[y][x]];
閾値の種
地形から閾値の種を取得します。山や砂漠は危険度が高くなります(ちなみに、そもそも移動出来ない場所には閾値は設定されていません)。
//閾値の種
encountSeed = [0, 0, 12, 5, 10, 10, 14, 10, 0, 0, 10, 0];
var seed;
if (map.dungeon) {
seed = 6;
} else {
seed = encountSeed[t];
}
歩数による危険度の増加
次に歩数による危険度の反映(歩くほどにエンカウントしやすくなる)ですが、まず短い歩数に対して、閾値を減じます。
e; //現在の歩数
th; //閾値
//短い歩数の場合の補正
if (e < 5) {
th = Math.floor(seed/ 8);
} else if (e < 9) {
th = Math.floor(seed / 4);
} else if (e < 12) {
th = Math.floor(seed / 2);
}
次は地形による危険度増加カーブの反映です。補正前の種を使用します。
要約すると危険な地形ほど短い歩数(thの値が小さい)で危険度が上がります。
//種を基にした歩数による危険度計数
encountThreshold = [0, 255, 128, 85, 64, 51, 42, 36, 32, 28, 25, 23, 21, 19, 18, 17, 16];
w_th = encountThreshold[seed];
if (e < th) {
th = Math.floor(w_th * .75);
} else if (e < w_th * 2) {
th = Math.floor(w_th * 1.5);
} else if (e < th * 3) {
th = Math.floor(w_th * 2);
} else {
th = Math.floor(w_th * 4);
}
判定
本来ならこの後、聖水の効果を判定します。余談ですが、DQ1などでは、エンカントが確定後にモンスターを決定し、その防御値が補正後のプレイヤーの防御値を下回れば、エンカウントが回避されるようです。
ここでは割愛するので、最終判定です。
//乱数ルーチンは割愛
return getRandom() < th;