第一ステージの障害物の動作編
ご訪問いただき誠にありがとうございます。
今回は第一ステージの障害物の処理について解説いたします。第一ステージは上で表示しているように上下のみに動く障害物と上下左右を組み合わせた動きをする障害物の二種類を用意しています。本来は自キャラが左端に表示されていて、スペースキーで前進させるのですが、自キャラの表示は割愛しています。
今回も重要なポイントに絞って解説していきたいと思います。
実際の「避けゲー」で遊びたい方は以下よりアクセスしてください。
ソースコードはGitHub上にアップしていますので適宜参考にしてください。
上下移動の障害物(左側の障害物)制御
上下に移動する左側の障害物はenemy1関数で制御しています。上下移動だけですのでコードはいたってシンプルです。enemy1関数のアクティビティ図とソースコードを掲載しておきます。
enemy1関数のアクティビティ図
enemy1関数のコード(avoider.jsから抜粋)
function enemy1() {
//障害物の上下移動
ctx.beginPath();
ctx.rect(200+Rex, ex1, 100, 20);
ctx.fillStyle = "red";
ctx.fill();
ctx.closePath();
ex1+=exm1;
if (ex1>=320) { //キャンバスエリアの一番下にきたとき
exm1=-3.9; //移動量を上方向に切り替える
}
if (ex1<=-20) { //キャンバスエリアの一番上にきたとき
exm1=3.9; //移動量を下方向に切り替える
}
if (ex1>=140&&ex1<=160) { //障害物のy軸が140~160の間にいるとき
if (x>=180&&x<=320) { //自キャラのx座標が180~320の間にいるとき
gameover=true; //障害物にぶつかったと判定し、ゲームオーバーの判定をセットする
}
}
}
キャンバスの座標は左上が原点(x座標=0、y座標=0)です。x座標は右に行くほど値が大きくなり、y座標は下に行くほど値が大きくなります。普段グラフを書くときのy座標は上方向側が値が大きくなると思いますが、キャンバス上の座標は逆向きであることに注意しましょう。コンピューターで座標を扱うときは基本的にはこの仕様になっています。
座標がキャンバスのエリアの外(例えばx座標、y座標ともにマイナスの値)を指定したらどうなるでしょうか?その場合はユーザが見ている画面上には画が表示されません。ただし、表示はされていなくてもちゃんと枠外に描かれています。例えば、オブジェクトの座標の初期値をキャンバスの枠外に設定しておき、その後少しずつ座標を移動してキャンバスの枠内に持ってくれば、オブジェクトが徐々に姿を現す、といった演出が可能になります。
気を付けなければいけないのは、枠外で表示されていなくてもオブジェクトが存在すれば処理の対象となっているため、そのオブジェクトがそれ以降表示されることがないのであれば、そのオブジェクトは削除しておくべきです。
四角形の描画
ctx.beginPath();
ctx.rect(200+Rex, ex1, 100, 20);
ctx.fillStyle = "red";
ctx.fill();
ctx.closePath();
rect()は現在のパスに矩形を追加するときに呼び出すメソッドです。rect()を呼び出すだけではパスが追加されただけですので描画されません。キャンバスに四角形を表示するには続けてfill()メソッドを呼び出す必要があります。今回は赤色で塗りつぶしたかったのでfillStyleというプロパティに赤色を指定しています。fillStyleで色を指定する場合はfill()メソッドを呼び出す前に設定しておく必要があります。このようにAPIには使用する順番に依存するAPIもありますので、API仕様を必ず確認するようにしましょう。
rect()とfill()を合わせたようなメソッドも提供されています。
void ctx.fillRect(x, y, width, height);
fillRect()メソッドはキャンバス 2D API のメソッドで、塗りつぶした矩形を現在のfillStyleに基づいて描きます。このメソッドはキャンバスに直接描画を行いますので、現在のパスに影響しないという仕様になっているため、便利なメソッドです。
上下左右移動の障害物(右側の障害物)制御
上下左右に移動する右側の障害物はenemy2関数で制御しています。上下だけでなく、左右にも同時に移動しますが、コードは難しくありません。y座標だけでなく、x座標も移動させればいいだけですね。enemy2関数のアクティビティ図とソースコードです。
enemy2関数のアクティビティ図
enemy2関数のコード(avoider.jsから抜粋)
function enemy2() {
//障害物の上下左右移動
ctx.beginPath();
ctx.rect(ey2+Rex, ex2, 80, 80);
ctx.fillStyle = "red";
ctx.fill();
ctx.closePath();
ex2+=em2; //y軸方向への移動
ey2-=em2; //x軸方向への移動
if (ex2>=240) { //キャンバスの下に到達
em2=-1.9; //負の方向への移動に切り替える
}
if (ex2<=0) { //キャンバスの上に到達
em2=1.9; //正の方向への移動に切り替える
}
if (ex2>=80&&ex2<=160) { //障害物のy軸が80~160の間にいるとき
if (x>=ey2-20&&x<=ey2+100) { //自キャラのx軸と障害物の横幅の間にいるとき
gameover=true; //障害物にぶつかったと判定し、ゲームオーバーの判定をセットする
}
}
}
enemy1関数とほとんど同じ内容ですので、1つの関数にまとめても良かったかもしれませんね。enemy2関数では障害物の移動量は「±1.9」としています。enemy1関数の障害物の移動量は「±3.9」としていました。移動量(次の描画時に移動している量)が大きくなると、見た目には速く動いて見えます。移動量を調整することで速めに動かしたり、ゆっくり動かしたりできます。今回は自キャラがギリギリすり抜けられるタイミングで移動量を設定しています。キャラクタの移動量をどのくらいに設定するかは、机上でも計算きますが、実際に動かしながら微調整していった方が効率がいいと思います。
最後までご覧いただきありがとうございます。
今回は第一ステージの障害物の動作について見ていきました。座標を定期的に更新することで自動で動き回るキャラクタを作り出すことができます。ゲーム開発では敵キャラやボット、ミサイルなど自動で動かす必要のあるキャラクタが多く登場すると思いますので、その際の参考になればと思います。例えば、障害物の座標を自キャラに徐々に近づくように移動量を調整すれば、敵が近寄ってくるといった演出も可能ですし、移動の方向をランダムに設定すれば予想外の動きをさせることも可能ですね。
次回は第二ステージの障害物の動きについて見ていきます。よろしければ次回のブログにもお付き合いください。