CocosCreator2.0で廃止(Deprecated)されたもの。cc.random0To1は廃止

CocosCreator 1.xではccモジュールにrandom0To1関数などがあり、標準のMath.randomをラップした関数が複数ありましたが、CocosCreator2.0では廃止されました。

廃止されるものの確認方法ですが、ブラウザーの開発者ツール(デバッグツール)を起動して、アプリを実行すると削除した関数のエラーと、廃止予定の関数を使っていたら警告が表示されます。

CocosCreatorのコンソールには、警告表示等が表示されないので、ブラウザーからでないとこれに気づけません。

Edgeの開発者ツールで、廃止関数を確認したところ

https://github.com/cocos-creator/engine/blob/next/cocos2d/deprecated.js

TypeScriptのcreator.d.tsファイルには、すでにcc.random0To1がないため、コード入力時にエラー検知できます。

CocosCreatorの公式チュートリアルを試してわかったこと

CocosCreatorの公式チュートリアル「Quick Start:Make your first game」を1日やってみた感想です。大まかには以下のような感じでした。

  • Unityの仕組み(GameObject,Componentなど)でCocosCreatorは使える。
  • Unityユーザーはすぐにできるが、Cocos2d-xユーザーにとっては使いづらい。
  • Cocos2d-xとは別物
  • コード編集してフォーカスをCocosCreatorに戻すと、ブラウザーリロードで開発が楽(JavaScriptのlivereload)
  • ドキュメントを期待する前にまずはサンプルプロジェクトを起動

作ったゲームの簡単な説明

このゲームは、紫スライムがプレイヤーで、ADキーで左右に移動してスターを取るゲームです。スターは一定時間で消えるので、消えたらゲームオーバーです。

スターが消えるまでに取るエンドレスゲーム。消えたらゲームオーバー

Unityの仕組み(GameObject,Componentなど)でCocosCreatorは使える。

CocosCreatorはUnityの考え方を土台にして作られているのでいくつか共通な概念を確認します。

HierarchyWindowに対応するNodeTree

UnityではGameObjectに画像、音声、スクリプトなどをコンポーネントとして追加する構造です。CocosCreatorでは、Nodeという言葉を使いますが構造は同じでした。

操作もUnityと同じで、アセットからシーンウィンドウに画像をドロップしてSpriteNodeを作れます。

UnityのHierarchyWindowに対応するNodeTreeがあり、そこで右クリックすると、EmptyNodeやSpriteNodeが作れます。これはUnityでいうEmptyGameObjectやSpriteRendererコンポーネントと同じです。

InspectorWindowに対応するPropertiesウィンドウ

以下は、紫スライムのPlayerNodeのプロパティーです。これはUnityのGameObjectのInspectorWindowと同じで、「Add Component」ボタンでコライダーや、Physicsをコンポーネントとして追加できるのも全く同じです。

Unityのスクリプト変数がインスペクターに反映されるのとCocosCreatorは同じ

Unityでは変数がインスペクターに反映されます。この仕組みがあるのでC#スクリプトにパブリックフィールドを用意してUnityエディターで値を調整できます。CocosCreatorも同じで、スクリプトを作成するとひな型にpropertiesオブジェクトがあるので、ここにプロパティを書いていきます。

UnityユーザーからするとC#と記述は違いますが、やりたいことは一致しているので問題なく書いていけますが、Cocos2d-xユーザーは、この概念を新しく学ぶ必要があって面倒かもしれません。

Playerスクリプトに4つプロパティを書いたところ

Playerノードに上記Playerスクリプトを「Add Component」ボタンで追加すると以下のようにPlayerスクリプトがコンポーネントとして追加され、プロパティが表示されます。Unityと全く同じです。

Unity同様PlayerスクリプトのプロパティがGUIで編集できるようになっている

Prefabもある

Unityでは現在のシーンでオブジェクトに画像や音声、スクリプトをコンポーネントとして追加し、ProjectウィンドウにドラッグするとPrefab化できます。CocosCreatorでは、NodeTreeウィンドウからAssetsウィンドウにドラッグするとPrefab化できます。

いままで見てきたように、CocosCreatorはUnityを参考に作られているのが分かります。

Unityユーザーはすぐにできるが、Cocos2d-xユーザーにとっては使いづらい?

いくつか機能を比較してきましたがCocosCreatorは、Unityの概念を参考に作られています。そのためCocos2d-xのようなソースコード主体の開発ではなく、オーサリングツールやGUIデザイナーがある開発ツールと同様な開発手法が求められます。音声、画像など各種リソースの設定や配置は、ソースコードで書かれずにツールで設定するようになります。

今までのCocos2d-xと同じだろうと思ってやってみると名前だけが同じなので、全然別物のためUnityユーザーが始めるよりもCocos2d-xユーザーの方が大変かもしれません。

コード編集してフォーカスをCocosCreatorに戻すと、ブラウザーリロードでするので開発が楽(JavaScriptのlivereload)

HTML+JavaScript+CSSでWebアプリを開発している感覚で、オートリロードでゲームを再確認できます。かなり軽いためこれは非常に良かったです。

またブラウザーゲームの場合そのままブラウザーの機能を使えるので、例えば音声認識APIなどと連動する場合は、相性が良いと思います。

ドキュメントを期待する前にまずはサンプルプロジェクトを起動

Unityのような感覚でドキュメントや参考となるプロジェクトを見つけることはできません。また日本語のドキュメントを探すのも難しいです。ですが、DashboardにExample Collectionがあり、これはいろんな機能をシーンで分けて一覧化したプロジェクトです。なのでまずは起動してみるとよいです。簡単なゲームを作る際に必要な情報は手に入ります。

少々強引なJavaScript

JavaScriptはC#やJavaと異なり、動的型付けなので、以下のような記述はできません。

ソースコード上のプロパティとGUIのインスペクターを連動するために、以下のようにJavaScriptのオブジェクトにtypeプロパティでcc.Prefabのように型を設定して対応しています。

またTypeScriptでプログラミングする場合は、注釈があるため2行ですっきり書けます。class構造もすっきりして入力補完も完全対応なので慣れるとこちらのほうが開発しやすそうです。

まとめ

CocosCreatorとUnityの似ているところをUIやソースコードで確認してみました。

CocosCreatorは動作が軽く、Phaserなどコードベースのライブラリーと比較するとシーン管理、画像やテキストの配置や音声ファイルの設定などがドラッグアンドドロップでできるため、ソースコードが少なくなります。

またJavaScriptのためブラウザー機能と連携する場合は、ブラウザーの機能(音声認識APIなど)を単純に呼び出すだけでよいのでこれも相性が良いです。

ブラウザーゲームとして公開する場合は、瞬時にCanvas起動するのでこれはUnityより良いです。

此処までいくつかメリットを書きましたが、まとめるとWebブラウザーベースのちょっとしたゲームを素早く作りたい。UnityのWebGLのロードが待てない。リソース管理をコードベースで書きたくない。などの理由がある場合はよいツールと感じました。

Unityは、とにかく入門情報が、英語でも日本語でも動画でもgithubのソースコードでも豊富です。初心者向けの入門書もたくさんあり問題が発生しても誰かが解決策をブログで書いていたりします。良いツールですが、広く使ってもらうのは難しいのかもしれません。

Windows10でCocos2d-xのsetup

Cocos2d-xはPython2.7系のセットアップツールがあるので、setup.pyを実行すると環境変数を設定してくれます。

 

 

プロジェクト作成、カレントディレクトリーにMyGameディレクトリーが作成される。

 

MyGame\proj.win32\MyGame.sln が用意されるのでこれで開発できます。Cocos2d-xはソースコードとして含まれるので、初回ビルド時は、Cocos2d-Xをビルドするので数分かかります。VisualStudio2017問題なくビルドできました。

カレントディレクトリーの複数ターゲットに対応したNASMのMakefile

.asmファイルが増えるたびにMakefileに、helloworld: helloworld.oなどのように書いていたので書きかたを調べてみました。

  • wildcard *.asmをすべての.asmファイルを取得
  • 変数展開で*.asmファイルを*.oファイルに変換しOBJECTS変数に保持
  • ターゲットファイル名を同様に変数展開でTARGETSに保持

あとは、11行目と13行目を用意することで、複数のターゲットに対応してasmファイルをビルドできるようになりました。

NASMで簡単なコードを書く場合、C言語の逆アセンブリーでサンプルを用意する

NASMを始めたばかりだと、すこしのコードを書くのにも時間が掛かります。sum関数やfactorial関数など、ちょっとした関数やいくつか複合した条件分岐などを作る場合は、まずC言語で実装してそれを逆アセンブルして、コードを入手するのもよい案かもしれません。

gccで逆アセンブル

-fverbose-asmを追加すると、引数や戻り値のヒントがコメントとして表示されます。もっとコードと比較しながら確認したい場合は、gdbを使ったほうがよいです。

objdumpで逆アセンブル

factorial.sの抜粋

以下がgccで逆アセンブルした結果です。コメントで<retval>と引数nが確認できます。またn * factorial(n-1)の部分をimul命令(imul eax, ebx)で行っています。ここまでくればあとは、このコードを解析していけば、自分でNASMのfactorialを作る子tができます。

 

 

 

 

 

スタックフレームの確認

簡単なC言語を逆アセンブルするとx64の場合、push rbpから始まります。これはスタックフレームを理解すれば、この意味が分かります。

「スタックセグメントを確認してみる」が初心者にわかりやすいx64版のgdbを使ったスタックフレームの確認方法です。

NASMを見ると関数呼び出しで、必ずpush rbp, mov rbp, rspと書かれているがこれはスタックフレームを新しく用意して、引数やローカル変数をこの後に保持します。また最後にleave命令で、mov esp, ebp; pop ebpとして、呼び出し元関数のスタックフレームを復元します。

 

 

leave命令の意味

スタックフレームを戻す2つのmov,popを1回で行う命令

lea命令

アドレス計算して転送する命令(Load Effective Address)

nasm x64でprintfを呼び出す

PIC対応でNASM x64でprintfを呼び出す

-no-pieオプションでPIC対応にしない場合

call printfでよい。

gccのオプション-no-pieを付ける

 

 

 

 

nasm x64のWRT ..plt

nasmのチュートリアル(http://cs.lmu.edu/~ray/notes/nasmtutorial/ )で、C言語のputs関数を呼び出す簡単なプログラムを作りましたが、gccでオブジェクトファイルから実行ファイルを作るときに以下エラーが発生しました。

https://www.nasm.us/xdoc/2.10rc8/html/nasmdoc9.html#section-9.2.5

NASMから外部関数を呼び出す場合は、PLT(procedure linkage table)を使わなければいけないようです。以下のようにWRT ..pltを付けて解決しました。

これでオブジェクトファイルを作成しgccでリンケージして実行できました。