2014年2月8日土曜日

Hypeの iframe でスクロールバウンス抑止 その2

前回のHypeの iframe でスクロールバウンス抑止の続きです。
iframeを入れ換えるコードの実装先が課題になっていました。

解決策を考えた結果、以下のiframeを入れ替えるコードを start.js というスクリプトファイルの関数にして、window.onload でその関数を呼ぶようにしました。

var changeinnerhtml = '<iframe src ="www_melonjs/index.html" width="240px" height="320px" scrolling="no"></iframe>';
document.getElementById("iframe5").innerHTML = changeinnerhtml

これを、まず以下のようにスクリプトファイルにして、

var start = {
    "onload" : function () {
        var changeinnerhtml = '<iframe src ="www_melonjs/index.html" width="240px" height="320px" scrolling="no"></iframe>';
        document.getElementById("iframe5").innerHTML = changeinnerhtml;
    },
};

index.html の body を以下のように修正しました。
Hypeが自動生成したコードを手動でコピペしていますが、その後に追加しました。

<body>
   <script src="cordova.js"></script>
   <div style ="margin:auto;width:480px">
   <!-- copy these lines to your document: -->
      <div id="xxx_hype_container" style="position:relative;overflow:hidden;width:480px;height:320px;">
      <script type="text/javascript" charset="utf-8" src="XXX.hyperesources/XXX_hype_generated_script.js?77789"></script>
      </div>
   <!-- end copy -->
   </div>
   <script src="start.js"></script>
   <script>
      window.onload = function() {
         start.onload();
      };
   </script>
</body>

取りあえず、Hypeが自動生成するコードを変更する必要はなくなりました。

2014年2月5日水曜日

Hypeの iframe でスクロールバウンス抑止

HypeMelonJSで電子書籍のプロトタイプみたいなものを作っています。
Hypeのバージョンは1.6.2です。MelonJSは0.9.11です。

以下の画像のような感じで、iPhoneをランドスケープにし、本文とゲームで半分に分けて表示させる仕様です。下地となる本文エリアは、サイズを480x320にし、ゲームエリアは、その上から iframe を貼付けました。このiframeでは、MelonJSのサンプルを改造したHTMLファイルを指定しました。

下地が白なので境界が見えませんが…
これを、PhoneGap2.9.1を使用して実機で試したところ、タッチでスクロールバウンスをしてしまいます。スクロールを無効にする方法を検索したところ、XCodeのプロジェクトフォルダの下のResourceフォルダの中に config.xml という設定ファイルを変更すればよいとのことです。よって、以下の DisallowOverscroll 属性の値を true に変更します。

<preference name="DisallowOverscroll" value="true" />

これで、本文エリアはスクロールバウンスを抑止できたのですが、ゲームエリアの方がまだできていないようです。Hypeで その iframe をインスペクタで一通り見ても、そのようなスクロールに関する項目がありませんでした。

Hypeのフォーラムによると、iframe にID(仮に iframe5 とする)を付けて、Hypeのドキュメントのロード直後に以下のスクリプトを実行すればできるそうです。

var changeinnerhtml = '<iframe src ="http://site.com/" 'width="240px" height="320px" scrolling="no"></iframe>';
document.getElementById("iframe5").innerHTML = changeinnerhtml

scrolling="no"というところが、スクロール禁止の属性のようです。あらかじめHypeで設定されたiframeを後で置き換えるというものです。同じiframeを2回表示することになるので、Hypeのiframeの設定で、TypeをEmdeded HTML にして適当なテキストでも入れておいた方がよさそうです。

さて、このスクリプトをどこに置いたらよいのでしょうか?
取りあえず、Hypeがエクスポートで吐き出すスクリプトに追加してはみましたが、
これで、良いのかどうかはわかりません。吐き出すたびに追加する作業をしないといけないのが面倒です。

エクスポートすると、XXX_hype_generated.jsというファイル名で生成されます。そのファイルの最後に、以下のように追加しました。hypeDoc.documentLoad(this.body); の直後です。
www_melonjs/index.html MelonJSのサンプルですが、iPhoneで表示するために若干修正しています。

   HYPE.documents[documentName] = hypeDoc.API;
   document.getElementById(mainContainerID).setAttribute("HYPE_documentName", documentName);

   hypeDoc.documentLoad(this.body);

   var changeinnerhtml = '<iframe src ="www_melonjs/index.html" width="240px" height="320px"

scrolling="no"></iframe>';
   document.getElementById("iframe5").innerHTML = changeinnerhtml


}());


以上、実機で試してみたところ、スクロールバウンスは抑止できました。


その2に続きます。

2014年1月25日土曜日

Kobold2D2.0.4でのアプリ申請時のValidationWarning

アプリ申請のために、XCodeでArchiveビルドして、OrganizerのValidateチェックをしたところ以下のようなWarningが発生しました。

layerNamesという変数が、SDKのAPIと名前がかぶっているのでしょうか?取りあえず検索してみると、Kobold2DのTMX関連のクラスで使用しているようです。


上記の"layerNames"を、一通り"layerTMXNames"に変更して解決しました。そして、無事アップロードして、ただいまレビュー待ちです。使用していないクラスでしたので、適当に変更してしまいました。

iOS4.3にも対応させるためにKobold2D2.0.4を使用しているのですが、そろそろ疲れてきました。これからは、5.0以降か6.0以降で作成していこうかと思っています。





2014年1月22日水曜日

Kobold2D2.0.4で、UIWevViewの動画再生後はサウンド再設定が必要

現在のゲームのシーンをreplaceSceneで、UIWebViewの載ったシーンに切り替えて、動画を再生させます。次に、シーンをゲームにもどしてプレイ開始すると、音が鳴りませんでした。

UIWebViewから呼び出したAVPlayerが、サウンド出力を占有してるのか?、と検討をつけていましたが、具体的な解決策が分からず一日中調べていました。
前にMOSAのセミナーで、Core Audioの入門セミナーに参加したのですが、そのときの資料が役に立ちました。講師は、当時、HDMTにいらした永野さんでした。
ゲームのシーンに切り替えた後に、以下のコードを実行しないといけないようです。

インポートするファイル
#import <AudioToolbox/AudioToolbox.h>
#import <AVFoundation/AVFoundation.h>

実装するコード
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setCategory:AVAudioSessionCategoryAmbient error:nil];

[session setActive:YES error:nil];

AVAudioSessionCategoryAmbientについては、他にも種類がありますので、場合によって変更したほうが良いそうです。

サウンド関係も複雑で難しいです。永野さんのCoreAudioの本を買っておけばよかったと後悔しております。

2013年12月28日土曜日

Kobold2D 2.0.4 でのAdMobのバージョンに注意

以前、XCode5.0アップグレードとKobold2d2.0.4のリンクエラー という投稿をしましたが、AdMobのバージョンアップをせずにリンクの修正のみを行いました。
その後、アプリの申請を行ったのですが、AdMobのAPIに対して以下の指摘がリジェクトメールで返されました。レビュー前のバイナリアップロードの直後で返されたものです。

Non-public API usage:
Apps are not permitted to access the UDID and must not use the uniqueIdentifier method of UIDevice. Please update your apps and servers to associate users with the Vendor or Advertising identifiers introduced in iOS 6.

参考ブログのiOS開発ブログさんによれば、AdMobのバージョンを、最新にすればよいということです。GoogleよりAdMob 6.7.0 をダウンロードし、参考ブログのデベロプメンさんの方法で、以下の作業を行いました。

・Valid Architecturesは、armv7のみにした。
・Kobold2Dインストール先のKobold2D-2.0.4/__Kobold2D__/libs/GoogleAdMobAdsSDK
のヘッダファイルとライブラリファイルを最新と入れ換える。←ただし、これはルール違反ですので、プロジェクトの下にディレクトリを作ったほうがよいでしょう。
・デベロプメンさんの方法ではBuild Phases→Link Binary With LibrariesにlibGoogleAdMobAds.aを追加するとありますが、リンクエラーが発生したために削除しました。
・Build Phases→Link Binary With LibrariesにAdSupport.frameworkを追加しOptionalにする。
・Other Linker FlagsのDebugとReleaseの両方に-ObjCというフラグを追加する。

私の場合は、config.luaでは、iAdのみ有効にし、AdMobを無効にしています。
よって、AdMobを有効にして設定を行った場合、もしかすると不具合が出るかもしれません。以上の作業を行い再度バイナリアップロードしました。無事レビューへと行けました。

参考ブログ

2013年12月21日土曜日

CocosBuilderで作成するとReleaseビルドでクラッシュする

何気なくCocosBuilderで検索していたところ、下記のようなブログの投稿を発見しました。

Taiatari さんのブログで、
CocosBuilderにリジェクトの罠!このバグ致命的!

同じような問題が、他に投稿されていないかと検索してみたところ、

cocos2d iphone の公式サイトのフォーラムに、

iPad project using CocosBuilder fails release, runs debug

という投稿がありました。

今年、2013年の5月に投稿されていたようで、今頃になって見つけてしまいました。
私も、CocosBuilderの2.1でアプリを制作していまして申請直前でしたので、助かりました。
これからは、こまめにチェックしておかないといけないですね。
どうも、ありがとうございます。

自分のアプリをReleaseで実機 iPodTouch 4th iOS6.1.5 で実行させたところ。
見事にクラッシュしました。
Organizerのデバイスログで見ると、

Thread 0 name:  Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0   hoge-iOS                 0x000d74b8 -[CCBReader readFloat] (CCBReader.m:199)

やはり、CCBReader.m のメソッド readFloat で落ちているみたいです。
上記の公式サイトの投稿によると readHeader も修正したほうがよさそうです。

readHeader 修正後
- (BOOL) readHeader
{
    // if no bytes loaded, don't crash about it.
    if( bytes == nil) return NO;
    // Read magic
    int magic;
    unsigned char* pData = ( bytes + currentByte );
    //    int magic = *((int*)(bytes+currentByte));
    memcpy( &magic, pData, sizeof( int ) );
    currentByte+=4;
    if (magic != 'ccbi') return NO;
    
    // Read version
    int version = [self readIntWithSign:NO];
    if (version != kCCBVersion)
    {
        NSLog(@"CCBReader: Incompatible ccbi file version (file: %d reader: %d)",version,kCCBVersion);
        return NO;
    }
    
    return YES;
}
 readFloat 修正後
- (float) readFloat
{
    unsigned char type = [self readByte];
    
    switch (type) {
        case kCCBFloat0:
            return 0;
        case kCCBFloat1:
            return 1;
        case kCCBFloatMinus1:
            return -1;
        case kCCBFloat05:
            return 0.5f;
        case kCCBFloatInteger:
            return [self readIntWithSign:YES];
        default: {
            // using a memcpy since the compiler isn't
            // doing the float ptr math correctly on device.
            float f = 0;
            unsigned char* pData = (bytes + currentByte);
            memcpy(&f, pData, sizeof(float));
            currentByte+=4;
            return f;
        }
    }
}
 このバグの原因は、armv7のメモリアロケートにあるらしいのですが…
…よく理解できませんでした。勉強し直します。

2013年10月12日土曜日

XCode5.0アップグレードとKobold2d2.0.4のリンクエラー その2

XCode5.0アップグレードとKobold2d2.0.4のリンクエラーのつづきです。
CCAsyncObjectに関する以下のエラーですが、以下のstackoverflowに解決方法がありました。


どうやらCCBigImageの定義に原因があったようです。
下のCCBigImageのグループ内のソースファイルに対して設定を変更します。

















それぞれのファイルに対してインスペクターを開き、次の作業をします。
インスペクターは、メニューのView -> Utilities -> File Inspector で開きます。


チェックが付いている項目のチェックを無効にします。
以上で、無事にビルドができました。