ポンクソフト

アクションゲームを作ってみよう(ぬりかべ) - jQuery入門

前ページ jQuery入門 TOP 次ページ

目次

  1. jQuery入門
  2. jQueryのインストール・簡単な使い方
  3. クイズゲームの作り方
  4. 秘密の暗号を作ってみよう(たぬき暗号)
  5. アクションゲームを作ってみよう(ぬりかべ)
  6. 画像を使ったジグソーパズルを作ってみよう
  7. もぐらたたきっぽいゲーム
  8. ドラッグ可能なポップアップウインドウを作ろう
  9. jQuery UI Sortableで1ラインオセロゲーム
  10. ブラウザ全体をブロックしてみる
  11. Geolocation APIを使って都道府県のセレクトボックスを現在地に近い順にソートする
  12. 発生したイベントの状態を保持・保存する6つのパターン
  13. Ajaxを利用したシンプルなイメージギャラリーを作ってみる
  14. テーブルにページ送り(ページング)を実装してみる
  15. jQuery UI Draggableを使って付箋(sticky)を作ってみる
  16. カラムでソートできるテーブルを自作してみる
  17. テーブルを使ったシンプルなドット絵エディタを作ってみる
  18. iPhoneのようにマウスではじいてスクロール(フリックスクロール)を実装してみる
  19. テキストフィールドの数値をマウスの上下移動で増減する
  20. iPhoneのように大きい画像の表示領域をマウスのドラッグで移動してみる
  21. iPhoneのように画像をダブルクリックした地点を中心に拡大縮小する
  22. リアルタイムプレビュー付きのHTMLエディタを作ろう
  23. 保存できる付箋を作ってみる(Cookie、localStorage)

ぬりかべ

jQuery入門第5回は、JavaScriptでアクションゲームを作ってみます。jQueryはゲーム製作に向いた作りでは無いので、ちょっと無理矢理なところがあると思いますがご勘弁を。作るゲームはもちろん超大作MMOです。MMOとは(M)丸いのが(M)モリモリ(O)大きくなるゲームの略です。まずは遊べるゲーム画面をどうぞ。

実行結果

自分自身や壁にぶつからないように、なるべく沢山の壁を塗ってください。マウスをクリックすると曲がります。IEで実行するとプレイしづらいかも知れませんが、その修正方法は後述します。

ぬりかべのソース

前回よりも少し長めですが、きっと大丈夫。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.0/jquery.min.js"></script>
<title>ぬりかべ</title>
<script>
$(function() {
  $('#start').click(function() {
    $(this).hide();

    // 変数初期化
    var FLEN = 16;                  // フィールドの大きさ
    var px = 0, py = 1;             // プレイヤー座標
    var pd = 1;                     // プレイヤー方向(0:上 1:右 2:下 3:左)
    var score = 0;                  // 得点

    // フィールドを表示する。
    var field = '';
    for (var y = 0; y < FLEN; y++) {
      for (var x = 0; x < FLEN; x++) {
        field += '<span id="field_' + x + '_' + y + '">';
        if (x == 0 || x == FLEN - 1 || y == 0 || y == FLEN - 1) field += '■';
        else field += '□';
        field += '</span>';
      }
      field += '<br>';
    }
    $('#field').html(field);

    // マウス押下時に移動方向を時計回りに90度動かす。
    $(document).mousedown(function() {
      pd = (pd + 1) % 4;
      return false;
    })

    // 100ms毎に繰り返し
    var id = setInterval(function() {
      // 移動と当たり判定
      if (pd == 0) py--;
      else if (pd == 1) px++;
      else if (pd == 2) py++;
      else px--;
      var item = $('#field_' + px + '_' + py);
      if (item.html() == '□') {
        score++;
        $('#score').html(score);
      } else {
        clearInterval(id);
        $('#start').show();
      }
      item.html('●');
    }, 100);
  });
});

</script>
</head>
<body>
<div id="field"></div>
<p><a id="start" href="javascript:void(0)">スタート</a> 得点:<span id="score"></span></p>
</body>
</html>

プログラムの解説

$('#start').click(function() {
  ・・・
});
「スタート」リンクをクリックしたときにこの中身が実行されます。内部で実行している処理は大きく分けて「変数の初期化」「フィールド表示」「マウス押下時の処理」「タイマーイベントによる繰り返し処理の設定」の4つです。

変数の初期化

var FLEN = 16;                  // フィールドの大きさ
var px = 0, py = 1;             // プレイヤー座標
var pd = 1;                     // プレイヤー方向(0:上 1:右 2:下 3:左)
var score = 0;                  // 得点
FLENはフィールドの幅と高さで、それぞれ16マスになります。この値を変えるとフィールドの大きさを変更できます。pxとpyはプレイヤーの現在位置です。左上から数えて、pxは右がプラス、pyは下がプラスです。pdはプレイヤーの進行方向です。0が上、1が右、2が下、3が左となります。scoreは得点です。

フィールドの表示

var field = '';
for (var y = 0; y < FLEN; y++) {
  for (var x = 0; x < FLEN; x++) {
    field += '<span id="field_' + x + '_' + y + '">';
    if (x == 0 || x == FLEN - 1 || y == 0 || y == FLEN - 1) field += '■';
    else field += '□';
    field += '</span>';
  }
  field += '<br>';
}
$('#field').html(field);
ゲーム画面を表示している部分です。空のdiv(idがfield)をbody内に作り、その中にHTMLを流しこんでいます。HTMLを要素内に流し込む方法にはappendメソッドを使って少しずつ要素を入れて行く方法もありますが、要素の挿入は遅いので、今回は文字列でHTMLを組み立てて、最後のhtmlメソッドで一気にdiv内に流し込んでいます。

このHTMLで重要なポイントは、フィールドの要素(壁・空白)ひとつひとつをspanタグで包み、idとしてそれぞれのx,y座標をくっつけている点です。これによってプレイヤーが移動したときに簡単にその場所が壁であるか空白であるかが判断できるのです。

マウス押下時の処理

$(document).mousedown(function() {
  pd = (pd + 1) % 4;
  return false;
})
ドキュメント内でマウスボタンを押したときに、プレイヤーの進行方向を時計回りに90度ずつ回転させる処理を行なっています。クリックされるたびにpdには0,1,2,3,0,1…と繰り返し値が入ります。「return false;」の行でデフォルトのイベントを無効にしています。これによってマウスをクリックしたときに他のボタンが押されたり文字列を選択したりなどの誤動作を防いでいます。

タイマーイベントによる繰り返し処理の設定

var id = setInterval(function() {
  // 移動と当たり判定
  if (pd == 0) py--;
  else if (pd == 1) px++;
  else if (pd == 2) py++;
  else px--;
  var item = $('#field_' + px + '_' + py);
  if (item.html() == '□') {
    score++;
    $('#score').html(score);
  } else {
    clearInterval(id);
    $('#start').show();
  }
  item.html('●');
}, 100);
setInterval関数は第2引数で指定した時間(ミリ秒)ごとに第1引数で指定した関数を実行します。ここでは100ミリ秒ごとに実行されます。まず進行方向の変数pdを見て実際の座標px,pyを増減させます。次にプレイヤーが進んだ位置で当たり判定を行ない、壁以外だったらスコアを増加し、壁ならばタイマーイベントを消去(clearInterval)してゲームオーバーとしています。変数itemには、プレイヤーの現在位置から、その場所のspanタグのidを作成して格納しています。

IEでの不具合修正

IEでこのゲームを動かした場合いくつかの不具合が出る可能性があるので、その修正方法を示します。

記号が小さい・クリック時に文字が選択される

フォントの関係上、●や□の文字が小さくなる場合がありますが、そのときはフォントファミリを指定します。またクリックしたときに文字が選択されて画面が見づらくなる場合があります。その場合、IEでは「onSelectStart」ハンドラをfalseで返すと良いらしいです。この2点をbodyタグに書いた例がこちらです。
<body style="font-family: Osaka,'MS Pゴシック','MS PGothic',Sans-Serif" onSelectStart="return false;">

マウスボタンを素早く押したときに反応しない

IEではマウスボタンを連続で押すと、2回目のmousedownイベントが発生しないという不具合があります。その場合、「mousedown」の部分を「mouseup」に変更すれば動きます。ただしmouseupイベントはマウスを押下したときではなく離したときに発生するので、少し反応が鈍くなります。

IE修正版はこちら。nurikabe_ie.html
前ページ jQuery入門 TOP 次ページ
このエントリーをはてなブックマークに追加 そっか0