2015年07月26日

Cocos2d-JS > ASSETS MANAGER EXTENSION

原文はこちらです。

このドキュメントは、Cocos2d-JS における新しいエクステンションであるアセットマネージャを紹介します(JSB のみ)。このエクステンションは、あなたのゲームにおいて使われる画像、音声ファイルやゲームスクリプトに対するホットアップデート用に設計されています。あなたは、あなたのウェブサーバ上でリソースの新しいバージョンを更新できるようになり、あなたのゲームは、あなたのリモートリソースをトラッキングし続けることができ、それらをデバイスにダウンロードできるようになるでしょう。全体的な新しいデザイン、新しいエクスペリエンス、あるいは新しいコンテンツさえ、それぞれのアプリストアであなたのアプリをアップデートする必要なしに即時に有効化できるでしょう。

ユースケース

あなたがあなたのゲームを既にアプリストアでリリース済みであると想像して下さい、しかしながら、あなたは幾つかのデザインが気に入らない、あるいは幾つかのネガティブなフィードバックがユーザによって報告されているとします。普通なら、あなたはあなたのゲームを再パッケージするだけで、それをそれぞれのアプリストアにサブミットして、さらに待つ... それが審査を通るか、あるいはそうでないかが分かるまで。私が言いたいのは、それが非常に辛い手続きであり、そしてプロセスの間に、多くのユーザが既に去ってしまっている、ということです。

他のケース:

  • あなたはゲーム内のアクティビティをバレンタインデー向けにオーガナイズしたくて、絶対にタイミングを逸したくない。
  • もしあなたはあなたのゲームに致命的なバグを発見し、それがあなたのゲームのバランスに強くダメージを与えているとしたら。
  • 遊べる時間を伸ばすためにあなたのゲームにレベルかシーンの新しいパッケージを追加したい。
  • などなど...

これらの全てに対して、もしあなたが徹夜で何か施すためのチャンスがあるとしたら、凄くないですか?アセットマネージャは、真にこれらの目的のために設計されています。

機能

Cocos2d-JS v3.0 RC0 におけるアセットマネージャは、多くの有益な機能を持ち、あなたがホットアップデートを非常に便利に効率的に行うのを手助けします。

  • マルチスレッドダウンロードサポート
  • 2つのレベルのプログレッションサポート:ファイルレベルプログレッションとバイトレベルプログレッション
  • Zip 圧縮ファイルサポート
  • ダウンロード再開
  • 詳細なプログレッション情報とエラー情報
  • リトライに失敗したアセットのための候補

利用方法

アセットマネージャを使うのは非常にシンプルであり、まず最初に、あなたのアプリのパッケージに JSON フォーマットでイニシャルマニフェストファイルを用意します。

マニフェストファイルでは、リモートマニフェストファイル、現在のバージョン及びリソースセットのオンラインアドレスを記述でき、それからゲームプロセス中に(訳注:マニフェストファイルを?)更新できるように jsb.AssetsManager クラスを使うこともできます。

マニフェストファイル

以下に json フォーマットのマニフェストファイルの例を示します:

{
    "packageUrl" : "http://example.com/assets_manager/TestScene/",
    "remoteVersionUrl" : "http://example.com/assets_manager/TestScene/version.manifest",
    "remoteManifestUrl" : "http://example.com/assets_manager/TestScene/project.manifest",
    "version" : "1.0.0",
    "engineVersion" : "Cocos2d-JS v3.0 RC0",

    "assets" : {
        "Images/background.jpg" : {
            "md5" : "..."
        },
        "Images/icon.png" : {
            "md5" : "..."
        },
        "Images/button.png" : {
            "md5" : "..."
        },
        "src/game.js" : {
            "md5" : "..."
        },
        "src/layer.js" : {
            "md5" : "..."
        },
        "compressed.zip" : {
            "md5" : "...",
            "compressed" : true
        }
    },

    "searchPaths" : [
        "res/"
    ]
}
  • packageUrl : アセットマネージャが全てのアセットをリクエストしダウンロードしようとするための URL
  • remoteVersionUrl : 新しいバージョンがサーバにアップロードされているかどうかを決定するためのリモートバージョンのチェックを可能にするリモートバージョンファイルの URL
  • remoteManifestUrl : 全てのアセット情報を含むリモートマニフェストファイルの URL
  • version : マニフェストファイルのバージョン
  • engineVersion : マニフェストファイルによって使われるエンジンのバージョン
  • assets : 全てのアセット情報
    • key : アセットの相対パスを表すそれぞれのキー
    • md5 : アセットのバージョン情報を表す md5 フィールド
    • compressed : [オプション] 圧縮フィールドが真の場合、ダウンロードされたファイルは自動的に解凍されます。zip フォーマットだけがサポートされます。
  • searchPaths : cocos2d エンジンに追加されるべきサーチパス

version.manifest ファイルは、マニフェストファイルの最初の5つのフィールドと正確に同じ情報を含むべきです。オプションで、もしそれ(訳注:version.manifest ファイル?)が見つからなければ、アセットマネージャは直接的に完全なマニフェストファイルをダウンロードします。しかし、それ(訳注:version.manifest ファイル?)が非常に有益なのは、もしあなたのマニフェストファイルが非常に大きくて、それ(訳注:version.manifest ファイル?)がバージョン情報の比較のための時間を大いに節約してくれるためです。

jsb.AssetsManager の利用方法

以下に使用例を示します:

var manager = new jsb.AssetsManager(manifestUrl, storagePath);

manager.update();
// プロセスが非同期化されているので、あなたはアセットマネージャを、プロセスが終了させられる前にリリースされないことを確信できるようにするためにリテインする必要があります。
manager.retain();

if (!manager.getLocalManifest().isLoaded()) {
    cc.log("Fail to update assets, step skipped.");
}
else {
    var listener = new jsb.EventListenerAssetsManager(manager, function(event) {
        switch (event.getEventCode())
        {
            case jsb.EventAssetsManager.ERROR_NO_LOCAL_MANIFEST:
                cc.log("No local manifest file found, skip assets update.");
                break;
            case jsb.EventAssetsManager.UPDATE_PROGRESSION:
                var percent = event.getPercent();
                var filePercent = event.getPercentByFile();
                cc.log("Download percent : " + percent + " | File percent : " + filePercent);
                break;
            case jsb.EventAssetsManager.ERROR_DOWNLOAD_MANIFEST:
            case jsb.EventAssetsManager.ERROR_PARSE_MANIFEST:
                cc.log("Fail to download manifest file, update skipped.");
                break;
            case jsb.EventAssetsManager.ALREADY_UP_TO_DATE:
            case jsb.EventAssetsManager.UPDATE_FINISHED:
                cc.log("Update finished.");
                // あなたがアセットマネージャをそれ以上必要としないと確信するなら、あなたはアセットマネージャをリリースする必要があります。
                manager.release();
                break;
            case jsb.EventAssetsManager.UPDATE_FAILED:
                cc.log("Update failed. " + event.getMessage());
                // 以前に失敗したアセットを直接的にアップデートしようとするなら、我々はあなたに回数をカウントし、数回のリトライの後にアボートすることをお勧めします。
                manager.downloadFailedAssets();
                break;
            case jsb.EventAssetsManager.ERROR_UPDATING:
                cc.log("Asset update error: " + event.getAssetId() + ", " + event.getMessage());
                break;
            case jsb.EventAssetsManager.ERROR_DECOMPRESS:
                cc.log(event.getMessage());
                break;
            default:
                break;
        }
    }
}

あなたはテストケースとして我々の js-tests プロジェクトにある Extensions/AssetsManagerTest を参照することもできます。他のパブリックな jsb.AssetsManager の API を以下に示します:

  • checkUpdate()
  • getState()
  • getStoragePath()
  • getLocalManifest()
  • getRemoteManifest()

既知の問題

アセットマネージャは、windows や iOS シミュレータ上ではファイルの生成やダウンロードに失敗するかもしれず、我々は速やかに回収しようとしていますが、しばらくは実際の iOS デバイス上でテストして下さい。

posted by cbbandtqb at 06:15| Comment(0) | TrackBack(0) | 備忘録 | このブログの読者になる | 更新情報をチェックする

2015年07月25日

Cocos2d-JS > 4.6 DIRECTOR OF GAME

原文はこちらです。

4.6.1 概念

もしあなたが映画好きなら、あなたのお気に入りのディレクタを何人か名前を挙げることができると思います。彼らは実際には彼らの映画に出演しませんが、彼らは映画に命を与えます。ディレクタは、映画作りにおいて最も重要な役割となります。

それではゲームにおけるディレクタとは何でしょう?もちろんデベロッパのことであり、あなたは本当のディレクタですが、ゲームエンジンにおいてあなたが行おうとするあらゆることを成し遂げるためのエグゼクティブディレクタも必要です。これは、Cocos2d-JS におけるディレクタの責任であることは間違いなく、偉大なゲームを作る上で最もよい友人となるのです。

さらに具体的には、Cocos2d-JS におけるディレクタは、ゲームに対する実行環境をセットアップし、メインとなるゲームのルールを制御し、シーン間の遷移を管理するオブジェクトです。この章では、ディレクタの主なタスクとディレクタがどのように動作するかを示します。

4.6.2 ディレクタのタスク

ディレクタオブジェクトは、Cocos2d-JS における cc.director によって表現されます。以下に主なタスクを示します:

  • 環境のセットアップ

    まず最初に、ゲームに入る前に、ディレクタはあなたのゲームのために作業環境をセットアップします:

    1. プロジェクション、ピクセルフォーマット等を含んだビューのコンテキストをセットアップします。
    2. フレームレートをセットアップします。
    3. ゲームに対するスケジューラ、アクションマネージャそしてイベントマネージャを初期化します。
    4. テクスチャキャッシュやレンダラを初期化します。
    5. デフォルト値となっているディレクタの他の変数をセットアップします。
  • メインループの実行

    ビデオゲームの基本的なセオリーは、古い学校のアニメーションに似ています。アニメーションを作るために、アーティストはページ毎に静的な画像を描き、それらは非常に短い時間、例えば 1/24 秒で他のページの後に表記され、それぞれのページはフレームと呼ばれます。

    ビデオゲームも同じ方法で、毎回 1/60 秒でレンダリングされ、プログラムはスクリーンに表示されるように画像(フレーム)を描画し、このようにして毎秒60フレームを生み出します。それぞれのフレームのレンダリングプロセスは、実行中のシーンの全てのグラフィックエレメントの正確な変形や他の情報を計算します。それらはその後、ひとつひとつスクリーンにレンダリングされます。ゲームが進むに連れて、それぞれのフレームは少しづつ変化し、結果として美しいビデオゲームをあなたは目にすることになるのです。

    上記の全てが、cc.director のメインループにて実行されます。メインループのそれぞれのイタレーションは、スクリーン上にフレームを描きます。以下にそれぞれのフレームの間の詳細なプロセスを示します。

    1. 最後のフレームから過ぎた時間を計算しますが、それはパフォーマンスに関するデバッグ情報を提供するために使われます。
    2. スケジューラに、スケジュールされたタスクを実行させます。
    3. `cc.eventManager` 経由で `cc.Director.EVENT_AFTER_UPDATE` イベントを上げます。
    4. ゲームスクリーンを消去します。
    5. 必要であれば実行中のシーンを次のシーンに切り替えます。
    6. 実行中のシーンのコンテンツノードをトラバースし、必要であればそれらの変形を更新し、それからレンダリングコマンドをそれぞれのノードのレンダラに送ります。
    7. `cc.eventManager` 経由で `cc.Director.EVENT_AFTER_VISIT` イベントを上げます。
    8. レンダラは全てのレンダリングコマンドをスクリーンを描画するために実行します。
    9. `cc.eventManager` 経由で `cc.Director.EVENT_AFTER_DRAW` イベントを上げます。
    10. グローバルトータルフレームを一つ増加させます。

    さらに、`cc.director` はまたいくつかの関数をメインループを制御するために提供します:

    1. メインループを一時停止します:`cc.director.pause()`
    2. メインループを一時停止から復帰させます:`cc.director.resume()`
  • シーンマネジメント

    cc.director のもう一つの重要なタスクは、シーンマネジメントです。ディレクタは同時に一つだけのシーンを実行できますが、あなたは必要な時にいつでも実行中のシーンを切り替えることができます。平均的なゲームでは、しばしば異なるユースケースに対していくつかのシーンを有しており、あなたのプログラムは cc.director の API を経由してシーンフローを制御すべきです:

    // cc.director にターゲットとなるシーンを実行させます。
    cc.director.runScene(scene);
    
    // 実行中のシーンを取得します。
    var scene = cc.director.getRunningScene();
    
    // シーンをシーンスタックにプッシュし、
    // 実行中のシーンをそれに置き換えます。
    var scene = cc.director.pushScene(scene);
    
    // シーンスタックの先頭シーンをポップし、
    // 実行中のシーンを次のトップシーンに置き換えます。
    cc.director.popScene();
    
    // シーンスタックにあるルートシーンを除いた全てのシーンをポップし、
    // 実行中のシーンをルートシーンに置き換えます。
    cc.director.popToRootScene()
    

    加えて、cc.TransitionScene を使うことで遷移エフェクトを伴ったシーン間の切り替えができます。

    // 遷移エフェクトは2秒要します。
    var transitionTime = 2;
    // 次のシーンを生成します。
    var nextScene = new cc.Scene();
    // 次のシーンを伴った遷移シーンを生成します。
    var transitionScene = new cc.TransitionProgressInOut(transitionTime, nextScene);
    // 遷移シーンを実行します。
    cc.director.runScene(transitionScene);
    

    上記の例から見てわかるように、我々は cc.TransitionProgressInOut 遷移エフェクトを使っていますが、それはベースクラスの cc.TransitionScene が実際のエフェクトを有していないからです。Cocos2d-JSには、他のビルトインの遷移エフェクトがあり、あなたは API リファレンスもしくは TransitionScene テストケースを参照できます。

4.6.3 設定及びプロパティ

ディレクタは実行環境を制御するために、設定及びプロパティもまたいくつか有効になっています:

// ディレクタが一時停止されているかを得ます。
var paused = cc.director.isPaused();

// アニメーションの間隔設定のためのセッタとゲッタ
var interval = cc.director.getAnimationInterval();
cc.director.setAnimationInterval(value);

// コンテンツのスケールファクタのためのセッタとゲッタ
var scale = cc.director.getContentScaleFactor();
cc.director.setContentScaleFactor(scaleFactor);

// 見た目の原点とサイズのためのゲッタ
var origin = cc.director.getVisibleOrigin();
var size = cc.director.getVisibleSize();

//  ウィンドウサイズのためのゲッタであり、ウィンドウサイズはデザインされた解像度サイズに等しいです。ピクセル単位でのウィンドウサイズは、ゲームウィンドウの本当のピクセルサイズです。
var winSize = cc.director.getWinSize();
var winSizeInPixel = cc.director.getWinSizeInPixels();

// デバッグ統計が表示されているか否かのどちらかのためのゲッタとセッタ
var isDisplaying = cc.director.isDisplayStats();
cc.director.setDisplayStats(displayStats);

// ビューに対するゲッタとセッタであり、cc.view を参照します。
cc.director.var view = cc.director.getOpenGLView();
cc.director.cc.director.setOpenGLView(openGLView);

// WebGL もしくは OpenGL プロジェクションのためのゲッタとセッタ
// 有効なプロジェクション:cc.Director.PROJECTION_2D, cc.Director.PROJECTION_3D, cc.Director.PROJECTION_CUSTOM
cc.director.getProjection();
cc.director.setProjection(projection);

4.6.4 スケジューラ

以前に言及したように、メインループはスケジューラにあるスケジュールされたタスクを実行していきます。スケジューラはディレクタの内部システムであり、あなたは実行中のシーンにおけるノードに対して、スケジュールされたタスクからなるいくつかのタイプを実行できます。スケジューラは、いつどのようにしてそれらのタスクを実行するのかを管理します。

タスクをスケジュールするための一般的な方法が幾つかあり、それらは以下のコードの断片にて例示されます:

var node = new cc.Node();

// ノードの更新関数は、フレーム毎に実行されます。
node.scheduleUpdate();
// 
コールバック関数は、´interval´ 時間経つごとに実行され、´repeat´ 回に繰り返され、タスクは ´delay´ 時間遅延されます。
node.schedule(callback, interval, repeat, delay);
// コールバック関数は、´delay´ 時間後に一度だけ実行されます。
node.scheduleOnce(callback, delay);
// コールバックタスクをキャンセルします。
node.unschedule(callback);
// ノードのスケジュールタスクの全てをキャンセルします。
node.unscheduleAllCallbacks();

注記

  • スケジュールされたコールバック関数の全ては、実行コンテキストとして、そのターゲットノードと共に実行されます。このことが意味するのは、コールバック関数中の this オブジェクトがターゲットノードを参照しているということです。
  • もし遅延時間が0に等しければ、最初のスケジュールされたコールバックは、次のフレームの期間で、スケジュール関数の実行の後に実行されるでしょう。

4.6.5 アクションマネージャ

アクションマネージャは、ディレクタのもう一つの重要な内部システムです。実行中のシーンの全てのアクションを管理し、フレーム毎に登録されたアクションの全ての update 関数を起動します。アクションシステムの詳細は、以下のドキュメントに記載されています。

4.6.6 ディレクタのイベント

幾つかのビルトインイベントがあり、ディレクタにおいてあなたのゲームに関心があるかもしれません。

  • cc.Director.EVENT_AFTER_DRAW:このイベントはフレーム毎のレンダリングプロセスの後にトリガされます。
  • cc.Director.EVENT_AFTER_VISIT:このイベントはフレーム毎のシーングラフ巡回後にトリガされます。
  • cc.Director.EVENT_AFTER_UPDATE:このイベントはフレーム毎のスケジュールタスクの後にトリガされます。
  • cc.Director.EVENT_PROJECTION_CHANGED:このイベントはディレクタのプロジェクションの変更後にトリガされます。
posted by cbbandtqb at 07:04| Comment(0) | TrackBack(0) | 備忘録 | このブログの読者になる | 更新情報をチェックする

2015年07月15日

Cocos2d-JS > 4.5 SCENE GRAPH IN COCOS2D-JS

原文はこちらです。

4.5.1 シーン

あなたのゲームにおいて、あなたはメインメニュー、いくつかのレベル、そしてエンディングシーンがおそらく欲しくなるでしょう。これらのバラバラのピースから、これらの全てをまとめるにはどうすれば良いのでしょうか?あなたは、シーンを使うことに思い至るでしょう。あなたのお気に入りの映画について考えると、それは明確にシーンに分解されているか、ストーリーラインのパーツに分かれていることが分かるでしょう。もし我々がこれと同じ考え方の過程をゲームに適用するなら、我々は、ゲームが問題なくシンプルになるように少なくとも2つから3つのシーンでまとめられるようにすべきでしょう。

通常のゲームシーンを見てみましょう:

このメインメニューは、単一のシーンです。そう、このシーンは、終了結果を示すために全てを一緒に併せたいくつかのピースから構成されています。シーンは、レンダラによって描画されています。レンダラは、画面内のスプライトや他のオブジェクトをレンダリングする役目を持っています。このことをより理解するに、我々はシーングラフについて少し説明する必要があります。

4.5.2 シーングラフ

シーングラフはデータ構造であり、グラフィカルなシーンをアレンジします。シーングラフは、木構造の中に Node オブジェクトを含みます(そう、それがシーングラフと呼ばれていますが、実際には木として表現されます)。

難しそうに聞こえます。あなたは自問するかもしれません、'なぜ私がこのような技術的詳細についてケアしなければならないのか、もしかして Cocos2d-JS は私には荷が重いのでは?'。シーンがレンダラによってどのように描画されるのかを理解することは本当に重要なことです。あなたがノード、スプライト、そしてアニメーションをゲームに追加し始めたら、あなたはあなたが求めるビジュアルな結果が得られるか確認したくなるでしょう。もし正しい結果が得られなかったらどうしますか?あなたのスプライトが背景に隠れていて、それらを前面に持ってきたいとしたらどうしますか?一歩戻って紙片上のシーングラフをウォークスルーしてみたら、私はあなたが容易に間違いを特定できると断言します。

シーングラフは木構造なので、あなたは"木を渡り歩く"ことができます。Cocos2d-JS は中間順(訳注:in-order)の探索アルゴリズムを使っています。中間順での探索では、木の左側がまず探索されていきます。それからルートノードが探索されて、最後に木の右側が探索されます。木の右側が最後にレンダリングされるので、シーングラフ上で最初に表示されます。

シーングラフは容易に図示されるので、4.5.1 にあったシーンをブレークダウンしたものを見てみましょう:

考えるべきもう一つの点は、木の左側にある負の zIndex を伴ったエレメント群と、一方で木の右側にある正の zIndex を伴ったエレメント群です。あなたのエレメントを並べるときにはこのことをよく考えましょう!

このコンセプト上で構築するので、我々はシーンをノードオブジェクトのコレクションとして考えることができます。上記のシーンを、シーングラフが zIndex をシーンをレイアウトするためにどのように使うかを以下で分解して見てみましょう:

左側のシーンは実際にはマルチプルノードオブジェクト群によって作られており、それらは互いの上にそれらを"スタック"させるために異なる zIndex を与えられています。

4.5.3 シーングラフの構築

Cocos2d-JS では、cc.NodeaddChild API を使ってシーングラフを構築し、cc.Scene を含む全てのノードクラスは cc.Node から拡張します。

// 新しいシーンを作成する
var scene = new cc.Scene();

// -2の zIndex を伴ったノードを追加する
// それは木の"左側"になる(なぜなら負であるため)
scene.addChild(title_node, -2);

// もう一つのノードを追加する。 zIndex を指定しないと、0を使うことになる
scene.addChild(label_node);

// 1の zIndex を伴ったノードを追加する
// それは木の"右側"になる(なぜなら正であるため)
scene.addChild(sprite_node, 1);

4.5.4 シーングラフのレンダリング

TBD

posted by cbbandtqb at 00:24| Comment(0) | TrackBack(0) | 備忘録 | このブログの読者になる | 更新情報をチェックする
×

この広告は1年以上新しい記事の投稿がないブログに表示されております。