2012年2月29日水曜日

公開直前

InvaderBlock2の公開が間近ですが、色々と変更します。

(1)価格設定 → 最低価格にする
実は、有料だと全然売れないと思っているのですが、それでも、「値段の所為で売れなかった」という事態を避けるため、最低価格に修正。(そもそも、元々は無料で配ろうとしていたぐらいだし)
とはいっても、100円が99円になっただけですが。

(2)コピー防止機能 → 入れない方向とする
外的に埋め込むモノとはいえ、これが原因で何か起きた時に何も対処出来ない(しかも、間もなくサービス終了するという勧告もある)というリスクを避けるため。
そもそも、全然売れないと思うので、あまり目くじらを立てる必要も無かろう・・・と、推測してます。
そして、仮に1本でも売れた場合、その購入者に確実なサポートができなくなる方がマズイ。

ついでに、売れるとしても日本か米国のみだと想定している(和文と英文しか準備していない)ので、あまり心配する必要は無いでしょうし。ちなみに、BSAの調査(2010年版)では、日本、米国、ルクセンブルクの不正コピー率の低さは世界1位です。
http://www.bsa.or.jp/press/release/2011/0512.html

という訳で、対策を講じるとしても、ライセンスサービスの内容を把握して第二弾以降で。
完全に購入者の善意に委ねます。
先日の記事で「違法コピーを望まない旨の意思表示云々」言ってましたが、ソフトウェアの開発者サイドで違法コピー=不利益を望む人なんてそもそも居ないですし。

あとは、約3時間後に(24:00を回ったら)公開ボタンを押すだけ。
審査とかに数日掛かったりする・・・なんて、オチが無いことは事前に確認済み。
実は、今日気付いて確認したんですが。危ない危ない...

一応、公開できたら自腹で購入テストをする予定。

2012年2月28日火曜日

いいかも・・・

InvaderBlock2は、AndroidManifest.xmlでポートレイト・モード(android:screenOrientation="portrait"=縦画面固定)にしていたのですが、アスペクト比調整のデバッグで横画面にしてテストしたりしていました。

・・・で、気付いたんですが、私がデバッグに使っているタブレット(7インチ)は、横置きでアスペクト比調整すれば、ピッタリ、スマートフォンサイズになります。

で、先ほど気にしていた16スロットの問題が本当に押し難いかチェック。
普通に押し易かったです。

とりあえず、スロット数を減らす修正は入れなくて良さそうです。
ターゲットユーザがスマートフォンなら、7インチ横置きでテストするのがベストかもしれない。
(ただし、リリース時はポートレイト・モードに戻すけど)


本当は、ターゲットユーザがスマートフォンなら、スマートフォンでテストするのがベストですが。。。
スマートフォンは高い・・・ランニングコスト的な意味で。

アスペクト比修正など

本当に3月1日にリリースする気があるのか・・・?
というぐらいの問題が発覚。

InvaderBlock2は、QVGAの縦置き(240x320ピクセル)という画面仕様で、デバッグ用のAndroid機は、画面がデカイけど、比率はそんなもんだろう・・・という想定で画面一杯に拡大していたのですが、どうも、手持ちのデバッグ機は600x1024ピクセルというサイズ(QVGA=横0.75:縦1.00と比率が違う)でした。

その問題は、アスペクト比調整する修正を入れて軽く直しました。
しかし、画面が小さくなると、セーブスロット(16個)を選ぶ作業が大変・・・
そして、スマートフォンだともっと画面が小さいから、もっと大変・・・という問題も発覚。
何を今更・・・と、思ってますが、セーブスロットを16個→8個に減らそうか検討中。
(会社が休みだった昨日の内に気付かなかったのが悔やまれる)

2012年2月27日月曜日

難易度調整

簡単過ぎるゲームは好きではありません。
昨今のゲームは簡単すぎるものが多い。
しかし、単に難しければ何でも良いという訳でもありません。
恐らく、適度な達成感の得られるゲームというのが、最善です。

という訳で、InvaderBlock2の難易度を調整。
ボールの動きを少し遅くしてみたり...etc
こういう部分は、一度リリースしてしまうと「リプレイデータの互換性」という柵ができてしまうので、変更可能な唯一のタイミングが今です。単なるバグなら、アップデートで更新できる仕組みがあるから、こういう部分の調整に力を入れるのが吉だということに、本日夕方頃、気付きました。

実は、Androidの場合、画面(SurfaceView)の更新間隔が16msに1回のようです。
つまり、秒間の描画回数は62~63の間。(62.5fps)
Windows(DirectGraphic)のフルスクリーンのゲームであれば、簡単に60fpsに調整できますが、実はこの60fpsというのはあまり良い数字ではありません。60fpsだと1秒(=1000ms)で割り切れないので。(16.6666666....msになってしまうから、例えナノ秒精度でウェイトしてもダメ)

つまり、60fpsにしようとすると、16ms→17ms→17ms(50ms/3回)の不均等な間隔で描画する必要があります。そうすることで、1000ms÷50ms=20になり、20×3回=60fpsという具合になり、めでたく60fpsが実現できる訳です。(ハードウェア的に60fpsをサポートしているGPUの場合、もっと細かい単位(μ秒やナノ秒単位)でズレを設けているかも・・・ハードには疎いから分かりませんが)

例え1ミリ秒であっても、不定期にズレが生じると違和感を感じることができます。
(故に、ガーベージコレクションというのはかなり厄介なシロモノ)
しかし、3回に1回という形で規則的に動作すれば、脳(視覚)は「均等に動いている」という錯覚を起こします。つまり、60fpsというのは、錯覚の原理を利用しているのでフレームの視覚的均一性は、実は幻だった・・・という訳です。ただし、人間は時間の単位を基本的に60進法で管理するので、60の方が良いのかも(=1ミリ秒を1/1000秒としたのが誤りなのかも)しれませんが。

余談が長くなりましたが、要するに
「Android版InvaderBlock2は62.5fpsで、それを60fpsに調整する気はない」
ということです。(Windows版も公開時は62.5fpsに調整予定)

しかし、当初Windowsでは60fpsでテストしていたので、ゲームスピードが4%速くなってしまいました。
その分(4%)を調整するためにボールの速度を調整・・・という訳です。
もちろん、これの所為で達成感を損なうレベルに難度が落ちる事だけは避けたい。
なので、慎重に調整します。

公式HP

公式HPでInvaderBlock2の情報を開示。
http://hp.vector.co.jp/authors/VA040196/android/

シンプルに纏めました。
(トップページもシンプルに修正)

動作環境・公開先・(予定)価格は、今後作るゲームで皆同じにするつもりなので、第二弾以降を出したらレイアウト変更が必要ですね。

一応、第三弾ぐらいまでは、作りたいゲームのアイディアがあります。
第二弾は、シューティング(SHOT04)の予定。
予定は未定ですが。
しかし、タッチパネルでシューティングというのは、操作性の面が悩ましいです。ただし、ちょっとしたアイディア(もちろん、ゲームパッドなどの外部ハードは不要)があるので試してみたい。

あと、外部ハードで思い出しましたが、以前の日記で「タッチペン推奨」と書いていたかもしれませんが、試しに、600円ぐらいの安価なタッチペンを買ってきて使ってみたら、結構微妙でした。
結構筆圧をかけないと、反応してくれない感じです。
もうちょっと高価なタッチペンじゃないとダメかな?
本質的な仕組み(先っちょ部分)に大差は無いようだったので、定かではないですが。
現時点のInvaderBlock2は、指で快適に操作可能なので、高価なタッチペンで試す予定はありません。

アップロードまでの流れ確認

3月1日にInvaderBlock2を公開すると決めたは良いんですが、これまでの流れから推察して、
「色々と手間取ってリリース遅延するんじゃないか?」
と、心配になったので、アップロードまでの手順をギリギリの所(公開する直前)まで進めてみました。
「保存」をやったのに、何故か保存されなかったようですが、手順は把握しました。
概ね問題ありません。

ひとつ問題になったのが価格設定。
とりあえず、米ドル基準で1$の価格設定をしようとしました。
なので、日本円なら79円ぐらいということで80円。
1本あたりの私の利益は、56円。(Google按分が30%のため)

マーケットアカウント取得費用(約2000円)+英作文費用(約500円)の原価を稼ぐのが目標。
なので、約45本売れればプロジェクト成功です。
一応、デバッグ用のデバイス購入費や参考書(2冊)の購入費の設備投資費用もありますが。

・・・しかし、どうも最低価格というのが有るらしく、日本円なら99円が一番低い設定らしい。
という訳で、米国=1$、欧州=1€、日本=100円という価格設定にします。
この方がスッキリして良いと思います。
端数はあんまり好きじゃないから、ワンコインでお釣り無しが良いので。(皆、クレジット決済でしょうけど・・・)

という訳で、1本あたりの私の利益は、70円にハネ上がりました。
目標売り上げ本数は約29本・・・これなら、なんとかなるかな?
微妙です。
というより、1本でも売れるのかが疑問。

あと、どうでも良いですが、YouTubeの動画はフルアクセス設定に修正。

不正コピー防止処置

Androidマーケットで公開するアプリケーションの防止処置としては、

  • コードの難読化
  • コピー防止(将来廃止予定)
  • LVLの実装(Googleライセンスサービスの利用)

の3種類があるようです。

コードの難読化は、Java特有の事情でしょう。
なので、InvaderBlock2(殆どCのみで実装)ではほぼ影響なしだと思います。
※ただし、ARMの逆アセンブルは、6502系統だけあって純RISCアーキテクチャ(Rシリーズ等)と比較して解析し易いと思いますが。

コピー防止は将来廃止予定とのこと。
とりあえず、root化した端末で簡単にコピーできない程度のもののようです。
外的にAPKに埋め込むものらしいので、恐らく、突破は簡単。
外的にAPKに埋め込むから導入も簡単。

LVLは、コード変更が必要。
サンプルと解説を斜め読みした限り、通信が発生しそうな気がしています。
結構複雑なので、読みきれてませんが。

・・・で、「何をやり、何をやらないか」ですが。

  • コード難読化 → 殆どCで実装しているからやらない
  • コピー防止 → やる
  • LVLの実装 → やらない

かな。

InvaderBlock2は今のところ通信処理を一切入れていないです。
アフィリエイト広告はヤメにしたので。
折角、無通信&処理も軽い電池にやさしいアプリなのに、LVLのためにそれを行うのは・・・

もちろん、不正コピーの横行は防止したいですが。
しかし、公式ドキュメントを未だ理解しきれていない。(結構複雑です・・・英語だからかもしれませんが)
その状態で実装を入れるのは、かなりリスクが高い。

最低限のコピー禁止の意思表示はコピー防止の導入で伝わる筈。
そもそも、悪意がある人への防止は、如何にLVLを導入しても難しいと思います。

という訳で、利用者の善意に委ねるのがベストと判断。

動画を投稿完了

InvaderBlock2の動画を投稿完了。
http://www.youtube.com/watch?v=ecYfLS14WZc&feature=youtu.be


URLダイレクトアクセスで見れる設定なので、多分上記リンクからなら見れる筈。
Androidマーケット公開時にフルアクセスにします。


しかし・・・画質が、粗い。
YouTubeエンコで30FPSになったので、フレーム間隔で表示しているものが、見えたり、見えなかったりしているし・・・まぁ、良いか。

ちなみに、1回撮影後に画面の細かい仕様変更をしたため、TAKE-2です。
あと、ゲームは実機ではなくWindows版です。(カメラが無いので、Android版は録画できない...)

宣材なんだから、もっとシッカリ編集したいところですが、動画編集系のツールは持っていないので、未編集のノーカット放送でお届けしています。(ゲームのプレイはリプレイ再生ですが)
そもそも、開発機のメインPCのCPUがAtomなので、動画編集など無謀。。。

2012年2月26日日曜日

InvaderBlock2のリリース予定日

3月1日リリース予定です。

残す作業は、

⑤最終デバッグ
⑧紹介文(英語)執筆
⑨紹介動画の録画

明日、会社が休みなので、⑨(動画)は今日~明日中にはできる筈。
⑤(最終デバッグ)は、バグらしいバグはもう無いので、Windows版の方でデバッグコードを仕込んで、通常ではありえないケースの検証をしたりします。これも今日、明日中には完了する筈。

一番の難関は⑧(英文)。
⑧(英文)は、会社の英語が得意な人(TOEICが900点台?の人)にお願いする予定。
私も一応、英検4級をもっているので、そこそこデキるんじゃないかと思っていますが、念のため。
今回の開発での唯一の他力本願部分。
煙草一箱で引き受けていただく請負契約を口約束で締結済み。

あとは、Android版の公開が完了次第、ホームページに紹介ページを作って、Windows版(無料)の配布を開始する準備とか。ちなみに、Windows版はVectorに掲載する予定なので、掲載は早くとも3月中旬頃だと思います。

Android特有のバグ

今回、Windows版を最初に開発し、Android版へ移植という開発プロセスで開発してきました。
総括してみると、Windows/Androidでのプラットフォーム誤差というのは、大して無いです。
なので、この開発プロセスが一番生産性が高いんじゃないかな?と、思っています。

唯一、悩んだWindows/Android間のプラットフォーム誤差は、
タッチを離した瞬間の座標情報
です。

Windows版の場合、デバイスの入力にマウスを用います。
そして、
  • マウスのクライアントウィンドウ内での座標情報をタッチ位置
  • マウスの左クリックの状態をタッチ有無
という感じで入力情報を取得していました。

で、ゲーム中のボタンなどについては、タッチを離した瞬間(1フレーム)を判定機会とします。
その時、タッチを離した瞬間の座標情報が当り判定する位置となります。
マウスの場合、タッチ状態(左クリック)を離しても、座標情報は生きています。
しかし、Android(タッチパネル)の場合、タッチ状態を離すと座標情報も死にます。

冷静に考えてみれば、当たり前のことなんですがね。
しかし、このバグ原因を究明するのに結構時間が掛かりました。(2時間ぐらい)



まぁ、上記の問題はプラットフォーム依存コード(=VG-Engine)で吸収できます。
なので、VG-Engineの設計ミス。

こういうマイクロな問題を単純な「アプリケーションのバグ」ではなく「設計ミス」と認識することが、共通プラットフォームエンジンを作る上では重要な考え方になります。両方とも同じバグですが、プラットフォーム共通化エンジンの代表格であるOS設計ベンダーというのは、得てしてそれを「アプリケーションのバグ」という・・・ある程度、仕方の無い事情もありますが。

その他の事(グラフィックやサウンド等の純粋なハード依存部分)は、仮想的なエンジンを自前で作れば、割と簡単にプラットフォーム共通化ができます。(それが大変な訳ですが)

今回設計したプラットフォーム依存コードのWindows/Android各々の規模を見てみると、
  • Windows+DirectX → 1030行(C++)
  • Android → 533行(C) + 229行(Java) = 762行
という感じ。

つまり、Windows+DirectXのプログラミング知識があれば、Androidの方が必要な知識(情報量)が少ない分、楽。
恐らく、iPhone化ならもっと簡単なんじゃないかな。想像ですが。
Objective-C(=Apple専用言語)というのが厄介ですが、Cのソースコード互換性を100%保っていてくれれば、別に大きな問題ではないと思います。(iPhone化を見越して、プラットフォーム非依存コードはすべてC++ではなくCを使うようにしていたりする)

リプレイ保存機能

リプレイ保存機能が完成。
あと、サウンドミュート機能も。
タイトル画面はこんな感じになりました。

直前にゲームオーバーになった情報があれば、「SAVE REPLAY」を選択できます。

「LOAD REPLAY」を選択すると、ロードするリプレイデータ・スロットを選択する画面になります。

リプレイデータ・スロットは、ファイル形式でSDカードに保存されています。
なので、ネットで公開したり、他人の神プレイを好きな時に再生できたりします。
この機能があれば、プロモーション動画の作成も大分楽になるという開発者側のメリットもあります。

ただ、タッチパネルだと入力情報がジョイスティックと比べて多いから、必然的にデータサイズが大きくなってしまう・・・(リプレイデータは最大、約4MB...普通にプレイすれば100KB前後だと思いますが)



2012年2月25日土曜日

Android版のサウンドシステムが完成

Android版VG-Engineのサウンドシステム完成。
大分楽でした。
OpenXXシリーズ特有の手続きの面倒臭さはありましたが。

それでも「楽だった」と思ったのは、ストリーミング再生するシステムを実装するのに必要な処理を、DirectSoundみたいにマルチスレッド化する必要が無かった為です。
つまり、OpenSL部分の理解は面倒でも、独自システム部分の実装は簡単ということ。


何はともあれ、これでほぼ完成しました。
公開までの残作業は、

(1)プログラム的な部分
①スコア保存処理の修正(assetにする必要がある→sdcardに変更(2/26)
②リプレイ保存+再生機能の追加(これは当初予定には無かったけど、やってて欲しくなった)
③音声ミュートをタイトル画面で設定できるようにする
④ブランドロゴの挿入(これは要らないかも)
⑤最終点検


(2)事務的な部分
⑥正式な署名の準備
⑦アイコンの準備
⑧紹介文(英語)執筆
⑨紹介動画の録画

あと1~2週間ってとこか。

APIレベル引き上げ

サウンド制御のAndroid移植をしていて大きな穴が発覚。
どうも、C言語でOpenSL/ESを利用する場合、APIレベルを10以降にしなければならないらしい。

今まで、最低動作環境をAndroid2.2以降にしてました。
しかし、APIレベルを10にしてしまうとAndroid2.3.3以降になってしまう・・・。
別に、私が2.2に愛着がある訳ではないですが。
(日本では)2.2が最初に普及したので、2.3.3以降にするのはかなり微妙。

何より、Android2.3.3以降を前提とするのなら、NativeActivityにしなかったのが悔やまれる。
ただし、NativeActivityだとCanvasの使い方がよく分かりませんが。
NativeActivityは、色々とかゆい所に手が届かない。


Javaの方(AudioTrack)を使う方法もありますが、Javaだとメモリの扱いがCと比べて難しいので、バッファリング等の処理をGCを発生させずに作りこむのが、私のJava知識だと無理そうなので、Java部分ではサウンド処理は1ステップも書かせたくない・・・と考えています。
恐らく、Javaでサウンド処理を組むと、GCが多発してストレスの溜まるゲームになる筈。
パズルゲームなら良いですが、アクションゲームでは致命傷です。

やはり、Javaはキライです。
コンピュータのプログラムを作るのに向かない言語だから。
コンピュータのプログラム以外のものを作るためのプログラム言語=存在意義なし。
Javaでプログラムを作り続けると効率性の悪いプログラムしか作れなくなる=存在価値なし。
唯一のメリットは、保守性が悪く、将来システム障害の引き金になる可能性が極めて高い、ハイリスクなプログラムを比較的短い期間で作ることができることのみ。

あとは作るだけ

Androidマーケットへのデベロッパ登録や、口座登録などの事務処理が完了。
デポジットの確認が難儀でした。
口座登録をすると、その口座にGoogleからデポジットという物(小額の現金)が振り込まれるので、その金額を確認&入力して初めて登録完了になります。

しかし、通帳に最後に記帳したのは約7年前で、記帳できる余白があと1行しか無い状態。
必然的に、デポジットを確認するには窓口に行かなければならないから、非常に面倒です。
なので、気合で記憶を掘り起こして、ネットバンキングのパスワードを思い出し、確認しました。
(ちなみに、ネットバンキングにログインしたのは約3年ぶり)

まぁ、色々と面倒でしたが無事済んで良かったです。
あとは作るだけ・・・と思ったのですが、商品を登録する画面に妙な記述が。。。

[抜粋] マーケティング除外
Android マーケットや Google 所有のオンライン/モバイル サイト以外ではアプリケーションを宣伝しません。この設定への変更が有効になるまでに 60 日程度かかることについて了承しています

上記の項目がデフォルトでチェックされている意味がサッパリ分からない。

「チェックを入れる」ということは、甲(Google)に対する乙(私)の意思表示という意味になります。
なので、主語は必ず「乙(=私)は」です。

つまり、「マーケティング除外」とは、
①乙は、当該物件(アプリケーション)につき、甲サイト以外での宣伝をしない事に同意する。
②乙は、この設定への変更を有効にするのに60日程度の期間を要する点につき、同意する。
という契約だと解釈できます。

まぁ、①は別に分からなくもないです。(納得できるか否かは別として)
チェックを外せるということは外せば問題無いので、問題ありません。

問題は②。「この設定への変更」の「この設定」部分の解釈。
これは、
(1)デフォルトでチェック状態になっている設定
(2)登録時に行った設定
の二通りの解釈ができます。
(1)の場合、重要事項に該当するので、登録前に事前に通知しなければ無効にできる旨で訴訟すれば認められると思います。なので、(2)と解釈するのが自然。

とりあえず、(2)という風に解釈して、チェックを外した上で堂々と説明文に「Windows版をVectorでフリー配布中です」と宣伝しておけば、仮に私に錯誤があれば審査段階で弾かれると思うから問題無いと思います。

しかし、こういうやり方はあまり(というか「かなり」)良くないので、ググってみたところ以下の記事を発見しました。
http://d.hatena.ne.jp/adsaria/20110518/1305734496
上記ブログによると、これは「Googleが宣伝することについて」の制約事項らしい。

確かに、文章からは誰が宣伝することについてか、何れでも解釈は可能でした。
なので、上記ブログの通りに解釈を改めると、
①乙は、甲が当該物件(アプリケーション)につき、甲サイト以外での宣伝をしない事に同意する。
②乙は、この設定への変更を有効にするのに60日程度の期間を要する点につき、同意する。

これならスッキリ納得できる。
なので、これが正解でしょう・・・多分。
英語は、こういう部分が曖昧な言語だから苦手です。
(一応日本語ですが、英語をそのまま訳した感じだから、ほぼ英語)

2012年2月24日金曜日

私信

色々とGoogle系の作業が増えてきたので、ブラウザをIE9からChromeに変更。
このブログは、Chromeの方が大分書き易いような気がしないでもないです。
ニコニコ動画等はちょっと微妙に重くなったかも。

ちなみに、ブログをYahooから移行して2週間ぐらいですが、その期間のアクセス統計を見ると、
・国内のアクセスが多かった頃→IE率が高い
・米国からのアクセスが先週ドカッとあったとき→Chrome率が高い
という感じでした。

何故、米国からのアクセスが有ったのかは不明。
亜米利加人が興味を持ちそうなネタを書いた覚えは無いですし。
謎です。
ただ、米国ではChrome率の方が高いのかな。

それはさておき、InvaderBlock開発は本日はノータッチ。
来週の月曜日に有給を取得したので、土曜日~月曜日に一気にサウンド系統+その他諸々の細かい部分を完成させて、その次の週ぐらいから配信開始が目標。

ちなみに、InvaderBlockの価格設定ですが、まだ未定。
1$以下にするのは確定ですが。
色々と悩んでいます。

2012年2月22日水曜日

指が疲れなくなった

ちょっとした工夫により、InvaderBlockがタッチペンを使わなくても指が全然疲れなくなりました。

そもそも、何故、疲れたのか?
という点について、考察が甘かった。
実は、肉体的に疲れたのではなく、精神的に疲れていたようです。

元々の仕様は、タッチの変化(スライド)量をバーの移動量としていました。
つまり、下図のような感じ。


だから疲れた訳です。「nピクセルもスライドしなければ、バーがnピクセル動いてくれないっ!!><」
という感じで、精神的に。
一応、指を動かす動作で肉体も疲労しますが、精神的な疲労の方が一般的に厄介。

そこで、タッチしている位置をターゲットとしてバーを移動させる形に仕様変更(バーの移動量をタッチで示すのではなく、バーが移動すべき位置をタッチで示すように変更)したところ、Androidでプレイしても全然疲れなくなりました。

ゲーム画面中では、目標位置がパッと見て分かり易いように、タッチしている間、青色のラインを表示する感じにしました。

公開準備は焦る必要がなかった

一応、Androidマーケットへアプリを公開するのに必要な準備を一通り済ませました。
即日でできるから、焦って今やる必要はなかったかも。
第一、まだアプリは完成してないし。

昔、Vectorでシェアウェアのプログラムを公開するための手続きをやったときは、2週間ぐらい掛かった気がしたので、前もってやっておきました。

Androidの場合、開発アカウント作成、販売アカウント設定、口座情報の登録がそれぞれ分かれていて、開発アカウント作成(※25ドル必要)と販売アカウント設定は即日でできます。

口座情報の登録完了には、デポジット確認が必要なので、3~5営業日程度掛かるかもしれませんが、恐らく振込み発生のタイミングで問題無い状態であれば問題無い筈。
なので、有償アプリであっても、即日公開が可能じゃないかと思います。

ちょっと大きな問題

小一時間ぐらい、Android版のInvaderBlockを遊んでいて気付いた問題・・・
スライドしまくっていると指が疲れる。

ん~・・・仕様です。
タッチペン推奨ということで。
こればっかりは、どうしようもない。(仕様だけに)

ソフトウェア的なボタンを実装しているゲームも結構有ります。
でも、私が遊んだ限り、ソフトボタンは使い難いものばかりだったので、気が乗らない。
何というか、「押している」感が無いので、精神的に不安定になります。

音を鳴らして誤魔化しているものもあるけど。
でも、やはり聴覚というのは、触覚と比べて脳に伝わる刺激が弱いものだから、申し訳ない程度の解決要素にしかなりません。

iPod TouchやAndroidで決定的にマズイのは、十字キー+4ボタン程度のゲーム・インタフェースをハードウェア的に標準搭載していないこと。
まぁ、ゲーム機ではないから、当然ですが。
(私はゲーム(開発)でしか使ってないけど)

2012年2月21日火曜日

動いた

スクリーンのタッチ検出処理を実装したところ、完全に動作するようになりました。
まだ、音は出ないけど。
ちょっとパッド(バー)の位置が下過ぎたので、指と重なって邪魔だったから、ちょっとだけ上の方に移動する程度の修正をしました。
体感的には、Windows版と概ね同じ感覚。
こうなることは想定済みでしたが、完璧です。
これでようやく、Androidで遊べます。

あとは音をつければ本当に完成。
そろそろ、Androidマーケットに登録する手続きを調べたほうが良さそうです。

色がおかしかった原因

先ほどの記事で、色がちょっとおかしかった原因が判明。
凡ミスでした。
スプライトの仮想VRAMをAndroidBitmapに設定するのは、ちゃんとAndroid用のパレットテーブル(16bitカラー)を咬ませていたのに対し、BGの仮想VRAMを設定するときに誤ってWindows用のパレットテーブル(32bitカラー)を咬ませていたのが原因。

という訳で、修正して実行したところ、問題解決。
AndroidでもちゃんとWindowsと全く同じ画面が表示されました。

ちなみに、現時点でのVG-Engine+InvaderBlockのソースコードのファイルは次のような構成になっています。

それぞれのファイルの意味は、
  1. Android.mk: ndk-buildをするためのmakefile
  2. com_suzukiplan_IBLOCK_IBLOCK.h: javahで生成したJNIヘッダ
  3. game.c: InvaderBlockの処理
  4. NUL: ndk-buildをした時に生成されるゴミファイル
  5. vge.h: VG-EngineのAPIを使うためのヘッダファイル
  6. vge_a.c: VG-Engine本体(Android版)
  7. vge_w.c: VG-Engine本体(Windows版)※Android版ではビルドしない
  8. vgeapi.c: VG-EngineのAPI
  9. vgeint.h: VG-Engine本体とAPI間で共用する内部データ定義等のヘッダファイル
灰色の網掛け部分は、私が作ったファイルではなく、自動生成物です。
今回のVG-EngineのAndroid対応で作っているソースはvge_a.cのみ。
その他のソースは、Windows版から1行たりと修正していません

要するに、Windows版とAndroid版の動きは全く同じです。
なので、今後、InvaderBlockV2のスクリーンショット等を掲載するときは、Windows版のものを載せます。

(補足)
先ほどの記事では、(テンションが高かったため)携帯でタブレットの写真撮影をし、メールでPCに飛ばし、それを載せていたのですが、私の携帯は従量課金制なので勿体無い。ついでに、携帯のSDカードは、バッテリーを外さないと取れないという、素晴らしく使い難い設計(iida製のPLYという機種)なので、SDカードに保存したデータをPCへ持ってくるのも面倒くさい。

2012年2月20日月曜日

初画面表示~テンションが上がらざるを得ない

きたぁーーーーーーー!!!


はじめて、Androidの画面にInvaderBlockのタイトルが表示されました。
ただ、パレットのbit演算(24bit→16bit変換)をミスっているらしく、画面の色が変な感じですが。
それでも、画面が概ね想定通り表示されてくれたので、テンションが上がらざるを得ません。

フレーム速度は、63~62fpsで安定しています。
音声処理を追加したとしても、VG-Engineの性能面での問題は全く無さそうです。

データ格納方式の改善

一つ前の日記で、「失敗したなぁ~」と思っていた部分を残す必要は無いので改善。
良質なモノ作りをするコツは「思い立ったら即行動」です。

まずは、Windows版を修正。
Windows版のInvaderBlockV2を構成するファイルは次のようになりました。

ファイル構成
  • IBLOCK.EXE: Windows版VG-Engineを組み込んだInvaderBlockV2実行モジュール
  • ROMDATA.BIN: 画像データ(独自形式)+音声データ(独自形式)
  • LOG.TXT: 実行ごとにラップラウンドするログファイル(RAM-DATA)
  • SCORE.DAT: ハイスコア情報を保持するファイル(RAM-DATA)
だいぶスッキリしました。
これで、Android版のJavaコードもスッキリと書けます。

ROMDATA.BINというのがファイルを纏めたヤツです。
.BINというのは独自形式。
これは、昔作ったシューティングゲーム(SHOT03)で採用した方式です。
ソースコードは99%そのまま流用できました。

ちなみに、.BINファイルに圧縮されている画像データ&音声データも独自形式。
独自形式ばかりだから、ハッカーが解析するのが面倒かも。
一応、簡単な独自処理の暗号化処理をやっているので。
面倒なアルゴリズムは使っていないので、見る人が見れば、すぐに解読できますが。全世界向けに公開するゲームとなると、面倒なアルゴリズムを使うと、実装以上に面倒なことにもなりかねませんし。

なお、全て独自形式にしておけば、プラットフォーム間の移行性が高くなります。
もちろん、独自形式のレコード仕様の設計方式次第ですが。
「設計方式」というと大層なモノに聞こえますが、ポイントは、
  • エンディアンの考慮
  • バウンダリ調整の考慮
程度の一般的なことだけで十分。
その二点さえ抑えておけば、プラットフォーム間でのデータ互換性は概ね保たれます。

2012年2月19日日曜日

意外と面倒くさいリソースの扱い

Androidの場合、独自形式の読み込み専用データファイルは、コンテキスト上のRawResourceという領域(正確にはzip形式に圧縮したapkファイル内にあり、AndroidJVMがそれをアプリケーション・コンテキストの一部として扱う)で保持していて、それを取得してFileReadStream等で読み込むのですが、それが意外と面倒くさい。

上記の説明内容からして、明らかに面倒臭い訳ですが。
ただ、面倒なのはJNIからそれを読み込ませる方法。
結局以下のような形で、実装。
簡単に解説すると、
  • RawResourceの内容を読み込むextractResource関数というのを実装
  • バイト配列形式で読み込みsetResource(独自JNI関数)でCヒープに展開
  • Cヒープでは、リソース名(getResourceName)をキーとした線形リストで保持
という感じ。

ちょっと失敗したなぁ~と、思っているのは、独自形式のファイルを1つのファイルに纏めて、それだけJava経由でCヒープに展開すれば良かったか・・・という点。


グラフィック系統のAndroid化

VG-Engineのグラフィック系統のAndroid移植に難産中。
技術的なところの疑問は綺麗に解消しているのですが、「どの方式でいくか」で。

一般的に、画像処理性能が求められるAndroidプログラムの場合、OpenGLを用います。
しかし、OpenGLは3D専用だからやめました。
もちろん、巷ではOpenGLを使って2Dゲームを作っている方も多いと思います。
それらを否定するものではありません。

OpenGL非採用の原因は、ビデオメモリをロックしてメモリ内容を転送する手段が無いこと。
一応、テクスチャ画像をロックして、テクスチャ領域へメモリ内容を転送し、ポリゴン経由で出力する手段も無くは無いでしょうけど。

しかし、それを用いて画面全体分(240x320)の大き目の画像表示する性能が、果たして実用に耐え得るものなのか・・・が、疑問。ついでに、テクスチャのサイズが一片につき2のn乗でなければならない制約が引っ掛かりました。(つまり、私が目的とする使い方を想定した仕様ではない可能性が高い)

という訳で、SurfaceView+AndroidBitmap+Canvasを用いる方式で実現する方向性に切り替え。
(その決断をするための判断材料を得るのに難産しました)

とりあえず、グラフィック部分のみのJava側の実装はアッサリ完了。
折角なので、晒しておきます。

■アクティビティの実装
単純にスクリーン設定をしてサーフェースビューをコンテントビューに設定するだけ。

■サーフェースビューの実装
div class="separator" style="clear: both; text-align: center;">
ちょっと長いですね。
コンストラクタで仮想VRAM情報のAndroidBitmapを作成し、メインループ(スレッド)関数で仮想VRAM情報を更新する関数を呼び出し、その結果をカンバスクラスのビットマップ書き込み関数で更新する感じです。

Javaは反吐が出るほど大キライなので、Java実装はこれにてほぼ完成です。
可能な限り、Javaでは書きたくありません。
あとは、不可避な事情が発生した場合に限り、必要に応じて最小限の実装を追加するだけ。

2012年2月18日土曜日

やり込む

InvaderBlockのWindows版を公開する場合、昔作ったInvaderBlock(2009年版)とは別ゲームとしてVectorに登録しようと思っているので、InvaderBlockV2に名称を改めることにしました。
「改める」と言うのがはばかれる程度のマイナーチェンジですが。

で、肝心のAndroid環境へVG-Engineを移植する作業は不調。
ポーティングはやるべきことが決まっているから苦手です。
InvaderBlockV2のデバッグ・・・という名の遊ぶ作業に夢中でした。

とりあえず、最大で32,680点をたたき出しました。
ちなみに、ステージ(ラウンド)は全5面。
まだ、実力では2面をクリアしたことがないけど、良い感じの難易度だと思います。

得点のシステム的には、
  • 打撃得点(初期値10pts~お札を5枚取る毎に10pts増加)
  • 破壊得点(ヒット数×10pts)
  • お札得点(ヒット数×100pts)
  • クリア得点(お札数×100pts)
  • ヒット数はステージ毎にリセット
  • お札数は累積
という感じに落ち着きつつあります。
まだ、若干調整するかもしれませんが。

序盤は見た目も派手だし得点を稼げるヒット数の高いパターンを狙うのが吉です。しかし、終盤は序盤から溜め込んだお札の数に応じて打撃得点とクリアスコアが大きくなるから、必ずしも多段ヒットを狙うことがハイスコアを狙う秘訣ではない・・・という感じ。(多段ヒットで倒せば、それだけお札が大きく散らばってしまうから、それだけ回収率が悪くなってしまいます)

デバイスとの同期

ようやく、Android上で動くものを開発する前準備が整いました。
・・・が、やはりAndroidのエミュレータ上で開発するのは色々と面倒。
エミュレータが遅すぎなので。

そこで、実機とPCをUSB接続で同期し、PCでコンパイル→実機転送という方式に切り替え。
この方が、エミュレータでデバッグするよりも楽。

実機(LenovoのIdeaPadA1)のWindows7(64bit)用のUSBドライバを探すのにちょっと手間取りましたが。
正規のLenoveサイトだとサッパリ見つからないかったので、以下のフォーラムから入手。
http://forums.lenovo.com/t5/IdeaPad-Slate-Tablets/Ideapad-A1-Windows-7-USB-Connection/td-p/587655
http://www.tinybeetle.us/A1_USB_Driver_20110816.zip

有志制作のドライバ?
アメリカ語が達者ではないので、よく分かりませんが。

ランキングをどうするか

とりあえず、InvaderBlockが一通り完成。

スコアアタック主体のゲームなので、当然、ローカルでのスコア保存には対応。
下図のように、1位~16位まで。

しかし、本当はネットランキングに対応させたい。
Androidならそういう環境が整っているかなぁ~と、思ったりしていましたが、不明。
まだ、よく調べていませんが、たぶん、無いでしょうねぇ。
ある程度、余剰収益が出たら、iPhone化の後でサーバを立てる計画。
たぶん、それは無理だろうなぁ~と、思ってますが。

追記:完成というのは、VG-Engine上で動くほうのゲームのことで、VG-EngineのAndroid移植は未だです。

2012年2月17日金曜日

計画~どう公開するか

ようやく、InvaderBlockゲーム本編の実装が完成しつつあります。
ゲーム本編が完成したら、いよいよVG-EngineをAndroid移植する作業。
VG-Engineの仕様は固まっているので、移植は流れ作業みたいなものです。

それが完成後にどのように公開していくのかが悩ましい。
完全無料でポンと出すのでも良いです。
ですが、折角だからちょっとお小遣いを稼ぎたいという淡い欲望もあります。
VG-EngineをiPhone/iPod touchに移植する設備投資費用に充てたいので。
しかし、無名個人が出す&ろくにマーケティングしないソフトが1本でも売れるのかが疑問。

という訳で、
  • Android版(1): 無料&広告(アフィリエイト)有り
  • Android版(2): 1$程度の広告無し
  • Windows版: 完全フリー(Android版を紹介するマーケティング用)
という3本立てで出そうかと検討中。
Windows版はオマケみたいなもんなので削るかも。

さらにその先の課題としては、
  • VG-EngineのiPhone/iPod touch移植
  • VG-Engineの機能拡張(音声合成+PSGエミュレーションなど音声関連の強化)
  • 他ゲームの開発+公開
他ゲームについては、今回のInvaderBlockの公開方法を去就する予定。
予定は未定ですが。
まずは、目先のゲーム仕上げ+Android移植が優先。

2012年2月16日木曜日

Windows版の扱い

InvaderBlockのWindows版の扱いをどうしようか結構迷います。
もちろん、Android版については完成したら迷うことなく公開しますが。

課題は2点ぐらい。

①入力系統
Androidで遊ぶことを想定したゲームだから、入力は当然タッチパネルを想定してます。
Windows版はマウス。
マウス専用ゲームというのは若干抵抗があるような気がしてます。
BAMBOO TOUCH等を使えば、ほぼAndroidと同等の操作性だと思いますが。
(BAMBOOはペンのやつしか持っていない・・・ペンだと滑りが微妙)

②DirectX9
元々、Windows版はデバッグ用途だから、画像系は扱いが簡単なDirectX9で作ってます。
しかし、DirectX9のランタイムはWindowsにプリインストールされていません。
大方の環境で遊ぶ場合、End User Runtimeのインストールが必要なので面倒です。

公開する場合、プリインストールされているDirectX8用に作り直したいけど、DirectX8のSDKは持っていないし、公式なサポートも終了しているから、正規ルートでの入手はできない。
公式がサポートしていない以上、どうこういっても仕方がないですが。
DirectDrawで作り直すとか・・・・は、面倒くさい。。。

2012年2月14日火曜日

ゲームシステム~ドット効果

ちょっと、ボールの軌道が追い難いかも。
Androidでのプレイを想定すると尚更。
という訳で、ボールの残像を表示。

この残像を表示するのと同じ仕組みを使って、ついでに背景で星を表示してみたり。
少し分かり難いですが、残像自体の残像も入れてみたり。
静止画だと分かり難いですが、結構美しくアニメーションしてます。
この残像は、いわゆるパレットアニメーションってヤツですね。

これで若干難度が緩んだかも。
私のゲームは全般的に、難度が高すぎるので、適度に調整していきたいです。

2012年2月13日月曜日

ゲームシステム~ボーナス

侵略者を撃破すると、ボーナスアイテムを出すようにしてみました。

ボーナスアイテムをパッドに当てれば、現状の最大HIT数×10点が入るという具合。
今の最大HIT数を確認するため、左下に現状の最大HIT数を表示。

これで、欲望に忠実な人にとって、ゲームの難度があがったかも。
稼ぎ要素として大分幅が広がりました。
まだまだやりたい事が多いのですが、如何せん、平日は時間が少ない。。。

2012年2月12日日曜日

ゲームシステム~HIT数

とりあえず、
「昔つくったものを、そのまんまAndroidに移植しましたぜ!」
という路線でもいくのもアリです。
それでも、目的は果たせるので。

しかし、色々と新しい要素を盛り込みます。
やはり、同じものを2度つくるのは苦痛なので。
何より、オリジナルのInvaderBlockは、全然人気が出なかったので、「完全な移植物」に対するニーズがそもそも皆無ですし。作り手としては、こういう状況はありがたい。全然人気が出ないのはありがたくありませんが。

InvaderBlockは、かなり面白かったと思うのですが、開発当時、地味にやり過ぎたのかも。
ただ、今でも面白いと思っているので、Android対応の第一弾をInvaderBlockにしたことには、それなりの意義が有るんじゃないかと、思ったり、思わなかったり。

という訳で、付加要素は、思いつく限りじゃんじゃん追加していこうと思います。
手始めに、怒首領蜂みたいな感じのHITシステムを導入。
HIT数は、プレイヤ(バー)にぶつかるまで、連続して倒した侵略者の数です。
1HITなら10点、2HITなら20点・・・最大1侵略者につき400点(40HIT)という感じ。
1回もバーに着けずに、侵略者を全滅できるかは、定かではないですが。

サウンド系統(4)~これでok

とりあえず、合成機能の無い効果音で、Invader Blockの実装を進めていたところ、今回は、合成機能が無い方が都合が良いということに気付きました。
という訳で、サウンド系統(Windows版)は、完成。
思っていたよりも、安産でした。

「今回は」というのがミソ。

今回作るInvader Blockというゲームは、昔(2009年ごろ)Windows用に作ったゲームで、その名の通り、インヴェーダアクションをリスペクト(という名のパクリに近い)した作品です。ただ、まんまパクッている訳ではなく、ブロック崩しのルールに則ってやる点が若干特殊。

「インヴェーダに飽き足らず、ブロック崩しまでパクリおって」

と、言われれば、返す言葉もありません。
まぁ、ゲーム作りのお勉強的な位置付けで作ったゲームだから、あまり独自性とかそういうのは意識せず、とりあえず作った感じです。ちなみに、オリジナルのInvader BlockはVectorで公開中ですが、ModeX専用なので、最近のパソコンでは動かないかも。

で、何故今回は合成不要かという理由ですが・・・
 

インヴェーダの場合、隊列が下から順番に動きます。
上図のように、デカイ侵略者、中型の侵略者、小型の侵略者という順序で繰り返し。
その際、隊列ごとに異なる効果音が鳴ってたのですが、これを合成で鳴らすと結構うざったい。
なので、今回に限り効果音は合成せずに鳴らした方が都合が良いという訳です。

そういうゲームの方が稀でしょうけど、とりあえず、Invader Block時点では、現状のサウンド系統(合成モードなし)で問題無いから、さっさとWindows上でゲームを仕上げて、VGEをAndroid化する作業に移りたいです。

Androidアプリの開発状況を綴るブログの筈でしたが、今の所、Windows要素(VG-Engineのデバッグ環境構築)のみというのは如何なものかと思いますし。

サウンド系統(3)~PCMの罠

そういえば、一つ前の記事で、VG-Engine側(サウンド制御スレッド)では、2205バイト=22050(Hz)×1ch(mono)×2(16bit)÷20(50ms)といってましたが、これは、二つ前の記事でいっていたことと矛盾しています(矛盾点は網掛け部分)。二つ前の記事では、システム側はステレオ(2ch)にすると言ってたのですが、一時的に仕様変更しました。

実は、今回の実装にあたり、PCMのデータ形式をチェックしたところ、PCMは波形1(1ch)、波形2(2ch)、波形3(1ch)、波形4(2ch)・・・という具合に交互のチャネルのデータがセットされています。独自形式のPCMデータはモノラルで、パンを指定して鳴らせる仕様にしようとしたのですが、それを実現しようとすると、2バイト(1波形)づつ交互にバッファリングしなければならない・・・という問題が生じます。つまり、ブロック転送(memcpy)ができないから、性能面で問題があります。

PSGエミュレータを実装するときは、そういう風にせざるを得ないけど、効果音用のサウンドシステムでそれをやるのは、とても微妙な気分・・・PSGエミュレータを実装した時は、当然、効果音と合成が必須だから、元々の仕様に戻すつもり(故に、一時的に)ですが。

BGM付きのゲームを作りたい欲求が無ければ、この仕様を定着させる可能性もありますが。

追記:あ・・・どうせ、合成時に戻さざるを得ないか。
ってことは、音声処理をソフトウェアで実装するケースでは、ブロック転送しないのが常識か。
音声プログラミングは素人同然なので、色々と常識が足りない。

サウンド系統(2) ~ 微妙に音が違う・・・の巻

とりあえず、昨日(今日)の記事で書いた、サウンド系統の実装を行ないました。

方式は至ってシンプル。
サウンド系統を制御するスレッド(サウンド制御スレッド)というのを作り、VGEAPIが発音指示をしたスロット番号の効果音の波形データ(PCM)をセカンダリバッファに書き込む・・・という感じ。

サウンド制御スレッドの処理内容は、下図のような感じ。

ds_bufという関数がスロット情報の波形データを合成する処理です。
合成されたデータ(buf)をセカンダリバッファ(lpBuf)へコピーして、発音して、停止するのを待って(WaitForSingleObject)というのを繰り返すだけ。

スロット情報には、「発音するか?」というフラグと位置情報を持っていて、セカンダリバッファサイズ分の音声情報がds_bufでコピー&ポジショニングします。ds_bufの実装は下図。

「合成します」とか言いながら、現時点ではプライオリティが高い(スロット番号が小さい)効果音だけ優先的に鳴らす手抜工事の状態ですが、まぁ、とりあえずこれで音は鳴りました。

しかし、若干原音と違う・・・。
データ変換にミスった訳ではなさそうだから、バッファリングに問題がありそう。
現状、セカンダリバッファは50ms分(=22050×1ch(mono)×2(16bit)÷20=2205byte)にしているのですが、どうもこれだと誤差分によるノイズの影響が大きいのかもしれません。50msということは秒間20fpsだから、リアルタイム性(描画処理=60fpsとの誤差)を考慮すると、その辺が限界だと思いますが。

これは、セカンダリバッファを2面構造にして対処する必要があるのだろうか・・・?
音声周りのプログラミングに関しては、素人同然なので、難産が続きそうです。


追記:この問題は、セカンダリバッファを100ms(10fps)分にすることで解消。
・・・妥協しました。
でも、体感上、気にならない程度のリアルタイム性は確保できたので、ヨシとします。

サウンド系統

VG-Engine(Windows側)のサウンド系統の実装は、過去に作ったWindows用ゲームの実装を流用してお手軽に・・・と、考えていましたが、Android版作成時(OpenSL対応)を考慮して、ちょっと大幅に作り直すことにしました。

今までは、効果音は「鳴れば良い」レベルだったので、昔のDirectX SDKのサンプルに付随していたdsutil.cppを流用してお手軽にメモリ展開したWAVを鳴らしていましたが、OS非依存のサウンドシステムを新たに作る感じにすることで、Android化する作業を楽にした方が生産性が高い・・・という目論見があります。更に、先述の日記でいっていた独自のPSG音源エミュレータをVG-Engineに実装するときの作業も、大分楽になるんじゃないかと思われます。

ちなみに、VG-Engineのサウンドシステムとしては、SE用、BGM用それぞれにスロット(0~255)があり、初期化時にSEデータ、BGMデータをそれぞれスロットに展開しておき、メイン処理で任意のスロットを指定して再生するAPIを準備するような仕様にするつもり。

SE用スロットの仕様は、
  • データ形式は、22050Hz×16bit×1ch(モノラル)のPCMデータ
  • 再生は2ch(ステレオ) ※任意のパンを指定して鳴らせるイメージ
  • 異なるスロットのSEは合成再生可能
という感じにするつもり。
DirectSoundだとそういう仕様で作り易い。
ですが、OpenSLだとよく分からないから、とりあえず合成はソフトウェア演算で実装。
そんな感じのサウンドシステムを実装しようとしたら、とてもじゃないけど、日曜日中にWindows版だけでも完成させるのが、無謀そうな感じがしてきました・・・今月一杯ぐらい掛かるかも。

2012年2月11日土曜日

フォント変更

フォントを刷新。

あまり大きな変化はありませんが。
ただ、同じフォントをずっと使っていると、飽きるタイプなので、ゲーム開発中にちょくちょくフォントが変わるのはよくあること。

ゲーム本編の方は、多分明日中には仕上がると思います。
これでようやくVGEのAndroid化という本編作業に入れる筈。
ちなみに、折角なので、Windows版の方の本編もAndroid版と同時にひっそりと公開するかも。VGEのAndroid化作業にどの程度難産するかが未知数なので、いつになるかは不明ですが。でも、技術的なポイントは概ね見えているので、そんなに苦労しないと思いますが。
何より、早くタブレット上で遊んでみたい。

InvaderBlock移植状況+音声について

だいぶ、できてきました。


そういえば、まだ、音声周りの実装を一切してません。
VG-Engineの音声周りの機能をどうするか・・・というのは、結構悩みどころです。

効果音については、普通にPCMで問題ありません。問題は、BGM。
PCMをループ再生させる手段も有りますが、流石にそれではショボ過ぎるし、サイズが無駄にデカくなってしまうので、BGMについては、デューティー比を弄れるPSG音源+ノイズ音源(のエミュレーション)で実装したいところ。

理想的には、FM音源ですが・・・
FM音源をエミュレートするのは、性能的なところが気になります。
そして、アルゴリズム的にもかなり面倒くさい。

ただし、PSG音源相当のものだとしても、すぐには作れないし、今回移植するゲーム(Invader Block)には、そもそもBGMが無いから、VG-EngineのBGM機能は後回し。とりあえず、効果音機能はさっさと実装しておきたい。

Windows版VG-Engineの性能改善

Windows版VG-Engine(=デバッグ環境)で、ちょっとした性能面の問題があり、改善中。
Android版とはまったく無関係。

ちょっとした性能面の問題
その問題とは、描画速度が通常60fps(フレーム/秒)のところ、稀に40~50fpsに落ちるというもの。恒常的に落ちる訳ではなく、あくまでも稀にです。なので、影響としては無視可能なレベルに軽微なんですが、なんか気持ち悪い・・・ということで、問題原因を調査~改修する作業を実施。

原因は概ね判明。(裏がとれないから、想像ですが)
VG-Engineは、仮想VRAM(スタティックメモリ上の領域)に書き込まれた情報を、DirectX9デバイス上のバックバッファに直書きしていたのが、どうやら、それがマズかったようです。仮想VRAM→テクスチャ→ポリゴン→DirectX9デバイスという具合にワンクッション(ツークッション?)入れることで、解消。

常識的に考えれば、元々の処理(直書き)の方が処理ステップ数が少ない筈ですが、上記で解消できたということは、システムメモリとバックバッファ(VRAM上の領域)のバスは直結していないという事だと思います。

要するに、
  • ○:システムメモリ→テクスチャ
  • ○:テクスチャ→ポリゴン→VRAM
  • ×:システムメモリ→VRAM
という感じに(回路上)なっているということ。
(回路上存在しない経路だから遅い)
あくまでも、推測ですが。

まぁ、これで解決してくれたので良しとします。ただし、性能面では解決したものの、テクスチャ経由だとグラフィックが若干粗くなる問題が浮上。直書きとテクスチャ経由を並べたものを図示すると分かり易いです。
(直書き)(テクスチャ経由)

これについては、放置の方向で。
グラフィックが粗い方がビデオゲームっぽい。
でも、Android版だとどうなるか分かりませんが。


追記:
ハードウェア頂点処理を使う設定(D3DCREATE_HARDWARE_VERTEXPROCESSING)を指定してDirect3Dデバイスを作成していたのが問題のような気がしたので、ソフトウェア頂点処理をするように設定し直したところ、それでも問題が解消されたっぽい。でも、粗いグラフィックも捨て難いから、設定ファイル(.iniファイル)で切り替えられるようにするつもり。

はじめに

すいません、元々図解していたのですが、図を表示すると乱れるようなので、図解は最小限にしました。

わたしが開発しているAndroid用ゲームの開発状況について書き綴っていきます。

これまで、Yahooのブログ(http://blogs.yahoo.co.jp/ysz_ym)の方で、ゲームの開発状況を書いていましたが、今後はAndroid用ゲームの開発をメインにしていく方向にしたので、それならGoogle系列の方が良いんじゃない?と思い、移行することにしました。
まずは、これまでの開発状況について、簡単にまとめておきます。

(1)目的
目的は、シンプルに「携帯端末用のゲームを作りたい」という欲求を満たすことです。
そうなると、選択肢はiPod touch/iPhoneかAndroid端末が妥当ですが・・・

iPod touch/iPhone: Mac導入が必須なのでNG
Macだと自作ツールの移行が面倒だし、外部調達しているツールが揃うか分からない。
恐らく、Windowsほどは充実していないのは確かな筈。
ちなみに、iPadはデカすぎるので、わたし的には「携帯端末」というカテゴリーから除外。

Android端末: Java専用だからNG
根っからのアンチJava派です。
Javaをメイン処理系にした意味が分かりません。
もちろん、石に依存したくないとか、その程度のことでしょうけど。
しかし、あまり大きなメリットは無いし、現時点ではリスクの方が大きい。
Javaが使えることは別に悪く無いけど、Javaメインというのはアーキテクチャとして微妙すぎる・・・

ということで、どちらも敬遠してました。
が、Android端末の場合、C言語も正式にOK(つまり、C言語で作っても正規のマーケットに流すことが出来る)ということを最近知り、とりあえずAndroid端末を導入。

(2)端末導入
当然、スマートフォンだろ?と、思いましたが、想像以上にランニングコストが高い。
携帯電話なら1ヶ月1,000円なのに、スマートフォンだと1ヶ月6,000円・・・
まだ、出始めなのでそんなもんかもしれません。
ということで、Wi-Fi接続のみで利用できる7インチのタブレットを導入。
ただし、スマートフォンで動かせるゲームを作りたいので、Androidは2.3のものを選択。
(本当は、2.2が良かったけど無かった)

(3)開発環境を導入
Android SDKとAndroid NDKを入手。
どうやら、C言語のみで開発する場合、Android 2.3以降限定らしいことを知る。
最低動作環境はなるべく低くしたかったので、仕方なくJava+JNIで作ることに。
しかし、「C言語のみ」とはいっても実はJVM経由で実行される事には変わらない模様。
若干、ダマされた感がある。(まぁ、「よく調べろ」ってことですが)

しかし、Androidのエミュレータがかなり遅い。
このままでは、まともなものは作れないと判断し、
・必要最小限の部分のみAndroid用に実装し、
・主要部分はWindowsで開発
というスタイルで開発できる環境(VG-Engine)の開発に着手。

(4)VG-Engineの開発 ← 今ココ
VG-Engine = Video Game Engineです。
ただし、日産の製品に同一名称のもの(VGエンジン)があるようなので、名前は後で変えるかも。
基本アーキテクチャは下図。
















krt(カーネル依存ランタイム)を用いて実装するVGE(Video Game Engine)とそれを操作するAPI(VGEAPI)から成り、主要部分(game)はカーネルに依存しない範囲のC言語ランタイム(crt)とVGEAPIのみ用いて実装するかたち。
VGEのみWindows用とAndroid用を作ればOKということです。

VGEAPIとWindows版のVGEは完成。
まだ、タイトル画面だけですが、昔造ったゲームをVG-Engineに移植中。

(5)VG-Engineの仕様 <暫定>
VG-Engineとは、要するに仮想VRAM機構を提供するエンジンです。
仮想VRAMは、8ビットカラー(256色)の2面構造。
BG面とスプライト面を持ちます。
・BG面: 一度描画(メモリ書き込み)した情報が保持(スタティックな性質)
・スプライト面: 描画情報は1フレームのみ表示(揮発的な性質)

とりあえず、VGEAPIとしては、
・独自形式の画像情報(パレットを含む)をスロット(0~255)にロードする機能
・スロット上の画像をBG面 or スプライト面に短径転送する機能(vge_put)
・図形描画機能(点、線、円、短径をとりあえず実装)
・BG面のスクロール機能
あたりを実装済み。
これから、ゲームを作りながら追加していきます。

(6)当面のTODO
・昔作ったゲームをVG-Engineに移植
・Android版VGEの作成
・完成したゲームをAndroidマーケットで無料で配布

とりあえず、こんなところです。
ちなみに、本業が忙しいので作業は土日が中心。