2013年2月17日日曜日

VGSでの広告表示(Tap for Tap)

先日、InvaderBlock2のフリー版(広告付き)を公開しました。
広告の実装には、Tap for Tapを採用してみました。
私は、どちらかというと広告ビジネスに否定的な見解を示していたので、その釈明を兼ねて考え&TIPS(VGSのアプリで広告を実装する方法)を記しておきます。

広告会社の概要

Tap for Tapは、カナダ(米国のブリティッシュコロンビア州)に拠点をおく広告会社です。
私のアプリ事業は、北米方面を中心に展開しているので、そっち方面の会社の方が良かろうという判断です。米国本土の方が良いかもしれませんが、サービス内容が興味深かったので、そこにしてみました。デベロッパー数は6,000人前後。(まだ新興企業ですね)

サービス概要

Tap for Tapの場合、プロモーション(ユーザ獲得)と収益化のバランスを、任意に調整できます。
例えば、広告で得た収益の全てをプロモーションに使うことができます。
# 実質的な費用対効果については、まだ十分なデータが集まっていないので未確認。

利用した経緯

NOKOGI Riderの販売を開始してもうすぐ半年ぐらい経過します。
その間の販売実績は、現時点で57本ぐらいと不調です。
ゲームそのものは面白いと思います。
しかし、如何せんプロモが弱すぎることが売れない原因かもしれません。
マネタイズのみの広告アプリというのは、未だにちょっと疑心暗鬼しています。
しかし、プロモ用途でちょっと使ってみるぐらいなら良いんじゃないかと思い始めました。

ただし、広告を入れれば結構沢山のパーミッション要求が必要になります。
NOKOGI Riderに関しては、それで汚したくないと考えました。
そこで白羽の矢が立ったのが「InvaderBlock2」です。

「InvaderBlock2」は、GooglePlayでの販売テスト用にリリースしたアプリです。
ゲームそのものの面白さは中々だと思ってます。
しかし、やはり実質的に有償販売だけなので、サッパリ売れません。
(一応、1年で10本ぐらい売れましたが)

ついでに、InvaderBlock2は、広告アプリで成功するために必要な要素を持っています。
恐らく、広告アプリとしての潜在能力は、NOKOGI Rider以上です。
そう思っていた矢先、Tap for Tapの担当者から「InvaderBlock2に広告を載せてくれ」というeメールがあり、サービスを確認したところ私の方針(プロモーション強化)にマッチしていると思ったので、それを利用してみることにしました。

VGSアプリでの広告の実装方法(基本編)

とても簡単です。以下、InvaderBlock2のソースコード(Java側)の抜粋で説明します。
    @Override
    public void onCreate(Bundle savedInstanceState) {
        try {
            ~VGS関連の初期化(中略)~
            } else {
                // View の設定
                mMainView=new VgeSurfaceView(this);
                mLayout=new FrameLayout(this);
                mLayout.addView(mMainView);
                getWindow().setContentView(mLayout);
                TapForTap.initialize(this, "自分のAPIキー");
                mAdView = new AdView(this);
                DisplayMetrics metrics = getResources().getDisplayMetrics();
                int width = metrics.widthPixels;
                int height = (int)(50 * (width / 320.0));
                LinearLayout.LayoutParams myLayoutParams = new
                                        LinearLayout.LayoutParams(width, height);
                mAdView.setLayoutParams(myLayoutParams);
                mAdParam=new FrameLayout.LayoutParams(
                    FrameLayout.LayoutParams.MATCH_PARENT,
                    FrameLayout.LayoutParams.WRAP_CONTENT,
                    Gravity.BOTTOM);
                mLayout.addView(mAdView,mAdParam);
                mAdPut=true;
            }
        } catch(Exception e) {
            Log.e(LOG_TAG, "AN EXCEPTION DETECTED.", e);
        }
    }
前半の初期化処理は、VGS固有の初期化処理なので中略しました。
ポイントは青色の網掛け部分です。
広告の処理は、ゲームとは別のビューで実装します。
大まかに、VGSのプログラムに広告を実装する場合、次のような実装をすればOKです。
(1) FrameLayoutクラスのオブジェクト(mLayout)を準備
(2) ゲーム本体のビュー(mMainView)を作成し、mLayoutに追加。
(3) 広告表示用のビュー(mAdView )を作成し、mLayoutに追加。
なお、実装中の緑色の網掛け部分は、広告ビューのスタイルを設定する処理です。
この部分は、レイアウトのxmlでも良いかもしれません。(サンプルはその方式でした)

メイン処理(C言語)との連携処理

広告を表示しっぱなしのアプリであれば、上記の実装でOKです。
ただし、ゲームの場合、ゲームのプレイ中に広告表示がされるのはハッキリ言って邪魔です。
そこで、広告の表示をON/OFFできる仕組みの実装方法を解説します。

VGSの場合、C言語で実装しているメイン処理に広告のON/OFFなどのオペレーションを要求するためのインタフェースを実装する必要があります。下記のような感じで良いと思います。
    /*
     *------------------------------------------------------------------------
     * Java側への要求を取得する (JNI)
     *------------------------------------------------------------------------
     */
    public static native int getRequest();
※数値(jint)でオペレーションを返す仕様にします(0 = None / 1 = put ads / 2 = delete ads)

そして、VgeSurfaceViewのスレッドでオペレーション(0以外)を取得した場合、アクティビティクラスでそれを処理できるようにするために、アクティビティクラスにハンドラ関数を実装します。
    public Handler handler = new Handler() {
        public void handleMessage(Message msg) {
            switch(mRequest) {
                case 1: //広告を表示
                    if(!mAdPut) {
                        mLayout.addView(mAdView,mAdParam);
                        mAdPut=true;
                    }
                    break;
                case 2: //広告を削除
                    if(mAdPut) {
                        mLayout.removeView(mAdView);
                        mAdPut=false;
                    }
                    break;
            }
            mRequest=-1;
        }
    };

VgeSurfaceView側の実装はこんな感じでOKです。

    public VgeSurfaceView(Context context) {
        super(context);
        act=(IBLOCKA)context;
        vram=Bitmap.createBitmap(XSIZE,YSIZE,Bitmap.Config.RGB_565);
        vram.setDensity(Bitmap.DENSITY_NONE);
        vramRect=new Rect(0,0,XSIZE,YSIZE);
        getHolder().addCallback(this);
    }


    @Override
    public void run() {
        SurfaceHolder holder=getHolder();
        Canvas canvas;
        int rc=0;
        int rq;
        while (isAttached) {
            canvas=null;
            try {
                rc=IBLOCKA.setVram(vram);
                canvas=holder.lockCanvas();
                if(null!=canvas) {
                    canvas.drawBitmap(vram,vramRect,screenRect,screenPaint);
                }
            } finally {
                if(null!=canvas) holder.unlockCanvasAndPost(canvas);
                if(rc!=0) break;
            }
            rq=IBLOCKA.getRequest();
            if(0!=rq) {
                IBLOCKA.mRequest=rq;
                act.handler.sendEmptyMessage(0);
            }
        }
        if(0!=rc) {
            System.exit(0);
        }
    }
getRequestで0以外を取得した場合、値をアクティビティクラスのメンバ変数にセットして、sendEmptyMessage関数でハンドラ関数を実行して、1(広告を表示)または2(広告を削除)を実行します。
実は私はJavaが苦手なので、あまりJavaっぽくない作り方かも。
この辺りは、お好みでアレンジしてください。

概ねこんな感じの実装を使えば、VGSのアプリに広告を実装できます。
広告の実装方法については、AdMobなどの他の広告会社のものでも、基本的なことは概ね同じじゃないかと思います。





2013年2月11日月曜日

Google+へ移行気味

今年の初めぐらいからGoogle+を使い始めたのですが、出先からでも使い易いので結構重宝しています。
コミュニティ機能がかなり便利。
とりあえず、SUZUKI PLAN専用コミュニティを作り、せっせと開発状況を書き綴っています。
https://plus.google.com/u/0/communities/101901802119581380381

次回作の体験版(Lite版)が完成したら、GooglePlayの説明文からこのコミュへのリンクを張って誘導し、作品への要望や意見などをくれる方を募ってみようかと思っていたりします。ここのブログは、纏まった内容を記述する用途で便利なので残しておきますが、テンポラリ的な内容については概ねG+上でつぶやく感じになりつつあるかも。

2013年1月26日土曜日

広告出稿

SHOT04(Windows版)の広告をAdWordsにてテスト出稿中。
AdWordsを効果的に使えば、買ってくれるターゲット層の顧客を掴むことが可能ですが、その反面、クリック単価がもの凄く高い。単価はキーワードごとに異なるようです。

使いどころについて、色々と考えてみましたが、私の場合はまだ時期尚早かなという感じです。

1日流してみて、平均CPCが132円。
SHOT04(Windows版)の1本あたりの私の利益は735円。
つまり、5クリックで1本売れれば、75円の利益が発生することになります。
1/5ということで、CV率20%が目標値。

Googleの人曰く、有料販売のCV率というのは、だいたい2~5%の範囲らしい。
ということは、現状の利益額では、広告出資してもほぼ確実に赤字になる筈。
一応、定価を引き上げるという手段もありますが。
ただ、SHOT04だけで、CV率5%で利益が出る価格設定にはしたくありません。

売れるタイトルが数本揃ってから、宣伝すべきじゃないかと考え中。

要は、次タイトル作成のモチベーションを無理やり上げようとしている訳です。
さて、作るか・・・

2013年1月23日水曜日

放射失敗

オプションから放射線を描画。

静画で見るとそうでもありませんが、動画で見ると目がチカチカするので、流石にこれは却下で。
そういえば、明日がセミナーか。
名刺が要ると言われたけど、流石にSUZUKI PLANの名刺は作っていない。
とりあえず、本業の名刺の左上に「SUZUKI PLAN」と手書きで記載した、微笑ましい名刺で代用する。
一応、会社では副業のことは全く隠していない(明日の件も、Googleへ行ってくるので半休すると申告している)ので、会社バレしても全く問題はありません。問題は、参加申請の会社名を「SUZUKI PLAN」にしているので、それ(手書き)で通用するか否か。

とりあえず、ネタにもなりそうだし、本の持ち込み営業をする時にもあった方が良いから、名刺は作っておこうかと検討中。どうせ作るなら、本業で使っている安物のリサイクルペーパーじゃなくて、プラスチック紙のちゃんとしたヤツを。

ノータッチ

急きょ、Google主催のセミナーに参加することになりました。
24日開催のセミナーに、昨日(21日)、Googleの担当者の方から「参加してみないか?」と昨日言われ、今日(22日)決断して参加決定。当然、平日なので色々な調整が必要。

無償セミナーなので、たぶん、枠が埋まらなくて、運よくお零れに与ることが出来た感じでしょうか。
形はどうあれ、Googleと直接接する機会を逃す手は無いです。
ついでに、六本木ヒルズの中を見てみたいという好奇心が手伝って、無茶を承知で鬼調整。

本業はデスマ中なので、無理かと思いましたが、何とかなりました。
人間頑張れば何とかなるものですね。
金曜日(25日)じゃなくて、木曜日(24日)で助かりました。
つまり、金曜日が地獄・・・

という訳で、SHOT05の開発作業はノータッチ。
本業がどんなに忙しくても、開発の穴を空けたくなかったけど、今回は仕方がない。

2013年1月21日月曜日

回してみた

非タッチ状態の場合、オプションが自機周辺をグルグル回る感じにしてみました。

何となく、次にやるべきことのインスピレーションが湧いてきたかも。

ゲームの開発期間中、最も多く浪費する時間というのは、絵を描いたり、音楽を作ったり、プログラムを作ったりする時間ではなく、「次にやるべきことが分からない時間」だったりします。
これを解消するには、目標を小さく持つと良いです。大きすぎる目標は、足枷にしかなりません。
とりあえず、サクッと作れて、動きを見れる程度の小ささが理想。

とりあえず、キャラを表示する。
とりあえず、キャラを動かせるようにする。
とりあえず、ショットを打てるようにする。
 :

私のゲームの9割は、「とりあえず」でできています。

SW発動ギミック・・・

開発機をSonyのVaio-Duo-11という機種に変更。
http://www.sony.jp/vaio/products/VD21/

PM22:00頃、SHOT05の開発環境の引っ越しが無事完了。
出足は調子良く移行できていたのですが、色々とWindows 8固有の問題に引っ張られました。
やはり、まだ早すぎたような気がします。

それはさておき、開発環境が完成してからが絶不調。
サブウェアポンの発動ギミックを考えているのですが、中々良いアイディアが浮かばない。
明日、会社でゆっくり考え、そして帰宅してから実装しようZE・・・という、悪魔の囁きが聞こえます。
ウェルカム、サタン。

合理的ではないものを作りたい

ここ最近、実機版の東方VGSの開発が忙しくて、東方VGSの曲追加が滞っています。 東方VGS(実機版)のデザインを作りながら検討中。基本レトロUIベースですがシークバーはモダンに倣おうかな…とか pic.twitter.com/YOYprlDsYD — SUZUKI PLAN (...