2016年1月31日日曜日

Android アタックダンジョン MMF 開発記<承>

2016年最初の日記(前回)の内容が「成金大作戦」って、まったくダメですね。 YARUKIのYの字も感じられませんが、 1月は、まあ、そこそこ、やりました。 目標の30~40%は達成でしょう。私にしては上出来です。

現在開発中のAndroidアプリ「アタックダンジョンMMF」の進行具合を振り返ってみようと思います。 まあ、簡潔に言うと「ボスキャラに合わせてメンバーを選び、そしてボスを殺す」という RPG におけるボス戦闘の部分+その直前のダンジョン探索3分間だけを 抜き出したようなゲームです。 選べるキャラは18人もいます。そこから3人を選びます。 彼らの個性はぶっちゃけ、戦闘能力のバランス配分だけなんですよね。 ゲームとは言え、それでは寂しいので、彼ら18人の個性を戦闘以外のアングルからも説明してみたい。 で、川柳システムっていうのを考えたんですね。 下の写真みたいのが、ボスを倒したあとに出てきます。

この川柳はメンツの組み合わせによって、ぜんぜん別のものができます。 黒の呪術師バリ・バラなんかは「死んだふり」「サイレンス」「レクイエム」「無に帰る」…という感じで虚無です、ニヒリズム全開です。 緑の魔法使いアピなどは「踊りだす」「走り出したら」「止まらない」…という感じで躍動感に溢れています。 イタリアの都市から名前を付けた青の戦士ラベッロなどは「川辺だね」「イタリアン」「水の都と」「イエスタデーが」…という感じでファッション的です。 こういう感じで参加メンバーのセンスで川柳の仕上がりも変わってくる。 戦闘は強いけど川柳の質はイマイチ…、という組み合わせもあるだろうし、当然逆も考えられる。 面白い試みですね。 問題は、欧米人には理解されないだろう…というところですが、(ゲーム的に有利不利関係なしの)枝葉の部分なので気付かなかったことにします。

ちなみにこの川柳システムは去年の12月頭に完成させたものなので、ちょっと論外なんですけどね。 じゃあ今度こそ1月の達成内容として、消耗品アイテムの実装があります。 これも、7割方は元ネタから輸入しただけで、画面を横構成から縦構成用に作りなおしただけなんですけどね。 下の写真だと分かりにくいかも…ですけどドラッグすることで高速セッティングが可能です。 この画面で行うことに関しては、ゲーム機のコントローラーさばきよりもスマホのタッチパネルが操作快適性で勝利できそうです。

上の写真は、配色がちょっと意図的・人工的すぎる感じがするかもしれません。 しかし、その違和感は正解です。 このゲームでは色が○○を表すということを多用しています。 まず魔法は回復・防御の青、攻撃の赤、補助の黄、と役割が分かれていますし、 武器攻撃は白、アイテムは緑で表現しています。 緑じゃないアイテムは装着することで自動的に仕事をしますが、プレイヤーが任意のタイミングで発動させることができるのは緑属性のアイテムだけです。 青属性のキャラは青魔法が得意だし、青のアイテムを主に持っています。 黄属性のキャラは黄色のアイテム、緑属性のキャラは緑のアイテムをたくさん持っています。

元々横画面だったものを縦画面に移植しています。 これの手間は想像を絶するものがありましたが、敵の絵が小さくなったことによって ドットのキメが細かくなりグラフィックが綺麗になった気がします。 で、まあ下の写真はボスの一つなんですけど、雷攻撃系ですね。 とりあえず11面のうち、6~7面くらいは完成させたんですが、 あとはバランスですよね、ボスと味方キャラクターの。

例えば物理攻撃バカのボスに勝てるメンバーと、状態異常デパートのボスに勝てるメンバーはぜんぜん違います。 これは、いいんですよ、実際にテストプレイでも狙いどおりな感じなので。 しかし、運の要素がかなりデカイので、ベストメンバーで勝てないことも多々あるわけです。 逆に相性があまり良くないメンバーでも、運とノリで勝ててしまうこともあるんですが…。 これがまた難しい話でね、正解だったら絶対勝てる「将棋」的なものは目指していないんですよね。 じゃあ最適解、あるいは準最適解でメンバーを構成した場合、勝率何%あればいいのさ? ということになるんですが。 しかし、確率が絡むとジャンケンで3連勝する人もいれば、サイコロ2つ振って2を叩きだす人もいるわけで…。 だから、昔のファミコンのときのRPGボスなんかは強さの設定が難しかっただろうな、と思いますね。 まあ勝てんかったらレベルを上げればいいんですけどね、それにしたってどのくらい上げればいいの? っていうサジ加減があるわけですから。 まあ、コンティニュー機能を作ればいいと思うんですけどね。 「惜しかったなあ、今の」とプレイヤーが考えた時に「雑魚戦すっ飛ばしてもう一回ボス戦の直前からやれますけど、どうですか?」 と提案するわけですね。 で、そのときにリワード動画広告みたいなこともできたらいいかな、と思います。 いや、むしろコンティニューさせること前提のゲームバランスだったりして…。

2016年1月3日日曜日

成金大作戦という名のゲーム

元旦から今日に至るまで3日間かけてようやくクリアしました。 何って、成金大作戦決定版の通常マップ23-10ステージ目です。 成金大作戦が何かって? そんなのググってくださいよ。 あまりにもバカらしくなるくらい時間を浪費したことに悔いが残る。 記録を残すとともに、もう2度とやらない方向で。 マジで時間泥棒だぜ。

ここに至るまで通常マップ21、22と課金購入してクリアしてきました。 実は4年くらい前にやっていたことをふと思い出して、久しぶりにやってみた次第です。 21、22とも10ステージ構成で、時間のかかる広大なマップはラスト2つか3つだけですが、 ここまではリセットプレイ無しの一発クリアで決めてきました。 いや、やり直した面はあったかもしれないが、2回目でクリアできなかったことはなかったはず。

元旦、相棒を見ながらやっていた頃、難しいとは思うものの、まさかこんな泥沼になるとは思ってもみなかった。 夜中にイラっとしてタブレットを床に投げつける場面が数回。 諦めて寝る。 2日目、もしかしていけるかも? というところまでたどり着く。 おカネがないのに昼間にやったパチンコよりも緊張してきた。 しかし、今までの失敗をふまえてあるポイントを起点にして何回でもリセットしてやり直す作戦を導入する。 まさか、33Tから何回もやり直すことになるとは…。

写真1:ここが問題の激戦地である。この橋をまたいで両軍が激しい争いを続ける。 橋の右側にある赤軍のダブル基地を陥落させることがどうしてもできない。

写真2: 起点となる33Tのときの状況。今にして思うとぜんぜんダメだが、部隊数で赤軍を凌駕しており、 ある程度包囲できる環境には仕上がっていた。

写真3: 赤軍は収入を高めるために都市に投資を繰り返し行っており、だからこそ経済的に劣勢な青軍が敵陣奥深くに攻め込むスキができた。 青軍は都市への投資をかなり犠牲にして部隊を生産し続けた。

写真4:このマップでは海軍が活躍できるエリアは限られており、しかし水辺沿いに都市が集中しているので 制海権を得ることは重要である。

写真5:敵軍陣地の占領が進み、40Tの時点では自軍(青軍)は占拠街数で優位に立ち、収入差もかなり減っている。 しかし、敵軍(赤軍)の部隊数がかなり増えているぞ。 理由は二つあって、投資の完了した赤軍は収入のすべてを部隊の生産・補給に充てることできたのが一つ。 都市などを占領すると占領した側が占領された側へ補償金?を渡すというシステムがあることが一つ。 つまり、青軍がガシガシ占領しているそのとき、大量の資金で赤軍は強力な補強を行うことができたわけです。

写真6:赤軍の首都近辺まで占領したのにも関わらず、敵の大反撃にあって逆に攻め込まれる青軍。 こうなったらもうお手上げ。ジ・エンドです。 何回か33Tからやり直したけど、アレレ…。もう無理なんじゃね? イラっとして夜中にタブレットをぶん投げる。

3日目、途中セーブの33Tを放棄してまた最初からやる。 このマップ、最初の条件は両軍ともほぼ一緒なんですが、敵軍の方が早い段階で都市を大量にゲットできるような構成になっているので、 赤軍は青軍を常に収入でリードし続けます。 序盤はこちら2000の収入に対して相手が3500とかそんな感じです。 リードといっても過剰分は投資に回すので、そこまで戦闘力で圧倒的差にはならないのですが、 膠着(こうちゃく)状態になったら赤軍が超有利です。差が広がる一方ですからね。 つまり、青軍は少ない収入で貧乏部隊を編成しつつ投資もある程度行って、かつ早めに敵地を制圧しないといけない。l

写真7:で、やり直した結果、ベストな状況に持ちこめた。 この橋の右側に見える赤軍の空軍基地に何度も泣かされてきたわけです。 このゲームの常とう手段として遠隔攻撃のできる巡洋艦を配置して、ノーコスト・ローコストで敵軍を撃破するというのがあるんですが、 敵に飛行機系がいるとすぐに後ろを取られて巡洋艦を爆破されるので非常に厄介。 しかし、敵地になるべく接近しないことには巡洋艦の効力も得られないというジレンマ。 そこを安いユニットの大量投入で壁を作ることで解決しました。 武装高速艇は上の方にある港で生産して下ってくるのですが、その際に対岸で中立都市を占領しようとする敵歩兵を撃破します。 つまり、一仕事を終えてからガードの任に着くわけですから合理的ですね。

総じてポイントと言えるのは、 あらゆる小競り合いで負けないことです。 一度仕掛けた戦いは絶対に引いてはいけないし、勝てないのなら攻めないことです。 しかし、攻めきれない以上は守らないといけない。 この二つはときに反転しますので、守りの兵を増強しつつ、いざ勝てる突破口ができたら、機を見るに敏として攻めに転じねばなりません。 機を逸しないためにも防衛ラインは敵拠点に近くなるよう設営すべきです。 取れないけど敵に取らせたくない拠点はグレーのままにしましょう。 占領を妨害して、中立地点のまま中盤まで放置させるようにします。

写真8:今回は青軍の都市への投資も頑張っているので、そこまで相手にリードされていません。 ユニットを生産したいのを必死に我慢して、投資レースに参加しました。 この2000くらいの差っていうのがギリギリな気がします。

写真9:ここまできたら勝ちは確定です。 しかし、敵の部隊数が妙に多いのが面倒です。

写真10:敵地の内部はこんな風に岩山地帯になっています。 悪の軍団の総本部みたいな雰囲気です。 これだと地上軍は進みにくく、空軍をどうしても使いたくなりますし、実際のところ爆撃系が活躍します。 ただし、地上軍を盾にして敵の戦闘機を寄せ付けないという戦法ができないため、敵の戦闘機にバンバン落とされるという難しさもあります。 肉を切らせて骨を断つ、そういう戦い方を強いられます。

写真11:まあ紆余曲折いろいろあったが、チェックメイトです。 最後の方は完全に作業になるのが面倒なところ。 敵も絶対に勝てないんだから諦めて白旗を振ってほしいですな。 例えば単純な陣取りゲームであるスライというゲームでは、COMが劣勢を判断すると降伏を申し出てきます。 スライみたいな欧米系のいいところってのは案外こういうところなんですよね。

最後にこのゲームのだるい要素を批評して締めたいと思います。 課金してるから文句言っていいよね。 とりあえず最大の悪は前述している占領時に発生する補償金?システムです。 戦争しているのに何で敵拠点を占領したときに相手に賠償みたいなコトをせないかんの? 理屈はともかく、 これがあるせいで劣勢の相手が息を吹き返します。時間かかるよね。 あと、成長した拠点を占領するのに歩兵が完全10体の状況で4ターンかかるのもだるい。 まあ成長させた都市だって1ターンで占領できるシステムだったら、逆にプレイヤー側も嫌な思いを多々するだろうから仕方ない面もあるだろうけど…。敵歩兵の動きに常に神経を尖らせないといけないのはシンドイ。 まあ、だから~占領中の歩兵は歩兵でしか攻撃できない、とかの工夫がほしいところ。 敵都市を占領するときは歩兵の周囲をグルッと完全に囲んで守らないといけないのはだるい。 あと生産中の敵ユニットに攻撃できるようにしてほしいですね(もちろん生産中の方は反撃できない)。 敵軍の戦車とかがすぐ横にいるのに、のんびり生産できてしまうあたりがゲームゲームしてて嫌になる、というか面倒くさい。 勝ちが見えてから本当に勝つまでが長いこと長いこと…。 結論としては、何だかんだ言って作業がすき~、ってことで…。

2015年12月31日木曜日

タスクキラーを見切れ!の巻

今回も Android アプリにおけるメモリリークだとかアクティビティーのライフサイクルだとか、そういう話です。 「アタックダンジョンMMF」は12月10日リリース予定でしたが、案の定のびのびとなっています。

先に結論を書いて、そのあとに解説していくというスタイルで今回はいきたいと思います。 まずは、これから。 これは開発途中で棚上げしたマイアプリなんですが、単一のアクティビティーで作られている単純な代物です。 で、右上に 3 という数字が見えます。 これは、3回転したという意味なので、アプリを少しばかり稼働させたという証明です。 で、これを中断から再開します。 中断・再開の間に10時間以上は経過しており、その間にスマホのブラウザでインターネットを50分くらいしています。 つまり、デバイスに負荷を与えてからの再開です。

で、どうなるか。 開いてみたら右上のカウンターが 0 になっています。 これは、初期状態であることを意味します。 中断した後にすぐ再開した場合は、カウンターの値を引き継ぐのですが、今回はデバイス(Android の OS)のメモリ管理でキルされたみたいです。

はい、この単一アクティビティーアプリと同時刻にスタートして中断した別のアプリがあります。 こちらのアプリは3つのアクティビティーを持っており、わざと初期立ち上げのアクティビティー(メインアクティビティー)以外のソレで中断しています。 条件は先ほどと同じです。 中断・再開の間に10時間以上は経過しており、その間にスマホのブラウザでインターネットを50分くらいしています。 改造前は、これで開くとエラーが起きて強制終了でした。 OS のタスクキラーで初期化されているので、参照する変数が null になっていてバグが発生します。 しかし、気を付けて欲しいのは中断時に launching じゃない Activity が前面に出ている場合に限ってこういう事態になるということです。 確かにさっきの単一アクティビティーのアプリでは再開時に何事もなかったかのように初期化されており、 エラーは発生しませんでした。

このエラーってやつが発生するとユーザー様は怒り絶頂になるので、エラーは根こそぎ解決してからリリースしたいとマジで今回は思っています。 結局のところ、メモリの都合上、それなりの時間が経過するとアプリは初期化されるようです。 で、今回仕込んだ解決策は、これを根本的に解決するというものではなく、 (中断再開時に null になった場合はアプリ側の処理で初期化してスタートするだけのこと) ―――エラーが発生するかどうかって違いしかありません。 しかし、こうやってエラーを蛇蝎(だかつ)のように嫌い、斬って斬って斬りまくる姿勢を徹底することは素晴らしい…ハズ。 ユーザー様からの評価を、三次元的広角領域から得られるものだと確信しております。

moveTaskToBack(boolean nonRoot) という処理を行い、 OS側でアプリをデストロイしてもらうようにしました。 もちろん、デバイスがメモリ不足になった場合のお話ですけどね。 破壊を適正に行うためにバックグラウンドで待機する仕様みたいです。 つまり、仮死状態で待ちながら本体であるアンドロイドOSさんが 「なんかメモリのやりくりきつくなってきたんですけど」ということになれば、自らを破壊することで端末の負担を軽くするみたいですね。

仕組みとしては、イリーガルな中断の場合に必ずメインアクティビティーにバックさせるようにしています。 で、メインの onResume() で、他のアクティビティーから数値を初期化せずに戻ってきたかを判別して、 初期化されていなかった場合は moveTaskToBack(boolean nonRoot) という処理を行います。 しかし問題があった。なぜかゲームの流れでメイン→マップ→バトル→メイン→マップというアクティビティー遷移のサイクルを行うと、 突然アプリが終了してしまうという不具合が発生してしまう。 これの解決は、moveTaskToBack(boolean nonRoot) という処理を行う際にわざと0.5秒の待機時間を 発生させることで解決できました。 これは、なぜそうなるのか? には踏み込まず、対処療法でまあいいかと華麗にスルーしていきたいところです。

ちなみに、中断してすぐ再開した場合はフツーに中断地点からの再開となります。 BGMだけは頭に戻りますが、その他の状況は中断したときと同じです。 変数の初期化を onCreate() onResume() onStart() などで行わないようにすれば、これは可能です。 スマホなんで、どうしてもプレイしている状況が多岐にわたります。 家でガッツリとマジでやっている可能性は低いので、 職場の休憩時間でやっていて「ちょっとおお!」と呼ばれてゴニョゴニョしないといけない様な不安定なシチュエーションを想定するしかありません。

余談ですが、マシンの性能は日々向上しているのだから、メモリ不足はスペック改善によって解決されるのではないかね? と考えたいのですが、 実際は Android5.0 以降で新機能を実装したが故にメモリ関係のクラッシュを連発したりするようで…やれやれです。 Windows7 より後発の Windows8 が無駄機能がゴテゴテしすぎて遅いやないか、とユーザーから不評だったのと似ています。 やはり人間は業の深い生き物です。 それが現状なので、アプリ作成者は「いつ何時、どんな風にでも」終了できるようにアプリを設計すべきなのでしょうね。

終了といえば今年も終わりです。 「アタックダンジョンMMF」は12月10日リリース予定でしたが、その辺までは割と真面目に作業に励んでおりました。 逆に12月10日以降はほとんど手を付けなくなって本日に至ります。端的に申してやる気の問題です。 来年になったら頑張ろう。

2015年11月23日月曜日

いまさら、だけど Activity の遷移と終了について

ツールでもゲームでも複数の土台を持ちたい場合がありますよね。 土台というと分かりにくいけれども、例えば単純なゲームであるインベーダーやテトリスなら、 タイトル画面とメイン画面だけ用意すればいいですよね? でも、 Wiz(3D迷宮RPG) なんかだとタイトル画面、街滞在中の画面、3Dダンジョンの画面、戦闘画面、といくつか必要になりそうです。 Android でアプリを作る際には、 画面のデザインが異なる場合は、そのデザインパターンの数だけアクティビティーを作ります。 これが面倒なら、一つのアクティビティーで複数のレイアウトを使い回すこともできます。

アプリを複数のアクティビティーで分割管理することにはいくつかのメリットがあります。 まず、プログラムの構成がアカデミックな感じになります。 インデックスといいますか、大分類>小分類みたいな感じで、大量に発生してしまう Class(特定の役割を担ったプログラムの塊)を、 上手に仕分けることができます。 上手に整理すれば、どこに何があるのか分かりやすいし、機能を変更・追加する場合にしたって最小限の労力で作業を終わらせることができます。 整理がきっちりされている方が、バグや不具合が発生しにくいという側面だってあります。 それに、実際に使う部分だけのリソース(画像ファイルとか)を読み込ませることで、 マシーンの負担を軽減させることだってできる。 メリットはたくさんあります。

で、結局のところ、ある程度以上プログラムの規模がでっかくなりそうなときは、 素直にアクティビティーを複数作って、作業を分業化する方が効率的です。 複数のアクティビティーがあるということは、 アクティビティーの遷移と呼ばれる行為が必要となります。 これは、要するにアクティビティーAからアクティビティーBにジャンプするという行為です。 これによってAは後ろに下がり、Bが表に出てくるということになります。 これは、Android でプログラミングする際の超基本なんですが、ちょっとちょっと今さらながら、理解を深める必要があると思っている次第です。

finish() で現在、進行中の Activity を終わらせる。そう思っていた時期がオレにもありました。 と、いうか今まで当然のようにコレを行っていた。 が、しかし、Activity の終了を明示的に行わない方がいいらしい。 どういうことか? つまり、Activity の遷移だけ指示して、あとの終了過程はお任せしてしまうのである。

Activity には3つの状態がある。
実行中:表に出てきていてアクティブな状態
一時停止:表に出ていないが、一部が見えているケースもある
停止:バックグラウンドであり、見えない。システムによって終了させられやすい
一時停止と停止のときは、まだ完全には死に絶えておらず、変数なども破棄されていない。 メモリの余裕がなくなってきた場合は、停止状態のアクティビティーが優先的に廃棄される。 一時停止状態も場合によっては強制停止される。 つまり、メモリが不足してきた際に、自動的にアクティビティーを強制終了させるという 便利システムをアンドロイドさんが搭載しているので、終了過程は端末にお任せすればよいということみたい。 現に携帯は、ブラウザ、電話、メール、Playストア、YouTube、ゲームA、ゲームB、ゲームC、電卓、メモ帳…みたいな感じでいろいろなアプリを 同時並行的に使いますからね。こういう乱立状態の中で上手にメモリをやりくりしようという Google さんの知恵がシステムに反映されているようです。

で、Android のプログラミングをやってみようという入門書に必ず書かれているライフサイクルというものがある。 特定のタイミングで自動的に呼び出されるメソッドがあるから、そこで初期化とか終了処理とかするといいぜ、という奴である。 一発目の初回に起動させた時は、 onCreate()→onResume()の順で呼び出される。 終了するときは、onPasuse()→onStop()の順で呼び出されるし、 再開時は、onResume()のみが呼び出される。 アクティビティーを強制終了させない限りは、onCreate() の部分はショートカットされるようだ。 また、本当に強制終了されたときは、onDestroy()が呼び出され、 この状態からアプリを開いたらご丁寧に onCreate() からスタートするみたいだ。

onCreate() に記述する内容は最低限にしておかないと、 onCreate() の中身がスルーされてしまうかもしれない。 onResume() に記述しておけば、確実に実行されるだろう。 onCreate() や onResume() で変数の初期化を行うと、再開時に微秒なことが起こるので気を付けないといけない。 このあたりは、よくよく注意してプログラミングしないとバグを引き起こす元となりますよ。

再開時は、最後に開いていたアクティビティーから復活するのが基本です。 例えば、MainActivity→FieldActivity→BattleActivity という具合に遷移していって、 最後のバトルアクティビティーをやっている最中にホームボタンで中断したとしましょう。 このとき、BattleActivity から再開しようとするが、ここが finish() されていたら、一つ前の FieldActivity から再開されてしまう。 とにかく、 finish() を使ってアクティビティーを強制終了させると逆に混乱を産んでしまうので使わない方がよいだろう。

また、バックキー押したときの対応だが、一つ前のアクティビティーに戻るものの、 変数の初期化に失敗してチグハグなことになりがちなので、特にゲームではバックキーそのものを無効化してしまうのが最も簡単な解決策となるでしょう。

セーブと一時保存

ここまで書いているのは、あくまで一時保存からの再開です。 一時保存なので、保存の信用性はそれほど高くありません。 スマホの使い方によって個人差が著しくあるでしょうが、1ヵ月の間に1、2回程度はデータが消失するリスクがあります。 クリアまでに1時間以上かかるようなゲームであれば、セーブ機能を付けるしかないでしょう。 特に今の時代ともなれば、オートセーブが必須でしょう。

ただし、何でもかんでもオートセーブを小刻みにすればよいわけではありません。 例えばRPGで、絶対に勝てない状態から再スタートしたならば、プレイヤーは対策がないまま全滅を繰り返すしかありません。 将棋でいう「詰みの状態に入るより前」から再開できないと、やり直しようがないのです。 もし、20時間もプレイしたところでこの手の「セーブハマリ」に直面したら、プレイヤーの落胆は深く苦しいものになるでしょう。 哀しみは怒りへと変わり、「二度とやるかボケッ!」と吐き捨てて、アンイストールするにちがいありません。

あらゆる変数が、どのタイミングで初期化され、どのタイミングで更新され、どのタイミングで保存されるのか? と そこまで考えた上で設計するのが理想的なのだろうが、そんな細かいことできるわけねぇっ、と思わずにはいられません。

メモリーとヒープ

元々「男男女ダンジョン物語」の頃は、Activity の finish() をやりまくっていた。 これによって、オートセーブが実施される拠点にいるとき以外(ダンジョン探索中、会話イベント中、戦闘中)に 中断してしまうと、また拠点からやり直しというコトになっていた。 一回の旅路が5~10分程度で終わるものだから、それでもいいやと考えていたが、 いざ、中断復帰システム(アクティビティーを強制終了しないやり方)に切り替えたら、中断→再開がサクッとできるのはスゴイし便利だと思った。

finish() しまくるやり方は、プログラム技術が未熟なため、そうしていた面が大きいが、 メモリの解放という意味合いも無いわけではなかった。 メモリが不足してきた際に、自動的にアクティビティーを強制終了させると先ほど書きましたが、 これって「Aのアプリを実行中に、Bアプリの(そんなにいらない)アクティビティーを終了させる」ということではありません。 いや、そういうケースもあるのかもしれませんが、 「Aのアプリを実行中に、メモリが不足したのでAのアプリが強制終了する」ということが起こりうるのです。 いわゆる "out of memory" ですね。 これは、一般ユーザーの方も多くが経験をしていることでしょう。 一般ユーザーはエラーで落ちた場合、何が原因なのかまでは把握することはできませんが、 間違いなく「アプリがバグる原因BEST3」に入っている因子です。

今回、「アタックダンジョン MMF」では臨機応変に中断→再開ができる仕様を目指して、アクティビティーを殺さない「不殺」主義を貫きました。 しかし、開発が進展してテストでプレイする量が長くなってくると、、、早くも「アウトオブメモリー」による強制終了が出たあぁ! 困ったぁ。 largeHeap という技を使えば解決できるのですが、メモリの使用量を自力で抑える努力も必要だとのことで、なるほど、なるほど。 秘奥義「羅味曾父(らあじひいぷ)」を使わずに、現場の技術で何とかなるまいか? こんな開発半ばで秘奥義に頼るようでは、今後必ず追いつめられる…。
で…。
結局、アクティビティーが遷移するタイミングで用済みのアクティビティーをキッチリ終了させてやった方がメモリは解放できそうです。 実際にテストしたところ、finish() を多様するほど「アウトオブメモリー」を回避できるという結果が得られました。 というわけで「不殺」の誓いを早くも破る方向で、アクティビティーを殺しにかかります。

「ちょっと待てよ!」と、心の中から反論が飛んできます。 臨機応変に中断→再開ができる仕様を目指してたんじゃないのかと? そう、そうなんだけど…。 ただ、これは意外と簡単に解決できまして。 要するに onPause() 内で、特定の条件を満たした場合だけ finish() するように if で分岐させます。 特定の条件とは、正常なルーチンの流れでアクティビティーが遷移するときです。 だから、ホームキーを押して強制的に中断した場合などは onPause() が呼び出されても、finish() は実行されません。 あくまで、次のアクティビティーに切り替わったときだけ、finish() させるという構造です。 これによって「アウトオブメモリー」を回避しつつ、中断→再開も自由自在という無敵仕様が完成しました。 やればできるじゃん。

2015年11月19日木曜日

Wow... アイツが殺されたワケを知りたいって?

今回の記事は個人開発者である私が、 将来しくじらないように自戒の意味を込めて執筆します。
for me

最近、何が流行っているのかまったく理解していないんですけどね。 ネットで「君の目的は僕を殺すこと。」というアプリの記事を読んだので、 アプリダウンロードのページ(GooglePlay)に飛ぶボタンを押したら…
接続されない。
ちなみに、GooglePlay の検索で「君」と入力するだけで「君の目的は僕を殺すこと」と 出てきます。 これは、検索ワードとして有力であるという証…。 で、作者自身が「私はGoogleに嫌われたようだ」的なことを発言されていますので、 どうも消されたみたいですね。

以下に記す内容はすべて推測ですので、話半分で読んでください。

上記の人気アプリが Google から削除された理由は、 グーグルのガイドラインに抵触したからだと思われる。 キミボクiPhone版の記事がいくらでも見つかるので、そこからヒントを探したところ、 何が神の逆鱗に触れたのかは容易に推測できた。

広告を見ることに対して見返りを与えた

ゲームのメインキャラである魔人さんが「他の面白いアプリのビデオがあるんだけど、見ないですか?」 みたいなことを発言します。 で、CMを見たら本来は30分に1度訪れるフィーバータイムがすぐに訪れます。 30秒の広告動画視聴の対価がフィーバータイム獲得なのです。 フィーバータイムとは放置ゲームでよく使われますが、いつもより大量にゴニョゴニョをゲットできるぜ! というタイムサービス(サービスタイム?)のことです。 業界用語で言えば、リワード広告の一種であるとカテゴライズできますね。

レビューに対して見返りを与えた

魔人さんが「あなたにお願いなんですけど、ゴニョゴニョフガフガってレビューに書いてくれないかな? お礼はさせてもらうよ」みたいなことも発言します。 実際は、ユーザーがレビューを本当に書いたのかを追跡するのは技術的に困難なので、 レビューページに進んだら「レビューを書いたという扱い」になると思います。 つまり、ボタンを押してリンク先に移動した時点で報酬が発生します。 それはさておき、お礼が欲しくてレビューを書くユーザーはいくらでも存在することでしょう。 お礼は定番のコイン(ゲーム内通貨)みたいですね。

放置ゲームの収益性が高いと言われる理由はよく分かります。 放置ゲームの基本は何もしなくても、進行すること。 だから、やることがないから広告をタッチしやすい! こんな単純な理論で終わるつもりは毛頭ありません。

放置ゲームでは世界観が重要。 ユーザーは続きや先が気になって、進行を早めるために操作します。タップだとかスワイプだとか、連打であるとか。 タップやスワイプによって、何もしなければ1分かかるところがググッと短縮されて、10秒とか5秒になります。 この、何らかの介入を行うことによって時間を早めている錯覚を起こさせるところが、放置ゲームの妙技と言えましょう。 要するに、広告を見るのも、レビューを書くのも、介入の一種なわけです。 ゲーム感覚で広告を見るのです。 レビューを書くのです。 介入によって時間を圧縮するのです。 「誰にでも平等であるはずの時間」、これを意図的に操作するという神の気分を味わえるのが魅力なのです。

(割とどうでもいい内容の)ビデオやDVDを見るときに、「早送りできるかできないか」というのは超重要です。 早送りができなければ、見るのが苦痛で途中でやめてしまうレベルのものでも、早送りができれば興味のあるところまで進めればいいだけなので、ぜんぜん楽しめます。 おもいっきりエロビデオの話ですが。

脱線しすぎたので、話を元に戻しますが、Google さんは「報酬をあげるからチョメチョメしてよね」というやり方を嫌います。 まずは、「広告を見ることに対して報酬を与えた」の件ですが、 「水着で鬼ごっこ~ポロリもあるよ~」などの広告を見ることでゲームが有利になるタイプのアプリが無事であることから考えるにセーフなのではないかと。 2015年11月現在、インタースティシャル広告に関しては細かくメスを入れてきているみたいですが、 エサをぶらさげて広告を視聴させることはグーグルさんは容認している。 その一方でレビューを誘導する方の問題はどうなのでしょうか? 以下は Google Play デベロッパー プログラムポリシーからの引用です。

● デベロッパーは、不正なインストール、レビューや評価に対する報酬やレビューや評価の捏造といった不正な手段や~(中略)~よって、 ストア内でのプロダクトの掲載順位を変更しようとしたり、プロダクトの評価やレビューを操作しようしたりしてはいけません。

レビューや評価に対して報酬を与えることにはレッドカードのようです。 つまり、「このアプリのレビューをしてくれませんか?(報酬は何もなし)」なら問題ないのでしょうが、 「このアプリをレビューをしてコインをゲットしませんか?」だとポリシーに引っかかるということです。 これが、「君の目的は僕を殺すこと。」のAndroid版が惜しむらくもプレイストアから削除された顛末です。

2015年11月15日日曜日

Android アタックダンジョン MMF 開発記<起・参>

(タテ)と(ヨコ)の操作性を考える

オリジナルの「男男女ダンジョン物語」は横固定画面(landscape)でした。 横固定画面だと、(床に置いていない限り)両手で持つしかないので、 デザインは楽です。 スマホを横向きで両手で持ったら分かると思いますが、 右手の親指と左手の親指でスクリーン上の全領域をカバーできます。 つまり、どこにボタンを配置しようが「押しにくい」ということはないのです。 タブレットまで考えると、レイアウトはなめちゃいけないんですが。

↑ Landscape

横画面両手持ちは、サッカーのゴールにキーパーが2人いるようなものです。 2人いるだけに、すべての領域をまんべんなくカバーできます。

で、今作っている「アタックダンジョン MMF」は縦画面固定(portrait)です。 縦画面の操作は次の2パターンがあると思います。
・片手で持って、反対の手で操作する
・片手で持って、持ち手で操作する
どうせ縦画面にするのなら、後者でしょう。 右手にコーヒー、左手にスマホ。 左手にタバコ、右手にスマホ。 右手が吊革、左手がスマホ。 人生には、片手しか使えない場面も多々あります。 ただし、片手で持って操作するためにはボタン配置を寄せないとダメです。 押さないといけない場所がスクリーン全領域に点在していたら、 縦画面である魅力は半減し、マイナスばかりが目立つようになります。

↑ Portrait

普通片手でスマホをタテに持てば、デバイスの下の方を持つ形になります。 その際にフリーになるのは親指でしょう。 で、親指が無理なく楽に動かせる範囲というのは、画面下半分の領域と言えましょう。 文字入力する際にテンキーみたいな疑似キーボードがでてくるでしょう。 アレの範囲っていうのがだいたい画面下半分ですからね。

縦と横のどちらにもメリットとデメリットがあるので、一長一短です。 ですが、ゲームの場合はカテゴリによってどちらを選ぶ方が無難か? という傾向はありそうです。 アクションやシューティングの場合はスクロール方向が縦・横どっちなのかという方が重要になりそうなので、ここでは割愛します。 RPG の場合は、縦横両方ありますが、縦の方が主流の気がします。 やはり時代は気軽に、手軽に、ポチポチ系なのか??? ソシャゲも一周回って古くなってきた感がありますが…。

でも今回、わざわざレイアウトをいじる手間を犯してまで縦画面に変更した私である。 何だかんだいってタテの方がいい理由があるんじゃないの?
 ああ、そうだ…。
タテ型だと画面底部にちょうどいい「広告枠」がある。

デザインっていうのは「見る枠」「操作する枠」「遊びの枠」「広告の枠」、すべてを見据えて行わなければならない。

2015年11月7日土曜日

Android アタックダンジョン MMF 開発記<起・弐>

「アタックダンジョン MMF」製作中です。 公開は目指せ2015年12月10日。

徐々に製作中のアレやコレやを小出しに見せていくことで、 アプリの宣伝になればええなぁ、という淡い期待を抱いて年内は開発記を続けてみたい。 どの色好きなの? ということで、キャラクターの紹介です。

白の魔女「スノー」
氷の魔法を極めた熟女。欧米人は老けて見えるから、意外と若いかもしれないが…。 メンバーとして連れて行けば頼もしい味方として大活躍してくれることだろう。 初期装備はマナの帽子。
黒の魔女「バリ・バラ」
エキゾチックな呪術師。魔法使いは基本的に魔抵抗の値が高いが、彼女は最大値を持ち、敵の特殊攻撃を受け付けない。 初期装備は魔除けの帽子。
赤の魔女「スコーピオン」
悪魔族の魔法使い。デビルレディーですね。赤LV7魔法、エナジーフレアは超強力。しかし、青LV1のシールドを受け付けない体を持つので、 ガードが弱いという欠点を持つ。角が生えているが、これが頭装備扱いとなる。もちろん、換装はできない。
青の魔女「ローティー」
青枠はエルフの設定です。スコーピオンと同じくエナジーフレアを使えるが、下位の赤魔法をほとんど習得していないというお茶目な一面も。治療系の青魔法は得意。初期装備は月光の鉢巻き。
黄の魔女「ヒョウ」
黄枠はダンマスでいうところのイアイドー枠ですね。タランティーノとかリュック・ベッソンが描くデタラメなジャパニーズ・ニンジャ・ゲイシャ・スパイス・ガールに仕上がりました。 ただし、刀を持っているのは伊達ではなく、魔女の中では唯一物理攻撃で敵を切り刻める。肝心の魔力はふつう。舞踏会の仮面によって素早さが激アップしているが、消耗アイテムを装着することができない。
緑の魔女「アピ」
マレー語で炎を意味する、だったと思う、アピさん。最初の予定では、緑枠はアース・サンダー、アース・ウインド、アース・ファイアの3人にするつもりだったのですが、名前短い方がいいよね、欧米系の命名体系は半分までに抑えた方がいいよね、などの考えから「雷」「風」「炎」をマレー語に変換する作戦に変更しました。頭の形が人間と異なるので、専用装備です。

6人もそろえばお祭り騒ぎ。ハロウィンっぽくていいですね。えっ? 何か既視感のあるキャラがいるって? き、気のせいじゃないのかなあ…。

2015年12月XX日(予定)まで待てないよ、という人はこのアプリで長い夜を過ごしてみてはいかがでしょうか? 「アタックダンジョン MMF」 の元になっている作品です。
「*男男女・ダンジョン物語*」