JavaScript ライブラリ tmlib.js を使った本格アプリ Reverse Reverse が公開されました!!

phiary に引っ越しました. 毎日プログラミングやWebに関する情報を発信しています! RSS 登録してたまに覗いたり, tweet やハテブして拡散してもらえると幸いです.

Pocket

先日, tmlib.js という JavaScript ライブラリを公開しました.

そして早くもその tmlib.js を使った本格アプリ 『Reverse Reverse』が公開されました.

開発してくれたのは Halt.
Web クリエイター && イケメン && オタク && 変態 && 私の大切な友人のひとりです.

tmlib.js を本格的に使った第一弾アプリになります. コードは GitHub 上で公開しているので参考にしていただけると嬉しいです. プレイして Tweet してくれると更に嬉しいです.

PlayGitHub

Table of contents

Reverse Reverse とは

ゲームのプレイはこちらでできます.

ゲームのルールは GitHub を見て頂けると幸いです.

開発者 Halt のブログは こちら.

開発に使用したライブラリ tmlib.js は こちら.

ゲーム自体はちょっと難しいですが, コツを掴むとポンポンクリアできて気持よくプレイできますよ♪

up

iPhone でプレイしよう!

tmlib.js でゲームを作ると自動で画面いっぱいにフィットします.

なので, iPhone 上でネイティブアプリのようにプレイすることができます. やり方を動画でざっくりと解説します.

手順

  1. iPhone Safari でゲームを起動する
  2. 下のバーの真ん中のアイコンをタッチする
  3. ホーム画面に追加を選択する
  4. 適当に名前を入力する
  5. ホーム画面にアイコンが追加されるので選択する
  6. フルスクリーンでプレイ!!
up

Halt との開発

このゲームはもともとHaltによって iPhone アプリとして Objective-C + cocos2d で開発されたもので, 私の方からHalt に tmlib.js で Web に移植してみないかと持ちかけて実現しました.

私にとってこの開発の目的は2つありました.

1つは tmlib.js のテスト && 安定化でした. 実際に今回のアプリ開発の過程でバグや足りない機能が見つけ対応することで実用化に向けてかなりブラッシュアップすることができました.

2つ目の目的は Halt のゲームプログラマとしてのスキルアップでした.

私は開発だけではなくゲームプログラマを育成するという教育の方面にも興味があり その第一歩としての取り組みでした.

勝手ながら Halt には私以上のゲームプログラマになって欲しいと思っています. そして正直言ってまだまだ未熟です.

そこで今回はできるだけ私はコーディングをせずに横から口出しをし, 手を加えるとしても少しリファクタリングをする程度に努めました.

結果として, 成長してくれたと思うしゲームプログラミングの楽しさを感じてもらえたと思っています. 現在も引き続き別のゲームをバンバン開発してくれてるみたいなので今後が楽しみです^^

私は生業 && 趣味としてゲームプログラミングに取り組んでいますが, Halt は Web クリエイターなのでこの開発に割ける時間は限られていました. そんな中で合間を縫って開発し, 勝手に抱いていた私の期待に応えてくれた Halt には本当に感謝しています.

up

注目 Code を抜粋

注目のコードを抜粋してみました. 少しでも tmlib.js を使うメリットを感じていただけると幸いです.

画像やサウンドデータは preload

tmlib.js には preload で登録したメソッド内でリソースの読み込みを行います. こうすることで main に登録した関数が実行される際にリソースの読み込みが完了していることが保証されます.

また, tmlib.js には TextureManager, SoundManager というクラスがあり, key とファイルパスを関連付けて管理することができます.

そのため, あとでファイルを差し替えたりといったことが簡単に行えます.

// リソースの読み込み
tm.preload(function(){
    // ゲームシーン中
    tm.graphics.TextureManager.add("whiteStone", "img/whiteStone.png");
    tm.graphics.TextureManager.add("blackStone", "img/blackStone.png");
    tm.graphics.TextureManager.add("stoneFrame", "img/stoneFrame.png");
    tm.graphics.TextureManager.add("gameStatus", "img/gameStatus.png");
    tm.graphics.TextureManager.add("gameBackground", "img/gameBackground.png");
    tm.graphics.TextureManager.add("nextStage", "img/nextStage.png");
    tm.graphics.TextureManager.add("missTake", "img/missTake.png");
    tm.graphics.TextureManager.add("timeUp", "img/timeUp.png");

    // タイトル
    tm.graphics.TextureManager.add("titleBackground", "img/titleBackground.png");
    tm.graphics.TextureManager.add("logoCircle", "img/logo/logo_circle.png");
    tm.graphics.TextureManager.add("logoCircle2", "img/logo/logo_circle2.png");
    tm.graphics.TextureManager.add("logoTile", "img/logo/logo_tile.png");
    tm.graphics.TextureManager.add("logoText", "img/logo/logo1.png");
    tm.graphics.TextureManager.add("logoText2", "img/logo/logo1-2.png");
    tm.graphics.TextureManager.add("logoTextReverse", "img/logo/logo2.png");
    tm.graphics.TextureManager.add("logoTextReverse2", "img/logo/logo2-2.png");
    tm.graphics.TextureManager.add("startButton", "img/startButton.png");

    // リザルト
    tm.graphics.TextureManager.add("resultBackground", "img/resultBackground.png");
    tm.graphics.TextureManager.add("resultText", "img/resultText.png");
    tm.graphics.TextureManager.add("returnTitle", "img/returnTitle.png");
    
    // github
    tm.graphics.TextureManager.add("octodex", "img/github/octodex.png");
    tm.graphics.TextureManager.add("tmlib", "img/github/tmlib.png");
    
    // サウンド
    tm.sound.SoundManager.add("bgm", "sound/bgm/bgm", 1);
    tm.sound.SoundManager.add("op", "sound/bgm/op", 1);
    tm.sound.SoundManager.add("decide", "sound/se/decide.wav");
    tm.sound.SoundManager.add("touch", "sound/se/touch.wav");
    tm.sound.SoundManager.add("clear", "sound/se/clear.wav");
});

▲ resource.js

UI をデータ化

tmlib.js にはスプライトやラベル, ボタンといった要素を JSON データから生成する仕組みがあります.

そのため, プログラミングと UI の情報を簡単に分離することができます.

    // ラベルのリスト
    var UI_DATA = {
        LABELS: {
            children: [
                {
                    type:"Label",name:"levelLabel",
                    x:255,y:60,width:150,fillStyle:"white",
                    text:"dammy",fontSize:32,align:"end"
                },
                {
                    type:"Label",name:"scoreLabel",
                    x:253,y:90,width:150,fillStyle:"white",
                    text:"dammy",fontSize:24,align:"end"
                },
                {
                    type:"Label",name:"whiteStoneLabel",
                    x:350,y:90,width:150,fillStyle:"white",
                    text:"dammy",fontSize:32,align:"end"
                },
                {
                    type:"Label",name:"goalStonesLabel",
                    x:440,y:90,width:150,fillStyle:"white",
                    text:"dammy",fontSize:32,align:"end"
                },
            ]
        }
    }
    
    ns.MainScene = tm.createClass({
        superClass: tm.app.Scene,
    
        init: function(){
            this.superInit();
            
            // ステータスリセット
            userData.gameOver = false;
            gameData.timeUp = 0;
            userData.touchTotalCount = 0;
            userData.time = 1;
            userData.level = 1;
            userData.score = 0;
            userData.gameOver = false;
            this.alpha = 1.0;
            gameData.time = gameData.maxTime;
    
            // 画像
            for(var key in IMAGES){
                var value = IMAGES[key];
                var sprite = tm.app.Sprite(value.rect[2], value.rect[3]);
                sprite.position.set(value.rect[0], value.rect[1]);
                sprite.scaleX = sprite.scaleY = CURRENT_SCALE;
                sprite.setImage( tm.graphics.TextureManager.get(value.image) );
                this[key] = sprite;
                this.addChild(sprite);
            }
            
            // ラベル
            this.fromJSON(UI_DATA.LABELS);

▲ mainscene.js

Twitter との連携

tmlib.js ではソーシャルサービスとの連携もサポートしています. 今回のゲームでは Twitter との連携機能を使って Tweet ボタンを配置しています.

            // ツイートボタン
            var tweetMessage = this.getTweetMessage(userData.score);
            var msg = tm.social.Twitter.createURL({
                type: "tweet",
                text: "Reverse Reverse\nScore : {0}\nTime : {1}秒生存\n{2}".format(userData.score, userData.time, tweetMessage),
                hashtags: "RxR,tmlibjs",
                url: "http://bit.ly/MsWyHn",
            });
            var tweetButton = tm.app.iPhoneButton(120, 60, "black");
            tweetButton.setPosition(360, 640);
            tweetButton.label.text = "Tweet";
            this.addChild(tweetButton);
            tweetButton.onpointingstart = function(){
                tm.sound.SoundManager.get("decide").play();

                window.open(msg, "_self");
            };

▲ endscene.js

ポーズ機能のサポート

タブブラウザが当たり前の時代にタブが切り替わっても BGM が鳴り続けたり処理が走り続けたりといったことは時代遅れです.

そこで制作したゲームでは タブが切り替わってゲームウィンドウからフォーカスが外れた際に自動的に Pause シーンに遷移するようになっています.

流れについて簡単に解説すると, ウィンドウへのフォーカスが外れた際にカレントのシーンに onblur イベントが発行され PauseScene に切り替わります.

        // ポーズ画面 : 別タブへ切り替わった時 / Tabキーを押した時
        onblur: function(){
            app.pushScene(PauseScene(this.bgm));
        }

▲ mainscene.js

Puase シーン内で BGM の再生をストップし, 画面を暗くしています.

そして, フォーカスが戻りタッチされると ontouchstart イベントが走り以前のカレントシーンに復帰します.

var PauseScene = tm.createClass({
    superClass: tm.app.Scene,
    
    init: function(audio){
        this.superInit();
        this.interaction;
        
        var filter = tm.app.Sprite(app.width, app.height);
        filter.setPosition(app.width/2, app.height/2);
        filter.canvas.clearColor("rgba(0, 0, 0, 0.75)");
        this.addChild(filter);
            
        app.stop();
        
        this.audio = audio; 
        if(this.audio){ this.audio.pause(); }
    },
    
    onfocus: function(){
        app.start();
    },
    
    onblur: function(){
        app.stop();
    },
    
    onpointingstart: function(){
        if(this.audio){ this.audio.play(); }
        app.popScene();
    },
});

▲ pausescene.js

up

現在, Halt の他にも数多くのクリエイターの方に tmlib.js を触って頂きアプリ開発を進めて頂いています.

もちろん私や Halt も引き続きアプリ開発中なので今後続々公開予定です. お楽しみに♪♪

TRACK BACK URL

POST COMMENT

メールアドレスが公開されることはありません。

COMMENT