• 2
    いいね
  • 0
    コメント

こんにちはeeic2017erの @totem です
この記事はeeic advent calenderの24日目の記事です


最近はUnityが話題ですね!
学科の先輩であるムヒョペさんがはじめてのUnity:3Dゲーム(RPG/アクション)の土台を作るまで
という神記事を書いてくださっていたり、学科で勉強会があったりと、学科民にも段々ユーザーが増えてきているかもしれません。
実際とても使い易いですしアセットストアも充実してますし情報も多くて最高ですよね。

また、最近はUnreal Engine4という、無料のゲームエンジンが流行りはじめていたりします。
こちらも素敵なエンジンがあってC++で書けてよさみが深いです。

今は次第に下火になってきていますが、少し前までUnityと並んでいた、マルチプラットフォームなゲーム開発フレームワークとしてcocos2d-xというものがあります。
これは主に2Dゲームに用いるフレームワークで、DisneyツムツムやFinal Fantasy Record Keeper等、有名ゲームにも用いられています。

そんなcocos2d-xもUnity5やUE4に対抗し、今年の3月に統合開発環境であるcocos creatorを公開しています。
今回はそのcocos creatorを紹介します。
cocos creatorのハックを紹介しようと思ってたのですが、間に合いませんでした...

cocos creator

cocos creatorはcocos2d-xを内包している、Electronで作られている統合開発環境です
http://cocos2d-x.org/creator
このページからcocos creatorをダウンロードすることができます。
残念ながらLinux版はありません....

オープンソースなのでエンジンのソースも公開されています。
https://github.com/cocos-creator/engine

まだ結構使いづらいところが多いのですが、頑張れば使えます(ならUnityを使えば?)
他のゲームエンジン同様、メモリを結構食うので気をつけてください。

Hello World!

Hello Worldをしてみましょう。
ダウンロードしたcocos creatorを動かすと以下のような画面で雛形を選択することができます。
今回はHello Worldを選択してみます。
スクリーンショット 2016-12-24 23.35.55.png

プロジェクトのパスを入力してCreateボタンを押すと以下のようなエディタ画面が出ます。
スクリーンショット 2016-12-24 23.43.34.png

Unityを使ったことがあれば、結構すんなり使えると思います。
説明をしておくと、

  • 左上・・・ Node Treeウィンドウです。編集中のシーンに配置されているオブジェクトが表示されます。
  • 左下・・・ Assetsウィンドウです。プロジェクトのファイルが表示されます。
  • 中央左・・・ Sceneウィンドウです。Unity同様、直感的にオブジェクトを配置して編集することができます。
  • 中央右・・・ Node Libraryウィンドウです。配置できるオブジェクトの一覧が表示されます。ここからドラッグ&ドロップでSceneウィンドウにオブジェクトを配置できます。
  • 右・・・ Propertyウィンドウです。UnityにおけるInspectorウィンドウで、オブジェクトの詳細が表示されます。
  • 下・・・ Console,TimeLineウィンドウです。Consoleウィンドウではデバッグ情報が出力できます。TimeLineウィンドウではアニメーションの編集などを行うことができます。

もちろん

Assetsウィンドウからスクリプトファイルをクリックすると、(のっぺりした)エディタが開きます。
ここでファイルを編集することができます。
スクリーンショット 2016-12-25 0.01.03.png

Unityを使ったことがあればわかりやすいと思いますが、
onLoadではUnityでのStart関数同様(?)、ロード時に行う処理を記述します。
updateではUnityでのUpdate関数同様(?)、毎フレームごとに呼ばれる処理を記述します。

このスクリプトでは実行時にHelloWorldと表示します。

タッチイベントを受け付ける

マルチプラットフォーム環境を想定して、タッチイベントを受け付けるスクリプトを書いてみます。
PC環境ではマウスのドラッグやクリックをタッチとして受け付けます。

HelloWorld.js
cc.Class({
    extends: cc.Component,

    properties: {
        canvas: cc.Node,
        follower: {
            default: null,
            type: cc.Node
        },
        followSpeed: 200
    },

    // use this for initialization
    onLoad: function () {
        var self = this;
        self.moveToPos = cc.p(0, 0);
        self.isMoving = false;
        self.canvas.on(cc.Node.EventType.TOUCH_START, function (event) {
            var touches = event.getTouches();
            var touchLoc = touches[0].getLocation();
            self.isMoving = true;
            self.moveToPos = self.follower.parent.convertToNodeSpaceAR(touchLoc);
        }, self.node);
        self.canvas.on(cc.Node.EventType.TOUCH_MOVE, function (event) {
            var touches = event.getTouches();
            var touchLoc = touches[0].getLocation();
            self.moveToPos = self.follower.parent.convertToNodeSpaceAR(touchLoc);
        }, self.node);
        self.canvas.on(cc.Node.EventType.TOUCH_END, function (event) {
            self.isMoving = false; // when touch ended, stop moving
        }, self.node);
    },

    // called every frame
    update: function (dt) {
        if (!this.isMoving) return;
        var oldPos = this.follower.position;
        // get move direction
        var direction = cc.pNormalize(cc.pSub(this.moveToPos, oldPos));
        // multiply direction with distance to get new position
        var newPos = cc.pAdd(oldPos, cc.pMult(direction, this.followSpeed * dt));
        // set new position
        this.follower.setPosition(newPos);
    }
});

このような記述でタッチイベントを取得することができます。(サンプルコードのコピペです)
タッチしている地点に向かってスプライト画像が移動します。
なお、シーン画面からpropertiesに対してオブジェクトを指定してやる必要があります。
スクリーンショット 2016-12-25 1.02.45.png

@devnull pic.twitter.com/uSsLT1EBOq

— totem@進捗ダメです (@bbottait) 2016年12月24日

他にもゲームに求められる記述は簡単に行うことができます。
http://cocos2d-x.org/docs/editors_and_tools/creator/
http://cocos2d-x.org/docs/api-ref/creator/v1.3/
といったページを参照することで簡単にゲームを作っていくことができます。

cocosアプリの解析

※以下はゲーム制作には一切必要のない話です。また初心者向けでもないです💦
Unityで作られたアプリケーションはil2cppを使用してビルドしている場合は、アセンブラを読むという方法で、使用していない場合はAssenbly-CSharp.dllをデコンパイルしてC#のソースコードに戻すことで見ていくという形で解析していくことになります。(Unityについては深く突っ込まないので興味があればtwitterとかで聞いてください、LINEの愛甲さんの記事が詳しいです)

cocosではどういった形で解析が行えるのでしょうか?
スクリーンショット 2016-12-25 1.16.59.png

cocos creatorで作ったアプリはこのようなファイル構成をしています
今回はmacOS向けのビルドですが、基本的にどのターゲットへのビルドでも似たようなファイル構成になります
基本的にユーザーが記述したコードはResources/srcの中に配置されます。
srcフォルダ中にあるproject.jscというファイルがユーザーの記述したコードの本体です。
cocos creatorに限らずcocos-2dxのjsbindingはいずれもこのような形になります。
スクリーンショット 2016-12-25 1.33.20.png
このファイルをfileコマンドでどんなファイルか判定してみるとdataと判定されます。
このままのファイル形式では人は読めません。

cocos-2dxのソースコードを読んでファイルをデコードすることを考えます。
cocos-2dxの中でjavascriptファイルのコンパイルを行っている部分を探します。
スクリーンショット 2016-12-25 1.38.22.png

見てみるとGoogle Closure Comlierを利用してjsファイルの圧縮を行い、その後jsbccというコンパイラでjavascriptをコンパイルしていることがわかります。

jsbccの中のコードを読むと内部でSpiderMonkeyを利用して、jsファイルをバイトコードに変換していることがわかります。
https://developer.mozilla.org/ja/docs/Mozilla/Projects/SpiderMonkey/Internals/BytecodeにSpiderMonkeyで使用されるバイトコードについての記述があります。
SpiderMonkeyのAPIにはJS_DecompileScriptというAPIがあります。
これはSpiderMonkeyでコンパイルしたコードをデコンパイルできるというものです。
こんな議論もあるのでわかりませんが、少なくともバイトコードについて記述がある以上、ある程度の解析は可能である可能性が高いです。
このAPIを用いて、ある程度解析を行おうと思っていましたが時間が足りませんでした、すみません。。。
またSpiderMonkeyでコンパイルを行う前のGoogle Clojure Compilerによる圧縮では、特に変数名の除去といった処理を行っていません。
解析の可能性を考えると難読化処理を自前で行ったほうがいいかもしれません。

まとめ

cocos creatorはお手軽に2Dゲームを制作することが出来ます。
たまにはUnityから離れて使ってみると視野が広がるかもしれません。

解析の話が単体で記事になるほど間に合わず、入門者向けのHelloWorldと、入門者には向かない解析の話が混在する意味のわからない記事になってしまいすみません。
誤り等ありましたら指摘していただけると幸いです。