おさらい
前回は熊さんの絵が方向キーによって自在に動くシンプルなゲームでした。掲載したサンプルの他、多くのHTML5の例題がインターネット上で参照可能です。javascriptのタグや一定時間で起動する関数、キーが押されたり離れるときに動作する関数の取り付け方などを理解する必要がありますが、実行結果から少しずつ慣れていきます。『習うより慣れろ』で進んでいきます。
ゲーム概要
今回はゲームらしい機能を追加します。左端に熊さんがいて右端のゴールを目指します。中間に赤丸で具象化された障害物が待ち構えていて進行を邪魔をします。矢印キーにより障害物を逃れゴールを目指しますが障害物に衝突すると爆音が轟きゲームは終了します。再読み込みキーを押して再開し、運よくゴールにたどり着くとファンファーレが鳴ります。
ソースコード
[html]
A game is starting.<BR>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script type="text/javascript">
const XMAX = 800-40;
const YMAX = 500-80;
const R = 50; // 半径
xLocate = 0;
yLocate = 200;
x = y = xr = yr = StopFlag = 0;
var timerID;
function start() { // 開始モジュール
canvas = document.getElementById (‘canvas_e’);
ctx = canvas.getContext (‘2d’); // キャンバスからコンテキストを取得
img1 = new Image();
img1.src = "bear.png"; // 熊さん
img2 = new Image();
img2.src = "goal.png"; // ゴール付近
img3 = new Image();
img3.src = "direction-key.png"; // 方向キー
img4 = new Image();
img4.src = "thunder.png"; // 雷
timerID = setInterval (‘draw()’, 33*3); // 33*n秒間隔でdrawを実行する
//キー操作イベントの設定
window.addEventListener (‘keydown’ , keydownfunc , true);
}
// 描画モジュール
function draw() { // 33秒*nごとに実行
ctx.beginPath();
ctx.clearRect (0 , 0 , 800 , 500); // 描画をクリア
ctx.drawImage (img1 , xLocate , yLocate); // 熊さん
ctx.drawImage (img2 , XMAX+5 , 0); // ゴール付近
ctx.drawImage (img3 , 10 , 10); // 方向キー
ctx.fillStyle = ‘red’;
x = Math.floor(Math.random()*600)+50; // 0~600->50~650までの乱数を発生させる
y = Math.floor(Math.random()*400)+50; // 0~400->50~450までの乱数を発生させる
ctx.arc(x, y, R, 0, Math.PI*2, false); // 円を描画
ctx.closePath();
ctx.fill();
xr = x + 2 * R; // 円に衝突するかチェック
yr = y + 2 * R; //
if((xLocate>x) && (xLocate<xr) && (yLocate>y) && (yLocate<yr)){// 障害物に衝突
ring("g-sound2"); // 衝突音を鳴動
clearInterval(timerID); // 描画を停止する
ctx.drawImage (img4 , xLocate, 320); // 雷
StopFlag = 1; // 衝突に印を付ける
}
}
function keydownfunc (event) { // キー操作された時の処理
var code = event.keyCode; // どのキーが押されたかの情報を取得する
if(StopFlag == 0){ // 衝突後は処理しない
switch (code) { // スイッチ文でケースにより処理を変える
case 37: // ←キーが押された場合の番号
if(xLocate < 5) break;
xLocate -= 5; // x座標を5px減らす(左に動かす)
break; // キーごとの処理完結
case 39: // →キーが押された場合の番号
if(xLocate >= XMAX) break;
xLocate += 5; // x座標を5px増やす(右に動かす)
break;
case 38: // ↑キーが押された場合の番号
if(yLocate < 5) break;
yLocate -= 5; // y座標を5px減らす(上に動かす)
break;
case 40: // ↓キーが押された場合の番号
if(yLocate >= YMAX) break;
yLocate += 5; // y座標を5px増やす(下に動かす)
break;
}
if(xLocate >= XMAX){ // ゴールに到達か
ring("g-sound1");
clearInterval(timerID); // 描画を停止する
StopFlag |= 2; // ゴールに印を付ける
}
}
}
function ring(tune){
document.getElementById(tune).play();
}
</script>
<audio id="g-sound1" preload="auto"><source src="success.mp3" /></audio>
<audio id="g-sound2" preload="auto"><source src="bakuon.mp3" /></audio>
</head>
<body onload="start()">
<canvas id="canvas_e" style="background-color:pink;" width="800" height="500" />
</body>
</html>
[/html]
説明
ゲームの構成関数は前回とほぼ同じでstart(),draw(),keydownfunc(),ring()から成り、音声ファイルを参照して音を出力する関数が加わりました。
その他、前回に追加された機能として33*nミリ秒間隔で動作するdraw関数に、障害物がランダムに現れ方向キーによって移動された熊画像が衝突するかどうかチェックされます。衝突した場合、爆発音を鳴動し衝突画像を表示します。
keydownfuncでは、右端のゴールに到着したかどうか確認され、到着すればファンファーレを鳴らしdraw関数が定期的に動作することを停止し、終了処理をします。
ファイル一覧
①EasyGame.html 簡易ゲームのソースコード
②bear.png 熊の画像
③direction-key.png 方向キー画像
④thunder.png 雷の画像
⑤goal.png ゴール画像
⑥success.mp3 ファンファーレ音声
⑦bakuon.mp3 爆音音声
上記ファイルのダウンロードはここです。
動作までの手順
動作までの手順はXAMPPの代替策を参考にしながら、上記ZIPを展開し、7つのファイルを同一フォルダに収めます。次にEasyGame.htmlにカーソルを当てクリックします。Javaの実行を許可しますかのメッセージが出力されたら許可します。Google ChromeとInternet Explorerで動作を確認しました。次項に示した細かな調整をする場合、EasyGame.htmlをテキストエディタで編集します。
動作の特徴
①33*nのnを大きくすればゴールへの到着確率が上がります。
②赤円の半径Rを小さくしても衝突しにくくなります。
③隠し技として最上端を移動させれば100%成功します。
④障害物の位置は乱数で決まります。
まとめ
今回、検証したゲームは非常にシンプルですがHTML5+CANVASでここまでできるようになりました。このサンプルで障害物との衝突をくぐり抜けてゴールに到着する確率は20%程度です。ゲームの作り方を通じてHTML5とCANVASを理解され、表現豊かなウェブサイトが完成されることを祈っています。