2012年9月30日日曜日

CocosBuilder2.1Beta2のリソースファイル設定での注意点

プロジェクトフォルダの下に"Resources/hoge"というように階層化してフォルダを作成し、その"hoge"フォルダの中に、"hoge.png"というスプライトの画像ファイルを置きます。CocosBuilderのシーンには、"hoge.png"がCCSpriteとして貼付けられているとします。
 そして、CocosBuilderの"Project Settings"で以下のように"Flatten paths when publishing"を非選択にします。






デバッグ実行すると、ccbiファイル読み込み時に、コンソールには以下のようなcocos2dの警告メッセージがでます。

-[CCFileUtils fullPathFromRelativePath:resolutionType:] : cocos2d: Warning: File not found: hoge/hoge.png

階層化したフォルダの下に置いたリソースファイルが見つからないというものです。
そこで、以下のように"Flatten paths when publishing"を選択にすると、無事に"hoge.png"を読み込んでくれます。








デフォルトでは選択状態になっているようですが、うっかり非選択にしてしまい、半日ほど悩んでしまいました。

2012年9月29日土曜日

CocosBuilder2.1Beta2で指定したCCSpriteのインスタンスを取得する方法

CocosBuilderで、シーンを作成したときに貼付けたスプライトなどに対して、コード上で処理を行いたい場合は、そのスプライトのインタンスを取得する必要があります。その場合の作業手順です。

以下のように、CocosBuilderでCCLayerとして設定したルートノードのクラス名を"hoge"とします。


以下のように、hogeクラスのメンバ変数とするために"Doc root var"を選択します。そして、取得したいCCSpriteを選択しインスタンス名を入力します。


ccbを保存し、ccbiファイルを"Publish"でXCodeのプロジェクト内に保存します。

XCodeで、CocosBuilderで設定したクラス名とサフィックスが同じファイル名になるようにして、"hoge.h"と"hoge.m"を追加作成します。
そして、以下のように"hoge.h"でCCLayerからの継承クラスに変更します。

@interface hoge  : CCLayer

"hoge.h"で"CCSprite *hogeSprite;"を宣言します。

以下のようにして、ccbiファイル読み込むと、自動的にhogeはインスタンス化され、
(この場合では、nodeという名前で参照されます。CCNodeではなくCCLayerでキャストする必要があると思います。) hogeSpriteは、このときにメンバ変数としてインスタンス化されています。

CCNode *node = [CCBReader nodeGraphFromFile:file];

また、"hoge.m"で、デリゲートメソッドとして"- (void) didLoadFromCCB"を実装すると、
ccbiファイル読み込み終了時に呼び出されますので、"hogeSprite"に対しての処理を行うことができます。

2012年9月26日水曜日

Kobold2D2.0.3とCocosBuilder2.1Beta2を併用するときの注意点

Kobold2Dは、ARC対応なのですが、CocosBuilderのライブラリは、ARCに対応していません。よって、以下のようにXCodeの設定の Build Phases でコンパイル時の設定が必要です。
















関連するファイルに、-fno-objc-arc をオプションに追加します。

参考: http://www.zero4racer.com/blog/334#comment-168

次に、CCScrollView.m で matrix.h が見つからないというエラーが発生しますので、以下のように宣言部分を変更します。

//#import "matrix.h" #import "kazmath/GL/matrix.h"

参考: http://www.cocos2d-iphone.org/forum/topic/38786


2012年9月21日金曜日

enchant.jsのLabelにHTMLを載せる


enchant.jsのLabelには、HTMLタグを使用したテキストをtextプロパティに設定できます。
それならばhtmlファイルごと読み込ませて、ついでにCSSまで適用できないものかなと考えました。
Labelのtextプロパティを以下のようにして、

label.text '<div id="contentsBox" style="width:100%; height:100%;"></div>';

そして、JQueryで以下のように、contentsBox  hoge.html を読み込ませています。

$('#contentsBox').load('./pages/hoge.html',function(response, status, xhr)

ここで、CSSを以下のように入れていたのですが、CSSが適用されませんでした。
再度これらの読み込み処理を行うと、なぜか適用されるのですが、タイミング的なものなのでしょうか?

label.text '<div id="contentsBox" style="width:100%; height:100%;"><link rel="stylesheet" href="./pages/hoge.css"></div>';

そこで、htmlの読み込みが成功したときに、以下のようにJQueryを使用して挿入するようにしてみました。

$('<link rel="stylesheet" href="./pages/hoge.css">').appendTo("head");

Label生成した後にすぐに scene.addChild(label); で子として追加としていますが、
これは、JQueryからLabelのtextに、コードを流し込む時にSceneの子の状態になってないと、
Label内部での更新が動作しないようだったからです。enchant.jsのソースを見た訳ではないので、
はっきりとはいえないのですが。

以下、参考ソースです。作成中のソースから少し変えただけですので見にくいのですが。

    var label = new Label();
    scene.addChild(label);
    label.visible = false;
    label.color = "#000";
    label.backgroundColor = "#FFF";
    label.text = '<div id="contentsBox" style="width:100%; height:100%;"></div>';
    $('#contentsBox').load('./pages/hoge.html',function(response, status, xhr){
          if (status == "error") {
            var msg = "Load Error!!";
            $("#error").html(msg + xhr.status + " " + xhr.statusText);
        }else{
            console.log('---Load Complete!!---');
            $('<link rel="stylesheet" href="./pages/hoge.css">').appendTo("head");
            label.visible = true;
            label.addEventListener('touchend',function(e){
                scene.removeChild(this);
            });
            return;
        }
    });

ちなみにたいしたことではありませんが、htmlファイルやcssファイル、それに含まれる画像ファイルは、
実行しているスクリプトファイルから見ての相対パスなんですよね。
情けないのですが、つい何回も間違えてしまいましたので、自分への戒めもかねて。

2012年9月4日火曜日

PhoneGapでChildBrowserをCloseする方法

PhoneGapのChildBrowserで表示したページからは、

window.plugins.childBrowser.close();

ができない。


そこで、ChildBrowserを呼び出したページかスクリプトで以下のイベントコールバックを定義する。

window.plugins.childBrowser.onLocationChange = function(loc){
    if (loc.indexOf("http://example.com") >= 0)
        window.plugins.childBrowser.close();
}

ChildBrowserで表示されるページに以下のようなリンクを入れる。

<a href="http://example.com" class="btn"><img src="../images/nav.png" alt="閉じる" /></a><br/></p>

"http://example.com"などといった、あり得ないURLを指定すればよい。

参考:http://newdailyblog.blogspot.jp/2012/04/how-to-close-child-browser-in-iphone.html

しかし、もっとスマートなやり方はないのだろうか?


2011年9月11日日曜日

Mac OSXのGimp でDBPをインストールする。

DBP(DAVID’S BATCH PROCESSOR)とは、Gimpでバッチ処理をするためのプラグインです。
まずは、下記のサイトを参照してください。


http://blog.jondh.me.uk/2011/07/davids-batch-processor-on-os-x/


日本語ではないのでキツイですが…
この下にある"gimp-deps.zip"をダウンロードして解凍します。
解凍したフォルダ"gimp-deps"を、ホームディレクトリにコピーします。


ターミナルで以下のコマンドを実行します。
sudo ln -s ~/gimp-deps/* /opt/local/lib


dpbというコンパイル済みのファイルをダウンロードして、
"環境設定→フォルダ→プラグイン"で設定されているフォルダにコピーします。
下記のようなフォルダになっていると思います。
/Users/"自分の名前"/Library/Application Support/Gimp/plug-ins


Gimpを起動してメニューのフィルタの下に"Batch Process…"という項目が
新たにできていますので、選択して開きましょう。

2011年8月6日土曜日

AVPlayerのAVPlayerItemDidPlayToEndTimeNotificationを受けて終了すると、バスエラーになった。

iOS4.0から実装されたAVPlayerですが、再生の終了通知の"AVPlayerItemDidPlayToEndTimeNotification"を受けたときに適切な終了措置をとらないと、後のアプリの動作で不具合を起こすようです。この件では、アプリが不正終了して落ちました。
具体的には、cocos2dのreplaceSceneでシーンを入れ替えるときに発生しました。
なぜか、Adhocでデバイスにインストールしたときに現象が発生し、Debugでは発生しませんでした。
結局、対策はできて、とりあえず解決はしました。

デバイス:iPodTouch,iPhone3GS
OS:iOS4.3.5
iOS4.3sdk
Xcode3.2.6
Deployment Target iOS4.0

cocos2d 0.99.5

まず、アプリが落ちたときですが、コンソールでは以下のように出力されます。


Aug  5 19:55:35 unknown ReportCrash[162] <Notice>: Formulating crash report for process ???[161]
Aug  5 19:55:35 unknown com.apple.launchd[1] <Warning>: (UIKitApplication:com.yourcompany.???[0x9ac8]) Job appears to have crashed: Bus error: 10
Aug  5 19:55:35 unknown SpringBoard[28] <Warning>: Application '???' exited abnormally with signal 10: Bus error: 10
Aug  5 19:55:35 unknown ReportCrash[162] <Error>: libMobileGestalt loadBasebandMobileEquipmentInfo: CommCenter error: 1:45
Aug  5 19:55:35 unknown ReportCrash[162] <Error>: libMobileGestalt copyInternationalMobileEquipmentIdentity: Could not get mobile equipment info dictionary
Aug  5 19:55:35 unknown ReportCrash[162] <Error>: libMobileGestalt copyInternationalMobileEquipmentIdentity: Could not get mobile equipment info dictionary
Aug  5 19:55:36 unknown ReportCrash[162] <Error>: Saved crashreport to /var/mobile/Library/Logs/CrashReporter/???_2011-08-05-195535_iPodTouch-4th.plist using uid: 0 gid: 0, synthetic_euid: 501 egid: 0

Bus error: 10 といわれてもどうしたらよいか分かりませんでした。


ソース内では、AVPlayerItemDidPlayToEndTimeNotificationを通知名としてAVPlayerからの終了通知を受けるようにしています。

[[NSNotificationCenter defaultCenter] addObserver:self                                                                     selector:@selector(moviePlayBackDidFinishNotification:) 
name:AVPlayerItemDidPlayToEndTimeNotification
                    object:nil];

対策方法ですが、上のコードで登録されたセレクタの moviePlayBackDidFinishNotification 内で、以下のように一旦停止と再生終了時のUIを出すかどうかの設定を行えば、エラーは出なくなりました。


[self.player pause];
[self.player setActionAtItemEnd:AVPlayerActionAtItemEndNone];

原因は、まだ分かりませんが、無理にcocos2dと共存させているのが悪いのでしょうか?