ゲーム実装で身に付くプログラミング 1

赤緑青の色ブロックをクリックする

赤緑青の色ブロックをクリックする

赤緑青の3つの正方形の色ブロックを「_stage」変数の数ずつ出現させます。いずれかの色ブロックがクリックされたら、徐々に透明になりながら拡大して消える、という動作をします。

赤緑青の色ブロックをクリック判定する

「js/color.js」ファイルを新規作成します。imgタグをjQueryで作成してランダムに配置し、それらがクリックされたら消します。まだXY移動量のデルタ(dx、dy、増分)はセットだけして使っていません。デルタは最後に使います。

・サンプルコード「js」→「color.js」ファイル
class Color {
  constructor(i) {
    this.dx = (Math.random()*2+2)*(Math.random()<0.5)?1:-1;
    this.dy = (Math.random()*2+2)*(Math.random()<0.5)?1:-1;
    var img = $('<img class="color" src="images/'+(i%3)+'.png" alt="'+(i%3)+'" />');
    img.css('left',Math.random()*($('body').width()-100));
    img.css('top',Math.random()*($('body').height()-100));
    $('#main').prepend(img);
  }
}

【サンプルコードの解説】
「Color」クラスで色ブロック1個ずつを表示します。
Colorクラスのコンストラクタで「dx」「dy」プロパティに各色ブロックのXY移動量をランダムに代入します。「.color」セレクタで0~2.png画像をalt属性に同じ番号で「img」タグをjQueryで作り「img」変数に代入します。imgのjQueryのスタイルシート(CSS)でx('left')とy('top')座標をランダムに配置します。Webアプリなのでimg変数をjQueryでプリロードします。

・サンプルコード「js」→「main.js」ファイル
$(function() {
  var _stage = 2;
  var _mainLoopID = null;
  var _colors = [];
  var _audio = $("audio").get();
  for ( i = 0; i < _audio.length; i++ ) _audio[i].load();

  function init() {
    var rgb = [0,0,0];
    $('#main').empty();
    _colors = [];
    for ( var i = 0 ; i < _stage*3; i++ ) {
      _colors.push(new Color(i));
    }
    while ( rgb[0] == rgb[1] ) {
      rgb = [~~(Math.random()*_stage),~~(Math.random()*_stage),~~(Math.random()*_stage)];
    }
    setBgColor(rgb);

    $('.color').on('click',function() {
      playAudio(3);
      rgb[$(this).attr('alt')]++;
      $(this).off().animate({'left':0,'top':0,'width':$('body').width(),'height':$('body').height(),'opacity':0},500,function() {
        isGameOver($(this));
      });
      setBgColor(rgb);
    });
    _mainLoopID = setInterval(mainLoop,50);
  }

  function setBgColor(rgb) {
(中略)
  }

  function mainLoop() {
  }

  function isGameOver(selector) {
    selector.remove();
  }

  function start() {
    clearInterval(_mainLoopID);
    $('body').css('background-color','rgb(255,255,255)');
    $('h1').off().on('click',function() {
      playAudio(0);
      $(this).empty();
      init();
    });
  }

  function playAudio(mp3) {
(中略)
  }

  start();
});

【サンプルコードの解説】
「_mainLoopID」変数には「setInterval」関数で50ミリ秒ごとに呼ばれるメインループのタイマーIDを代入します。
まず空で宣言した「_colors」配列に、forループで生成したColorクラスのインスタンスを追加します。
.colorセレクタが'click'されたら混色サウンドを再生し、alt属性から0~2の色の番号を取得してその番号のrgb配列の要素をインクリメントし、アニメーションしてから消し、ゲームクリア判定します。
「mainLoop」関数はまだ何もしませんが、定義だけします。
「isGameOver(selector)」はjQueryで引数の色ブロックセレクタを消します。
「start」関数で最初に_mainLoopIDのタイマーを消します。

index.htmlファイルに画像のプリロードをコーディングする

次のサンプルコードをコーディングし、index.htmlファイルをブラウザで開いてColorゲームをプレイします。js/color.jsをスクリプトとして読み込みます。

imgタグで画像ファイルを読み込みます。こうしてプリロードすることでjQueryで画像を扱う場合に画像の読み込み処理をしなくて済みます。「.images」セレクタは「pc.css」ファイルで非表示にしています。

・サンプルコード「index.html」ファイル
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8">
    <TITLE>カラーゲーム「Color」</TITLE>
    <link href="css/pc.css" rel="stylesheet" /> 
    <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
    <script src="./js/color.js"></script>
    <script src="./js/main.js"></script>
  </head>
  <body>
    <div id="main"></div>
    <h1><img src="images/Title.png" /></h1>

    <audio id="audioGameStart">
      <source src="sounds/GameStart.mp3" />
      <source src="sounds/GameStart.ogg" />
    </audio>
    <audio id="audioGameOver">
      <source src="sounds/GameOver.mp3" />
      <source src="sounds/GameOver.ogg" />
    </audio>
    <audio id="audioStageClear">
      <source src="sounds/StageClear.mp3" />
      <source src="sounds/StageClear.ogg" />
    </audio>
    <audio id="audioMix">
      <source src="sounds/Mix.mp3" />
      <source src="sounds/Mix.ogg" />
    </audio>

    <img class="images" src="images/Title.png" />
    <img class="images" src="images/GameOver.png" />
    <img class="images" src="images/StageClear.png" />
    <img class="images" src="images/0.png" />
    <img class="images" src="images/1.png" />
    <img class="images" src="images/2.png" />
  </body>
</html>

メインループとゲームオーバーを処理する

次のサンプルコードをコーディングし、index.htmlファイルをブラウザで開いてColorゲームをプレイします。メインループで色ブロックの移動処理をし、isGameOver関数でゲームオーバーかゲームクリアか続行かを判定して処理します。これでゲームは完成です(図3)。冒頭で紹介したURLのブラウザゲームとは若干動作が異なるのは、解説しやすいようにシンプルにしたからです。

図3:Colorゲームのゲームオーバー画面
・サンプルコード「js」→「color.js」ファイル
class Color {
  constructor(i) {
(中略)
  }

  update($this) {
    var x = $this.offset().left+this.dx;
    var y = $this.offset().top+this.dy;
    $this.css('left',x);
    $this.css('top',y);
    if ( x < -100 || y < -100 || x > $('body').width() || y > $('body').height() ) {
      return true;
    }
    return false;
  }
}

【サンプルコードの解説】
Colorクラスの「update」メソッドで(x,y)を(dx,dy)だけ色ブロックを移動します。jQueryでCSSのx(つまり'left')とy(つまり'top')をセットします。if文で色ブロックが画面外に出たか調べます。

・サンプルコード「js」→「main.js」ファイル
$(function() {
(中略)

  function init() {
(中略)
  }

  function setBgColor(rgb) {
(中略)
  }

  function mainLoop() {
    $('.color').each(function(index) {
      if ( _colors[index].update($(this)) ) {
        isGameOver($(this));
      }
    });
  }

  function isGameOver(selector) {
    selector.remove();
    if ( $('.color').length <= 0 ) {
      playAudio(1);
      $('h1').html('<img src="images/GameOver.png" />');
      $('h1').off().on('click',function() {
        $(this).html('Glt;img src="images/Title.png" />');
        start();
      });
    }
  }

  function start() {
(中略)
  }

  function playAudio(mp3) {
(中略)
  }

  start();
});

【サンプルコードの解説】
mainLoop関数で_colors配列のupdateメソッドを呼び出します。jQueryの「$(this)」を変数にしたものがupdateメソッドの「$this」引数です。色ブロックが画面外に出たらゲームオーバー判定します。
isGameOver関数で色ブロックが0個以下(全ての色ブロックが消えた場合)ならゲームオーバー処理します。ゲームオーバーならゲームオーバー画像を表示し、その画像のjQueryでクリック判定をイベントリスナーに登録します。クリックされたらタイトル画面に戻ります。

【コラム】モチベーション

アメリカでIQの高い学校へ飛び級した子が、頑張るのに疲れて普通の学校で平凡な学生生活を送ったと聞いたことがあります。やっぱりモチベーションがなければ何もできないから、モチベーションを高く保つことが大事なんでしょう。筆者も本を書いたり記事を書いたりするモチベーションぐらいならあるのですが、なかなか企画が通らないこともあり残念です。以前は新しいことにチャレンジするモチベーションがあったから色々な技術を身につけられたけど、やはり歳をとると新しいことにチャレンジするモチベーションは低下します…。

おわりに

今回は、JavaScriptのラッパーライブラリである「jQuery」を使って、「HTML5」+「CSS」+「JavaScript」によるWebページでColorゲームを作りました。jQueryはCDN(Contents Delivery Network)で取得しています。

この記事をシェアしてください

人気記事トップ10

人気記事ランキングをもっと見る

企画広告も役立つ情報バッチリ! Sponsored