2014年11月10日月曜日

AdMobのバナーサイズをcocos2d-xのOpenGLビューのサイズに変換する

AdMobのバナー型広告の裏に、cocos2d-xの描画領域に広告エリアとしてスプライトを表示するようにしたのですが、Android(Nexus7)での広告サイズの計算にちょっとはまりました。
bottom_banner.png

上図のようになって、バナーサイズの高さと、広告エリア用スプライトの高さが合わないのです。
スクリーンショットを撮って調べてみると、バナーの高さは66pxと、変換式がよくわからないサイズで描画されていました。


AdMobの通常のバナーサイズは320x50ですが、こちらは論理サイズなので、各デバイスに描画される物理サイズを知りたい場合は、別途計算する必要があります。

iOSの場合

iOSの場合は、ディスプレイがRetinaかそうでないかで、かんたんに計算できます。
float scale = [[UIScreen mainScreen] scale];
float width = 320 * scale;
float height = 50 * scale;
cocos2d-xの場合は、setDesignResolutionSize()でOpenGLビューのスケールが変更されるので、こちらを加味した計算式は以下のような感じとなります。
float scale = [[UIScreen mainScreen] scale];
auto glview = Director::getInstance()->getOpenGLView();

float width = 320 * scale / glview->getScaleX();
float height = 50 * scale / glview->getScaleY();

Androidの場合

Androidの場合もiOSと変わらないだろうと楽観していましたが、先の画像のように計算が合わず悩みました。
こういう時、Android開発の基礎が重要だとつくづく思い知らされます。

まず、バナーの物理サイズを求めるには、AdView(com.google.android.gms.ads.AdView)のgetWidth()、getHeight()で取得できるのですが、こちらは広告が一度ロードされてからでないと0を返してきてしまいます。

ありがたいことにAdSizeクラス(com.google.android.gms.ads.AdSize)に、物理サイズを取得するメソッドが用意されていました。getWidthInPixels()とgetHeightInPixels()です。
物理サイズを取得するメソッドを、以下のようにAppActivityクラスに加えておきます。

import com.google.android.gms.ads.*;

public class AppActivity extends Cocos2dxActivity {
  private static AppActivity _appActivity;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // staticメソッドからActivityにアクセスできるように保存しておく
    _appActivity = this;
  }

  // バナー型広告のアクティビティ上での実際の横幅ピクセル数を返す
  public static int getAdBannerWidthPhysicalPixels() {
    int width = AdSize.BANNER.getWidthInPixels(_appActivity);
    return width;
  }

  // バナー型広告のアクティビティ上での実際の縦幅ピクセル数を返す
  public static int getAdBannerHeightPhysicalPixels() {
    int height = AdSize.BANNER.getHeightInPixels(_appActivity);
    return height;
  }

上記メソッドをJNIを使ってc++から呼び出し、iOS版と同じようにOpenGLビュー上でのサイズを計算するのは以下のようになります。
float width = 0, height = 0;

auto glview = Director::getInstance()->getOpenGLView();

  { // 横幅
    cocos2d::JniMethodInfo t;

    if (cocos2d::JniHelper::getStaticMethodInfo(t, AppActivityClassName, "getAdBannerWidthPhysicalPixels", "()I")) {
      jint ret = t.env->CallStaticIntMethod(t.classID, t.methodID);
      t.env->DeleteLocalRef(t.classID);

      width = ((float)ret) / glview->getScaleX();
    }
  }

  { // 高さ
    cocos2d::JniMethodInfo t;

    if (cocos2d::JniHelper::getStaticMethodInfo(t, AppActivityClassName, "getAdBannerHeightPhysicalPixels", "()I")) {
      jint ret = t.env->CallStaticIntMethod(t.classID, t.methodID);
      t.env->DeleteLocalRef(t.classID);

      height = ((float)ret) / glview->getScaleY();
    }
  }

サイズの計算ができるようになり、広告エリアのスプライトも以下のようにぴったりはまりました。
bottom_banner2.png

テスト環境
  • Mac OS X 10.9.5
  • cocos2d-x v3.2
  • Google Mobile Ads SDK 6.12.0 (iOS)
  • Google Play Services Rev.17 (Android)

関連記事

0 件のコメント:

コメントを投稿

Related Posts Plugin for WordPress, Blogger...