どうも、まさとらん(@0310lan)です。
今回は、ブラウザだけを使って簡単なWeb開発に挑戦し、オンライン上でゲームのスコアを友人・知人と競争できるようなWebランキング機能を実現してみたいと思います!
利用するサービスやツールは以下のとおり。(すべて無料)
・開発環境に、オンラインコードエディタの「Cloud9」
・サーバー周りのバックエンドに「Milkcocoa」
・ゲームとして遊ぶテトリスに「Blockrain.js」
・公開用サーバーとして「GitHub Pages」
これらを組み合わせれば、今すぐブラウザを開いて誰でも簡単に開発を始めることが可能です!
■開発の準備をしよう!
まずは、開発を始める前に「GitHub」と「Cloud9」のユーザー登録を済ませておきましょう。
そして、「GitHub」のマイページから新しいレポジトリを作成します。
ここで作成する「レポジトリ名」は、最終的に公開するURLになることも考慮しておきましょう。
次に、「Cloud9」をGitHubアカウントと連携しておくと、先ほど作成したレポジトリが表示されるので、「Clone to edit」ボタンをクリック!
これで、GitHubと連携した開発環境の完成です!
あとは、このエディタ上でどんどんプログラミングしていくだけです。
ただし、今回は友人・知人と共有可能なWebランキング機能を作成したいので、どうしてもサーバー周りの開発が必要になってしまいます。
Cloud9だけでも可能ですが、もっと簡単に実現できる「Milkcocoa」を使ってみたいと思います。
そこで、Milkcocoaのユーザー登録を済ませ、管理画面から新規アプリを作成しましょう!
そして、アプリのダッシュボードに記載されている「アプリID」をメモしておきます。
このIDを使って、サーバーとやり取りすることが可能になっており、わずかなコードを書くだけでオンライン上にデータを「読み書き」できるようになるので便利です。
ここまで来たら、あとはプログラミングするだけです!
■必要なファイルを用意する!
今回のサンプルデモでプログラミングするのは、「index.html」と「app.js」の2つだけです!
あとは、スコアをランキングするために、遊べるゲームが必要なので「テトリス」にしようと思いますが、ゼロからプログラミングすると大変です。
そこで、数行のコードでテトリスを実現できるjQueryライブラリ「Blockrain.js」を使ってみました。
まずは、「index.html」を作ります。
<!-- index.html --> <!doctype html> <html lang="ja"> <head> <meta charset="UTF-8" /> <title>サンプルデモ</title> <link rel="stylesheet" href="css/blockrain.css" /> <link rel="stylesheet" href="css/milligram.min.css" /> </head> <body> <div class="container"> <h1>テトリスWebランキング</h1> <!-- テトリスを表示する --> <div class="game"></div> </div> <script src="js/jquery.min.js"></script> <script src="js/blockrain.jquery.min.js"></script> <script src="js/milkcocoa.js"></script> <script src="js/app.js"></script> </body> </html>
「Blockrain.js」を利用するためのCSS・JSファイルを読み込み、サーバー操作用の「Milkcocoa」のJSファイルも忘れないようにしておきましょう。
「divタグ」に任意のクラス名を記載することで、「Blockrain.js」から簡単にテトリスを表示できます。
あと、CSSに関しては超軽量でレスポンシブにも対応するフレームワーク「Milligram」を使うことで、今回のようのなサンプルデモであればCSSをまったく書かなくてもOKです!
次に、「app.js」ですが、最初はこんな感じに書いておけば良いでしょう!
// app.js var mlkcca = new MilkCocoa("【アプリID】.mlkcca.com"); var ds = mlkcca.dataStore("score"); $('.game').blockrain({ theme: "candy", autoBlockWidth: true, });
冒頭でメモしておいた「アプリID」を使って、まずは「Milkcocoa」を操作するための変数「mlkcca」を作成します。
そして、「mlkcca」を使って「mlkcca.dataStore(“score”)」と書くだけで、「score」という名前のデータベースを作ることが出来ます。
あとは、この「score」を変数「ds」へ代入し、データの「読み書き」をプログラミングしていくことになります。
「Blockrain.js」に関しては、「index.html」で指定した「divタグ」を使い、「$(‘.game’).blockrain()」と書くだけでブラウザ上でテトリスが遊べるようになるので驚きです。
ここまで準備できたら、次はゲームのスコアをMilkcocoaのデータベースを使って「読み書き」してみましょう!
■ゲームスコアを保存してみよう!
ゲームの「スコア」をデータベースへ「読み書き」するために必要なポイントは、以下のとおり!
・ゲームスコアの取得
・データベースへの書き込み方法
・データベースからの読み込み方法
この3つのポイントが分かれば実現できそうですね。
まず、ゲームのスコアを取得する方法ですが、これは「Blockrain.js」がすでに用意してくれています。
// app.js $('.game').blockrain({ onGameOver: function(score) { // 変数「score」に、ゲームのスコアが入っている } });
「onGameOver」は、ゲームが終了した時に発生するイベント処理で、最終的なゲームのスコアが変数「score」に入っています。
データベースへ書き込む方法ですが、これは恐ろしくシンプルで「ds.push()」と書くだけで実現してしまいます。
つまり、このように書けば、簡単にゲームのスコアをデータベースへ書き込めます。
// app.js $('.game').blockrain({ onGameOver: function(score) { ds.push({ score: score }); } });
これでOK!
データはオブジェクト形式である必要があるので、変数「score」をそのままpushしないように注意しましょう。
実際に「index.html」をブラウザで開き、ゲームで遊んだ後にMilkcocoaのダッシュボードから、データストアを見てみるとしっかり「スコア」が保存されているのが分かります。
さらに、保存されたデータを読み込んで取得したい場合には、「ds.stream()」を利用すればOK!
ds.stream().next(function(err, message) { console.log(message); })
このように書くことで、データベースに保存されているデータの一覧を取得できるわけです。
今回の目的である「Webランキング機能」に必要な「スコアの取得」「データの読み書き」がこれで実現できるようになりました。
あとは、スコアに応じてランキングを作り、ページに表示させれば完成です!
■「ランキング」を表示するための準備!
最初に、ランキングを表示させるためのHTMLを組み立てましょう。
<!-- index.html --> <div class="container"> <h1>テトリスWebランキング</h1> <div class="row"> <div class="game column"></div> <div class="column"> <table> <tr> <th>順位</th> <th>ユーザー名</th> <th>スコア</th> </tr> <tr> <td>1位</td> <td class="name1"></td> <td class="score1"></td> </tr> <tr> <td>2位</td> <td class="name2"></td> <td class="score2"></td> </tr> <tr> <td>3位</td> <td class="name3"></td> <td class="score3"></td> </tr> <tr> <td>4位</td> <td class="name4"></td> <td class="score4"></td> </tr> <tr> <td>5位</td> <td class="name5"></td> <td class="score5"></td> </tr> </table> </div> </div> </div>
「Milligram」を使うと、要素のクラスに「column」を指定するだけで、簡単にレスポンシブ対応になります。
あとは、「app.js」からランキングデータを表示させるだけなのですが、Milkcocoaにはデータベースからスコアに応じて並び替える機能が現時点で用意されていないので、独自にプログラミングする必要があります。
その関係で、スコアデータは1つの「オブジェクト」として保持していた方が何かと便利なので、新たに「scoreList」オブジェクトを作成し、Milkcocoaと連携させていきたいと思います。
// app.js //スコアデータの保持用 var scoreList = { id: null, data:[] }; setup(); // 初期設定用の関数 function setup() {} // ランキングデータ表示用の関数 function rankUpdate() {} // ランキングデータ作成用の関数 function rankSort(user, score) {}
「scoreList」は、スコア順に並んだランキングデータが常に保持されている状態にしておき、このオブジェクトを1つ参照するだけでデータベースへの「読み書き」や、ページへの「表示」ができるようにします。
■「ランキング」を表示させよう!
まず、ランキングデータをページに表示させる「rankUpdate()」ですが、これはHTMLのテーブル要素へ「scoreList」の情報をそのまま書き込んでいけば良いでしょう。
function rankUpdate() { // ランキング数の取得 var maxRank = scoreList.data[0].length; // ランキング順にページへ表示させる for(var i=0; i<maxRank; i++) { $('.name' + (i+1)).text(scoreList.data[0][i].name); $('.score' + (i+1)).text(scoreList.data[0][i].score); } }
ただし、初回は「scoreList」に何もデータが入っていない状態なので、データベースからスコアデータを取得する必要があります。
もっと細かく言うと、一番最初にプログラムを実行した時には、データベースにすら何もデータが無い状態になっています。
そこで、このような状況に対処するための「setup()」を作っておきましょう。
function setup() { ds.stream().next(function(err, message) { // ➀データベースに「スコア」が存在するかを確認 if(message[0] === undefined) { // ➁スコアデータの初期設定 scoreList.data.push([ {name: "----", score: 500}, {name: "----", score: 400}, {name: "----", score: 300}, {name: "----", score: 200}, {name: "----", score: 100} ]); ds.push(scoreList); rankUpdate(); } else { // ➂データベースからスコアを取得 scoreList.data.push(message[0].value.data[0]); rankUpdate(); } }); }
今回のサンプルでは、基本的に「scoreList」という1つのオブジェクトだけを使うようにするので、データベースにもこのオブジェクトが1つだけ保存されている状態ということになります。
そこで、➀のように「message[0] === undefined」と比較することで、データベースに何らかのデータが存在するかどうかをチェックします。
「undefined」ということは、何もデータが無い状態…つまり、プログラムの初回起動ということなので、➁のような初期データを代入します。
当然ながら、データが存在するのであれば、➂のようにそのまま「scoreList」へ代入すればOKですね。
次に、実際のランキングデータを生成する「rankSort()」を作りましょう。
これは、ゲームが終了した時の「スコア」と、「scoreList」が保持している「スコア」を比較してランキングデータを作成します。
ただし、注意が必要なのは、ゲーム開始時の「scoreList」に入っている「スコアデータ」と、ゲーム終了時のデータベースに入っている「スコアデータ」が大きく変わっている可能性がある点です。
これは「Webランキング」の特性で、自分が遊んでいる時に他の人も遊んでいることになるので、データベースのスコアはどんどん更新されているわけです。
そのため、ゲーム終了時にはなるべく最新のデータを取得してから、自分のスコアを比較した方が良いでしょう。
できれば「リアルタイム」に処理したいところですが、今回は簡単にするためゲーム終了時にチェックしています。
function rankSort(user, score) { // 最新のスコアデータにするために初期化 scoreList.data = []; ds.stream().next(function(err, message) { // 最新のデータを取得 scoreList.data.push(message[0].value.data[0]); // データベースを更新するためにIDを取得 scoreList.id = message[0].id; // ゲーム終了時のスコアを追加 scoreList.data[0].push( { name: user, score: score } ); // スコア順に並び替え scoreList.data[0].sort(function(a, b) { return b["score"] - a["score"] }); scoreList.data[0].pop(); rankUpdate(); // データベースのスコアを更新する ds.set(scoreList.id, scoreList); }); }
Milkcocoaでは、データベースに何か保存する時は「ds.push()」を使えば良いのですが、データを書き換える場合には「ds.set()」を利用します。
これは、データベースのIDが必要になるので、途中で取得するのを忘れないようにしましょう。
また、JavaScriptが標準で搭載している「sort()」を使うことで、簡単にスコア順に並び替えることが出来るので、まだ知らない方は丸覚えしておくと便利です!
■ゲームを公開してみよう!
それでは、完成したプログラムを公開してみたいと思います。
冒頭で、「cloud9」と「GitHub」を連携させましたが、これはGitHubをホスティングサーバーとして使い、手っ取り早く世界中に公開できる「GtiHub Pages」を簡単に利用できるので便利です。
方法は簡単で、Cloud9のターミナルから、以下のGitコマンドを実行すればOK!
$ git add . $ git commit -m “first commit” $ git push -u origin master
「Cloud9」と「GitHub」を連携した時点で、基本的なGitの初期設定は完了しているので、上記コマンドを叩くだけです。
すると、GitHubのレポジトリページに反映されているのが分かります。
さらに、ブランチを「gh-pages」に変更しておきます。
$ git branch gh-pages $ git checkout gh-pages $ git push -u origin gh-pages
これで、「GitHub Pages」の準備は完了です。
2〜3分ほど待ってから、以下のアドレスをブラウザで開きましょう!
http://【ユーザー名】.github.io/【レポジトリ名】
あとは、テトリスの「Webランキング」対戦を楽しむだけです!
URLを友人・知人へシェアして、複数人でランキングバトルすればきっと盛り上がりますよ!
今回、作成したプログラムの全ソースコードは、コチラから確認できます。
※「app.js」内の「アプリID」を書き換えれば、すぐにブラウザで遊べます。
■paizaラーニングについて
paizaは、技術を追い続けることが仕事につながり、スキルのある人がきちんと評価される場を作ることで、日本のITエンジニアの地位向上を目指したいと考えています。
自分のスキルを磨いていきたいと考えている方におすすめなのが「paizaラーニング」。オンラインでプログラミングしながらスキルアップできる入門学習コンテンツです。初心者でも楽しくプログラミングの基本を学ぶことができます。
そして、paizaでは、Webサービス開発企業などで求められるコーディング力や、テストケースを想定する力などが問われるプログラミングスキルチェック問題も提供しています。
スキルチェックに挑戦した人は、その結果によってS・A・B・C・D・Eの6段階のランクを取得できます。必要なスキルランクを取得すれば、書類選考なしで企業の求人に応募することも可能です。「自分のプログラミングスキルを客観的に知りたい」「スキルを使って転職したい」という方は、ぜひチャレンジしてみてください。
さらに、paizaが運営する無料オンラインプログラミング実行環境サービス「paiza.IO (パイザ・アイオー)」では、JavaScriptはもちろん、多数プログラミング言語のプログラミングが面倒な環境構築なしに無料でできますのでぜひご利用ください!