忍者ブログ
  • 2024.04
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 2024.06
[PR]
×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

【2024/05/19 06:15 】 |
QuadCommandでエラーのとき
cocos2d-xで、こんなエラーがでるときがある。



QuadCommand::init() 関数で、
glProgramState が null になっている。


これは、Spriteの初回draw()で発生する。

原因でよくあるのは、Sprite::init() が呼び出されていないとき。


Spriteクラスを継承して独自クラスにしたとき、
init()の中で

Sprite::init();


を忘れていないかチェック!

PR
【2015/10/02 13:11 】 | cocos2d-x | 有り難いご意見(0)
cocos2d-x(v3.7)の新しいプロジェクトを作成する
やることは大して変わらない。
まず、ダウンロードページへ行く

最新のバージョンをダウンロードしたら解凍。
cocos2d-x-*.*
という名前のディレクトリができる

<cocos2d-x-*.*>/README.md

に基本的に書いてあるが

$ ./setup.py
$ source ~/.bash_profile
$ cocos new MyGame -p com.your_company.mygame -l cpp -d NEW_PROJECTS_DIR

で作れる。


【2015/07/24 12:39 】 | cocos2d-x | 有り難いご意見(0)
cocos2d-xのラベルはグローバルZが実質使えない
cocos2d-xには、グローバルZ値を設定できる。
これによって、親子関係に依らず表示順序を設定できる。

グローバルZは、設定したそのノードだけに効く。
例えばノードAの子ノードBにグローバルZを設定し、一番手前に表示したとする。
ノードBの子ノードCがあったとき、ノードCは、ノードBより手前には表示されない。
ノードAの子として通常のローカルZによって描画順序が決定される。
ノードCをノードBより手前に表示したいときは、ノードCにもグローバルZを指定する必要がある。

なお、グローバルZは、値が小さい方が手前に表示される。
この点、ローカルZと逆になっている。
なぜこんなことになっているのか…。
ちなみにdouble型。


さて、グローバルZが子ノードに伝播しないと、
Labelが困ったことになる。
Labelは内部的にSpriteを子ノードに持っているため、
label->setGlobalZ()
を設定しても、実際の文字にはグローバルZの値が効かないのだ!

参考

大変困る話だ。

表示文字列が決まっているなら、文字全体を一枚のテクスチャで作ってしまっておけばSpriteで表示するといった手で逃げられるが。




【2015/07/07 02:14 】 | cocos2d-x | 有り難いご意見(0)
Eclipseの起動時に"Android SDK: resolving error markers"で動かないとき
以下のコマンドを実行する

$ cd <eclipseのworkspace>
$ cd .metadata
$ find . -name .markers -exec rm {} \;
$ path/to/adt-bundle-mac-x86_64-YYYYMMDD/eclipse/Eclipse.app/Contents/MacOS/eclipse -clean -refresh


参考
【2015/06/19 13:47 】 | cocos2d-x | 有り難いご意見(0)
cocos2d-xでAndroidでBGMが2度目以降再生されない
cocos2d-xでandroidで、同じBGMが2度目以降再生されないバグがある。

(cocos2d-xトップディレクトリ)/cocos/platform/android/java/src/org/cocos2dx/lib/Cocos2dxMusic.java

の中。

stopBackgroundMusic()
のあと、同じファイルで
playBackgroundMusic()
すると音が鳴らない。

結論言うと、
prepare()をしていないから。


cocosの音声周りの実装は、SimpleAudioEngineを介して、Cocos2dxMusic.java を呼び出している。

Cocos2dxMusic は、メンバにAndroidSDKのMediaPlayerを保持し、これを操作している。

初回のplayBackgroundMusicは、createMediaPlayerメソッドを実行し、内部で
mediaPlayerのインスタンス化、
setDataSource
prepare
setVolume
を行っている。

その後playを実行し、音が鳴り始める。

さて、2回目にplayBackgroundMusicが呼ばれたとき。
直前に鳴らした音声の情報はmediaPlayerの中に残っており、(stopBackgroundMusicを実行しても、stopするだけでreleaseはしていない)、同ファイルだった場合は初期化処理を丸ごと飛ばす。
ここが問題。
このとき、本来実行すべきprepare()が抜けているのだ。

そこで、同ファイルのplayBackgroundMusicのとき、
prepare
seekTo(0)…曲の先頭に移動
を行うようにした。




public void playBackgroundMusic(final String pPath, final boolean isLoop) {
if (this.mCurrentPath == null) {
:
:
} else {
if (!this.mCurrentPath.equals(pPath)) {
:
:
}
else{



try{
this.mBackgroundMediaPlayer.prepare();
this.mBackgroundMediaPlayer.seekTo(0);
} catch (final Exception e) {
Log.e(Cocos2dxMusic.TAG, "error: " + e.getMessage(), e);
}
}
:


これでOK。

ちなみにlibcocos2dxプロジェクトのjavaファイルを書き換えてビルドすれば
ゲームプロジェクトにもちゃんと反映される。
【2015/05/25 18:10 】 | cocos2d-x | 有り難いご意見(0)
cocos2d-xでのデバイスの画面サイズ調整方法
デバイスによって画面の縦横比は違う。
これをどう対応するかというと、
AppDelegate.cppの
bool AppDelegate::applicationDidFinishLaunching();
関数の中で、以下の記述をする。


glview->setDesignResolutionSize(SCREEN_WIDTH, SCREEN_HEIGHT, ResolutionPolicy::SHOW_ALL);


ここで、SCREEN_WIDTH, SCREEN_HEIGHTは自分で決めた値。
この値でcocos2d-xは画面を作る。
ゲームの実装部分は、この画面サイズと見なして作ればいい。

このサイズはいわば仮想画面のサイズで、デバイスの画面サイズとは違う。
この2つの画面をどう合わせるかが第3引数での指定になっている。

以下、指定できる値を列挙。


EXACT_FIT //デバイス画面にぴったり収まるように描画。仮想とデバイス画面の縦横比が合っていなくてもはみ出たり周囲に黒帯がついたりはしないが、縦横比が変化する

NO_BORDER //縦横比を維持。デバイス画面に描画の無い領域を作らないように描画する。そのため、縦横比が合っていないときははみ出る領域がある

SHOW_ALL //縦横比を維持。ゲーム画面全体が中心に描画される。縦横比が合っていないときは周囲に描画の無い黒帯ができる

FIXED_HEIGHT //縦がぴったり収まるように描画する。縦横比は維持する。デバイス画面の右寄せで描画される。縦横比が合わない場合、右がはみ出たり帯が入ったりする。

FIXED_WIDTH //横がぴったり収まるように描画する。縦横比は維持する。デバイス画面の下寄せで描画される。縦横比が合わない場合、上がはみ出たり帯が入ったりする




デフォルトはEXACT_FITになっている。
ぴったり描画するのは良いのだが、縦横比が変わるのはやはりよくない。

SHOW_ALLを使うのが良いと思う。

【2015/04/24 15:04 】 | cocos2d-x | 有り難いご意見(0)
cocos2d-x + Androidでの実装するときは、描画処理発行に気を配るべし
Androidアプリを作るときは、
必要に応じてスレッドを使いながら実装しないといけない。

とくに描画周りの処理を行うなら、必ず
runOnUiThread
の中に実装する。そうでないとすぐ落ちる。

cocos2d-xで動かしている場合、
mainLoopから呼び出される
Layer::update()
メソッドは、描画スレッドの内部であるようで、描画処理(リソースの読み込みやラベルの表示等)をしてもよい(当たり前。いつもそうしてる)

だが、たまにupdate()でないところから描画処理を呼び出す流れになる場合がある。

例えば
・JNI経由でJavaからC++側を呼び出したとき
・・アラートのコールバックからゲーム側を呼び出す
・・シェア結果のコールバックからゲーム側を呼び出す
・・など
・AppDelegateの中から呼び出す
・・applicationDidFinishLaunching
・・applicationWillEnterForeground
・・など
・RootViewControllerからゲーム側を呼び出す
・AppControllerからゲーム側を呼び出す
など

こういうとき、描画処理を行うと、

フリーズ(描画スレッドの停止。タッチには反応し、音楽も鳴るなど)
表示くずれ

などの現象が起きる

上記のような流れのときは、フラグを建てるだけにしておいて、
実際の描画処理はLayer::update()からフラグをチェックして行う
のように実装する。


【2015/04/21 17:53 】 | cocos2d-x | 有り難いご意見(0)
android5系で音が鳴らない
Qiitaのまとめ

修正した結果のファイル

LINEツムツムとかも動かなくなったらしい

Eclipseにおいては、cocos2d-xは外部ライブラリとしてリンクしているので、
修正する場合は、外部ライブラリのソースを書き換える。
ゲームディレクトリに内包されているほうのソースではない。

外部ライブラリのソースを変更し、外部ライブラリをビルドしてから
ゲームのプロジェクトをビルドすると、cocos2d-xへの変更が反映される。
【2015/04/21 16:04 】 | cocos2d-x | 有り難いご意見(0)
SNS周りの実装で注意する点
SNS周りの注意点

[twitter]
iOSはSocialFrameworkですぐできる

Androidは、Intentを使えば早いが、それだと投稿の成功・失敗が取れない。
インセンティブを付与したいときには、Twitterにアプリ登録をして、IDその他を取得。twitter4jを使ってOAuth方式で呼び出す
初回は認証を受ける処理に入るので、フローが変わることに注意。
認証用のIntentに飛ばすためだけのActivityを作ったりもする。
認証をキャンセルしたときに落ちたりもするので注意。(intent.getData().getQueryParameter("oauth_verifier”); が null になった場合、処理を続行させると落ちる)


[facebook]
iOSはSocialFrameworkですぐできる

Androidはかなり面倒。Intentで飛ばすだけならいいが、やらないことも多い


[LINE]
LINEは画像と文字列を同時に投稿できない。スクショなど画像投稿系はLINEを外すことも多い
成功・失敗の判断ができない。ボタンを押した時点でインセンティブを付与してもいいが、そもそもアプリが入ってないときとかはさすがに付与しないよう注意



[iOS]
該当のアプリがインストールされていない場合、どうする?

投稿完了時にアラート表示する?

スクショを撮るなどするとき遅いかもしれないので、インジケータを出す


[Android]
該当のアプリがインストールされていない場合、PlayStoreのページに飛ばす。PlayStoreもインストールされてないときは、ブラウザで該当のページに飛ばす

投稿完了時にtoast表示

スクショを撮るなどするとき遅いので、ProgressDialogなど出す


cocos2d-xの場合、シェアコールバックでそのままゲーム側の処理を行うべきでない。リソース周りへのアクセス等すると落ちる
→フラグを立てるだけなどにしておいて、処理はメインループで行うのがよい。




【2015/04/10 17:43 】 | cocos2d-x | 有り難いご意見(0)
addActionでエラー
cocos2d-x。

ActionManager::addAction()でEXC_BAD_ACCESS例外で落ちた。



void ActionManager::addAction(Action *action, Node *target, bool paused)
{
CCASSERT(action != nullptr, "");
CCASSERT(target != nullptr, "");

tHashElement *element = nullptr;
// we should convert it to Ref*, because we save it as Ref*
Ref *tmp = target;
HASH_FIND_PTR(_targets, &tmp, element); // <= ココ!!!!!!!!





こんな感じ。

(このスクショは別の件で起きたものだが、原因は同じ。いつもだいたいこういうコールスタックで落ちる)


thisがnullptrになっているとかではない。
なんだろう?と思ったら、呼び出し元の


node->runAction(action);




のnodeをaddChildしていなかった。
ので、メインループが1週したときにメモリが破棄された。
破棄されたがnodeポインタは破棄されたところをさし続けていて…というパターン。

簡単な話だが、nullptrになるわけではないので気付きにくいのはなんとかしたい。
【2015/04/05 22:51 】 | cocos2d-x | 有り難いご意見(0)
<<前ページ | ホーム | 次ページ>>