2015年12月13日

とりとまiOS版リリースしました

ようやく、とりとまのiOS版をリリースしました。

あまりにもアプリ開発が滞っていたので、ブログを更新するのを休んで少しでも早くリリースしようと思っていたのですが、あんまり効果はありませんでした。

とりあえず、App Storeのリンクです。



Android版はまだ開発中です。cocos2d-xなのでゲームの部分はほとんどそのまま動くようですが、ネイティブコードの部分は一から作らないといけないのでボチボチやっていこうかと思います。

ちなみにダウンロード数は今週1週間で56ダウンロード。たぶん最初の1周間がピークだと思うので、100DLにも届かずに終わってしまいそうな感じです。

傾撃の時には何もしなくても1000DLくらい行っていたので数年前と比べると、ゲームアプリも充実してきて、ただアプリを公開しただけでは簡単にはダウンロードされなくなったということでしょうか。
ラベル:とりとま
posted by かねだ at 22:28| Comment(0) | 開発記録 | このブログの読者になる | 更新情報をチェックする

2015年05月17日

cocos2d-xでTwitter投稿

今週はTwitter機能を実装していたのでメモ。一番手間が少なそうな標準のツイート投稿ビューを表示する方法です。ちなみに、調べている途中でPlugin-Xというネイティブコード連携のための仕組みがあることに気付きましたが、今回は面倒なので普通に作ることにしました。

なお、スクリーンショットをツイートするところは【cocos2dx】ソーシャルメディアへの「スクリーンショット」を工夫するを参考にしました。

まずはRootViewControllerにTwitterの投稿ビューを表示する関数を追加。

- (void)postTwitterMessage:(NSString *)message URL:(NSURL *)url Image:(UIImage *)image
{
    // Twitterが使用可能な場合のみ処理を行う
    if ([SLComposeViewController isAvailableForServiceType:SLServiceTypeTwitter]) {

        // Twitter投稿ビューを作成する
        SLComposeViewController *composeVC = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeTwitter];

        // 完了時のハンドラを設定する
        [composeVC setCompletionHandler:^(SLComposeViewControllerResult result) {

            // Twitter投稿ビューを閉じる
            [self dismissViewControllerAnimated:YES completion:nil];

        }];

        // 投稿するテキストの初期設定を行う
        [composeVC setInitialText:message];

        // 投稿するURLの設定を行う
        if (url != nil) {
            [composeVC addURL:url];
        }

        // 投稿する画像の設定を行う
        if (image != nil) {
            [composeVC addImage:image];
        }

        // Twitter投稿ビューを表示する
        [self presentViewController:composeVC animated:YES completion:nil];
    }
}

次にC++からネイティブコードを呼び出すためのクラスを作成。今回はそのままTwitterというクラス名にしました。

void Twitter::post(const char *message, const char *url, const char *imagepath)
{
    // RootViewControllerを取得する
    UIWindow *window = [UIApplication sharedApplication].keyWindow;
    if (window == nil) {
        window = [[UIApplication sharedApplication].windows objectAtIndex:0];
    }

    // RootViewControllerであることを確認する
    if ([window.rootViewController isKindOfClass:[RootViewController class]]) {

        // RootViewControllerにキャストする
        RootViewController *rootViewController = (RootViewController *)window.rootViewController;

        // 投稿画像を開く
        UIImage *image = [UIImage imageWithContentsOfFile:[NSString stringWithCString:imagepath encoding:NSUTF8StringEncoding]];

        // ネイティブコードのTwitter投稿ビュー表示処理を呼び出す
        [rootViewController postTwitterMessage:[NSString stringWithCString:message encoding:NSUTF8StringEncoding]
                                           URL:[NSURL URLWithString:[NSString stringWithCString:url encoding:NSUTF8StringEncoding]]
                                         Image:image];            
    }
}

最後にSceneからスクリーンショットを保存する処理と上のツイート投稿関数を呼び出す処理を作成します。

最新のcocos2d-xならスクリーンショットを保存するためのRenderTexture::saveToFile()にコールバック関数を渡すことができるので、保存が終了した後にツイートの処理ができるのですが、私が今使っているバージョンが3.1と古いもののため画像保存終了のタイミングがわかりません。

幸い、今回のアプリではツイートはゲームオーバー時にしかできず、ゲームオーバーになってからゲームオーバー画面が出るまでに若干ラグを設けているので、ゲームオーバーになった瞬間にスクリーンショットを撮ることで解決しました。本来は最新版を使うべきなんでしょうが。

とりあえずスクリーンショットを撮る処理。なおwidthheightCCDirector::getInstance()->getVisibleSize()で取得した値です。

// スクリーンショット用テクスチャを作成する
RenderTexture *texture = RenderTexture::create(width, height);
texture->setPosition(cocos2d::Vector2(width / 2, height / 2));

// スクリーンショットを撮り始める
texture->begin();

// 画面の描画
this->visit();

// スクリーンショットを撮り終える
texture->end();

// スクリーンショットを保存する
texture->saveToFile("screenshot.png", cocos2d::Image::Format::PNG);

最後にツイートボタンを押された時の処理を作成して終わりです。

// スクリーンショットの保存先パスを作成する
std::string fullpath = FileUtils::getInstance()->getWritablePath() + "screenshot.png";

// ツイートビューを表示する
Twitter::post("ツイート内容", "アプリのURL", fullpath.c_str());
ラベル:とりとま cocos2d
posted by かねだ at 23:01| Comment(0) | 開発記録 | このブログの読者になる | 更新情報をチェックする

2015年04月12日

cocos2d-xでAdMobメディエーションの実装

今週は広告表示の実装をしました。広告会社は傾撃の時と同じでAppBankNetwork、iAd、AdMobをAdMobメディエーションで切り替える感じです。アイコン型とかウォール型の広告にも興味があるのですがリジェクトされるという噂もあるので、とりあえずバナー型とインタースティシャル型だけで。

各Webサイト側での設定は以前に済ませていたようで全く覚えていないのでプログラム側だけメモ書きです。

  1. 次のファイルをダウンロードしてプロジェクトに追加。
    • GoogleMobileAds.freamwork
    • libAdapterIAd.a
    • NendSDKのNendAdフォルダ
    • NendSDKのlibAdapterNend.a
  2. 次のフレームワークを追加。
    • AdSupport
    • AudioToolbox
    • AVFoundation
    • CoreGraphics
    • CoreTelephony
    • EventKit
    • EventKitUI
    • MessageUI
    • StoreKit
    • SystemConfiguration
    • UIKit
    • CoreMedia
    • Security
    • iAd
  3. RootViewControllerに広告ビューのインスタンスと作成、表示処理を追加。
    • RootViewController.h
    • #import "GoogleMobileAds/GADBannerView.h"
      #import "GoogleMobileAds/GADInterstitial.h"
      
      @interface RootViewController : UIViewController {
          GADBannerView *bannerView_;
          GADInterstitial *interstitialView_;
      }
      
      @property (nonatomic, retain)GADBannerView *bannerView;
      @property (nonatomic, retain)GADInterstitial *interstitialView;
      
      - (void)createAdBanner;
      - (void)deleteAdBanner;
      - (void)createAdInterstitial;
      - (void)viewAdInterstitial;
      
      @end
      
    • RootViewController.mm
    • - (void)createAdBanner
      {
          // すでに作成済みの場合は処理しない
          if (self.bannerView != nil) {
              return;
          }
          
          // 画面下部に標準サイズのビューを作成する
          self.bannerView = [[[GADBannerView alloc] initWithAdSize:kGADAdSizeBanner] autorelease];
          
          // 広告のユニットIDを指定する
          self.bannerView.adUnitID = UNIT_ID;
          
          // ユーザーに広告を表示した場所に後で復元する UIViewController をランタイムに知らせて
          // ビュー階層に追加する。
          self.bannerView.rootViewController = self;
          [self.view addSubview:self.bannerView];
          
          // 広告リクエストを作成する
          GADRequest *request = [GADRequest request];
          
          // テスト広告のリクエストを行う。
          request.testDevices = [NSArray arrayWithObjects:TEST_DEVICE_ID, nil];
          
          // リクエストを行って広告を読み込む
          [self.bannerView loadRequest:request];
      }
      
      - (void)deleteAdBanner
      {
          // バナーを取り除く
          [self.bannerView removeFromSuperview];
          
          // バナーを削除する
          self.bannerView = nil;
      }
      
      - (void)createAdInterstitial
      {
          // インタースティシャル広告を作成する
          self.interstitialView = [[[GADInterstitial alloc] init] autorelease];
          
          // 広告のユニットIDを指定する。
          self.interstitialView.adUnitID = UNIT_ID;
          
          // デリゲートを設定する
          self.interstitialView.delegate = self;
          
          // 広告リクエストを作成する
          GADRequest *request = [GADRequest request];
          
          // テスト広告のリクエストを行う。
          request.testDevices = [NSArray arrayWithObjects:TEST_DEVICE_ID, nil];
          
          // リクエストを行って広告を読み込む
          [self.interstitialView loadRequest:request];
      }
      
      - (void)viewAdInterstitial
      {
          // インタースティシャル広告を表示する準備ができている場合、
          // 広告を表示する。
          if ([self.interstitialView isReady]) {
              [self.interstitialView presentFromRootViewController:self];
          }
      }
      
      - (void)interstitialDidDismissScreen:(GADInterstitial *)ad
      {
          // インタースティシャル広告の表示が終了した時に、
          // 再度作成を行う。
          [self createAdInterstitial];
      }
      
  4. C++からネイティブコードを呼び出すためのクラスを作成する。ここではクラス名はAdvertisementとした。
    • Advertisement.h
    • class Advertisement {
      public:
          static void viewBanner();
          static void hideBaaner();
          static void viewInterstatial();
      };
      
    • Advertisement.mm
    • void Advertisement::viewBanner()
      {
          UIWindow *window = [UIApplication sharedApplication].keyWindow;
          if (window == nil) {
              window = [[UIApplication sharedApplication].windows objectAtIndex:0];
          }
      
          if ([window.rootViewController isKindOfClass:[RootViewController class]]) {
              RootViewController *rootViewController = (RootViewController *)window.rootViewController;
              [rootViewController createAdBanner];
          }
      }
      
      void Advertisement::hideBaaner()
      {
          UIWindow *window = [UIApplication sharedApplication].keyWindow;
          if (window == nil) {
              window = [[UIApplication sharedApplication].windows objectAtIndex:0];
          }
          
          if ([window.rootViewController isKindOfClass:[RootViewController class]]) {
              RootViewController *rootViewController = (RootViewController *)window.rootViewController;
              [rootViewController deleteAdBanner];
          }
      }
      
      void Advertisement::viewInterstatial()
      {
          UIWindow *window = [UIApplication sharedApplication].keyWindow;
          if (window == nil) {
              window = [[UIApplication sharedApplication].windows objectAtIndex:0];
          }
          
          if ([window.rootViewController isKindOfClass:[RootViewController class]]) {
              RootViewController *rootViewController = (RootViewController *)window.rootViewController;
              [rootViewController viewAdInterstitial];
          }
      }
      
ラベル:とりとま AdMob
posted by かねだ at 21:54| Comment(0) | 開発記録 | このブログの読者になる | 更新情報をチェックする

広告


この広告は60日以上更新がないブログに表示がされております。

以下のいずれかの方法で非表示にすることが可能です。

・記事の投稿、編集をおこなう
・マイブログの【設定】 > 【広告設定】 より、「60日間更新が無い場合」 の 「広告を表示しない」にチェックを入れて保存する。


×

この広告は1年以上新しい記事の投稿がないブログに表示されております。