2014年10月16日

JavaScriptでスマホゲームアプリを作る - Cocos2d-JS編

前回のPlatino版に続いて、Cocos2d-JS版が出来た。



ソースコードはこちら。https://github.com/mikehibm/15puzzle-cocos2d


● 困ったところ


う〜ん、特になし。

あえて言えばy座標の指定方法(上下)がこれまでと逆になるのでそれを変更する必要があったぐらい。

あとそういえば、ifで座標が一致するかどうかを比較して分岐している箇所があって、

 if (piece.x !== new_pos.x || piece.y !== new_pos.y){
   ...処理...
 }

と書くと処理が実行されなくて困った。(浮動小数点数なので)
下の様に差分の絶対値で比較する様に変更した。

 if (Math.abs(piece.x - new_pos.x) > 1 || Math.abs(piece.y - new_pos.y) > 1){
   ...処理...
 }



● 良かったところ


アニメーションの作り方やシーン遷移の方法など、これまでに得たCocos2dの知識が活かせるので楽が出来た。

実機での実行速度も申し分無し。

デバッグが簡単。Cocos Code IDEからデバッグ実行しておくとJSファイルを修正して保存した瞬間にデバッグアプリ内でコードが再ロードされるのですぐに確認出来る。もちろんブレークポイントを設定する事も可能!


● アニメーション実行中にさらにアニメーションを実行する場合


MoveToを使ってピースを移動するアニメーションを実行中に、場合によってはさらに次のアニメーションを開始する必要がある場合がある。連続でタッチして同時に複数のピースを動かした場合などだ。

その場合、同じSpriteに対して同時に複数のMoveToアニメーションを実行してしまうと最終的な位置が思わぬ所にずれてしまう事になる。

これについては、2つめのMoveToアニメーションを実行する前に

 piece.stopActionByTag(ACTION_TAG);

を実行して前のMoveToを中止する事で解決出来た。


● Mac版デバッグアプリの設定変更


Cocos Code IDEから実行するとデフォルトだとMac版のデバッグ用アプリが立ち上がって来てその中でアプリが実行される。

このデバッグ用アプリの画面サイズ(Zoom設定)が、起動する度に100%になってしまいMBAだとiPhone5の縦画面がディスプレイに収まらないので、そこがちょっと使い辛かった。

これは下のページの通りに設定を変更する事で50%表示にする事が出来た。これでとても快適になった。
Lua - Cocos Code IDEのシミュレーターのデフォルト設定 - Qiita 



● ソースコード


今回のソースコードはこちら。
https://github.com/mikehibm/15puzzle-cocos2d




● 感想


さすがに注目度急上昇中のフレームワークだけあって Cocos2d-JS は使い易い。デバッグも素早く出来るので気分良く開発が出来る。

またXcodeやEclipseからもプロジェクトを開いて実行出来るので、広告表示やアプリ内課金などのネイティブ連携も頑張ればなんとかなりそうだ。

パーティクルエディタやシーンエディタなどのツール群も充実しているので、やっぱり一番安心して実戦で使えるのはこれかなあと思う。

あと次はUnityにチャレンジしてCocos2d-JSを上回るメリットがあるかどうかを試したい。








 .

2014年10月13日

JavaScriptでスマホゲームアプリを作る - Titanium + Platino編

ようやく15パズルのTitanium+Platino版が出来た。

Platino Game Engine


ソースコードはこちら。 https://github.com/mikehibm/15puzzle-platino


● Platinoプラグインの導入


プラグインの導入は至って簡単。トライアル版をダウンロードして解凍して所定のフォルダにコピーすればTitanium側で認識してくれた。

あとはプログラムの先頭に

var platino = require('co.lanica.platino');

をいれてガンガン使って行くだけだ。
BGMや効果音を鳴らす時は

var ALmixer = platino.require('co.lanica.almixer');

も必要。
さらにapp.jsなどで最初に一回だけ

ALmixer.Init(0,0,0);

を呼んで初期化しておく必要がある。最初この初期化をしてなかったせいで音が出なくて30分ほど悩んだ。


● まずはサンプルのソースを確認


Herlockと同じくPlatinoもドキュメントを見てもいまいち分からないので、最初はまずサンプルプログラムを全てダウンロードしてソースを熟読するのが良いと思う。


Flappy Birdや戦車ゲームのサンプルが面白いけれど、多分一番参考になったのは「Codestrong Shooter」というシューティングゲームのサンプルだ。


● マルチ解像度対応


サンプルプログラムのマルチ解像度対応がちょっと気に入らなかったので、自分なりに試行錯誤する必要があった。背景の画像などは全てiPhone5sの640x1136のサイズを基準にして作っておいて、端末の解像度に合わせて横幅を画面一杯にして縦が短い場合は上下が切れる様に調整した。ApplicationWindow.js の updateScreenSize 関数でその辺りをやっている。

スプライトなどを画面に配置する時は、横幅は常に640として固定値で指定して構わないのだけれど、縦の高さは端末によって変わるので、真ん中に寄せたいもの(パズルのピースなど)については中央からの相対指定として、上端または下端に合わせたいものはそれぞれ上端(y=0)または下端(y=画面サイズ)からの相対指定とする様にした。


● タッチイベント


画面に配置したSpriteのタッチイベントを取得するのが少々面倒だった。まず画面(Sceneオブジェクト)のタッチイベントを書いて、その中でスケールを考慮して座標を変換した上で Sceneの forwardTouchToSprites 関数を呼んでやる必要がある。


● 連続でアニメーションを実行


アニメーションは下の様な感じでTransformオブジェクトを生成して実行する形になる。
var transform  = platino.createTransform({
  duration: 500,
  alpha: 0,
  easing: platino.ANIMATION_CURVE_CUBIC_IN,
  autoreverse: true,
  repeat: -1
 });
sprite.transform(transform);
ただ、連続で複数のアニメーションを実行するための簡単な方法が標準では用意されていない。「Codestrong Shooter」のサンプルにもある通り、アニメーション終了時のcompleteイベントを拾って次のアニメーションを開始すれば良いのだけれど、非常に面倒だ。

そこで調べたところ下のモジュールを見つけた。


これを使えば例えば6個のアニメーションを連続で実行する場合でも下の通り簡潔に書くことが出来るのでとても便利だった。
highScoreTranstion = new Transition([
  { duration: 1000, x: CENTER_X-highScoreLabel.width/2, easing:   platino.ANIMATION_CURVE_QUAD_OUT }
  ,{ duration: 500, alpha: 0, easing: platino.ANIMATION_CURVE_CUBIC_OUT }
  ,{ duration: 1000, alpha: 1, easing: platino.ANIMATION_CURVE_CUBIC_OUT }
  ,{ delay: 500 }
  ,{ duration: 1000, x: game.screen.width*-2, easing: platino.ANIMATION_CURVE_QUAD_IN }
  ,{ duration: 1, x: game.screen.width*2 }
]);
highScoreTranstion.animate(highScoreLabel, -1);


● Androidでのフルスクリーン表示


Androidで実行すると画面の上部にタイトルバーが表示されてしまって困った。
とりあえず tiapp.xmlファイルに

<fullscreen>true</fullscreen>
<statusbar-hidden>true</statusbar-hidden>
<navbar-hidden>true</navbar-hidden>

と書いてみたけれども Android 4.4 では効果なし。調べると新しいAndroidではプログラム内で

   window.activity.actionBar.hide();

を呼ぶ必要があるという事だったのでその通りにしたら無事フルスクリーンで表示された。


● iOSとAndroidで微妙に挙動が違う所


TextSpriteを配置した時にiOSとAndroidで位置がずれてしまって困った。
どうもAndroidだとwidth,heightが自動では計算されていない(0,0になっている)みたいだ。これは platino.createTextSprite 関数を呼ぶ際に明示的に widthとheightをセットする事で解決した。

他に、Androidだと微妙に処理が遅いのか少しカクカクした感じがしてしまう。上にアップした動画でも雲の動きがちょっとカクカクしているのが分かるけれど、iOSだともっとスムーズに動いた。Titanium + Androidでは前にも、「今ひとつどうもな〜」という経験をした事があるので、今回もやっぱりそうかという感じはある。


● ソースコード


今回のソースコードはこちら。
https://github.com/mikehibm/15puzzle-platino


● 一応の結論


Titaniumでのアプリ開発をずっとやっている人で、「ゲーム開発にもTitaniumを使いたい!」と言う場合には良い選択肢かも知れない。

あとドキュメントの中の下のページはすごく参考になった。

http://docs.lanica.co/docs/#!/guide/javascript_best_practices
配列をクリアする時は
myArray = []; 
ではなく
myArray.length = 0;
と書いた方が良い、とか。