RC0で一度動いたーと思って、その後RC1環境にしてみて、それがだめだったので、やっぱりとRC0環境に戻してといろいろやってたらRC0自体もandroidエミュレータで実行できなくなってしまったので、どうしたものかと思ってたのですが、なんとかなったので、メモ。
起きていたエラーは以下のものでした。
dvmFindClassByName rejecting ‘org/cocos2dx/lib/Cocos2dxHelper’
です。
何が起きてるのかと思ったのですが、ライブラリ側がうまく連結されて無くてそちらを参照できないために動作してなかったみたいです。
で、このフォーラムのやりとりを見て対応。ライブラリ側のjavaファイルをコピーしてアプリのプロジェクトに追加するという力技でした。
というわけで、
HAXMのエミュレータでも、実機でも動くようになりました。
本来ならlibcocos2dxのプロジェクトをインポートしているので、そっちが参照されてうまいこといくはずなんだろうなーと思いつつ、それがうまくいかない場合は直接コピーして対処するしかないのかなーという印象です。
2014/04/06
2012/07/01
さいたま開発勉強会4回目で発表しました。シェーダーについてGLSL, cocos2d, UnityのShaderLabまで
6月30日に久しぶりにさいたま開発勉強会が行われましたので、蕨の商工会議所まで行って来ました。遅刻遅刻〜ってタクシーで急いで会場まで乗り付けたんですけど、どうやら会場があいて無くて入れない様子。会場代払ってるのに管理者が来なかったみたいです。なんということ!
急遽隣の区民会館に部屋を借りて勉強会を行うことになりました。プロジェクターが無くてスライド共有に苦労しましたけど結果的にはうまくいってよかったです。
さて、当日の発表内容は以下のとおり。
・@ajinotataki:シェーダーしよっ☆ GLSL, cocos2d, UnityのShaderLab
スライド:http://www.slideshare.net/xionchannel/lets-play-shaders
サンプルコード:http://xionchannel.no-ip.org/cocos2d_shaderTest.zip
・@tmokitaさん:iPhone開発 超超初心者Tips50 (寝たければ寝てね!)
スライド:http://www.slideshare.net/tmokita/saitama-beginner-tips50
・@f_megmeg5さん:Androidクラスタの私がcocos2d-xでマルチディスプレイ対応してみた
スライド:http://www.slideshare.net/megmegfive/vol4-13446073
・@shun_nakaharaさん:iOSのGCDについて
スライド:http://www.slideshare.net/shunnakahara/gcd-13499796
・@nun_さん:10時間で!無料で!アプリプロモーション
スライド:http://www.slideshare.net/AsamiNagasaki/10-13490251
・@yoichinejiさん:cocos2d-x + ○○でどうにかしてこれしたい
スライド:なし、tweetで発表でした。
急遽隣の区民会館に部屋を借りて勉強会を行うことになりました。プロジェクターが無くてスライド共有に苦労しましたけど結果的にはうまくいってよかったです。
さて、当日の発表内容は以下のとおり。
・@ajinotataki:シェーダーしよっ☆ GLSL, cocos2d, UnityのShaderLab
スライド:http://www.slideshare.net/xionchannel/lets-play-shaders
サンプルコード:http://xionchannel.no-ip.org/cocos2d_shaderTest.zip
・@tmokitaさん:iPhone開発 超超初心者Tips50 (寝たければ寝てね!)
スライド:http://www.slideshare.net/tmokita/saitama-beginner-tips50
・@f_megmeg5さん:Androidクラスタの私がcocos2d-xでマルチディスプレイ対応してみた
スライド:http://www.slideshare.net/megmegfive/vol4-13446073
・@shun_nakaharaさん:iOSのGCDについて
スライド:http://www.slideshare.net/shunnakahara/gcd-13499796
・@nun_さん:10時間で!無料で!アプリプロモーション
スライド:http://www.slideshare.net/AsamiNagasaki/10-13490251
・@yoichinejiさん:cocos2d-x + ○○でどうにかしてこれしたい
スライド:なし、tweetで発表でした。
私は、先週のcocos2d勉強会に続き、シェーダーを掘り下げた内容の発表を行いました。
おおまかな流れとしては、
・シェーダーとは何か、概念的な説明
・シェーダーを使って何ができるかの実例
・OpenGLESでのシェーダーを使うための流れ
・それを踏まえてcocos2dでシェーダー使用の流れ
・cocos2dでオリジナルシェーダーを使うための改造ポイント
・cocos2dでのシェーダーデモ
・Unityでシェーダーを使うために
・ShaderLabの基本的な説明
・VertexShader, FragmentShaderを内包する場合の例
・SurfaceShaderを使う場合の例
という感じです。
前の発表会ではそもそもシェーダーに対しての事前知識が無い受講者に対していきなりコア部分の話をしてしまってよくわからないという事態を引き起こしてしまったので、反省して、今回はシェーダーとは何かという部分にページを割いて概念としての説明を丁寧にやってみたつもりです。
他の発表者さんでは@tmokitaさんの発表内容が良かったです。1問1答形式でTIPSをバンバン紹介していく感じで、あまり知られていない内容のものもちょこちょこあり非常に為になりました。
@nun_さんの発表は時間の都合で割愛されてしまったようで残念でした。
で、我らが@yoichinejiさんのネタですけど、今回はプロジェクターが無いことでいつものようにネタを展開することができなかったようで、ネタバレにならないようにtweetを駆使してやる感じでしたね。
開発言語がC++であるということが共通項となるので、Kinect + cocos2d-xというのを組んでみたという発表でした。まだ未完成ではあるそうですけど、Kinect関連で画面描画するのはなかなかとっつきにくいらしいので、cocos2d-xを使用出来ればいいんじゃないかとのことです。
以上でした。
2012/06/22
cocos2d勉強会2回目で発表しました
●スライドはこちら
●サンプルソースはこちら
内容としては以下の様な感じです
・シェーダーとは何か
・OpenGLでのシェーダーを使うための基本的な流れの紹介
・それを踏まえてcocos2dではどの部分を修正すれば良いかを紹介
・実際のデモ
という感じでやりました。
twitterの発言の様子を後から見るとついてこれなかった方多数のようでしたので、申し訳ないです。先にデモをしたほうが良かったのでは?とおっしゃってくれた方もいらっしゃいました。
来週末のさいたま勉強会vol4でも同じ内容を多少詳しくしたものと、Unityでのシェーダーの記述方法について発表しますので、質問がある方はそちらに来てもらえると良いかと思います。また、twitterやメールでもご連絡いただければ答えさせて頂きます。
とはいえ確かにシェーダーを記述したり利用するのはハードルが高いし、そもそもcocos2dのような2Dライブラリで本当に必要なのかといえば、まず必要にならないので技術デモのような感じだったかと思います。逆にUnityではシェーダーは無くてはならない要素だったりするのでそちらの方が親和性が高いかもしれないなと思った次第です。
他の方の発表は以下のとおりでした。
・@Seasonsさんがこれまでのcocos2dの流れや海外の様子の紹介
・Walzer WangさんがSkypeを使用してのcocos2d-xの紹介
・@torotitiさんがOpenOfficeをレベルエディタとして使用してcocos2dで絵本を作ったという事例紹介
・@splhackさんがOpenfeintをアップグレードするとGREEになるよという話
OpenOfficeをレベルエディタに使用した話は非常に興味深かったです。OpenOfficeの保存ファイルはxmlと画像リソース等をzipで固めた形式なので、Rubyで展開してパースするのに便利だったということで、コンバートしたデータをcocos2dで再生するように環境を整えたとのことです。これは何かに使えそう!
そういやPSSSDKは地雷という話を懇親会で聞きました。まあiOSが並行開発出来ない時点でフレームワークとしてどうなのよと言われたら言い返せませんよね。
短かったですが、なかなか興味深い勉強会でした。
ではまたー。
2012/05/13
cocos2dでパレットっぽいことをしてみたい その2
以前書いていたエントリーの続きです。その時はシェーダープログラムが全くわからない状態だったので試さなかったのですが、cocos2d 2.0がRC1になったこともありますので、シェーダーに手を出してみました。ここ最近やってるUnityでのシェーダー入門がうまく役に立っているってのもありますね。ちなみにシェーダー入門にUnityは向いているような気がします。すぐに絵を出せますからシェーダーコードに注力できます。とはいえShaderLabという特殊な記述方法となるのでOpenGL ESでGLSLを使うのとは若干違いますけど。まぁ考え方は一緒です。
●以前のアイデア
1,テクスチャ書き換え
2,白い素材を用意し、マテリアル色指定
3,シェーダーでリアルタイム書き換え
というアイデアを出していました。2までは前回達成しています。1はバッチが効かず、メモリ圧迫も多いため事実上使わないほうがよい手法でした。2については前回のレベルでは限界値で、ぎりぎり実用レベルだった感じです。
さて、今回は3を実装しました。
●前回の評価を考えなおす
前回は以下のように3を評価していました。
利点:テクスチャが共通なので省メモリ
欠点:僕はシェーダー作ったこと無い。OpenGLES2に対応したcocos2d2.0のベータ版を使わないとならない。描画が遅いかもしれない。シェーダーに渡すパラメータが色ごとに変化するので、CCSpriteBatchNodeで処理させるには難しいかも?
最初の欠点は今では問題ないです。個人的に。
2番目はcocos2d 2.0 RC1となったので問題ないでしょう。
3番目はやってみないとわからない。
4番目はバッチ処理するためのいい方法を考えましたので、次項で説明します。
●バッチ処理のために
cocos2d 2.0のソースを見ていると、cocos2dの描画に必要な基本的なシェーダーが全部用意されています。その中身を読んでいくとスプライトの色を設定してもバッチ描画を可能にするための技を確認できました。
通常OpenGL等では、いわゆるマテリアル(テクスチャ)が違うものはバッチ処理ができないものですが、頂点座標、頂点カラー、頂点UV値、オブジェクトのTransform情報については違っていても1つのDrawコマンドで描画することができます。Transform情報についてはcocos2dの内部で1オブジェクトとなるようにバッチノードに登録されたすべてのスプライトを1つのバッファに入れ込んで参照しているからですね。その他のパラメータは頂点に備わっている情報なので、1つながりのバッファにしてしまえば1度に送れます。
というわけで、cocos2dでは1.0の時からそうだったようですが、スプライトの色は頂点カラーへセットすることでバッチ描画を可能にしてたんですね。これを使わない手はありません。
シェーダーでパレットチェンジするための色変化情報は頂点カラーへもたせましょう。頂点カラーはRGBAの4チャンネルしかないので1枚のスプライトのなかに持てるパレットインデックスは4種類しか持てなさそうです。その中でアルファにはスプライトの透明度が入っているので使えないでしょう。ということでRGBのチャンネルに色変化情報を与えてやって1枚のテクスチャにつき3色変更可能というようにしました。
●パレット処理の仕様
・テクスチャのRGBをそれぞれ好きな色に変更可能
・変更後の色は頂点カラーRGBへ3色セットする(Rが1色目、Gが2色目、Bが3色目)
・セットする色はビット圧縮をかけて入れる(RGB=3:3:2bit)
ビット圧縮で8bitに収めたのはccColor3BでCCSpriteを継承したクラスに色をセットしたり、cocos2d通常の描画ルーチンを流用するためです。ビット圧縮はHSVとかYUVを使った方が色の再現性がいいかもです。そのうちやってみます。
●パフォーマンスはどうかな?
●以前のアイデア
1,テクスチャ書き換え
2,白い素材を用意し、マテリアル色指定
3,シェーダーでリアルタイム書き換え
というアイデアを出していました。2までは前回達成しています。1はバッチが効かず、メモリ圧迫も多いため事実上使わないほうがよい手法でした。2については前回のレベルでは限界値で、ぎりぎり実用レベルだった感じです。
さて、今回は3を実装しました。
●前回の評価を考えなおす
前回は以下のように3を評価していました。
利点:テクスチャが共通なので省メモリ
欠点:僕はシェーダー作ったこと無い。OpenGLES2に対応したcocos2d2.0のベータ版を使わないとならない。描画が遅いかもしれない。シェーダーに渡すパラメータが色ごとに変化するので、CCSpriteBatchNodeで処理させるには難しいかも?
最初の欠点は今では問題ないです。個人的に。
2番目はcocos2d 2.0 RC1となったので問題ないでしょう。
3番目はやってみないとわからない。
4番目はバッチ処理するためのいい方法を考えましたので、次項で説明します。
●バッチ処理のために
cocos2d 2.0のソースを見ていると、cocos2dの描画に必要な基本的なシェーダーが全部用意されています。その中身を読んでいくとスプライトの色を設定してもバッチ描画を可能にするための技を確認できました。
通常OpenGL等では、いわゆるマテリアル(テクスチャ)が違うものはバッチ処理ができないものですが、頂点座標、頂点カラー、頂点UV値、オブジェクトのTransform情報については違っていても1つのDrawコマンドで描画することができます。Transform情報についてはcocos2dの内部で1オブジェクトとなるようにバッチノードに登録されたすべてのスプライトを1つのバッファに入れ込んで参照しているからですね。その他のパラメータは頂点に備わっている情報なので、1つながりのバッファにしてしまえば1度に送れます。
というわけで、cocos2dでは1.0の時からそうだったようですが、スプライトの色は頂点カラーへセットすることでバッチ描画を可能にしてたんですね。これを使わない手はありません。
シェーダーでパレットチェンジするための色変化情報は頂点カラーへもたせましょう。頂点カラーはRGBAの4チャンネルしかないので1枚のスプライトのなかに持てるパレットインデックスは4種類しか持てなさそうです。その中でアルファにはスプライトの透明度が入っているので使えないでしょう。ということでRGBのチャンネルに色変化情報を与えてやって1枚のテクスチャにつき3色変更可能というようにしました。
●パレット処理の仕様
・テクスチャのRGBをそれぞれ好きな色に変更可能
・変更後の色は頂点カラーRGBへ3色セットする(Rが1色目、Gが2色目、Bが3色目)
・セットする色はビット圧縮をかけて入れる(RGB=3:3:2bit)
ビット圧縮で8bitに収めたのはccColor3BでCCSpriteを継承したクラスに色をセットしたり、cocos2d通常の描画ルーチンを流用するためです。ビット圧縮はHSVとかYUVを使った方が色の再現性がいいかもです。そのうちやってみます。
●パフォーマンスはどうかな?
上:cocos2d 1.0 白テクスチャに色設定して重ねたもの
左:cocos2d 2.0 白テクスチャに色設定して重ねたもの
右:cocos2d 2.0 でシェーダーで色変化させたもの
3つテストしました。
前回作成した上のものは、アイドル時には60FPSが出ることもありましたが、画面がスクロールすると描画される頂点数が変化して頂点バッファを作り直すのに時間がかかるようで、最低では25FPSまで下がるようです。
左のものは、同じソースをcocos2d 2.0で動作させたものです。60FPSから落ちることなくスイスイ動いています。これでいいんじゃないかという気もします。cocos2d 2.0からはフレームレート表示に上から、ドローコマンド数、処理時間、FPSの3つが表示されます。バッチが効いているのでドローは3(背景、キャラたち、ラスター線)です。処理時間はアイドル時0.007で、画面スクロール時には0.017までかかります。
右のものは、パレットチェンジシェーダーで表示したものです。これも60FPSから落ちることはありません。バッチ描画ができているのでドロー数もかわりません。処理時間はアイドル時0.004で、画面スクロール時には0.017までかかります。
というわけで、なかなかの好成績です。結論から言うと通常描画が速いのでシェーダーでやらなくてもいいかもという気もしなくもないですw cocos2d 2.0は描画が速いですね。
今回は以上です。
今度6/21に行われる予定のcocos2d bootcampでcocos2d 2.0のシェーダーについてのLTをたぶんやるとおもいますので、もしよろしければ聞いてください。
2012/01/14
cocos2dでパレットっぽいことをしてみたい

こんな感じに同じキャラなんだけど色違いのキャラをいっぱい出したい場合、2D表現が主流だった頃はパレットの色を変更することで実現するということがメジャーでした。しかし今の主流はテクスチャを使用した画像処理なためパレットの効果を入れるにはちょっと大変です。cocos2dもOpenGLベースなので条件は同じですね。ということで実現するには…と考えてみた。
●アイデア
1,テクスチャ書き換え
2,白い素材を用意し、マテリアル色指定
3,シェーダーでリアルタイム書き換え
1と2の方法は「cocos2d for iPhone 1 Game Developer Cookbook」に処理の紹介がありますので、そちらがわかりやすいです。
1,テクスチャ書き換え
肝はCCTexture2DMultableというテクスチャ書き換え機能のついたCCTexture2Dクラスを使うことですね。これはOpenGL側で管理しているテクスチャメモリを書き換える為のメソッドが追加されたCCTexture2Dだと思えば良いです。
利点:元になるテクスチャが何色でもOK。
欠点:色変更後のテクスチャはそれぞれ別にメモリに載るので不経済。テクスチャが共通じゃないのでCCSpriteBatchNodeが使えない。そのため描画が多少遅い。
2,白い素材を用意し、マテリアル色指定
これは元の絵のなかの色を変えたい部分だけを切り分けた別レイヤーとして素材を用意し、白で描いておく。これを使ったCCSpriteを色指定することで色を載せるというもの。cocos2dの基本機能だけで実現できます。
利点:テクスチャが共通化するのでCCSpriteBatchNodeが使え、描画が高速なはず。省メモリ。
欠点:色を変えたい部分を分けた素材を用意するのが手間。
3,シェーダーでリアルタイム書き換え
OpenGLES2以降であればピクセルシェーダが使えるので、描画時にリアルタイムに色変更して表示することができるはず。
利点:テクスチャが共通なので省メモリ。
欠点:僕はシェーダー作ったこと無い。OpenGLES2に対応したcocos2d2.0のベータ版を使わないとならない。描画が遅いかもしれない。シェーダーに渡すパラメータが色ごとに変化するので、CCSpriteBatchNodeで処理させるには難しいかも?
以上が考えられるなぁと思いました。
まずはお手軽なところからと、1の案をテストしたのが冒頭の画像です。iPhone4での表示ですが、1キャラあたり6レイヤーつかっていて、50体表示という状態です。これで60FPS出ているので処理能力的には十分かもなぁという印象。ただし、MacBookPro上でシミュレーターでの実行結果は30FPSしか出ませんでした。CCSpriteBatchNodeは使ってません。
cocos2dのcookbookで紹介されているままの方法では、色変更後のテクスチャはCCTextureCacheへ乗らず、同じ色変更を何度も指定すると同じテクスチャが量産されてしまうコードだったため、その部分は自前でキャッシュへ載せて共用するように直しました。
次は2のアイデアを試そうと思ってます。そのためには絵素材を色別に分離して別々のテクスチャに分配する必要がありますが、手作業でやるのめんどい…。2の方が処理が速いのであれば、最終的には絵素材の分離ツールを作らないとだなぁとか思ったり。
●追記
2のアイデアを実装して試したところ、CCSpriteBatchNodeの威力もあるだろうが100人出しても60FPSラクラク回ってました。1レイヤー(というかCCSprite)には1色しか指定できないので、色分だけ枚数が増えてますがそんなの全く影響が見られないですね。下図は1キャラ11レイヤー使ってます。ちなみに、CCSpriteのcolorプロパティで色を設定するとその色が乗算されるので黒の輪郭を色変更せずにそのまま残したいという場合は、どこかのカラーのスプライトに入れ込んでしまってもOKです。黒なので他の色を重ねても黒以外になりませんから。
2011/12/25
coco2d Advent Calendar 2011 24日目: オーバートップレイヤーのすすめ
あいかわらず後からの投稿になっちゃいますが、めげずにcocos2d Advent Calendar投稿します。
今回は、以前さいたまiPhone勉強会で発表した内容からのピックアップで、オーバートップレイヤーというものを実装してみたという例のご紹介です。
<中級編>オーバートップレイヤーのすすめ
●まえがき
ゲームでは、よく画面を覆う枠があったり、画面上部に体力やスコア表示などが分けて表示されていたりするような画面配置がありますよね。たとえば、以下のような感じです。
Ysなどの往年の国産PCゲームでは、画面を覆う枠があり枠内がスクロールするゲーム画面。枠の下には体力などのパラメータ表示となっていました。たとえばこんな感じで検索するとヒットしますよ。
また、ファミコンのゲームではよく画面を上下に区切って画面上部にアイテムやパラメータ表示をして、画面下部はスクロールするゲーム画面として使用するようなものもメジャーでした。たとえばグーニーズとか。ほら検索すると画面がヒットしますよ。
こんな感じの表示を行う場合に、CCLayerを2つ用意して、1つは枠や画面上部のパラメータ表示用に使用し、もう1つはゲーム画面として使用するように作ると思います。しかし、ゲームの進行で別のマップへ移ったりする際にフェードアウト・フェードインして画面切り替えを行おうとするとcocos2dで普通に推奨されている方法で組むと、パラメータ表示用も含めてフェードがかかってしまい、あまりかっこ良く有りません。ちなみに、このcocos2dで推奨されている組み方はCCSceneにCCLayerを2つ子供にして別のCCSceneへ切り替えるというものです。
そこで、今回ご紹介する方法が出てくるわけです。
●オーバートップレイヤーの仕組み

仕組みはこんな感じとなります。通常cocos2dで用意されている画面遷移関数はCCSceneを入れ替えるものですが、この方法ではCCScene自体は基本的に入れ替わらず、ゲーム画面として使用しているCCLayerだけが入れ替わるという構造になります。もちろん、そんな便利なメソッドは用意されていないので、レイヤー入れ替え部分は自作しなければなりません。
CCSceneの定義自体はこんな感じとなります。
で、画面遷移用にとりあえずこの2つのメソッドを用意してみました。メソッドの中のコードはサンプルコードを参照してください。transitionFadeWithLayerは黒フェードを用いてレイヤーの入れ替えを行うものです。transitionFlowerWithLayerはオマケ的なものですが、花で画面が埋め尽くされて花が画面上から去るとレイヤーが入れ替わっているというものです。
●実装の注意点
実装にあたって、以下の部分に注意しました。
・関係するレイヤーのタッチイベントの無効化だけでは余り効果を発揮しなかったので、画面遷移の重複が起きないように注意した。
・トランジション中フラグを用意して、トランジションメソッドが複数動作しないように制御した。
と、こんな感じですが、荒削りなので実際に使用するにはもう少し改善の余地はありそうです。でも、夢が広がると思います。
●夢がひろがりんぐ
もともとオーバートップレイヤーが欲しいなと思ったのは、GameCenterでのアチーブメント解除表示を行う際に画面上部などにアチーブメント情報を表示し始めたとしても、その後すぐに画面遷移が行われてしまった場合にアチーブメント表示が消えてしまうのをなんとかしたいと思ったところから発想しました。もちろん、ネットをググれば同様の問題の対処としてcocos2dのCCSpriteオブジェクトなどをcocos2d外のものに適用して表示させる方法があったりしましたが、なんだかスマートじゃないなと思っていたのです。どうせなら表示はすべてcocos2dの中で完結させたいと。
オーバートップレイヤーがうまく動いてしまえば、往年のゲーム的な画面表示が簡単に行えるので、これはいいんじゃないでしょうか。おすすめですよ。
ではでは、今回はこのへんで。
今回は、以前さいたまiPhone勉強会で発表した内容からのピックアップで、オーバートップレイヤーというものを実装してみたという例のご紹介です。
<中級編>オーバートップレイヤーのすすめ
●まえがき
ゲームでは、よく画面を覆う枠があったり、画面上部に体力やスコア表示などが分けて表示されていたりするような画面配置がありますよね。たとえば、以下のような感じです。
Ysなどの往年の国産PCゲームでは、画面を覆う枠があり枠内がスクロールするゲーム画面。枠の下には体力などのパラメータ表示となっていました。たとえばこんな感じで検索するとヒットしますよ。
また、ファミコンのゲームではよく画面を上下に区切って画面上部にアイテムやパラメータ表示をして、画面下部はスクロールするゲーム画面として使用するようなものもメジャーでした。たとえばグーニーズとか。ほら検索すると画面がヒットしますよ。
こんな感じの表示を行う場合に、CCLayerを2つ用意して、1つは枠や画面上部のパラメータ表示用に使用し、もう1つはゲーム画面として使用するように作ると思います。しかし、ゲームの進行で別のマップへ移ったりする際にフェードアウト・フェードインして画面切り替えを行おうとするとcocos2dで普通に推奨されている方法で組むと、パラメータ表示用も含めてフェードがかかってしまい、あまりかっこ良く有りません。ちなみに、このcocos2dで推奨されている組み方はCCSceneにCCLayerを2つ子供にして別のCCSceneへ切り替えるというものです。
そこで、今回ご紹介する方法が出てくるわけです。
●オーバートップレイヤーの仕組み

仕組みはこんな感じとなります。通常cocos2dで用意されている画面遷移関数はCCSceneを入れ替えるものですが、この方法ではCCScene自体は基本的に入れ替わらず、ゲーム画面として使用しているCCLayerだけが入れ替わるという構造になります。もちろん、そんな便利なメソッドは用意されていないので、レイヤー入れ替え部分は自作しなければなりません。
CCSceneの定義自体はこんな感じとなります。
+(MainScene*)sceneWithLayerTop:(CCLayer*)layerTop
layerBelow:(CCLayer*)layerBelow
{
MainScene *scene = [MainScene node];
layerTop.tag = kLayerTop;
layerBelow.tag = kLayerBelow;
[scene addChild:layerBelow z:0];
[scene addChild:layerTop z:2];
return scene;
}
で、画面遷移用にとりあえずこの2つのメソッドを用意してみました。メソッドの中のコードはサンプルコードを参照してください。transitionFadeWithLayerは黒フェードを用いてレイヤーの入れ替えを行うものです。transitionFlowerWithLayerはオマケ的なものですが、花で画面が埋め尽くされて花が画面上から去るとレイヤーが入れ替わっているというものです。
- (BOOL)transitionFadeWithLayer:(CCLayer*)layer
duration:(ccTime)d;
- (BOOL)transitionFlowerWithLayer:(CCLayer*)layer
duration:(ccTime)d;
●実装の注意点
実装にあたって、以下の部分に注意しました。
・関係するレイヤーのタッチイベントの無効化だけでは余り効果を発揮しなかったので、画面遷移の重複が起きないように注意した。
・トランジション中フラグを用意して、トランジションメソッドが複数動作しないように制御した。
と、こんな感じですが、荒削りなので実際に使用するにはもう少し改善の余地はありそうです。でも、夢が広がると思います。
●夢がひろがりんぐ
もともとオーバートップレイヤーが欲しいなと思ったのは、GameCenterでのアチーブメント解除表示を行う際に画面上部などにアチーブメント情報を表示し始めたとしても、その後すぐに画面遷移が行われてしまった場合にアチーブメント表示が消えてしまうのをなんとかしたいと思ったところから発想しました。もちろん、ネットをググれば同様の問題の対処としてcocos2dのCCSpriteオブジェクトなどをcocos2d外のものに適用して表示させる方法があったりしましたが、なんだかスマートじゃないなと思っていたのです。どうせなら表示はすべてcocos2dの中で完結させたいと。
オーバートップレイヤーがうまく動いてしまえば、往年のゲーム的な画面表示が簡単に行えるので、これはいいんじゃないでしょうか。おすすめですよ。
ではでは、今回はこのへんで。
2011/12/22
coco2d Advent Calendar 2011 22日目: Tiledの使い方講座
cocos2d Advent Calendar 22日目としてさくっと書きました。
cocos2dとはちょっとズレた話かもしれませんが、CCTMXTiledMapを活かそうと思ったら使うことになるTiledというマップ作成ツールの使い方について解説します。
<初級編>Tiledの使い方講座
●基本機能
Tiledは正方形(トップビュー、サイドビュー)、平行四辺形(クォータービュー)、六角形(ヘックス)のスクロール可能なマップを作成するのに非常に便利なツールです。もともとはPythonのゲーム用に作られたこのツールですが、cocos2dのCCTMXTiledMapクラスでサポートされた形式tmx形式を出力可能なツールとなっています。というか、cocos2dの方がtmxに対応させたということになりますか。
以下のスクリーンショットを見てもらえれば、どんなマップが作れるのかよく分かると思います。



一番上のマップはHungryMasterで使用したもので、トップビューとなっています。真ん中はTiledのサンプルに用意されているもので、トップビューなのですが、左上に向かって上層がつながって表示されているややパースペクティブなもの。一番下の例はクォータービューとなっております。クォータービューのタイルチップはこちらのものを使用させてもらいました。
マップはレイヤー構造を持てますので、それを利用することで、地面、建物、2階部分などをレイヤー分けして載せていくことができます。クォータービューのものを例に取りますと、地面レイヤーだけでは以下のようになります。

これに建物レイヤーを重ねることで、次のようになります。

さらに、オブジェクトレイヤーという範囲指定が行えるレイヤーを設定し、範囲指定を行うと以下のように設定が行えます。この範囲を何に使うかはゲーム部分で自由に利用すれば良いのですが、得られるの矩形の4点となります。

●実践してみましょう
まず「ファイル>新規ファイル」コマンドにて、どんな形状のマップを作成するか設定します。ここでは、平行四辺形の並んだクォータービューマップにしてみましょう。これって結構たいへんなんですよね。ここで指定する数値は平行四辺形の地面部分が収まるサイズのドットを指定します。使用するマップチップの画像はこれを使用してみましょう。



こんな感じに空のマップが用意されます。さらに、使用するマップチップを登録して配置可能にしましょう。
「マップ>新しいタイルセット」コマンドを実行し、タイルセットとして登録します。

この時に、指定するタイルの高さは透明部分も含めたサイズになりますので、地面部分の高さしないように注意しましょう。
正しく登録できると、こんなふうにタイルを配置可能です。

次は、壁を配置しましょう。新しいレイヤーが必要になります。「レイヤー>タイル・レイヤーの追加」を実行すると、タイルレイヤーが1つ増えます。そのレイヤーをアクティブにしてタイルを配置すれば上のレイヤーに物が置けます。

どんどん上層レイヤーを増やしていけば、2階、3階などどんどん増築できます。

再度に範囲指定用のオブジェクトレイヤーを追加してみましょうか。
「レイヤー>オブジェクト・レイヤーの追加」を実行すると範囲指定用のレイヤーが生成されます。これをアクティブにして、「オブジェクトを追加」アイコンをアクティブにすると、範囲指定ができます。

以上です。
駆け足ですが、ざっと使い方についてのみ解説してみました。
cocos2dとはちょっとズレた話かもしれませんが、CCTMXTiledMapを活かそうと思ったら使うことになるTiledというマップ作成ツールの使い方について解説します。
<初級編>Tiledの使い方講座
●基本機能
Tiledは正方形(トップビュー、サイドビュー)、平行四辺形(クォータービュー)、六角形(ヘックス)のスクロール可能なマップを作成するのに非常に便利なツールです。もともとはPythonのゲーム用に作られたこのツールですが、cocos2dのCCTMXTiledMapクラスでサポートされた形式tmx形式を出力可能なツールとなっています。というか、cocos2dの方がtmxに対応させたということになりますか。
以下のスクリーンショットを見てもらえれば、どんなマップが作れるのかよく分かると思います。



一番上のマップはHungryMasterで使用したもので、トップビューとなっています。真ん中はTiledのサンプルに用意されているもので、トップビューなのですが、左上に向かって上層がつながって表示されているややパースペクティブなもの。一番下の例はクォータービューとなっております。クォータービューのタイルチップはこちらのものを使用させてもらいました。
マップはレイヤー構造を持てますので、それを利用することで、地面、建物、2階部分などをレイヤー分けして載せていくことができます。クォータービューのものを例に取りますと、地面レイヤーだけでは以下のようになります。

これに建物レイヤーを重ねることで、次のようになります。

さらに、オブジェクトレイヤーという範囲指定が行えるレイヤーを設定し、範囲指定を行うと以下のように設定が行えます。この範囲を何に使うかはゲーム部分で自由に利用すれば良いのですが、得られるの矩形の4点となります。

●実践してみましょう
まず「ファイル>新規ファイル」コマンドにて、どんな形状のマップを作成するか設定します。ここでは、平行四辺形の並んだクォータービューマップにしてみましょう。これって結構たいへんなんですよね。ここで指定する数値は平行四辺形の地面部分が収まるサイズのドットを指定します。使用するマップチップの画像はこれを使用してみましょう。



こんな感じに空のマップが用意されます。さらに、使用するマップチップを登録して配置可能にしましょう。
「マップ>新しいタイルセット」コマンドを実行し、タイルセットとして登録します。

この時に、指定するタイルの高さは透明部分も含めたサイズになりますので、地面部分の高さしないように注意しましょう。
正しく登録できると、こんなふうにタイルを配置可能です。

次は、壁を配置しましょう。新しいレイヤーが必要になります。「レイヤー>タイル・レイヤーの追加」を実行すると、タイルレイヤーが1つ増えます。そのレイヤーをアクティブにしてタイルを配置すれば上のレイヤーに物が置けます。

どんどん上層レイヤーを増やしていけば、2階、3階などどんどん増築できます。

再度に範囲指定用のオブジェクトレイヤーを追加してみましょうか。
「レイヤー>オブジェクト・レイヤーの追加」を実行すると範囲指定用のレイヤーが生成されます。これをアクティブにして、「オブジェクトを追加」アイコンをアクティブにすると、範囲指定ができます。

以上です。
駆け足ですが、ざっと使い方についてのみ解説してみました。
2011/12/10
coco2d Advent Calendar 2011 10日目: cocos2dキャラクタークラス設計の考察
cocos2d Advent Calendar 10日目、2回目の投稿なのですけどすみません。まだまだ空きはあるので我こそはという方はどしどし参加してみてください。前回、12/9日目の記事は@mybさんのこの記事でした。「CCMenuでラベル付きボタン、長押しボタン」
さて、今回はcocos2dでゲームを作る上で考え方の参考になるような記事を書ければと思ってこれを書いています。
<初級編>cocos2dキャラクタークラス設計の考察
●ゲームにおけるキャラクターに必要な要素
ゲームには多くの場合キャラクターが登場します。プレイヤーキャラクター、エネミーキャラクター、アイテムなんかもキャラクターに含まれるかもしれません。落ち物パズルなどでも落ちてくるブロックのパーツはキャラクターのようなものと考えられます。ゲームキャラクターにはどんな要素が必要なのか、まずは考えてみましょう。
・横スクロールのジャンプアクションの場合(スーパーマリオブラザーズなど)
A・キャラクターの絵
B・動作によって変化する絵のパターン、場合によっては動く
C・画面上の障害物によって移動制限がある
D・何らかのアイテム効果によって変化することがある
E・やられると画面から消える
F・武器を発射することがある
G・別のキャラクターを発生させることがある
・トップビューのアクションRPGの場合(イースなど)
A・キャラクターの絵
B・動作によって変化する絵のパターン、場合によっては動く
C・画面上の障害物によって移動制限がある
C2・画面上の建造物などによって一時的に隠れて見えなくなることがある
E・やられると画面から消える
・シューティングゲームの場合(ゼビウスなど)
A・キャラクターの絵
B・動作によって変化する絵のパターン、場合によっては動く
E・やられると画面から消える
F・武器を発射することがある
G・別のキャラクターを発生させることがある
ざっと思いつく限り書いてみましたが、よくあるゲームジャンルではこんなところが求められるでしょうか。パズルゲームは特殊なのでここでは省きますね。他のゲームよりも求められる要素は少ないはずです。あとで復習がてら考えてみてくださいね。
では、代表的な要素であるA, B, Eを考えてみましょう。
●キャラクターの絵を扱う
基本的なCCSpriteの扱いとそれほど変わりません。そのままCCSprite型をキャラクターとして扱って構わないことも多いでしょう。キャラクターの絵が変化する場合には少し要素が増えます。たとえば、絵が変わるたびに新たにCCSpriteを生成して割り当てるとすると以下のようになります。gmCharaという名前でクラス定義したとして仮に書いています。
あるいは、CCSpriteを継承して絵のフレーム自体を変更する場合は以下のようになるでしょう。
絵のフレームを変更するには、以下のようなコードで行うことができます。CCSpriteで使用しているテクスチャに必要な絵が全て入っていて、その一部を切り出して使用しているという状況が前提となりますが簡単に絵を変更できます。CCSpriteを再生成して割り当て直すよりも高速なはずです。CGRECT_FOR_NEWは新たに指定したい切り出し用のCGRectです。spriteはCCSprite型とします。
さて、これらの例に移動用の加速度パラメータはあるのに、移動後の位置を格納するプロパティは用意されていません。そうです。CCSprite自体に位置を扱うプロパティが存在するので、そちらを使う方が無駄が少ないからですね。ゲームの要求として表示位置とは別に位置情報が必要になる場合は別途プロパティを用意するべきでしょう。サイズ用のプロパティが存在しないのも同様の理由ですが、サイズの場合は当たり判定の大きさが絵の大きさとは異なることも多いので、別途プロパティを用意したほうがいいかもしれません。
実は、ElectroMasterやHungryMasterでは上記の方法でキャラクタークラスが構築されています。おそらく無駄が多いと思います。やっちまいましたね。
●やられると画面から消えるために
敵などをやっつけると、画面上から姿が消えるのがゲームのお約束であることはみなさんもお分かりのはず。
消すだけなら簡単です。絵を取り扱うCCSpriteを表示しなければ良いのですから。しかし、表示を消しただけではキャラクターの存在自体はメモリ上に残り続けてしまいます。ですから絵を消す代わりにキャラクターのオブジェクトを解放しちゃってもいいかもです。いいかもしれません。ゲームに登場するキャラが有限である場合はこれで十分でしょう。
では、ゲームに登場するキャラが無限に発生する場合は困ったことになります。敵が発生するたびにキャラオブジェクトを生成してゲームへ追加していくのも手です。一度倒してしまったキャラオブジェクトを再利用して追加のキャラとして復活させることもいいかもです。
A・キャラが有限の場合
ゲーム開始時にキャラオブジェクトを全て生成しておいて、倒すたびにクラス解放でいいでしょう。
倒せば倒すほど処理も軽くなりますね。
B・キャラが無限に発生する場合
1. キャラが発生するたびにキャラオブジェクトを生成してゲームへ追加とする。普通にやるとオブジェクト生成時のオーバーヘッドが大きいかもです。次善の策としてはひな形オブジェクトを用意しておいて、そのコピーを追加する。(newChara = [[chara copy] autorelease];とすればコピーが生成できますね)
2. キャラオブジェクトを再利用する場合。一度に画面に登場するキャラ数は事前に生成しておいたキャラオブジェクト数に制限されますが、キャラを初期値に最設定するメソッドを用意しておけば高速に復活させられそうです。また、一度に取り扱うキャラ数限界も管理しやすいので、メモリや処理能力的にも優しいかもです。手前味噌ですが、ElectroMaster, HungryMasterではこの方法を取っています。
●動作する絵のパターンを取り扱う(パターンアニメーション)
キャラクターが移動すると、歩いたり走ったり、ジャンプボタンでジャンプしたり。敵に触ったら痛がったりというようなキャラクターの動きに関するものです。これが無いと物足りないですよね。多くはキャラクターの絵を複数用意しておいて、場合によって絵を切り替えて動いているかのように見せています。パターンアニメーションですね。
cocos2dの入門書ではパターンアニメーションについて扱っていて、そういう動作を割りと簡単に与えることができるように説明されています。単一のパターンアニメーションを指定するだけなら難しくありません。よく悩んでる人が多いのは、右に移動すると右向きの絵で歩く、左に移動すれば左向きで、上なら上向き、下なら下向きといったように場合に応じて使用されるパターンアニメーションが変化するときにどうするのがよいかということでしょう。
パターンアニメーションの定義は以下のようにできます。これは入門書にも書かれていますね。下記の例では、512x64のテクスチャを用意してあって、横方向に8枚の絵が並んでいる状態を元に、64x64の絵が0.3秒毎に変化していくというパターンアニメーションとなります。生成されたパターンアニメーションはCCRepeatForever型(CCAction系列として取り扱える)として最終的に定義されます。TEXTURE_FILE_NAMEはスプライトに使用するテクスチャのファイル名です。

これをCCSpriteへ適用してパターンアニメーションを実行するには、通常以下のようにします。
こんな手順を適用するパターンアニメーションが変化するたびに行えば、パターンアニメーションを変更することが可能ですが、stopAllActionsを実行するとそれまで適用されていたアクションが解放されてしまうので、次に同じアクションを最適用する場合でも、新たに定義しなおしたアクションを与えなければなりません。となると定義に必要な処理が無駄になってしまいます。(stopAllActionsではなくstopActionを使用して名指しで停止するアクションを指定してあげても良いですが、同じことです)
では、パターンアニメーションのアクション再定義に必要な処理を軽くするためにはどうすれば良いでしょうか。キャラクターの絵について説明した部分でも書きましたが、1つの方法としては事前に定義しておいたアクションオブジェクトをコピーして与えてあげれば良いです。あらたにオブジェクトを初期化するよりも処理は軽いはずです。もう1つ考えられるとすれば、stopActionなどを行なっても解放されないようにretainしておくのも良いです。retainしておくにはCCArrayやNSArrayなどに格納しておくのが呼び出すのも楽なのでいいでしょう。
コピーして与える場合は、こんな感じでしょうか。事前にactionとして定義しておいて、使用する際に随時コピーします。コピーして与える場合は、キャラ毎にパターンアニメーションを保持するのではなく、キャラの種類毎に保持するような運用の場合に活きてきます。というのも単一のアクションオブジェクトを複数のスプライトに対して適用するとタイマーがそれぞれのスプライトから更新されて動作がおかしくなるため、各スプライトへ別々のオブジェクトを与えなければならないためです。個々のスプライトでアクションを保持していた場合はその点ではコピーする必要が無いと思われます。
でも、actionをまとめて管理しておくにはやはりNSArrayやCCArrayに入れておくと思いますので、以下のようにしますよね。そうすると、CCArrayなどに格納した時点でretainされますので、アクション終了後に解放されなくなります。というわけで、メモリの占有率が変化しないこっちのほうがおすすめです。
実際の適用はこちら。0番目に登録されているパターンアニメーションを適用させています。spriteはCCSprite型とします。
以上のような取り扱いでうまく制御ができると思います。
ところで、ElectroMaster, HungryMasterでは、かなり無駄な組み方をしていたことに、この記事を書きながら気づいてしまいました。上記のようなCCArrayなどに予めパターンアニメーションを格納して管理していたところまでは一緒なのですが、CCRepeatForeverを噛まさずに入れておいてアニメーション適用時にいちいちCCRepeatForeverを生成して適用しておりました。なので、その部分がオーバーヘッドになってました。これには理由があって、毎回新たにCCRepeatForeverを生成しないと再生開始フレームが最初からにならないかもしれないって思っていたからです。しかし、実際にはそんなことはなく過去に再生済みのアクションであっても最適用すれば最初から再生されますので、要らぬ心配でした。それから、アクションをコピーしてから適用しておりました。これも無駄で、CCArrayなどに格納した時点でretainされいるためにアクション終了時に解放されないわけです。なので、解放を恐れてコピーすることも無かったということになります。以下はそのダメコードの例です。
今回の記事はここまでにしておきます。今回解説しなかった障害物判定については機会がありましたらまた説明できればと思っています。次は@Seasonsさんの予定と聞いております。楽しみー。ではー。
追記:11日目の記事はこちら:@Seasonsさん「cocos2dパフォーマンスチューニングTips」
さて、今回はcocos2dでゲームを作る上で考え方の参考になるような記事を書ければと思ってこれを書いています。
<初級編>cocos2dキャラクタークラス設計の考察
●ゲームにおけるキャラクターに必要な要素
ゲームには多くの場合キャラクターが登場します。プレイヤーキャラクター、エネミーキャラクター、アイテムなんかもキャラクターに含まれるかもしれません。落ち物パズルなどでも落ちてくるブロックのパーツはキャラクターのようなものと考えられます。ゲームキャラクターにはどんな要素が必要なのか、まずは考えてみましょう。
・横スクロールのジャンプアクションの場合(スーパーマリオブラザーズなど)
A・キャラクターの絵
B・動作によって変化する絵のパターン、場合によっては動く
C・画面上の障害物によって移動制限がある
D・何らかのアイテム効果によって変化することがある
E・やられると画面から消える
F・武器を発射することがある
G・別のキャラクターを発生させることがある
・トップビューのアクションRPGの場合(イースなど)
A・キャラクターの絵
B・動作によって変化する絵のパターン、場合によっては動く
C・画面上の障害物によって移動制限がある
C2・画面上の建造物などによって一時的に隠れて見えなくなることがある
E・やられると画面から消える
・シューティングゲームの場合(ゼビウスなど)
A・キャラクターの絵
B・動作によって変化する絵のパターン、場合によっては動く
E・やられると画面から消える
F・武器を発射することがある
G・別のキャラクターを発生させることがある
ざっと思いつく限り書いてみましたが、よくあるゲームジャンルではこんなところが求められるでしょうか。パズルゲームは特殊なのでここでは省きますね。他のゲームよりも求められる要素は少ないはずです。あとで復習がてら考えてみてくださいね。
では、代表的な要素であるA, B, Eを考えてみましょう。
●キャラクターの絵を扱う
基本的なCCSpriteの扱いとそれほど変わりません。そのままCCSprite型をキャラクターとして扱って構わないことも多いでしょう。キャラクターの絵が変化する場合には少し要素が増えます。たとえば、絵が変わるたびに新たにCCSpriteを生成して割り当てるとすると以下のようになります。gmCharaという名前でクラス定義したとして仮に書いています。
@interface gmChara : CCNode(あるいはNSObject) {
CCSprite *sprite; //キャラクター用スプライト
CGPoint accel; //加速度
int vital; //体力
...などなど
}
あるいは、CCSpriteを継承して絵のフレーム自体を変更する場合は以下のようになるでしょう。
@interface gmChara : CCSprite {
CGPoint accel; //加速度
int vital; //体力
...などなど
}
絵のフレームを変更するには、以下のようなコードで行うことができます。CCSpriteで使用しているテクスチャに必要な絵が全て入っていて、その一部を切り出して使用しているという状況が前提となりますが簡単に絵を変更できます。CCSpriteを再生成して割り当て直すよりも高速なはずです。CGRECT_FOR_NEWは新たに指定したい切り出し用のCGRectです。spriteはCCSprite型とします。
[sprite setTextureRect:CGRECT_FOR_NEW];
さて、これらの例に移動用の加速度パラメータはあるのに、移動後の位置を格納するプロパティは用意されていません。そうです。CCSprite自体に位置を扱うプロパティが存在するので、そちらを使う方が無駄が少ないからですね。ゲームの要求として表示位置とは別に位置情報が必要になる場合は別途プロパティを用意するべきでしょう。サイズ用のプロパティが存在しないのも同様の理由ですが、サイズの場合は当たり判定の大きさが絵の大きさとは異なることも多いので、別途プロパティを用意したほうがいいかもしれません。
実は、ElectroMasterやHungryMasterでは上記の方法でキャラクタークラスが構築されています。おそらく無駄が多いと思います。やっちまいましたね。
●やられると画面から消えるために
敵などをやっつけると、画面上から姿が消えるのがゲームのお約束であることはみなさんもお分かりのはず。
消すだけなら簡単です。絵を取り扱うCCSpriteを表示しなければ良いのですから。しかし、表示を消しただけではキャラクターの存在自体はメモリ上に残り続けてしまいます。ですから絵を消す代わりにキャラクターのオブジェクトを解放しちゃってもいいかもです。いいかもしれません。ゲームに登場するキャラが有限である場合はこれで十分でしょう。
では、ゲームに登場するキャラが無限に発生する場合は困ったことになります。敵が発生するたびにキャラオブジェクトを生成してゲームへ追加していくのも手です。一度倒してしまったキャラオブジェクトを再利用して追加のキャラとして復活させることもいいかもです。
A・キャラが有限の場合
ゲーム開始時にキャラオブジェクトを全て生成しておいて、倒すたびにクラス解放でいいでしょう。
倒せば倒すほど処理も軽くなりますね。
B・キャラが無限に発生する場合
1. キャラが発生するたびにキャラオブジェクトを生成してゲームへ追加とする。普通にやるとオブジェクト生成時のオーバーヘッドが大きいかもです。次善の策としてはひな形オブジェクトを用意しておいて、そのコピーを追加する。(newChara = [[chara copy] autorelease];とすればコピーが生成できますね)
2. キャラオブジェクトを再利用する場合。一度に画面に登場するキャラ数は事前に生成しておいたキャラオブジェクト数に制限されますが、キャラを初期値に最設定するメソッドを用意しておけば高速に復活させられそうです。また、一度に取り扱うキャラ数限界も管理しやすいので、メモリや処理能力的にも優しいかもです。手前味噌ですが、ElectroMaster, HungryMasterではこの方法を取っています。
●動作する絵のパターンを取り扱う(パターンアニメーション)
キャラクターが移動すると、歩いたり走ったり、ジャンプボタンでジャンプしたり。敵に触ったら痛がったりというようなキャラクターの動きに関するものです。これが無いと物足りないですよね。多くはキャラクターの絵を複数用意しておいて、場合によって絵を切り替えて動いているかのように見せています。パターンアニメーションですね。
cocos2dの入門書ではパターンアニメーションについて扱っていて、そういう動作を割りと簡単に与えることができるように説明されています。単一のパターンアニメーションを指定するだけなら難しくありません。よく悩んでる人が多いのは、右に移動すると右向きの絵で歩く、左に移動すれば左向きで、上なら上向き、下なら下向きといったように場合に応じて使用されるパターンアニメーションが変化するときにどうするのがよいかということでしょう。
パターンアニメーションの定義は以下のようにできます。これは入門書にも書かれていますね。下記の例では、512x64のテクスチャを用意してあって、横方向に8枚の絵が並んでいる状態を元に、64x64の絵が0.3秒毎に変化していくというパターンアニメーションとなります。生成されたパターンアニメーションはCCRepeatForever型(CCAction系列として取り扱える)として最終的に定義されます。TEXTURE_FILE_NAMEはスプライトに使用するテクスチャのファイル名です。

CCTexture2D *texture =
[[CCTextureCache sharedTextureCache]
addImage:TEXTURE_FILE_NAME];
NSMutableArray *animFrames = [NSMutableArray array];
for (int x=0; x<8; x++) {
CCSpriteFrame *frame =
[CCSpriteFrame frameWithTexture:texture
rectInPixels:CGRectMake(64*x, 0, 64, 64)
rotated:FALSE
offset:CGPointZero
originalSize:CGSizeMake(64, 64)];
[animFrames addObject:frame];
}
CCAnimation *animation =
[CCAnimation animationWithFrames:animFrames
delay:0.3f];
CCRepeatForever *action =
[CCRepeatForever actionWithAction:
[CCAnimate actionWithAnimation:animation
restoreOriginalFrame:NO]];
これをCCSpriteへ適用してパターンアニメーションを実行するには、通常以下のようにします。
[sprite stopAllActions];
[sprite runAction:action];
こんな手順を適用するパターンアニメーションが変化するたびに行えば、パターンアニメーションを変更することが可能ですが、stopAllActionsを実行するとそれまで適用されていたアクションが解放されてしまうので、次に同じアクションを最適用する場合でも、新たに定義しなおしたアクションを与えなければなりません。となると定義に必要な処理が無駄になってしまいます。(stopAllActionsではなくstopActionを使用して名指しで停止するアクションを指定してあげても良いですが、同じことです)
では、パターンアニメーションのアクション再定義に必要な処理を軽くするためにはどうすれば良いでしょうか。キャラクターの絵について説明した部分でも書きましたが、1つの方法としては事前に定義しておいたアクションオブジェクトをコピーして与えてあげれば良いです。あらたにオブジェクトを初期化するよりも処理は軽いはずです。もう1つ考えられるとすれば、stopActionなどを行なっても解放されないようにretainしておくのも良いです。retainしておくにはCCArrayやNSArrayなどに格納しておくのが呼び出すのも楽なのでいいでしょう。
コピーして与える場合は、こんな感じでしょうか。事前にactionとして定義しておいて、使用する際に随時コピーします。コピーして与える場合は、キャラ毎にパターンアニメーションを保持するのではなく、キャラの種類毎に保持するような運用の場合に活きてきます。というのも単一のアクションオブジェクトを複数のスプライトに対して適用するとタイマーがそれぞれのスプライトから更新されて動作がおかしくなるため、各スプライトへ別々のオブジェクトを与えなければならないためです。個々のスプライトでアクションを保持していた場合はその点ではコピーする必要が無いと思われます。
[sprite runAction:[[action copy] autorelease]];
でも、actionをまとめて管理しておくにはやはりNSArrayやCCArrayに入れておくと思いますので、以下のようにしますよね。そうすると、CCArrayなどに格納した時点でretainされますので、アクション終了後に解放されなくなります。というわけで、メモリの占有率が変化しないこっちのほうがおすすめです。
@interface gmChara : CCSprite {
CCArray *actions; //パターンアニメーション保持用
...などなど
}
実際の適用はこちら。0番目に登録されているパターンアニメーションを適用させています。spriteはCCSprite型とします。
[sprite runAction:[actions objectAtIndex:0]];
以上のような取り扱いでうまく制御ができると思います。
ところで、ElectroMaster, HungryMasterでは、かなり無駄な組み方をしていたことに、この記事を書きながら気づいてしまいました。上記のようなCCArrayなどに予めパターンアニメーションを格納して管理していたところまでは一緒なのですが、CCRepeatForeverを噛まさずに入れておいてアニメーション適用時にいちいちCCRepeatForeverを生成して適用しておりました。なので、その部分がオーバーヘッドになってました。これには理由があって、毎回新たにCCRepeatForeverを生成しないと再生開始フレームが最初からにならないかもしれないって思っていたからです。しかし、実際にはそんなことはなく過去に再生済みのアクションであっても最適用すれば最初から再生されますので、要らぬ心配でした。それから、アクションをコピーしてから適用しておりました。これも無駄で、CCArrayなどに格納した時点でretainされいるためにアクション終了時に解放されないわけです。なので、解放を恐れてコピーすることも無かったということになります。以下はそのダメコードの例です。
id action = [[[actions objectAtIndex:0] copy] autorelease];
[sprite runAction:[CCRepeatForever actionWithAction:action]];
今回の記事はここまでにしておきます。今回解説しなかった障害物判定については機会がありましたらまた説明できればと思っています。次は@Seasonsさんの予定と聞いております。楽しみー。ではー。
追記:11日目の記事はこちら:@Seasonsさん「cocos2dパフォーマンスチューニングTips」
2011/12/02
coco2d Advent Calendar 2011 2日目: cocos2dでオリジナルフォントクラスを作ろうぜ!
@yoichinejiさんから連絡があって、なんでもcocos2dのAdvent Calendarをやるとのこと!なんだか楽しそうなので、1も2も無く参加してみましたー。というわけで、以前さいたまiPhone勉強会で発表した内容と同内容になりますが、詳しい解説を入れて再録させてもらいました。ネタはフォントクラスについて。一応中級編とさせてもらいます。内容的にはcocos2dを踏まえていますが、基本的なビットマップフォントの考え方みたいな感じになりますでしょうか。僕が勝手にこうだと思い込んでいるものなので、いろいろ間違ってたり、効率悪い点などご指摘いただけると幸いです。
cocos2d advent calendarのatnd:http://atnd.org/events/22814
以下本文ですー。
<中級編>cocos2dでオリジナルフォントクラスを作ろうぜ!
●フォントについてあれこれ
ゲームではよく変わったフォントで文字が表示されることが多いですよね。特に昔のゲームなんかはゲームの世界観を表す上でかなり重要なポジションを担っていたと思います。iOSデバイスが出てからはそのスペックに適したゲームとしてレトロ風味のものも多数出ていますが、やはり時代性を表す上でドットで作られたフォントは美味しい要素です。
以下の図は拙作のアプリからですが、上図が等幅フォント、下図はプロポーショナルフォントで日本語を取り扱っています。


cocos2dにはTrueTypeフォントを直接展開してテクスチャ化し使用する文字スプライトクラス(CCLabelTTF)や、ツール(Hiero Bitmap Font ToolやBMFontなど)で事前にテクスチャ化して準備しておき、それを切り出して使用するためのフォントクラス(CCLabelAtlas, CCLabelBMFont)が元々用意されていますが、今のゲームのテイストの場合は良いですが、レトロ風味ということでいうと向いていません。
なぜなら、公開されているツールを使用する場合だと、テクスチャにフォントがアンチエイリアス有りで展開されてしまったりするからですね。まあ、テクスチャの作り方にも依るので一概に向いていないとは言えませんが…。なお、上記の上画像の下の方に表示されている日本語の文章はCCLabelTTFを使用したもので、それ以外の文字はテクスチャからの切り出しです。
あと、日本語のことを考えるともっと向いてない要素があります。基本的にキャラクターコードに従ってテクスチャへ展開するので、無駄な領域が多く必要になってしまうわけです。その点、自前でクラスから作る場合は、トリッキーなことも含めて自分の管理下にあるわけで、仕様から好きに決められて良いというところがあります。
正攻法でいけば、cocos2dのフォントクラスに合うフォントファイルとテクスチャを用意すれば良いですが、それは別の機会にとっておきましょう。正直言うと調べて対応するより自分で作ってしまったほうが早いってのもあります。あと、どうせ作るならcocos2dのフォントプロトコル(CCLabelProtocol)に沿った作りにすればよかったのですが、それに気づいたのは作った後だったので、すみません。以下の例はかなり変則的です。
と、そんな前提がありまして、自前でフォントクラスを用意してみてはどうですか?という例のご紹介です。
サンプルコードはこちらからどうぞ:http://xionchannel.no-ip.org/advent_calendar_cocos2d_day2.zip

●等幅フォントクラスを作ってみよう!
まずは、ドットを打って文字をデザインしていきます。要領はドット絵と同じですね。作りを簡単にするには等幅フォントがいいので、その場合は、格子状に文字を配置しながらデザインしていきます。
フォント用のテクスチャができたら、それを切り出して使用するということになります。フォントクラスを簡単に設計するためには、文字コード順に文字が並んでいると良いです。途中必要ない部分があれば省いてしまっても良いです。省かれた部分のコードの取り扱いはフォントクラスの方で対処すれば良いです。
こんな風に文字コードを元に切り出しCGRectを生成して、CCSpriteを作成するようにします。あとはスプライトを並べていけば文字列の表示が達成できるというものです。等幅フォントの肝はこんな感じになります。簡単ですね。切り出しはもっとスマートにやる方法もありそうですね。汚いソースですみません。
●プロポーショナルフォントクラスを作ってみよう!
レトロ風味から少し高級な印象になりますが、プロポーショナルフォントは見た目に美しいので、それをつくろうとする場合はどうしましょうか。はい。それぞれの文字の幅が異なる可能性があるので、その情報をどこかに持たなければなりません。
まずはフォント用のテクスチャを用意してみましょう。横書き前提とすると、文字の高さは変化せず幅のみ変化することになります。たとえば以下のような感じでテクスチャを作ることになります。なお、縦書き用プロポーショナルフォントとする場合は、幅が変化せず、高さが変化するような作りが良いでしょう。もちろん高さも幅も変化するように作ることも可能ですが、それについては自分で効率良い配置を考えてみてはどうでしょうか。
さて、テクスチャは用意できたとして、切り出しサイズをまとめる必要があります。どのような形式でも良いですが、iOSっぽくplistにいれてみた場合、以下のような感じにできます。データの置き方は自分でわかれば良いので、ほかの並びでも良いと思います。

このデータを元にフォントクラス側でテクスチャを切り出して文字を並べていくことになります。文字コードとの対応は等幅の場合と同じようにしても良いです。以下の例の場合、カタカナも扱いたかったため文字コードを意識しない構造にしました。切り出し情報の中に対応する文字を情報として入れておき、ソース文字列に合致する文字があった場合に切り出して文字を配置するという流れです。処理は文字コードを使用したものよりも重いでしょう。
以下は切り出しの例ですが、先ほどのplistをcharactersというNSDictionaryオブジェクトに読み込んでおきます。キーに対応する文字情報を入れてあるので、キャラクターが入ったNSStringを与えてやれば切り出しサイズが得られるという寸法です。
以上のようにしてオリジナルフォントクラスの基本的な部分が出来ました。切り出し用plistを用意するのは面倒ですけど、その分、切り出し自体は簡単ですね。あとは、サイズに応じて並べるときにずらすドット数もあわせてやれば、プロポーショナルな文字を並べることができますね。
なお、一番最初の例では、カタカナのみ日本語対応していますが、濁点や半濁点を別の文字としてまとめることでキャラクター数を減らしています。なので、表示する際に、濁点や半濁点がある場合は、内部で分割して2文字分として処理して表示するように調整を入れています。昔のファミコンゲームでよく使用している手法ですね。そのために、濁点・半濁点の対応表を作っておいて照らしあわせて処理するようにしています。
●フォントクラス応用編
さあ、ここからがおいしいところですよ。おまけですけど。ゲームに於いて文字で表示されたメニューをタップしたり、文字の内容を変更したり、文字の色が変わったり、一文を与えただけで途中改行されたりというようなよく使う機能があると思います。そのあたりをメソッドやマクロとして組み込んでおくとゲームに使う場合にかなり便利になります。下記はそんな例です。
ここから先は僕も作ってはいませんが、こんなネタもあったらいいんではというものをご紹介。文字がバラバラになって飛んでいくとか、文字が一文字づつカードがめくれるように回転するとか、ピカっと光るとか、シャクトリムシのように伸び縮みするとか、どれもcocos2dの基本機能を使ってアニメーション登録すればいけますが、一文字一文字バラバラに制御する必要があるので、フォントクラスの外側から制御するよりも、フォントクラス内でアニメーションを与えるような作りの方がやりやすいと思います。みなさんもそんな効果をつけてみてはいかがですか?ひと味違った文字表現になって楽しいですよ!
そんなこんなで、フォントについてはここまで!お付き合いありがとうございましたー。
3日目は、@ZuQ9Nnさんです。「cocos2d Advent Calendar 2011 -3日目 波紋のアニメーションやてみた。オッパイぷるるんもあるんだよ!」
cocos2d advent calendarのatnd:http://atnd.org/events/22814
以下本文ですー。
<中級編>cocos2dでオリジナルフォントクラスを作ろうぜ!
●フォントについてあれこれ
ゲームではよく変わったフォントで文字が表示されることが多いですよね。特に昔のゲームなんかはゲームの世界観を表す上でかなり重要なポジションを担っていたと思います。iOSデバイスが出てからはそのスペックに適したゲームとしてレトロ風味のものも多数出ていますが、やはり時代性を表す上でドットで作られたフォントは美味しい要素です。
以下の図は拙作のアプリからですが、上図が等幅フォント、下図はプロポーショナルフォントで日本語を取り扱っています。


cocos2dにはTrueTypeフォントを直接展開してテクスチャ化し使用する文字スプライトクラス(CCLabelTTF)や、ツール(Hiero Bitmap Font ToolやBMFontなど)で事前にテクスチャ化して準備しておき、それを切り出して使用するためのフォントクラス(CCLabelAtlas, CCLabelBMFont)が元々用意されていますが、今のゲームのテイストの場合は良いですが、レトロ風味ということでいうと向いていません。
なぜなら、公開されているツールを使用する場合だと、テクスチャにフォントがアンチエイリアス有りで展開されてしまったりするからですね。まあ、テクスチャの作り方にも依るので一概に向いていないとは言えませんが…。なお、上記の上画像の下の方に表示されている日本語の文章はCCLabelTTFを使用したもので、それ以外の文字はテクスチャからの切り出しです。
あと、日本語のことを考えるともっと向いてない要素があります。基本的にキャラクターコードに従ってテクスチャへ展開するので、無駄な領域が多く必要になってしまうわけです。その点、自前でクラスから作る場合は、トリッキーなことも含めて自分の管理下にあるわけで、仕様から好きに決められて良いというところがあります。
正攻法でいけば、cocos2dのフォントクラスに合うフォントファイルとテクスチャを用意すれば良いですが、それは別の機会にとっておきましょう。正直言うと調べて対応するより自分で作ってしまったほうが早いってのもあります。あと、どうせ作るならcocos2dのフォントプロトコル(CCLabelProtocol)に沿った作りにすればよかったのですが、それに気づいたのは作った後だったので、すみません。以下の例はかなり変則的です。
と、そんな前提がありまして、自前でフォントクラスを用意してみてはどうですか?という例のご紹介です。
サンプルコードはこちらからどうぞ:http://xionchannel.no-ip.org/advent_calendar_cocos2d_day2.zip

●等幅フォントクラスを作ってみよう!
まずは、ドットを打って文字をデザインしていきます。要領はドット絵と同じですね。作りを簡単にするには等幅フォントがいいので、その場合は、格子状に文字を配置しながらデザインしていきます。フォント用のテクスチャができたら、それを切り出して使用するということになります。フォントクラスを簡単に設計するためには、文字コード順に文字が並んでいると良いです。途中必要ない部分があれば省いてしまっても良いです。省かれた部分のコードの取り扱いはフォントクラスの方で対処すれば良いです。
//指定のキャラクターのCGRectを返す
- (CGRect)getRectWithASCII:(char)ascii {
char c;
if (ascii>='0' && ascii<='9') {
c = ascii-'0';
}
else if (ascii>='A' && ascii<='Z') {
c = ascii-'A'+10;
}
else if (ascii=='!') { //!
c = ('Z'-'A'+10)+1;
}
<中略>
else {
c = ('Z'-'A'+10)+8; //スペースに置き換える
}
return CGRectMake(8*(c%8), 8*(c/8), 8, 8);
}
こんな風に文字コードを元に切り出しCGRectを生成して、CCSpriteを作成するようにします。あとはスプライトを並べていけば文字列の表示が達成できるというものです。等幅フォントの肝はこんな感じになります。簡単ですね。切り出しはもっとスマートにやる方法もありそうですね。汚いソースですみません。
●プロポーショナルフォントクラスを作ってみよう!
レトロ風味から少し高級な印象になりますが、プロポーショナルフォントは見た目に美しいので、それをつくろうとする場合はどうしましょうか。はい。それぞれの文字の幅が異なる可能性があるので、その情報をどこかに持たなければなりません。まずはフォント用のテクスチャを用意してみましょう。横書き前提とすると、文字の高さは変化せず幅のみ変化することになります。たとえば以下のような感じでテクスチャを作ることになります。なお、縦書き用プロポーショナルフォントとする場合は、幅が変化せず、高さが変化するような作りが良いでしょう。もちろん高さも幅も変化するように作ることも可能ですが、それについては自分で効率良い配置を考えてみてはどうでしょうか。
さて、テクスチャは用意できたとして、切り出しサイズをまとめる必要があります。どのような形式でも良いですが、iOSっぽくplistにいれてみた場合、以下のような感じにできます。データの置き方は自分でわかれば良いので、ほかの並びでも良いと思います。

このデータを元にフォントクラス側でテクスチャを切り出して文字を並べていくことになります。文字コードとの対応は等幅の場合と同じようにしても良いです。以下の例の場合、カタカナも扱いたかったため文字コードを意識しない構造にしました。切り出し情報の中に対応する文字を情報として入れておき、ソース文字列に合致する文字があった場合に切り出して文字を配置するという流れです。処理は文字コードを使用したものよりも重いでしょう。
以下は切り出しの例ですが、先ほどのplistをcharactersというNSDictionaryオブジェクトに読み込んでおきます。キーに対応する文字情報を入れてあるので、キャラクターが入ったNSStringを与えてやれば切り出しサイズが得られるという寸法です。
//指定のキャラクターのCGRectを返す
- (CGRect)getRectWithString:(NSString*)s {
NSArray *rect = [characters objectForKey:s];
if (rect) {
float x = [[rect objectAtIndex:0] intValue];
float y = [[rect objectAtIndex:1] intValue];
float width = [[rect objectAtIndex:2] intValue];
float height = [[rect objectAtIndex:3] intValue];
return CGRectMake(x, y, width, height);
}
else {
return CGRectZero;
}
}
以上のようにしてオリジナルフォントクラスの基本的な部分が出来ました。切り出し用plistを用意するのは面倒ですけど、その分、切り出し自体は簡単ですね。あとは、サイズに応じて並べるときにずらすドット数もあわせてやれば、プロポーショナルな文字を並べることができますね。
なお、一番最初の例では、カタカナのみ日本語対応していますが、濁点や半濁点を別の文字としてまとめることでキャラクター数を減らしています。なので、表示する際に、濁点や半濁点がある場合は、内部で分割して2文字分として処理して表示するように調整を入れています。昔のファミコンゲームでよく使用している手法ですね。そのために、濁点・半濁点の対応表を作っておいて照らしあわせて処理するようにしています。
//文字スプライトの初期化(private)
- (CCSprite*) __makeCharacterSpriteFrame:(CCSpriteFrame*)f
string:(NSString*)c
position:(CGPoint*)pos
isShadow:(BOOL)isShadow
{
CCSprite *s = [CCSprite spriteWithSpriteFrame:f];
[s.texture setAliasTexParameters];
s.anchorPoint = ccp(0,0);
s.scale = 2.0f;
if (![c compare:@"゛"] || ![c compare:@"゜"]) { //濁点・半濁点
s.position = ccp(pos->x -4*2, pos->y +8*2);
}
else {
s.position = *pos;
if (!isShadow) pos->x += s.contentSize.width*2;
}
return s;
}
//カタカナの濁点等を分解する(private)
- (NSString*) __correctString:(NSString*)string {
NSMutableString *ret = [NSMutableString string];
for (int i=0; i < string.length; i++) {
NSString *c = [string substringWithRange:
NSMakeRange(i, 1)];
NSString *replace;
if ((replace = [self.dakuten objectForKey:c])) {
//濁点の差し替えがあれば差し替える
[ret appendString:replace];
}
else {
[ret appendString:c];
}
}
return ret;
}
●フォントクラス応用編
さあ、ここからがおいしいところですよ。おまけですけど。ゲームに於いて文字で表示されたメニューをタップしたり、文字の内容を変更したり、文字の色が変わったり、一文を与えただけで途中改行されたりというようなよく使う機能があると思います。そのあたりをメソッドやマクロとして組み込んでおくとゲームに使う場合にかなり便利になります。下記はそんな例です。
ここから先は僕も作ってはいませんが、こんなネタもあったらいいんではというものをご紹介。文字がバラバラになって飛んでいくとか、文字が一文字づつカードがめくれるように回転するとか、ピカっと光るとか、シャクトリムシのように伸び縮みするとか、どれもcocos2dの基本機能を使ってアニメーション登録すればいけますが、一文字一文字バラバラに制御する必要があるので、フォントクラスの外側から制御するよりも、フォントクラス内でアニメーションを与えるような作りの方がやりやすいと思います。みなさんもそんな効果をつけてみてはいかがですか?ひと味違った文字表現になって楽しいですよ!
そんなこんなで、フォントについてはここまで!お付き合いありがとうございましたー。
3日目は、@ZuQ9Nnさんです。「cocos2d Advent Calendar 2011 -3日目 波紋のアニメーションやてみた。オッパイぷるるんもあるんだよ!」
2011/09/23
cocos2d for iPhone レッスンノート レビュー

@hkato193さんから献本いただきまして、じっくり読ませて頂きました。
ありがとうございます。非常に光栄です!
そうです。昨日発売になりましたcocos2d日本語本2冊目の「cocos2d for iPhone レッスンノート」です!
いいですよー。これ。読んで実践するには多少は基本的なObjective-Cに触れていることが必要かと思いますが、iOSアプリの開発経験はなくともcocos2dを利用したゲームやアプリの開発、それをAppStoreへ申請するまでの流れをひと通り学習できます。
というわけで入門者に向けた本ではあるのですが、iOSアプリの開発初心者もそうですが、ゲーム開発初心者にも役に立ちそうです。というのも、ゲームを作る上での基本的な考え方や組み方についても丁寧な解説がされているからですね。
さて、僕はというと、cocos2dで2本ほどゲームアプリを開発したことがあります。その上で恐縮ながらコメントさせていただくと、1本作った程度の経験の方はいろいろと目からウロコが落ちる部分があるかと思います。特に、昔国民機が流行った頃にゲームを作ったきりなんて方にはcocos2dが推奨する組み方が今ひとつ馴染めずに、メインのCCLayer内に作ったメインループで全オブジェクトの処理を回すということをしてしまうので、この本の中盤に解説されているシューティングゲーム作成の項はなかなか理解を助けます。
やはり、ゲーム全体のフレーム落ちを避ける等を考慮したり、あるいはcocos2dの特徴でもあるCCAction系を活かすとなると個々のオブジェクトに自律的な制御を入れて、イベント駆動的な扱いでゲームを構築する方法が推奨されていそうですから。とはいえ、僕はそういう作りでは情報の更新タイミングがつかみにくいと思ってメインループ方式で組んでしまったりしているわけですが…。
cocos2dの猛者のような方にも、巻末のAppendixは必見です。
列挙しますと、イージングを実現するアクション一覧、つまりEaseという名称が使われているCCAction群です。これがどのようなアニメーション変化を与えるのかについて図示されているため、非常に資料価値があります。これって探しても無いんですよね。
CCParticleSystemのパラメーター。そうです。パラメーターの意味が日本語で解説されているんですよ。いいでしょう。その他パーティクル関連の細かい情報がまとめられています。
CocosDenshionについて。これについては、高度な使い方を使用とするといずれはOpenALを触らざるを得なくなるので、上級者は特に読まなくてもいいかもしれませんが、どういう構造になっているのか見ておくのも良いかも。
それから、開発に必要な各種情報源がまとめられていますので、困ったときに紐解いてみるといいかも。でも、本当に困ったら@hkato193さんや@Seasonsさんに聞くのが良いかもですねw てへw
以上が率直な感想です。
なので、入門者は買い!そして上級者はAppendixを見て買いたくなるよきっとw
と、ここまで書いてHungryMasterの開発について細かい記事を書きたくなって来ました。
おいおい発想から完成までを流れに沿って記事にしてみようかな。cocos2dにも触れるよ。
ではでは。
2011/08/01
さいたまiPhone勉強会で発表しました!
@yoichinejiさん主催で先日開かれた「さいたまiPhone勉強会」の第一回に発表者として参加してきました。当日の演目は以下のとおりですが、期せずして2Dゲーム系フレームワークが集まった形でかなり豪華な内容だったなぁと思います。僕の発表した内容はまぁ置いといてw
会場は蕨(わらび)の駅から10分くらいの商工会議所。なかなか広くて良い会場でしたよ。思ったよりも遠くて荷物多い人には大変だったかもですけど。
・@Seasonsさん:IMPACT入門
・@ajinotataki:cocos2d事例編 HungryMasterの実装から
・@corosuke_kさん:Coronaで始めるiPhoneアプリ開発
・@yoichinejiさん:○○○とおまけてきなもの
発表リストはこんなでした。
●IMPACT(@Seasonsさんの発表より)
javascriptとHTML5でゲームをつくろうっていうフレームワークは数あれど、iOSでの実行まで考慮したものはなかなか無いのが実情。IMPACTはiOSでは描画系関数がOpenGLESでの動作に置き換えられていることで高速に動作することが特徴ですね。一部の設定やメソッド変更でほぼそのままiOSで動作させられるという点はすごいの一言。
ライセンスが$99買い切りで、iOS用の環境も手に入るってのはいいですねー。1本出せば元取れますね。レベルエディタもついてくるって言うからなかなかいい気がします。WEBのこと考えないならcocos2dには到底かないませんが良い選択肢になりそう。
難点があるとすれば解説や資料が英語ですら極端に少ないことと、体験版が無いことのようですね。
あとは、作者の方の更新スピードがちょっと最近芳しくないとか…。
当日のスライドは後日公開となるそうなのでここではお見せできません><
●Corona(@corosuke_kさんの発表より)
iOSとAndroidでの動作を目的に2Dゲームを作成するフレームワーク。体験版では最新バージョンで無いことと、ストア用のビルドができないことくらいで、テスト用に手持ちの実機への転送はできるようです。描画系はOpenGLで行われ、動作スピードは30〜60FPS出るのでスペック的に問題はないらしいですが、日本では食わず嫌いの人が多いとのこと。
紹介を見るとなるべくソースを書かずにロジック部分に集中するために作られているそうで、Luaを使って記述します。なんと物理演算エンジンは非常に簡単に利用可能で、AngryBirdのクローンは2日で実装できたとか!まじか!
ライセンスはiOS版は$199/年と少しお高い。Luaを覚えるっていうのもちょっと僕には敷居が高く感じてしまった。
当日のスライドはこちら
●yoichinejiさんの発表より
いろいろと多岐に渡った発表をされてました。もはやiPhone勉強会というよりもスマートフォン勉強会!
こちらもスライドの公開はないのが残念ですが、cocos2dからはじまって、Windows Phone 7の開発環境の紹介、GameSaladまで!
GameSaladは正直僕には馴染めそうもないのですが、文字でコーディングするのに抵抗がある方にはおすすめなのかも…。見た感じFlashというよりもMacromedia Directorに感覚は近いのかもしれませんね。しかもLingoで記述しなくてもコンポーネントを載っけて設定していけばロジックが組めるという。とはいえ、文字を使ってコーディングすることに慣れている人からすると回りくどく感じる部分もありそうなので、メンテやリファクタリングなどに難がありそうな…。このあたりはjavascriptなどのスクリプトを使用するフレームワークにも心配なところ。良いエディタや統合環境がないとうまくやれそうもないっす…。
●cocos2dとHungryMasterについて(私の発表より)
私はというと、先日リリースしたHungryMasterを作った経験からcocos2dの使用の実例を紹介するようなものを行いました。前提をすっ飛ばしていきなり応用というか実例紹介だったので、cocos2dで多少なりとも何かを作ったことがある人じゃないとピンと来ない内容だったので、ついてこれなかった方すみません。誰得ですよね。
cocos2dの理念的なものを理解するのに自分は少し時間がかかりまして、最初に作ったElectroMasterではかなり勘違いした使い方になっておりました。そのあたりは以前のスライドと見比べてもらえると良いかも?いやわからないかもですけど。
cocos2dはメインループで配列を回して各オブジェクトに対して毎回何かを指示するという作り方ではなく、それぞれのオブジェクトに状態更新用のメソッドを登録しておいて、勝手に更新されることでゲームが進行していくという作り方をします。ってのに気づくのに時間がかかりました。この部分については以前西東京iPhone開発者勉強会で発表させてもらいました。
今回はというと、そこから1歩進めて、cocos2dで開発する上で不満になる部分やこうやりたいよねという部分について自分なりの回答を紹介するようなものでしたので、cocos2dに不満がある方はぜひスライドを見てもらえると良いかと思います。サンプルコードも公開しておりますので、面白いかと。ではー。
あ、そうそう。iCadeを手に入れましたので、そのあたりについても触れましたw 現在配信中のHungryMaster ver1.13ではiCadeで操作することができますよ!
サンプルコードはこちら
当日のスライドはこちら

●まとめ
当日のつぶやきのまとめがtogetterに作られておりますので、合わせて御覧ください。
会場は蕨(わらび)の駅から10分くらいの商工会議所。なかなか広くて良い会場でしたよ。思ったよりも遠くて荷物多い人には大変だったかもですけど。
・@Seasonsさん:IMPACT入門
・@ajinotataki:cocos2d事例編 HungryMasterの実装から
・@corosuke_kさん:Coronaで始めるiPhoneアプリ開発
・@yoichinejiさん:○○○とおまけてきなもの
発表リストはこんなでした。
●IMPACT(@Seasonsさんの発表より)
javascriptとHTML5でゲームをつくろうっていうフレームワークは数あれど、iOSでの実行まで考慮したものはなかなか無いのが実情。IMPACTはiOSでは描画系関数がOpenGLESでの動作に置き換えられていることで高速に動作することが特徴ですね。一部の設定やメソッド変更でほぼそのままiOSで動作させられるという点はすごいの一言。
ライセンスが$99買い切りで、iOS用の環境も手に入るってのはいいですねー。1本出せば元取れますね。レベルエディタもついてくるって言うからなかなかいい気がします。WEBのこと考えないならcocos2dには到底かないませんが良い選択肢になりそう。
難点があるとすれば解説や資料が英語ですら極端に少ないことと、体験版が無いことのようですね。
あとは、作者の方の更新スピードがちょっと最近芳しくないとか…。
当日のスライドは後日公開となるそうなのでここではお見せできません><
●Corona(@corosuke_kさんの発表より)
iOSとAndroidでの動作を目的に2Dゲームを作成するフレームワーク。体験版では最新バージョンで無いことと、ストア用のビルドができないことくらいで、テスト用に手持ちの実機への転送はできるようです。描画系はOpenGLで行われ、動作スピードは30〜60FPS出るのでスペック的に問題はないらしいですが、日本では食わず嫌いの人が多いとのこと。
紹介を見るとなるべくソースを書かずにロジック部分に集中するために作られているそうで、Luaを使って記述します。なんと物理演算エンジンは非常に簡単に利用可能で、AngryBirdのクローンは2日で実装できたとか!まじか!
ライセンスはiOS版は$199/年と少しお高い。Luaを覚えるっていうのもちょっと僕には敷居が高く感じてしまった。
当日のスライドはこちら
●yoichinejiさんの発表より
いろいろと多岐に渡った発表をされてました。もはやiPhone勉強会というよりもスマートフォン勉強会!
こちらもスライドの公開はないのが残念ですが、cocos2dからはじまって、Windows Phone 7の開発環境の紹介、GameSaladまで!
GameSaladは正直僕には馴染めそうもないのですが、文字でコーディングするのに抵抗がある方にはおすすめなのかも…。見た感じFlashというよりもMacromedia Directorに感覚は近いのかもしれませんね。しかもLingoで記述しなくてもコンポーネントを載っけて設定していけばロジックが組めるという。とはいえ、文字を使ってコーディングすることに慣れている人からすると回りくどく感じる部分もありそうなので、メンテやリファクタリングなどに難がありそうな…。このあたりはjavascriptなどのスクリプトを使用するフレームワークにも心配なところ。良いエディタや統合環境がないとうまくやれそうもないっす…。
●cocos2dとHungryMasterについて(私の発表より)
私はというと、先日リリースしたHungryMasterを作った経験からcocos2dの使用の実例を紹介するようなものを行いました。前提をすっ飛ばしていきなり応用というか実例紹介だったので、cocos2dで多少なりとも何かを作ったことがある人じゃないとピンと来ない内容だったので、ついてこれなかった方すみません。誰得ですよね。
cocos2dの理念的なものを理解するのに自分は少し時間がかかりまして、最初に作ったElectroMasterではかなり勘違いした使い方になっておりました。そのあたりは以前のスライドと見比べてもらえると良いかも?いやわからないかもですけど。
cocos2dはメインループで配列を回して各オブジェクトに対して毎回何かを指示するという作り方ではなく、それぞれのオブジェクトに状態更新用のメソッドを登録しておいて、勝手に更新されることでゲームが進行していくという作り方をします。ってのに気づくのに時間がかかりました。この部分については以前西東京iPhone開発者勉強会で発表させてもらいました。
今回はというと、そこから1歩進めて、cocos2dで開発する上で不満になる部分やこうやりたいよねという部分について自分なりの回答を紹介するようなものでしたので、cocos2dに不満がある方はぜひスライドを見てもらえると良いかと思います。サンプルコードも公開しておりますので、面白いかと。ではー。
あ、そうそう。iCadeを手に入れましたので、そのあたりについても触れましたw 現在配信中のHungryMaster ver1.13ではiCadeで操作することができますよ!
サンプルコードはこちら
当日のスライドはこちら

●まとめ
当日のつぶやきのまとめがtogetterに作られておりますので、合わせて御覧ください。
2011/07/01
新作予告その2!HungryMaster
今審査中なんでもうじきだと思うのですが…。
予告動画その2をアップしました。
今度は歌付きだよ!
とはいえ歌はゲームには含まれません。
あとで公式サイトでダウンロードできるようにします!
公式サイトはこちら:http://xionchannel.no-ip.org/hm/
あと数日だと思うので、しばしのお待ちを!
デリカ「絶対買いなさいよね!」
てへ。
予告動画その2をアップしました。
今度は歌付きだよ!
とはいえ歌はゲームには含まれません。
あとで公式サイトでダウンロードできるようにします!
公式サイトはこちら:http://xionchannel.no-ip.org/hm/
あと数日だと思うので、しばしのお待ちを!
デリカ「絶対買いなさいよね!」
てへ。
2011/06/25
pngSplitterビルド版アップしました

wxPythonのままだと実行するのが大変だと思うので、py2appでスタンドアローンにビルドしたものをアップしました。
これで、wxPythonを入れなくても使えるはずです。あと、マニュアルというか多少の解説付けました。
今回もソースとかついてます。
ダウンロード:25MBくらいあります
2011/05/02
西東京iPhoneDev勉強会第5回に参加しました
4/30西東京iPhoneDev勉強会第5回に参加しました。
前回に引き続き発表者になったわけですが、今回のネタはcocos2dです。
最近新作アプリを開発中で、それで作ってるうちにいろいろと分かったことがありましたので、そのあたりをまとめて発表という感じになりました。
題して「cocos2d実践編」
スライドはこちら。
サンプルコードはこちら。
主にゲームを作る上でこういうことやりたいよねって言う部分を実例で解説的な感じです。
会場での質問では「ゲームではよくタスクシステムが使われると思いますけど、cocos2dにはありますか?」てのが出ましたけど、基本的には無いという感じでしょうか。CCNodeにはscheduleメソッドで毎フレーム(あるいは指定間隔で)実行して欲しい関数を登録することが出来ますが、これは直接タスクシステムにはなりませんし。というか、そもそも自分がタスクシステムを使ったことがないので、ズバリどういうものがそれなのかわからないってのがアレですね。誰か教えてください。
今回は試験的にUStreamでの配信も行われたので、発表の映像とかが下記にアップされてます。回線状況が悪かったらしく一部途切れているそうですけど、興味が有る方は見て見てはいかがでしょうか。
●UStream
http://www.ustream.tv/recorded/14370281
http://www.ustream.tv/recorded/14370519
http://www.ustream.tv/recorded/14370967
http://www.ustream.tv/recorded/14370982
http://www.ustream.tv/recorded/14371244
http://www.ustream.tv/recorded/14372212
http://www.ustream.tv/recorded/14372851
http://www.ustream.tv/recorded/14373371
あと、当日ツイートまとめはtogetterでこちらにまとまってます。
●togetter - 2011/4/30 #wtidev 西東京iPhoneDev勉強会 〜第5回〜
発表者は僕の他に、以下のとおりでした。
@yoichinejiさん
「openframeworksとおまけてきなもの」
kinectとか色々面白かったです。
@tmokitaさん
「xAuthTwitterEngineとASIHTTPRequestを使ったTwitPic投稿」
アプリからxAuth使うときに参考になると思いました。
@k_katsumiさん
「iPhoneで高速に全文検索」
膨大なテキストでの検索が超スピードで帰ってきてびっくりでした。
以上ですー。
前回に引き続き発表者になったわけですが、今回のネタはcocos2dです。
最近新作アプリを開発中で、それで作ってるうちにいろいろと分かったことがありましたので、そのあたりをまとめて発表という感じになりました。
題して「cocos2d実践編」
スライドはこちら。
サンプルコードはこちら。
主にゲームを作る上でこういうことやりたいよねって言う部分を実例で解説的な感じです。
会場での質問では「ゲームではよくタスクシステムが使われると思いますけど、cocos2dにはありますか?」てのが出ましたけど、基本的には無いという感じでしょうか。CCNodeにはscheduleメソッドで毎フレーム(あるいは指定間隔で)実行して欲しい関数を登録することが出来ますが、これは直接タスクシステムにはなりませんし。というか、そもそも自分がタスクシステムを使ったことがないので、ズバリどういうものがそれなのかわからないってのがアレですね。誰か教えてください。
今回は試験的にUStreamでの配信も行われたので、発表の映像とかが下記にアップされてます。回線状況が悪かったらしく一部途切れているそうですけど、興味が有る方は見て見てはいかがでしょうか。
●UStream
http://www.ustream.tv/recorded/14370281
http://www.ustream.tv/recorded/14370519
http://www.ustream.tv/recorded/14370967
http://www.ustream.tv/recorded/14370982
http://www.ustream.tv/recorded/14371244
http://www.ustream.tv/recorded/14372212
http://www.ustream.tv/recorded/14372851
http://www.ustream.tv/recorded/14373371
あと、当日ツイートまとめはtogetterでこちらにまとまってます。
●togetter - 2011/4/30 #wtidev 西東京iPhoneDev勉強会 〜第5回〜
発表者は僕の他に、以下のとおりでした。
@yoichinejiさん
「openframeworksとおまけてきなもの」
kinectとか色々面白かったです。
@tmokitaさん
「xAuthTwitterEngineとASIHTTPRequestを使ったTwitPic投稿」
アプリからxAuth使うときに参考になると思いました。
@k_katsumiさん
「iPhoneで高速に全文検索」
膨大なテキストでの検索が超スピードで帰ってきてびっくりでした。
以上ですー。
2011/04/29
cocos2dでスクロールするレイヤーを作りました
いわゆるUIScrollViewみたいなやつです。
でもメソッドの命名とかはかなり自分勝手にやってるから使いづらいかもですけど。
CCScrollLayer.zip←ここからダウンロードできます
これ単体で使うには、以下のようにします。
と、これでタッチイベントを検出してスクロールします。
上のソースでは縦に0から1024までの座標でスクロール可能です。
2行目を
のようにすれば縦横にスクロールします。
デフォルトでは縦スクロールが可能になるようにセットされているので、
横だけのスクロールにするんであれば、設定を変えてください。
とまあこんな感じです。
でもメソッドの命名とかはかなり自分勝手にやってるから使いづらいかもですけど。
CCScrollLayer.zip←ここからダウンロードできます
これ単体で使うには、以下のようにします。
CCScrollLayer *layer = [CCScrollLayer node];
[layer setScrollAreaWithMinPosition:ccp(0,0) maxPosition:ccp(0,1024)];
[layer schedule:@selector(moveScroll)];
と、これでタッチイベントを検出してスクロールします。
上のソースでは縦に0から1024までの座標でスクロール可能です。
2行目を
[layer setScrollAreaWithMinPosition:ccp(0,0) maxPosition:ccp(1024,1024)];
[layer setHorizontalScrollEnable:YES];
のようにすれば縦横にスクロールします。
デフォルトでは縦スクロールが可能になるようにセットされているので、
横だけのスクロールにするんであれば、設定を変えてください。
[layer setScrollAreaWithMinPosition:ccp(0,0) maxPosition:ccp(1024,0)];
[layer setHorizontalScrollEnable:YES];
[layer setVerticalScrollEnable:NO];
とまあこんな感じです。
2011/04/06
pngSplitter修正しました

全角の要素名が対応してなかったので、バグ修正しました。
あと、ドラッグ&ドロップとかに地味に対応。
アイコンの位置も使いやすいように位置を変更。
などなど。
ダウンロード:pngSplitter.zip (要wxPython)
pngSplitterを作りました

cocos2dで複数のフレームを1枚のテクスチャに描いたりしてると、再配置したくなったり使用する際の切り出し座標を知りたくなったりなどいろいろ苦労すると思いますが、再配置はTexture Packerという便利なツールがあるのでいいんですけど、ドット絵を描く時は色とか揃えたりするのにそのキャラの全パターンが1枚になってたほうが便利だったりとかありますよね。
で、このツールなんですが、たとえばフォントテクスチャをプロポーショナルで作ったときの切り出し用のPLISTが欲しい時に使えます。
あと、キャラのパターンを1枚で描いてたけど最終的にTexture Packerでまとめ直したい場合にも使えます。これで切り出しの枠を設定しておいて、バラのPNGを吐き出せばOK。
てな感じのツールです。
pythonの勉強を兼ねて作りました。
使用するには、pythonとwxPythonが必要なので、インストールしてくださいな。
ではでは。
pngSplitterをダウンロードする(ソース付きだよ)
2011/04/02
cocos2dのvertexZパラメータでソートしたい
cocos2dのCCSpriteを多数表示して、Y座標によって奥から手前へのソートを行うことで以下のような表示をする場合に、

簡単に行うには、CCSpriteクラスの中のupdateメソッドなどで現在のY座標を元にソートしなおすことを繰り返すと良いのですが。
たとえば、以下のようなコードですね。
-(void)update:(ccTime)delta {
[self.parent reorderChild:self z:-position.y];
}
これでは結構処理が無駄になるのではないかと心配になりますよね。
で、vertexZプロパティを使うとOpenGLのZバッファを参照して前後比較をして描画してもらえるので、それを使って処理を軽くしたいと思います。
こんな感じです。
-(void)update:(ccTime)delta {
self.vertexZ = -position.y;
}
こうすると、前後比較は正しくなるのですが、キャラクターの透明部分までZバッファに描かれてしまって四角い枠が見えるようなおかしな描画になってしまいます。
そこで、さらに以下のメソッドをオーバーライドといい感じになります。(ALPHA_TESTで透明部分はそもそも描画しないということを行ってキャラの絵が描かれている部分のみZ値を書きこむようにするということです)
-(void)draw {
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0.0f);
[super draw];
glDisable(GL_ALPHA_TEST);
}
これで万事解決ですね。
と思いますよね。
でも、さらに高速化しようとしてCCSpriteBatchNodeを使い始めると、上記のCCSpriteに設定したdrawメソッドが呼ばれなくなるために、せっかく設定したALPHA_TESTが無効化されてしまいます。
その場合は、CCSpriteBatchNodeの方のdrawをオーバーライドしましょう。
こんな感じです。(CCSpriteBatchNodeのdrawはDEPTH_TESTがデフォルトで無効になっているので、その設定も追加しています)
-(void)draw {
glEnable(GL_DEPTH_TEST);
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0.0f);
[super draw];
glDisable(GL_ALPHA_TEST);
glDisable(GL_DEPTH_TEST);
}
以上で楽しいcocos2dライフを送りましょうー。
簡単に行うには、CCSpriteクラスの中のupdateメソッドなどで現在のY座標を元にソートしなおすことを繰り返すと良いのですが。
たとえば、以下のようなコードですね。
-(void)update:(ccTime)delta {
[self.parent reorderChild:self z:-position.y];
}
これでは結構処理が無駄になるのではないかと心配になりますよね。
で、vertexZプロパティを使うとOpenGLのZバッファを参照して前後比較をして描画してもらえるので、それを使って処理を軽くしたいと思います。
こんな感じです。
-(void)update:(ccTime)delta {
self.vertexZ = -position.y;
}
こうすると、前後比較は正しくなるのですが、キャラクターの透明部分までZバッファに描かれてしまって四角い枠が見えるようなおかしな描画になってしまいます。
そこで、さらに以下のメソッドをオーバーライドといい感じになります。(ALPHA_TESTで透明部分はそもそも描画しないということを行ってキャラの絵が描かれている部分のみZ値を書きこむようにするということです)
-(void)draw {
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0.0f);
[super draw];
glDisable(GL_ALPHA_TEST);
}
これで万事解決ですね。
と思いますよね。
でも、さらに高速化しようとしてCCSpriteBatchNodeを使い始めると、上記のCCSpriteに設定したdrawメソッドが呼ばれなくなるために、せっかく設定したALPHA_TESTが無効化されてしまいます。
その場合は、CCSpriteBatchNodeの方のdrawをオーバーライドしましょう。
こんな感じです。(CCSpriteBatchNodeのdrawはDEPTH_TESTがデフォルトで無効になっているので、その設定も追加しています)
-(void)draw {
glEnable(GL_DEPTH_TEST);
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0.0f);
[super draw];
glDisable(GL_ALPHA_TEST);
glDisable(GL_DEPTH_TEST);
}
以上で楽しいcocos2dライフを送りましょうー。
cocos2dでマルチタッチを取得するには
cocos2dで用意されているCCLayerには以下のようなタッチイベントを有効化するためのメソッドが用意されていますが、マルチタッチをビューに対して有効にするか否かの設定はこれでは行えません。
[self setIsTouchEnabled:YES];
そんなわけで、以下のようにcocos2dのEAGLViewが乗っているウインドウかビューに対して、マルチタッチ有効化を宣言する必要があります。
[window setMultipleTouchEnabled:YES];
あるいは
[glView setMultipleTouchEnabled:YES];
などです。
これで、ccTouchesBeganなどでマルチタッチを取得できるようになりますが、この後少し注意が必要です。
たとえばタイトル画面や他の画面などで画面をタッチすると次のシーンへ移行するというような仕組みになっていた場合に、シングルタッチの場合は速度的に連打してもシーンの移り変わりの再コール行われた場合にほぼ問題なく次のシーンへ移行できるのですが、マルチタッチの場合は連打の間隔が極端に短く取得されることもありえますので、シーン移行中の場合は再コールされても応答しないようなコードを追加しておかないとシーンの移行が正しく終わらないうちに次への移行が呼ばれたりして落ちる場合があります。
[self setIsTouchEnabled:YES];
そんなわけで、以下のようにcocos2dのEAGLViewが乗っているウインドウかビューに対して、マルチタッチ有効化を宣言する必要があります。
[window setMultipleTouchEnabled:YES];
あるいは
[glView setMultipleTouchEnabled:YES];
などです。
これで、ccTouchesBeganなどでマルチタッチを取得できるようになりますが、この後少し注意が必要です。
たとえばタイトル画面や他の画面などで画面をタッチすると次のシーンへ移行するというような仕組みになっていた場合に、シングルタッチの場合は速度的に連打してもシーンの移り変わりの再コール行われた場合にほぼ問題なく次のシーンへ移行できるのですが、マルチタッチの場合は連打の間隔が極端に短く取得されることもありえますので、シーン移行中の場合は再コールされても応答しないようなコードを追加しておかないとシーンの移行が正しく終わらないうちに次への移行が呼ばれたりして落ちる場合があります。
登録:
投稿 (Atom)


