追加マップvol.3-1

 東京経済大学のおみぬーです。
今回も追加マップの作成です。今回作成するマップではモンスターの動きに変化を与えます。

前回のマップから今回のマップに移動するためのコードは以下になります。

if (jelly1.life == 0 && jelly2.life == 0 && map[slime.py-1][slime.px] == 7 && slime.dir == -2) {
location.href = "hitcheck8ex-4.html";
}

作成したマップ画像は以下になります。


今までに比べ、複雑なマップになりました。このようにしたのは、モンスターの動きの変化が要因です。マップのコードを紹介した後、モンスターの動きについても紹介します。
以下がコードです。

var map = [
[8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8],
[8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8],
[8, 8, 9, 9, 9, 9, 9, 8, 8, 9, 9, 9, 9, 9, 8, 9, 9, 9, 8, 8],
[8, 8, 9, 8, 9, 8, 9, 8, 9, 9, 8, 8, 8, 9, 8, 9, 8, 9, 8, 8],
[8, 8, 9, 8, 9, 8, 9, 8, 9, 9, 9, 8, 8, 9, 8, 9, 8, 9, 8, 8],
[8, 8, 9, 8, 9, 8, 9, 8, 9, 9, 9, 9, 8, 9, 8, 9, 8, 9, 8, 8],
[8, 8, 9, 8, 9, 8, 9, 8, 8, 9, 9, 9, 8, 9, 8, 9, 8, 9, 8, 8],
[8, 8, 9, 8, 9, 8, 9, 8, 8, 8, 9, 9, 8, 9, 8, 9, 8, 9, 8, 8],
[8, 8, 9, 9, 9, 8, 9, 9, 9, 9, 9, 8, 8, 9, 9, 9, 9, 9, 8, 8],
[8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8],
[8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8],
];

このモンスターは直線移動をし、壁にぶつかるとランダムに方向転換し、再び直線移動を始めます。その特性を最大限利用したいと考えた結果、今回のようなマップが完成しました。

モンスターにこのような動きをさせるためには、今までのコードを改造する必要があります。まず、前回までのモンスターの動きを定義していたコードを紹介します。

function monster(px, py, life, imgid) {
this.px = px;
this.py = py;
this.dx = 0;
this.dy = 0;
this.dir = 2;
this.life = life;
this.movecnt = 0;


monster関数のpxプロパティ、pyプロパティで、モンスターを描画するためのX座標、Y座標を仮引数px、pyで指定しています。
dxプロパティ、dyプロパティはモンスターの動く方向を指定するのに使用します。dxプロパティが1の時右へ、-1の時に左へ移動するようにし、0の時は移動しない、つまり停止するようにします。dyプロパティが1の時下へ、-1の時上へ移動するように、0の時には停止するようにします。
dirプロパティは、モンスターが移動する方向を記録するのに使用します。移動方向に応じて、代入する値が異なり、左ならば1、上ならば-1、右ならば1、下ならば2をそれぞれ代入します。モンスターが主人公に攻撃され、吹き飛ばされる方向も、このdirプロパティによって決定されます。
lifeプロパティは文字通りモンスターのライフを定義するものです。movecntプロパティはモンスターの移動を連続的にするために使用します。

this.movecounter = function () {
if (this.dx == 0 && this.dy == 0) {
return;
}
this.movecnt++;
if (this.movecnt >= 4) {
this.px = this.px + this.dx;
this.py = this.py + this.dy;
this.movecnt = 0;
}
}


続いてmovecounterメソッドです。これはmovecntプロパティの値をカウントするためのメソッドです。
if (this.dx == 0 && this.dy == 0)の条件式ではどのキーも押されていないため、処理は行われず、return文を実行しこの関数から抜け出しています。
次にmovecntプロパティです。this.movecnt++でプロパティの値をインクリメント、つまり増加し、if文でmovecntプロパティの値が4以上になった際にモンスターのX座標、またはY座標を隣のマスに移動させます。移動方向は先ほどのコードで示したように、dxプロパティが1の時右へ、-1の時に左へ、dyプロパティが1の時下へ、-1の時上へ移動します。そしてthis.movecnt = 0でmovecntプロパティの値を0に戻します。

this.move = function () {
this.movecounter();
if (this.movecnt > 0) {
return;
}
this.dx = 0;
this.dy = 0;
var nx = 0, ny = 0;
switch (Math.floor(Math.random() *100)) {
case 0: nx = -1; ny = 0; this.dir = -1; break;
case 1: nx = 0; ny = -1; this.dir = -2; break;
case 2: nx = 1; ny = 0; this.dir = 1; break;
case 3: nx = 0; ny = 1; this.dir = 2; break;
default: nx = 0; ny = 0; break;
}
if (map[this.py + ny][this.px + nx] == 9) {
this.dx = nx;
this.dy = ny;
}
}

続いてmoveメソッドです。このメソッドはモンスターの移動先を決めるためのものです。
まずmovecounterメソッドを実行し、if (this.movecnt > 0)の条件式では、プロパティの値が0より大きいかをチェックしています。movecntプロパティの値が0より大きかった場合、隣のマスへ移動している最中であるため移動先を決めることはせず、return文を実行しmoveメソッドから抜け出します。movecntプロパティの値が0の時、その後の内容は実行されます。
次にthis.dx = 0、this.dy = 0でそれぞれのプロパティの値を0に戻し、変数nx、nyを定義しそれぞれに初期値0を代入します。その後、swith文を使用し、変数nx、nyの値を決めます。Math.random、Math.floor関数を使用して乱数により移動方向を決定します。0以上100未満の数字の中からランダムに値が決定され、0であれば左に、1であれば上、2であれば右、3であれば下へ、それら以外の値では移動をしないようになっています。
そしてif文の条件式でモンスターの現在のX座標、Y座標にそれぞれnx、nyの値を足した値の位置がマップ上の道(値9)であるかどうかをチェックします。これが真の時モンスターは移動し、dxプロパティ、dyプロパティの値をそれぞれnx、nyのあタイで確定させます。偽であった場合、この処理 は実行されずdxプロパティもしくはdyプロパティの値は0のままです。

this.paint = function () {
var x = this.px * 40 + this.dx * this.movecnt * 10;
var y = this.py * 40 + this.dy * this.movecnt * 10;
var img = document.getElementById(imgid);
gc.drawImage(img, x, y, 40, 40);
}
    }

最後にpaintメソッドです。これはモンスターを描画するためのメソッドです。
まず変数x、yを定義し、モンスターを描画する位置のX座標、Y座標を格納します。それぞれの座標の計算式が右辺になります。それらの計算式の結果から変数x、yに描画位置が格納され、モンスターを描画しています。

今までのモンスターの動きの解説で長くなってしまったので、変更後のモンスターの動きのコード紹介は次回にしたいと思います。
今回はここまでです。

参考文献
田中賢一郎『ゲームで学ぶJavaScript 入門』インプレス,2015年
田中賢一郎『ゲームで作りながら楽しく学べる HTML5+CSS+JavaScript』インプレス,2017年
田中賢一郎『ゲームで学ぶJavaScript 入門 増補改訂版~ブラウザゲームづくりでHTML&CSSも身につく!』インプレス,2022年

コメント

このブログの人気の投稿

追加マップvol.2

追加マップvol.3-2