× [PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。 |
cocos2d-xにおいては、すべてのクラスは
cocos2d::Ref の子孫クラスである。 Refクラスは、参照カウンタを扱っている。 Refクラスのautorelease()メソッドを呼んでおくと、 Refとその子孫クラスのインスタンスを生成したとき、破棄処理を自分でしなくても ゲームのメインループが来たときに自動で破棄してくれる。 CCRef.cpp
CCDirector.cpp
CCAutoReleasePool.cpp
CCRef.cpp
CCAutoReleasePool.cppを見るとわかるが、_managedObjectArrayに格納されているすべてのobjectに対してrelease()を実行している。 ずいぶん潔いやり方だ。生成しても放っておいてよい、というか放っておかなくてはいけない。自分でrelease()とか呼ぶと却ってバグる。 その使い方についてはCCRef.cppのrelase()メソッド内に詳しく書いてある。 一言で言うと new/retain() と autorelease()/release() を対で呼び出さなければならない。 ということだ。 生成時にnewが呼ばれる。 cocos的には、Node::create()やSprite::create()などのように、static関数のcreate()メソッドが相当。create()の中でnewをしている。 例としてNode::create()を見てみると
となっている。 createの中で new と autorelease() を両方やっている。 それ以外にも、retain()を呼ぶならrelease()かautorelease()をどこかで呼んでおく。 対で呼び出されるようになっていれば、メモリリークは起こらない。 autorelease()は複数回呼び出しても問題ないようだ。autoreleasePoolに2回登録されるので、2回releaseが走る。 なお、Nodeインスタンスの場合、別のNodeの子になる(addChild)と参照カウンタが1増える。
これは、parentNodeのメンバ変数 Vector<Node*> _children; に追加されるから。 cocos2d-xのVectorクラスは、pushBack(またはinsert,replace)したときにretain()を呼ぶようになっている。 このため、addChildされた子ノードは破棄されずに残る。 PR |
cocosでアニメーション作成する
以下は、立っている絵から歩きアニメーションを再生するところ。
standSpriteは、アニメーションを再生しなければ単なるスプライト。 アニメーション(この場合スプライトアニメーション)を再生することで、立ち絵のスプライトが歩きスプライトのアニメーションに変わる。 setRestoreOriginalFrame(true) を指定していると、アニメーションが終了したときに元のスプライト(立ち絵の表示)に戻る。ただしここではRepeatForeverアニメーションなので、終了することがないので設定が無意味だが。 |
なんで2.2か、という話でもあるが。
まずAndroidの環境設定(これ書くの何回目?) 参考 まずandroidとeclipseダウンロード 公式からダウンロード 展開。この時点でeclipseは起動する。 次にNDKインストール。 公式からダウンロード これ、このままだと展開できない。 $ chmod a+x android-ndk-r10c-darwin-x86_64.bin $ ./android-ndk-r10c-darwin-x86_64.bin とすると展開できる。 android-ndk-r10c/ のようなディレクトリができるので、どっかに置いておく。 ここまででandroidは終了 cocosのインストールを行う(割愛) 以下のシェルスクリプトを実行 $ PROJ_NAME/cocos2d-x-2.2.4/projects/PROJ_NAME/proj.android/build_native.sh これをすると、 proj.android/libs/armeabi/libcocos2dcpp.so というライブラリが生成される。 これがないと、C++ネイティブのcocosの機能が使えないので。 ちなみにこれをロードするには、 MainActivity.javaに以下のように記述する。
ここまでやったら、eclipseを起動する。 該当のプロジェクトを開く。 File->New->Other->Android->Android Project from Existing Code->Next ブラウザからディレクトリ指定。 プロジェクトが開くのを確認。 さらに、cocos2dxのプロジェクトも開く。 該当のプロジェクトから、プロパティを開き、Androidタブを開く。 ライブラリの設定が外れていると思うので、再度設定。 |
cocosでスクロールビューを使う方法。
ここが詳しい スクロールは設定が少し多いので気をつけよう。 基本は以下のような形。
気をつけるポイント1 ScrollViewはsetAnchorPoint()が効かない(バグ?)。setPosition()は常に左下座標を指定すること。 気をつけるポイント2 スクロールビューは、デフォルトだと一番下までスクロールした状態になっている(VERTICALまたはBOTHの場合)。 普通は一番上にスクロールさせるはずだと思う。
こうしておくと、一番上にスクロールした状態になる。 第2引数をtrueにすると、アニメーションしながらスクロールする。 通常はtrueがいいが、この場合は一瞬でスクロールさせたいのでfalseが適切。 スクロールビューは、たとえsetVisible(false)にして見えないようにしていても、タッチイベントに反応してスクロールしてしまう。 これに関する解決は別の記事で。 |
cocos2d-xでタッチを検知する方法は主に2つ。
1. MenuItemを使う方法
この方法だと、Menuの範囲内をタップしたときだけコールバックが呼ばれる。 menu->setEnabled(false); または item->setEnabled(false); とすると反応しなくなる。スプライトは表示されたまま。 menu->setVisible(false); または item->setVisible(false); とすると、スプライトも非表示で、タップも反応しなくなる。 2. イベントリスナーを使う方法
となる。 この場合、スクリーン全体のどこでもタップが検知されるので、範囲チェックを自分で行うこと。 タップ座標が欲しいときは、 touch->getLocation(); touch->getLocationInView(); のいずれかを使う。 cocosが普通使っている左下原点の座標系はgetLocation()のほうである。 上記の例だと、タップした座標をspriteの座標系に変換している。 また、画面のどこをタップしてもonTouchBegan()らが呼ばれるわけではなく、 タップした位置がMenuであれば、そちらのコールバックの呼び出しが優先され、onTouchBeganは呼ばれなくなる。 参考 |
cocos2d-xのスプライトインスタンス。
座標を取りたいときは Rect bgRect = bgSprite->getSpriteFrame()->getRectInPixels(); Rect bgRect = bgSprite->getSpriteFrame()->getRect(); などが使える。 ただしこれは、cocoaとは違い、frameというのは自分から見た座標系らしく、bgRect.originは零ベクトルになっている。 Vec2 bgPoint = bgSprite->getSpriteFrame()->getOffset(); というメソッドもあるが、これを使っても零ベクトル。 仕方ないので bgSprite->getPositionY() + bgRect.size.height みたいにやることになる。 ここでさらに注意したいのは、cocosはy座標が上向きになっていること。 自己流でyを下向きに持っていたりすると、getPositionY の値が意外なところにいたりするので注意 |
これは簡単で、
まずcocos2d-xの公式ページへ行く ダウンロードページ で、最新のバージョンを選択。 ダウンロードされます。 適当なディレクトリに解凍したあと、 コンソールから setup.py を実行。 $ ./setup.py バージョンアップでなく、初めてのcocos2d-xのインストールだった場合は、ここでAndroidのSDK_ROOTなどを入れる必要がある。それはまた別記事で。 完了すると、bash_profile を更新するよう言われる。 そこで以下のコマンドを実行する。 $ source ~/.bash_profile で、コンソールを再起動する。 反映されたかを確認してみる。 $ which cocos -> /path/to/cocos2d-x-3.2/tools/cocos2d-console/bin/cocos という具合に表示される。 ディレクトリのバージョン数値があっていればOK。 これにてバージョンアップは完了。 新しいcocosプロジェクトを作成する場合は、以下のコマンド。 $ cocos new NewProject -p com.yourcompany.NewProject -l cpp -d /path/to/NewProject |
毎回使うので、cocosを使ったゲームのプロジェクトのひな形を作った。
フレームワーク化すべきところだが、 臨機応変にやりたいので、git-hubにまるっと置くことにした。 git-hubのプライベートリポジトリに、cocos(や他のフレームワークなども全部入りの状態)のプロジェクトを丸ごと置いて、 新しいゲームを作るときはそれをforkしてローカルに取ってきて始めるという形。 共通部分を手直ししたいときも、git-hubの元プロジェクトを書き換えて、 各自ゲームのプロジェクトで再度pullすればいいだけのはずだ。 ブランチを機能ごとに細かく分ける。 master(基本) ad_imobile (アイモバイル広告部分) landscape(横持ち設定部分) project_name(プロジェクト固有の設定部分。スプラッシュロゴとか、定数マクロとか) とりあえず、1つのブランチに細かくコミットしていって あとで各ブランチに分けるときにcherry-pickしていけばよい。 |
cocos2d-x 3.1rcで、ARC設定を有効にした。
プロジェクトの設定で Build Settings の Objective-C Automatic Reference Counting を Yes にする ただしこれだとコンパイルに失敗する。 一部のファイルをARC対象から除外する。 その方法は Build phases の Compile Sources から AppController.mm RootViewController.mm main.m の3つを選択し、Compiler Flagに -fno-objc-arc と書く。 これでコンパイルが通る。 ちなみにAppController.mm もARC対象にしたい場合は コンパイルエラーがでる dealloc や release の行を消せば概ね良く、一カ所だけ
という行だけ、キャストに問題があるエラーが出る。ここは
と書き換えればOK。 残り2ファイルも行けるか? http://tf.hateblo.jp/entry/2013/04/06/175000 cocos2d-x 2.0の記事だけど。多少参考になる Cocos2D 2.X プロジェクトをARCに対応させる方法 |
フレームワークを入れるまではマニュアル通りでOK。
コードを書く段になるとややこしい。 cocos2d-xなのでビューコントローラがテンプレートと違っているとか、コードがC++で書かれているからObj-C側が呼び出しにくいとかそういう問題を解決していく必要がある。 この辺、appCCloudだとcocos2d版SDKも用意されていてとても開発者フレンドリーなのだが、見込める広告収入はアイモバイルのほうが高いとのことなので、そもそも何のためにゲーム作ってるのかと考えると頑張ってアイモバイルを入れることに意味がある。 バナー広告 まずバナー広告を入れる。 バナー広告はViewとして用意されている。(IMobileAdView) なので、いずれかのビューに addSubview する形を取る。 cocos2d-xの場合、RootViewController が用意されていて、このビューコントローラについているビューは CCEAGLView である。設定箇所は AppController.mm になる。 つまりこのCCEAGLViewに addSubview することになる。 なので、そのままAppController.mmの - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions メソッド内で addSubview しちゃえばよい。マニュアルに書いてあるコードをほぼそのまま使えるぞ。 あとは…分かるな? もうこれで表示されるぞ! ちゃんとアイモバイルのほうで設定はしてあるな?シミュレータ上では表示されないぞ! アイコン広告 アイコン広告を入れる。 仕組みはバナー広告と同じ。Viewとして提供されているので、適切なビューに addSubview するだけ。生成時の引数の形が少し違うだけ。(並べるアイコンの数の指定があったりする) やることはバナーと同じだ! マニュアルによると、1画面に出せる広告は1種類だけ、と書いてあるけど、別にそんなこともなくバナーとアイコン同時に出せる。 ミディアムレクタングル広告 なぜか別のSDKとして提供されている。(一緒にしろよ なぜかこっちはパブリッシャーIDとかが文字列指定になってる。(揃えろよ 表示するとき、ビューコントローラを指定する方法と、ビューを指定する方法とがある。どっちでも好きな方を使おう
ちなみにこちらには、広告取得が完了したときに呼び出すdelegateが指定できる。 クラスにIMobileSdkAdsDelegate を継承させて [ImobileSdkAds setSpotDelegate:@"spotid" delegate:self]; としておくと、 - (void)imobileSdkAdsSpot:(NSString *)spotid didReadyWithValue:(ImobileSdkAdsReadyResult)value というメソッドが呼び出される。 これ以降、表示メソッドを呼び出すと広告が出る。(この前に表示メソッド呼んでも何も起きないので注意) (バナーとかアイコン広告は準備でき次第表示されるので、先にビューを作っておいても構わない。ミディアムレクタングルとかのインライン系はそうでないので、必ず広告取得完了したかの確認をすること) ちなみに、Web上で広告スポットの登録をしてから実際に使えるようになるまで何時間もかかるので注意。 この間、広告はでないしエラーも出ない。(お粗末! 「安心しろ!君のプログラムは間違ってなんかいない!」 雑感 とりあえず、SDKは相当お粗末。(この点appCCloudは優秀だった) バナー・アイコン版とインタースティシャル版でSDKが別になってるし、 インタースティシャル版のサンプルプロジェクトで広告表示されないし(何のサンプル?) 中のコードも大概な感じ。
書いた人プログラミング素人なの? |