i-appli 開発情報

最終更新 2003.09.14

目次

はじめに

このページは、クロノス・クラウン合同会社でi-appliを作った際に参考にしたサイトのリンク集および、柳井が得た知識をまとめたページです。開発に役立つ情報などをまとめておきます。開発担当の柳井が忘れないための覚書です。

開発環境の導入

総合情報

サンプル

テクニック

機種依存に関する情報

Javaに関する情報

その他

軽量化

考え方

Javaでは、変数やメソッド、クラスを定義すると、それらに伴う初期情報が色々と付加されます。

そのため、変数やメソッド、クラスの数を減らせば大幅にプログラムは軽くなります。減らせない場合でも、極力初期情報が伴わない形で定義することで、プログラムサイズを小さくすることができます。

また、アプリ本体で持たなくてもよい情報は、極力外部に持つようにします。

クラス

クラスの数は少なければ少ないほどよいです。クラスを1つ定義すると、Jarファイルの状態で2kbぐらい重くなります。i-appliでは、クラスを極力使わないプログラムを書く必要があります。

メソッド

メソッドの数は少なければ少ないほどよいです。メソッドを1つ定義すると、Jarファイルの状態で10~20byteぐらい重くなります。ただし、メソッド化することで、よりサイズが小さくなる場合はこの限りではありません。プログラム内で共通部分が多い場合はメソッド化した方が軽くなります。

メソッドは可能な限りstaticにする必要があります。これだけで1つのメソッドにつき、10~20byteぐらいは軽くなります。

また、入出力が似ているメソッドはまとめてしまい、複数機能のメソッドにすると軽くなります。

変数

グローバル変数は、public staticにする必要があります。これだけで1変数につき5byteぐらいは軽くなります。

グローバル変数は極力数を少なくする必要があります。配列化して変数の数を減らすとよいです。

ただし、プログラム中で配列内の値を定義してはいけません。プログラム中で配列内の値を定義した場合、それらは1つずつの別の変数とみなされて、初期情報が付加されます。

配列の中身はプログラム的に生成するか、外部ファイルから読み込んで代入すると劇的に軽くなります。

構文

ifはswitchより軽いです。また、if elseの構文より、if ifの構文の方が軽いです。a ? b : cの構文は、内部的にif elseに展開されるので重いです。forも重いので、まとめられる所はまとめた方がよいです。

if 1つにつき、Jarファイルの状態で5byteぐらい重くなります。ifは極力使わないようにするとよいです。

例えば、aが0~5の値を取るとして、

if ( a > 3 ) {
   b = 90;
} else {
   b = 10
}

といったプログラムは、

b = 10 + 80 * ( a / 3 )

と書くと10byteぐらい節約できます。

外部ファイル化

文字列やデータは必ず外部ファイル化します。そのため、スクラッチパッドやネット上のリソースをDLするためのファイルシステムをまず構築する必要があります。

文字列は言語ファイル化して持ちます。

配列データは、外部からバイナリ配列として読み込みます。

504以前は圧縮ファイルの解凍メソッドがないのですが、自前で解凍メソッドを組み込むとデータを多く詰め込むことができます。

ツールの活用

Jargやレトロガードなどの、難読化ツールを使うと5%ぐらい軽くなります。

また、定数は定数埋め込みツールを作ってコンパイル前に適用することで5%ぐらい軽くなります。

機種依存

i-appliは機種依存が甚だしいです。その中でもゲームにおいて重要になるのが、グラフィック関係の機種依存です。以下、グラフィック関係の機種依存を中心に触れていきます。

Javaヒープとネイティブヒープ

D50xとN50xでは、メモリがJavaヒープとネイティブヒープとに分かれています(その他の機種はメモリは1つだけです)。

Javaヒープとは、Javaのオブジェクトなどが格納される領域です。ネイティブヒープは、画像などのメディアリソースが格納される領域です。

このメモリが分かれていることによって、メディアデータを多く使うゲームアプリでは、問題が発生します。どういう問題が起きるかと言うと、開発環境ではメモリが十分に足りていたのに、実機に移すとメモリが足りないという問題です。

これは、ネイティブヒープが、主に画像によって食いつぶされてしまうことで発生する問題です。

また、機種によって同じクラスを初期化しても消費メモリーの量が違います。

さらに、メモリサイズを取得するメソッドでは、どうもJavaヒープの値しか取得できないようで、ネイティブヒープでどれだけメモリを使ったが分かりません(これは私が気付いていないだけの可能性もありますが)。

そのため、実機で動かすまで、メモリが本当に足りているかどうかは分かりません。

実機では、こういった制限があることを、念頭に入れておかなければなりません。

D504、D503のImageクラスの仕様

Dでは、Imageクラスを作る時に、画面より大きなImageを作ることができません(ゲームでバッファを作る時に困ります)。

また、グラフィック用のメモリー領域が他の機種より狭くなっています。そのため、Imageクラスを作ると、このメモリー領域を真っ先に食いつぶします。

さらにDでは、他の機種に比べ、同じサイズのImageクラスを作った場合のメモリーの消費量が激しく多いです。

そのため、結果的にDだけ凄い少ない量しかImageを持つことができません。

端的に言うと、画像の先読みをしようとして、ある程度の画像を読み込んでおくような処理をすると、Dだけエラーで落ちます。

以下推測です。多分、Dでは内部的にImageの持ち方にバグがあって、非常に多くのメモリーを消費してしまうのだと思います。そのため、そのバグを隠す目的で「画面より大きなImageを作れない」という特殊な条件を「仕様」として謳っているのだと思われます。

N505のファイルDL時の謎の挙動

N505では、ファイルをDLした時とそうでない時では、ネイティブヒープの使用量に違いがある可能性があります。

N505では、ファイルをDLした直後に画像をImageとして読み込んでいると、ある程度の画像を読み込んだ時点で「Out Of Memory Err」が発生します。しかし、同じ量の画像を読み込んでも、ファイルをDLしていない時にはエラーが起こりません。ちなみに、DLした直後も、DLしていないときも、Javaヒープの使用メモリ量に差はありませんでした。

この現象に関して色々と実験した結果、以下の2種類のうちのどちらかの仕様になっているのではないかという推測に落ちつきました。

詳細は不明ですが、ファイルをDLした場合とそうでない場合で、ネイティブヒープの使用量に差がある可能性があります。

速過ぎるP

i-appli利用可能機種の中で、最もゲームに適した能力を持っているのはPシリーズです。ともかくPは早くて強力です。

そのため、開発時にPをデバッグ用のマシンにすると、他の機種で遅くなり過ぎるという問題が発生します。逆に、他の機種でちょうどよいように作ると、Pでは速くなり過ぎる可能性があります。

速度が重要なアクション系ゲームを作る場合は、こういった機種の違いを把握しておく必要があります。

遅過ぎるN

i-appli利用可能機種の中で、最もゲームに適さない描画能力を持っているのはNシリーズです。ともかくNは遅いです。

どこが遅いかと言うと、描画時間分解能が、他の機種に対して著しく劣っていることです。100msecに一回しか画面が再描画されないために、秒間10フレームが最大となります。そのため、まともなアニメーションはできません。

速度が重要なアクション系ゲームを作る場合は、こういった機種の違いを把握しておく必要があります。

505は504よりも非力

505系は504系よりも非力です。何故かと言うと、画面サイズが縦横2倍の4倍になったのに、CPUはほとんど早くならず、メモリ量もそれほど増えていないからです。

そのため、画面バッファなどのImageクラスをたくさん作っていると、504から505に移植した際にエラーが出る危険性があります。

その対策として、505からは、小さな画像を大きな画像に拡大するメソッドが追加されたのですが、これははっきり言って使えません。機種によっては、0.5~2秒(聞いた範囲)も、そのメソッドの実行に時間がかかるそうです。

504、505対応で作る場合は、504を作って505に移植するという考え方ではなく、505も504も同時に実験しながら作るという考え方で作る必要性があります。

Cronus Crown(クロノス・クラウン)のトップページに戻る
(c)2002-2017 Cronus Crown (c)1997-2017 Masakazu Yanai
このWebPageに関するご意見・お問い合わせは
サイト情報 弊社への連絡
までお願いします。