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

「jQuery」でWebゲーム「Color」を開発してみよう

第1回の今回は、「jQuery」を使用して「HTML5」+「CSS」+「JavaScript」によるWebゲーム「Color」を開発する解説をします。

大西 武 (オオニシ タケシ)

6:30

目次

  1. はじめに
    1. Colorゲームについて
    2. プログラミング言語について
  2. 開発のために必要となる環境の準備
  3. VS CodeでHTMLファイルを作成しよう
  4. タイトル画面をクリックする それでは、jQueryを使ったJavaScriptのコードを書いて、ゲームらしくタイトル画面(図2)がクリックされたらゲーム開始してみましょう。ここでは、まだ背景色が変わるだけです。
    図2:Colorゲームのタイトル画面
    pc.cssをコーディングする 「css/pc.css」を新規作成します。CSSはタグを装飾などするスタイルシートです。CSSの書式についても「WebGPUではじめる3DCGアニメーション入門」の第2回を参考にしてください。 ・サンプルコード「css」→「pc.css」ファイル * { user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; -webkit-user-drag: none; -ms-user-drag: none; } body, html { height: 100%; padding: 0; margin: 0; } h1 { position: fixed; width: 100%; text-align: center; top: 35%; font-size: 400%; } #main { width: 100%; height: 100%; } .color { position: fixed; } .images { display: none; } タイトル画像をクリック判定する 「js/main.js」ファイルを新規作成します。タイトル画像をクリックしたらゲーム開始の音声を再生し、真っ白以外のランダムな背景色になります。JavaScriptの文法については「WebGPUではじめる3DCGアニメーション入門」の第2回を参考にしてください。jQueryについては【サンプルコードの解説】を見てください。 ・サンプルコード「js」→「main.js」ファイル $(function() { var _stage = 2; var _audio = $("audio").get(); for ( i = 0; i < _audio.length; i++ ) _audio[i].load(); function init() { var rgb = [0,0,0]; $('#main').empty(); while ( rgb[0] == rgb[1] ) { rgb = [~~(Math.random()*_stage),~~(Math.random()*_stage),~~(Math.random()*_stage)]; } setBgColor(rgb); } function setBgColor(rgb) { var max = (rgb[0]<rgb[1])?((rgb[1]<rgb[2])?2:1):((rgb[0]<rgb[2])?2:0); var color = 'rgb(0, 0, 0)'; if ( rgb[max] != 0 ) { var i = 255/rgb[max]; color = 'rgb('+~~(i*rgb[0])+','+~~(i*rgb[1])+','+~~(i*rgb[2])+')' if ( rgb[0] == rgb[1] && rgb[0] == rgb[2] ) { _stage++; $('h1').html('<img src="images/StageClear.png" />'); playAudio(2); start(); } } $('body').css('background-color',color); } function start() { $('h1').off().on('click',function() { playAudio(0); $(this).empty(); init(); }); } function playAudio(mp3) { try { _audio[mp3].currentTime = 0; _audio[mp3].play(); } catch (e) { _audio[mp3].play(); } } start(); });【サンプルコードの解説】
    jQueryの「$(function() { })」は、DOM(HTMLの読み込み)が完了したら、この中の処理を実行します。
    「_stage」変数は2が第1面(ステージ)になります。
    「_audio」変数に後に出てくるHTML5のaudioタグを配列として取得し、プリロードします。
    「init」関数で「#main」セレクタをjQueryで空(から)にし、背景色の「rgb」変数をランダムな色に作成します。(R,G,B)は正の整数です。
    「setBgColor」関数で「rgb」引数を元に背景色を決めます。(R,G,B)で最も大きい色を「max」変数に取得し、255をその色の要素の値で除算して「i」変数に代入し、rgb(R,G,B)の3色にiを乗算してそれぞれ0~255の値になるようにして「color」変数に代入します。背景色が真っ白になったらステージクリア処理します。「body」タグのスタイルシート(CSS)の'background-color'プロパティにcolor変数をjQueryで指定します。
    「start」関数でh1タグが'click'されたかjQueryでイベントリスナーを登録し、クリックされたらサウンドを再生し、タイトル画面を消してinit関数を呼んで初期化し、ステージを開始します。
    「playAudio」関数でaudioタグのサウンドを頭出しして再生します。
    変数の初期化後、jQueryコードは「start();」でstart関数を呼び出すことから開始します。 index.htmlファイルをコーディングする 次のサンプルコードをコーディングしたらブラウザでindex.htmlファイルを開き、Colorゲームを開始します。タイトル画像をクリックできましたね。 audioタグはJavaScriptの「for ( i = 0; i < _audio.length; i++ ) _audio[i].load();」で、「#audioGameStart」の上から順に0、1、2、3インデックスになります。 ・サンプルコード「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/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> </body> </html>
    【コラム】ホワイトハッカー
    単なるプログラマーより、サイバー攻撃を守る側のホワイトハッカーの方が平均年収が高いそうですね。ホワイトハッカーのトップは年収数十億円だそうです。でも僕は自分さえ守れません…。
    赤緑青の色ブロックをクリックする 赤緑青の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)で取得しています。
    1. pc.cssをコーディングする
    2. タイトル画像をクリック判定する
    3. index.htmlファイルをコーディングする
  5. 赤緑青の色ブロックをクリックする
    1. 赤緑青の色ブロックをクリック判定する
    2. index.htmlファイルに画像のプリロードをコーディングする
  6. メインループとゲームオーバーを処理する
  7. おわりに

はじめに

今回から、図1のような「Colorゲーム」を様々なプログラミング言語を使って開発することで、そのプログラミング言語を簡単に学んでみようという連載を始めます。

図1:Colorゲームをプレイしているところ

Colorゲームについて

Colorゲームは「赤緑青の色ブロックをクリックしていくと背景色にその色が混ぜられるので、どんどんクリックして真っ白な背景にしていこう」という内容です。

先のURLにアセットとして画像ファイルのpngファイルとサウンドファイルのmp3ファイル、oggファイルが同梱された「color.zip」があるのでダウンロード(「Colorゲームのアセットをダウンロード」のリンク)しておいてください。アセットはテストでのみお使いください。言うまでもなく、色は赤緑青(RGB)の三原色で成り立っています。どんな色もこの三原色のそれぞれの明るさの組み合わせで表されます。

プログラミング言語について

第1回の今回は「jQuery」を使って開発します。jQueryは、HTML5をJavaScriptから簡単に操作できるようにするためのライブラリです。ややレガシーな存在ではありますが、現在でも広く利用されています。jQuery自身もJavaScriptで実装されています。

また、次回以降は「Python」「C/C++」「C#」「Visual Basic」「Rust」「Go」「Ruby」「Java」などのプログラミング言語や様々なライブラリでColorゲームを開発していきます。さまざまな言語で同じColorゲームを開発することで、各言語の特徴や違いなどを確認してみてください。

開発のために必要となる環境の準備

ゲーム開発を始める前に、今回必要となるブラウザと「Visual Studio Code」(以下、VS code)を準備します。VS Codeは今後も使うことがあると思いますので、この機会にインストールしておきましょう。

⚫︎ブラウザ
ColorゲームはWindowsなら「Edge」「Firefox」「Chrome」、macOSなら「Safari」「Firefox」「Chrome」、Linuxなら「Firefox」「Chrome」など、モダンなブラウザであればたいてい動きます。使い慣れたブラウザをお使いください。

⚫︎VS Codeの準備
こちらのURLからVS Codeをダウンロードしてインストールしてください。セットアップの手順は省略します。

VS CodeでHTMLファイルを作成しよう

次に「index.html」ファイルを新規作成します。次の最小限のサンプルコードをコーディングして、index.htmlファイルをブラウザで起動します。タイトル画像が左上に表示されましたね。HTML5の文法については「WebGPUではじめる3DCGアニメーション入門」の第2回を参考にしてください。

画像フォルダとサウンドフォルダ、cssフォルダ、jsフォルダの階層図は次のようになります。「images」フォルダの画像と「sounds」フォルダのサウンドは今後も使い回します。

colorフォルダ
┠cssフォルダ(スタイルシートフォルダ)
┃┗pc.cssファイル(メインのスタイルシート)
┠imagesフォルダ(画像フォルダ)
┃┠0.pngファイル(赤の色ブロック画像)
┃┠1.pngファイル(緑の色ブロック画像)
┃┠2.pngファイル(青の色ブロック画像)
┃┠GameOver.pngファイル(ゲームオーバー画像)
┃┠StageClear.pngファイル(ステージクリア画像)
┃┗Title.pngファイル(タイトル画像)
┠jsフォルダ(JavaScriptフォルダ)
┃┠color.jsファイル(色ブロッククラスのJavaScriptファイル)
┃┗main.jsファイル(メインJavaScriptファイル)
┠soundsフォルダ(サウンドフォルダ)
┃┠GameOver.mp3ファイル(ゲームオーバーサウンド)
┃┠GameOver.oggファイル(ゲームオーバーサウンド)
┃┠GameStart.mp3ファイル(ゲームスタートサウンド)
┃┠GameStart.oggファイル(ゲームスタートサウンド)
┃┠Mix.mp3ファイル(色が混ざる時のサウンド)
┃┠Mix.oggファイル(色が混ざる時のサウンド)
┃┠StageClear.mp3ファイル(ステージクリアーサウンド)
┃┗StageClear.oggファイル(ステージクリアーサウンド)
┗index.htmlファイル(トップページ)
・サンプルコード「index.html」ファイル
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8">
    <TITLE>カラーゲーム「Color」</TITLE>
  </head>
  <body>

    <h1><img src="images/Title.png" /></h1>

  </body>
</html>
【コラム】情報の共通テスト必修化

「情報の共通テストが必修になる」と聞いたとき、ちょっと嬉しかったです。なぜなら「筆者のプログラミング入門書も売れるか」と期待したからです。でも他の科目でも参考書を買わない人ばかりなのに、よく考えたらプログラミング入門書も買わないかもしれない、と気づきました…。

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

人気記事トップ10

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

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