読者です 読者をやめる 読者になる 読者になる

paiza開発日誌

paiza(https://paiza.jp)の開発者が開発の事、プログラミングネタ、ITエンジニアの転職などについて書いています。

ブラウザだけでWeb開発に挑戦! 「Cloud9」&「Milkcocoa」でテトリスにWebランキング機能を搭載しよう!

開発ネタ Webサービス紹介

f:id:paiza:20160411120138j:plain
どうも、まさとらん(@0310lan)です。

今回は、ブラウザだけを使って簡単なWeb開発に挑戦し、オンライン上でゲームのスコアを友人・知人と競争できるようなWebランキング機能を実現してみたいと思います!

利用するサービスやツールは以下のとおり。(すべて無料

・開発環境に、オンラインコードエディタのCloud9

・サーバー周りのバックエンドにMilkcocoa

CSSフレームワークとしてMilligram

・ゲームとして遊ぶテトリスBlockrain.js

・公開用サーバーとしてGitHub Pages

これらを組み合わせれば、今すぐブラウザを開いて誰でも簡単に開発を始めることが可能です!

■開発の準備をしよう!

まずは、開発を始める前にGitHub」と「Cloud9」のユーザー登録を済ませておきましょう。

そして、「GitHub」のマイページから新しいレポジトリを作成します。
f:id:paiza:20160411131817j:plain

ここで作成する「レポジトリ名」は、最終的に公開するURLになることも考慮しておきましょう。

次に、「Cloud9」をGitHubアカウントと連携しておくと、先ほど作成したレポジトリが表示されるので、「Clone to edit」ボタンをクリック!
f:id:paiza:20160411131856j:plain

これで、GitHubと連携した開発環境の完成です!
f:id:paiza:20160411131907j:plain

あとは、このエディタ上でどんどんプログラミングしていくだけです。

ただし、今回は友人・知人と共有可能なWebランキング機能を作成したいので、どうしてもサーバー周りの開発が必要になってしまいます。

Cloud9だけでも可能ですが、もっと簡単に実現できる「Milkcocoa」を使ってみたいと思います。

そこで、Milkcocoaのユーザー登録を済ませ、管理画面から新規アプリを作成しましょう!
f:id:paiza:20160411131924j:plain

そして、アプリのダッシュボードに記載されている「アプリID」をメモしておきます。
f:id:paiza:20160411131935j:plain

この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()」と書くだけでブラウザ上でテトリスが遊べるようになるので驚きです。
f:id:paiza:20160411132340j:plain

ここまで準備できたら、次はゲームのスコアを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のダッシュボードから、データストアを見てみるとしっかり「スコア」が保存されているのが分かります。
f:id:paiza:20160411132436j:plain

さらに、保存されたデータを読み込んで取得したい場合には、「ds.stream()」を利用すればOK!

ds.stream().next(function(err, message) {
    console.log(message);
})

このように書くことで、データベースに保存されているデータの一覧を取得できるわけです。
f:id:paiza:20160411132459j:plain

今回の目的である「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」を指定するだけで、簡単にレスポンシブ対応になります。
f:id:paiza:20160411132556j:plain

あとは、「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

f:id:paiza:20160411132844j:plain
「Cloud9」と「GitHub」を連携した時点で、基本的なGitの初期設定は完了しているので、上記コマンドを叩くだけです。

すると、GitHubレポジトリページに反映されているのが分かります。
f:id:paiza:20160411132906j:plain

さらに、ブランチを「gh-pages」に変更しておきます。

$ git branch gh-pages
$ git checkout gh-pages
$ git push -u origin gh-pages

f:id:paiza:20160411132923j:plain
これで、「GitHub Pages」の準備は完了です。

2〜3分ほど待ってから、以下のアドレスをブラウザで開きましょう!

http://【ユーザー名】.github.io/【レポジトリ名】

あとは、テトリスの「Webランキング」対戦を楽しむだけです!
f:id:paiza:20160411132946j:plain

URLを友人・知人へシェアして、複数人でランキングバトルすればきっと盛り上がりますよ!

今回、作成したプログラムの全ソースコードは、コチラから確認できます。

github.com

※「app.js」内の「アプリID」を書き換えれば、すぐにブラウザで遊べます。

paizaについて

f:id:paiza:20150730172136p:plain
paizaでは、プログラミングスキルチェック問題(9言語に対応)を多数ご用意いたしております。もちろん今回の記事で使用しているJavaScriptにも対応しておりますので、「JavaScriptでプログラミング問題を解いてみたい」「自分のスキルを試してみたい」という方にもピッタリです!

paizaでプログラミング問題を解くと、結果によりS・A・B・C・D・Eの6段階で自分のスキルのランクが分かります。問題はレベルごとに分かれており、初心者から上級者の方まで挑戦していただけますので、自分のプログラミングスキルを客観的に知りたいという方は是非チャレンジしてみてください!!

プログラミング問題による学習コンテンツ(paiza Learning)もございますので、「まったくのプログラミング未経験者です」「初心者なのでプログラミング学習から始めたいな」という方もぜひご利用ください。

さらに、paizaが運営する無料オンラインプログラミング実行環境サービス「paiza.IO (パイザ・アイオー)では、JavaScriptはもちろん、多数プログラミング言語のプログラミングが面倒な環境構築なしに無料でできますのでぜひご利用ください!

■まとめ

今回ご紹介したように、簡単なサンプルデモであれば、いくつかのサービスを組み合わせることで誰でも実現できるようになりました。

また、「Milkcocoa」を使って公開する場合には、ダッシュボードから「許可Origin」「セキュリティルール」を設定するのを忘れないようにしましょう。

余裕のある方は、スマホ対応や機能追加、オリジナルのデザインなどにトライしてみてください!




paizaではITエンジニアとしてのスキルレベル測定(9言語に対応)や、プログラミング問題による学習コンテンツ(paiza Learning)を提供(こちらは21言語に対応)しています。テストの結果によりS,A,B,C,D,Eの6段階でランクが分かります。自分のプログラミングスキルを客観的に知りたいという方は是非チャレンジしてみてください。

http://paiza.jp

プログラミング入門講座|paizaラーニング

PHP入門編Ruby入門編Python入門編Java入門編JavaScript入門編C言語入門編C#入門編アルゴリズム入門編