iphoneのアプリケーション開発は、着々と、磐石なものになっているようです。
とうとう、スタンフォード大学が、アップルのエンジニアと協力して、
開発ノウハウの講座まで作ってしまっています。

それに対して、Google様のアンドロイド端末のアプリケーション開発の体制を
みていると、どうもさびしいような気がしてなりません。

下手に、OSのソースコードそれ自体も、公開してしまったので、
アンドロイドに興味のあるディベロッパーのフォーカスも拡散したのかな。
ましてや、ゲーム・プログラミングの開発となると、さらに情報は
少なく。
アンドロイドの書籍を購入しても地図を使ったアプリケーションのノウハウにカタヨッテイマス。

Googleの定例イベントになりつつある、Google I/Oにて、
実際に、ゲームの開発会社に勤務していたことのあるGooglerが、アンドロイドで
遊べる2次元のスクロールゲームを開発して、その開発・完成にいたるまでの
いろいろなノウハウをプレゼンしています。
クリス・プルエットという、Google東京オフィスで働いているゲーム・プログラマーです。
彼の、プレゼンテーションスライドを部分的に日本語訳にしました。
渋谷で、彼が講師になって、ゲームの学校開いてほしいですよ。
本当に。


ゲーム開発の実務のいったんが垣間見えるかもしれません。


CS 193P iPhone Application Development

特に、再生開始してから、12分から15分のところで、試作ゲームのデモを開発者が自らやります。

この動画の、12分から15分の間に、ゲームのデモがあります。

レプリカ・アイランドという、タイトルの、横スクロール型のゲームです。

http://www.youtube.com/watch?v=U4Bk5rmIpic


このプレゼンテーションのために、準備された、スライドです。
話の内容のレジュメです。
とくに、大事なのは、11枚目 12枚目 14枚目になります。
ゲームプログラムの全体の構造が図になっています。

http://dl.google.com/io/2009/pres/WritingRealTimeGamesforAndroid.pdf

Did You See That Awesome Fade?
• Holy Crap!
– The text was all sliding before that too.
– How do they do that?!
• Right, this slide is about me, the presenter. Chris Pruett.
That’s me.
• I’m a Developer Advocate for Android.
– That means I advocate development for Android. Please make
something. Maybe I can help you.
– I work in Japan. 宜しくお願いします。
• Before that, I wrote code for Lively.
• Prior to working at Google, I made video games.
– I shipped about 10 titles for lots of platforms: GBA, PS2, PSP,
Wii.

私は、クリス・プルエットといいます。
私は、Androidで、ゲームを開発する人たちへの、営業を担当するプログラマです。
言いたいことはひとつです。アンドロイドをつかって、何かを作ってください。
こちらも、なにか、お助けできます。
日本で働いています。
いまのポジションになる前は、Livelyというゲームの開発をしていました。
Googleに入社する前は、ビデオ・ゲームの開発をしていました。
いままでに、10作のゲームを開発しています。
ゲームボーイ・アドバンス PS2 PSP、それと、Wiiです。

Making Games on Android
• Writing games is awesome, and Android is awesome, so
writing games on Android must be awesome2.
• This theory required testing. So I made a game. Many
lessons learned.
• Topics to cover today:
– Why games? Why Android? I mean, besides awesome2.
– Game engine architecture.
– Writing Java code that is fast. For serious.
– Drawing stuff on the screen efficiently.
– Tips, tricks, and pitfalls.

アンドロイドで、ゲームをつくること

ゲームプログラムを書くのは、やっかいだ。
アンドロイドも厄介だ。
ということで、アンドロイド携帯電話で遊べるゲームプログラミングを書くのは、やっかいなのに
違いない。

この仮説が本当かどうか、実際、プログラムを書いて試してみないといけない。
ということで、ゲームをつくってみた。おおくの、貴重なノウハウを得ることが出来ました。

本日の公演の内容について

なぜ、ゲームなのか?
なぜ、アンドロイドなのか?

ゲーム・エンジン・アーキテクチャについて
早く動く、JAVAのコードを書く。(これは、マジで大事)
スクリーンに、効率よく、「もの」を描く
コツ 仕掛け 落とし穴

Who Cares About Games on Mobile Devices?
• Dude, what rock have you been living under?
iPhone: 79% of users have downloaded at least one game.
(According to a report by Compete, Inc.)
– There are more than 100 million Nintendo DS devices
throughout the world. (According to Nintendo, see http://www.nintendo.co.jp/ir/pdf/
2009/090507e.pdf)
– Sony’s Playstation Portable has just passed 50 million devices
(see: http://www.computerandvideogames.com/article.php?id=208211%3fcid)
– The Nintendo Game Boy and Game Boy Advance together
account for about 200 million devices (see http://www.nintendo.co.jp/ir/library/
historical_data/pdf/consolidated_sales_e0806.pdf).
• Portable games appeal to a huge audience, but traditional
phones have not been good game devices.
• Game tech is extremely specific.
– If your platform can support good video games, other apps
should be a walk in the park.

だれが、携帯電話の端末で遊ぶことができるゲームのことを気にしているのか?

どれだけ、でかい山にあんたはいるのかということについてご説明。

iphoneの79パーセントのユーザは、少なくとも、1本のゲームをダウンロードしている。
(これは、Compete Incという会社の資料から数字をとりました。)
全世界で、ニンテンドーDSの端末を持っている人は、1億人以上います。
(これは、任天堂が公表している数字です。)
ソニーのプレステも、5千万台売れています。(統計数字あります。)
任天堂ゲームボーイゲームボーイアドバンスで、2億台以上、すでに売れています。

携帯することができる端末で遊ぶことができるゲームは、たくさんの人に売り込みができるかもしれない。
でも、いままでに、販売されてきた携帯電話は、ゲームで遊ぶのには、あまりいい出来ではなかった。

ゲームプログラミングを完成させる技術って、とっても特殊です。
もしも、あなたが、実際にアプリケーションを作ろうとしている開発環境・プラットフォームが、質のいいビデオゲーム
世に送り出すことができるようになっているなら。
ほかのアプリケーションを開発することなんて、とても簡単なことです。

Why Games on Android?
• Traditional PC and console game markets have been come
so high-risk that only a few companies can even compete.
• Smaller games on non-traditional platforms are steadily
gaining popularity with both traditional gamers and folks new
to the medium.
– See also: Nintendo Wii, iPhone, Flash, XBLA, etc.
– Lower risk = more interesting and diverse content!
Android provides an avenue for innovative games across a
wide, internet-savvy audience.

なぜ、AndroidというOSを組み込んだ携帯電話で遊べるようなゲームを開発することが、おいしいのか?

伝統的なパソコン向けのゲームや、コンソール機向けのゲームを販売して利益を得る市場は、とても、ハイリスクに
なってきています。だから、たくさんの人員、あふれるばかりの資金をもっているような、数のすくない大企業でないと、
ゲーム開発にお金を使って、売り上げをとって、利益を回収することができなくなっています。

従来、あまりなかった、プラットフォームで、より小さい素朴なゲームが、昔ながらのゲームファンと、ここ最近、
アイフォンなどにはまってくれた消費者の間で、人気が出ています。

新しい端末の具体例 Nintendo Wii iphone Flashj XBOX

ゲームを開発して、販売してみて、たとえ売れなかったとしても、そんなに大きな損害を受けることはない。
より、面白みがあって、多様なコンテンツが広がっています。

アンドロイドというOSを組み込んだ携帯電話では、革新的なゲームを、インターネットが大好きなお客さんに提供することが
できる。

Why This Game for Android?
• My goal is three-fold:
– To produce a fun game for Android.
– To produce a reusable, open source game engine to allow
others to make fun games for Android.
– To stress test our platform with regards to games; only
publically-available code and tools are to be used.
• I went for an orthodox 2D side-scroller.
– Parallax layers, tile-based worlds, animated sprites, etc.
– Pushes all the right hardware buttons: input systems, OpenGL
ES, sound, etc.
– Proper game is feasible with one 20% engineer (that’s me) for
six months and 1 full time artist for four months.
– Tools are pretty easy to write.
– Popular and recently under-served genre.

私が、開発したアンドロイド向けのゲームがどうして、このような形になったのか?

私が、今回、開発にあたって、設定した目標は三つあります。

その1 アンドロイド用の楽しいゲームを生み出すこと。

その2 ほかの、開発者が、アンドロイド向けのゲームを作ってみる際に、使いまわしができるような
    ゲームプログラムコードを提供すること。

その3  ゲームの開発に関して、アンドロイド向けのプラットフォームの負荷テストを行いたかった。
     合法的に入手可能、作成可能なプログラムコードと、開発ツールしか使っていません。

2次元のサイド・スクロールゲームを作りました。

視差を生むように重ねられたレイヤー、タイル表示をベースにした世界、動くキャラクター
すべての標準のハードウェアのボタンを押すようにつくりました。 入力システム OPENGLES、音声

今回のゲーム開発にあたって、通常の業務時間のうち、20パーセントを費やすプログラマーひとりが、半年の間、開発作業をして、
4ヶ月の間、フルタイムで働くアーティストが、投入されました。

開発ツールは、コードで書くのがとても簡単なものです。
このジャンルのゲームは、とても人気があるのですけど、現在、アンドロイド携帯電話で、このジャンルで遊ぶことができるゲームは
少ないです。(つまり、この分野で開発ができれば、ヒットが狙えるかもしれない。)


ここでゲームのデモ画面が入ります。

Game Engine Architecture
• Lots of approaches, but the basic problems are similar.
• My approach is a “game graph” that can be traversed every
frame, taking time and motion events as input and resulting
in a list of things to draw to the screen.
– The root of the graph is the “main loop.”
– Children of the main loop get called once per frame.
– Children further down the tree might get called once per frame,
depending on their parent.
– “Game objects” are children of a “game manager” node, which
only visits children within a certain activity bubble around the
camera.
– Game objects themselves are sub-graphs of “game
components,” each implementing a single characteristic or
feature of the object.


ゲームプログラミング全体の構造について

プレゼンテーションのスライドの11枚目と12枚目を見てください

全体の構造を組み立てるのには、いろいろな方法があると思います。でも、基本的な問題は、どんな方法を使ったとしても
似たようなものです。

私の方法は、ゲーム・グラフというものです。すべてのフレームを横断することが出来て、時間と、モーション・イベントを入力として
設定できて、スクリーンに出力させるべきもののリストをつくっていくようにするものです。

グラフのルートの部分は、“main loop.” になります。

フレームの一枚、一枚ごとに、the main loop の子供が呼び出されます。

一枚、一枚のフレームごとに、3世代まで下る子供が呼び出されます。その子供の親にもよりますが。

ゲーム・オブジェクトは、ゲーム・、マネージャーの子供になります。マネージャは、あるアクティビティーのバブルが、カメラの周辺で
おきるときにだけ、その子供のところに、降りてきます。

ゲームオブジェクト、そのものは、ゲーム・コンポーネント(構成要素)のしたのグラフになります。
ゲーム・コンポーネントは、オブジェクトの一つ一つの特徴や、特性を実行します。

• At least, that’s how I do it.
• Important point: time is passed to each node in the graph so
that framerate independent motion is possible.
• Second important point: this system collects things to draw in
a draw list each frame, but it doesn’t actually draw anything
to the screen.

MainLoop
  ↓               ↓             ↓             ↓
InputSystem  GameObject System  CameraSystem   RenderSystem
入力システム   ゲームオブジェクトシステム   カメラシステム        画面表示システム(レンダリング
            ↓        ↓
BackgroundGame Object  Player Game Object
背景ゲームオブジェクト      ゲームプレイヤーオブジェクト

背景ゲームオブジェクトの下には

Scroller Component  これで、レイヤーの一枚目が出来る
Render Component 

Scroller Component これで レイヤーの2枚目が出来る
Render Component

Scroller Component  これで、レイヤーの3枚目が出来る
Render Component

ゲームプレイヤーオブジェクトの下には

Player Component
Gravity Component  重力 構成要素
Movement Component 運動 構成要素
Collision Component  衝突 構成要素
Physics Component  物理 構成要素
Sprite Component  キャラクター 構成要素
Render Component  表示構成要素
Animation Component アニメーション構成要素


                          

すくなくとも、私は、こんな感じで、プログラムの全体の構成をつくりました。

大事なところ、をひとつ。 グラフにおける各ノードにおいて、時間は経過します。
ですから、フレームレートから独立した動きが可能になっています。

次に大事なところ。 このシステムは、おのおののフレームにおいて、「描くべきもの」のリストのなかに、
「描くもの」を集めてきます。
しかし、このシステムは、実際に、スクリーンに何かを描くということはしません。

I have three threads:
– The main thread spawned by the
Android activity.
• Responsible for bootstrapping the game
and receiving input events.
• Mostly dormant.
– The game thread.
• Handles all non-rendering parts of the
game: physics, AI, collision detection,
animation, etc.
• Owns the game graph.
– The rendering thread.
• Controlled by a SurfaceHolder.
• Just runs through its draw list and fires
off commands to OpenGL every frame--
knows nothing about the game content.


Main Thread
Game
Thread
Rendering
Thread
Hardware
Blocking
Blocking
Input Events
Surface Holder

ゲームプログラムを構成するのは、3つのスレッドです。
プレゼンテーションの。スライドの14枚目を見てください。

メイン・スレッド これは、アンドロイドOSで、動くアプリケーションの画面の一つ一つであるアクティビティーによって生み出されるものです。

ゲームを起動させることと、インプットのイベントを受け取ることが、役割です。
ほとんどの場合、休眠状態です。

ゲームスレッド  
画面への絵の表示に関係しないすべてのゲームの構成要素が入っています。
物理コンポーネット 人工知能コンポーネント 衝突検定コンポーネント アニメーションコンポーネントなどなどです。

ゲームグラフをもちます。

レンダリングのスレッド

サーフェス・ホルダーによって操縦されます。

描画リストの中で、走ります。 各フレームにおいてOPENGLに命令をします。
このスレッドは、ゲームの内容に関しては、なにも知りません。

I Love Coffee, I Love Tea
• I am pretty much a C++ engineer.
– In fact, I wrote my first line of Java ever for this project.
– So you should take my advice on the topic of Java-specific
optimization with a grain of salt.
– Still, I have done a lot of optimization work in the last six
months, and maybe at a level that most Java apps do not
require, so maybe I can offer some useful tidbits.
• Writing real-time games is an exercise in finding the perfect
balance between flexibility and performance.
• My (non-language-specific) approach is:
– Start with the simplest possible implementation, but design for
future rework.
– Choose flexibility over speed every day of the week... until the
gameplay is damaged.
– Profile early and constantly.

私は、C++プログラマーです。
実は、今回のゲーム開発で、はじめて、JAVAのコードを書きました。
そういうわけで、私が、ゲーム開発に関して、アドバイスをすることは、
JAVAでゲームを作るという局面で、使えるかどうかという判断をしながら、眉につばをつけながら、
聞いてください。
この半年の間に、たくさんの「最適化」の仕事をしました。つまり、JAVAでゲームを書くために、最良な方法がなにか、探してきました。
この最良の方法は、ほかのJAVAのアプリケーションを開発するときには、おそらく要求されないようなレベルです。
ですから、私は、いくらかの、有益なアドバイスをみなさんに提供できると思います。
リアル・タイムのゲームのプログラムを書くということは、柔軟性と、パフォーマンスの完璧なバランスを探していく訓練のようなものです。

私のゲーム開発の方法論(これは、どのプログラミング言語を使うのかということとは、無関係です。)

可能なかぎり、単純な実装からはじめる→ただし、デザインに関しては、将来のやり直しの仕事を考慮にいれます。

スピードと、柔軟性については、柔軟性を優先します。ゲームの遊びやすさにダメージが行かない限りは。

常に、そして、すばやく、プロフィールをするようにします。

Step One: Memory Management
• Never allocate memory. Or release it.
– Well, never allocate during gameplay.
– The GC will stop your game for 100 ~ 300 ms. That’s death for
most real-time games.
• Revised: Allocate as much as possible up front, don’t release
things until you have natural pause time. Invoke the GC
manually when you know it to be safe.
• Use DDMS to track allocations.
– Hey, Java allocates memory CONSTANTLY. Ugh!
– Hidden allocations in things like enum.values(),
Class.getClassName(), Iterator, HashMap, Arrays.sort() etc etc
etc.
– Some of these are not really avoidable.

メモリーの管理

GCとは、OSのメモリ管理機能の一つ。プログラムが使用しなくなったメモリ領域や、プログラム間の隙間のメモリ領域を集めて、連続した利用可能なメモリ領域を増やす技術。これが不完全なOSは次第に利用可能なメモリが減ってゆくため、一定期間ごとに再起動を強いられることになる。Java言語の実行環境(JVM)は自身がガーベジコレクション機能を持っており、Javaプログラマがメモリ管理に気を使わなくてもいいようにしている。

メモリーを確保しようとしたり、リリースしたりしないようにしましょう。
GCは、ゲームを、100ミリ秒から300ミリ秒とめることになります。これは、リアルタイムのゲームにとっては致命的です。

更新→ メモリー確保は、なるべく、アップフロントで。自然な停止時間になるまで、ものを、リリースしてはいけません。
GCを手動で起動させてください。それが、安全だということがわかったら。

http://www.javadrive.jp/android/debug/index5.html



Androidにはデバックを行うためにDDMS(Dalvik Debug Monitor Service)と呼ばれるGUIツールが用意されています。
それでは実際に起動してみます。エミュレーターが起動している場合は一度終了して下さい。コマンドプロンプトから「ddms」と実行します。

メモリが、どうやって確保されているのかを、追跡するために、DDMSをつかってください。
JAVAは、メモリーを、常に、確保します。

隠されたメモリー確保 具体例 Class.getClassName(), Iterator, HashMap, Arrays.sort() etc etc
etc.

このうちのいくつかは、避けられるものではありません。

Allocation-Related Java Language Contortions
• Treat Java like C++
• Lots of the standard Java utility objects allocate memory.
– Collections are out, as are iterators.
– Forget about enums (they are really heavy-weight anyway).
– Arrays.sort() and similar functions
– Anything returning a String that needs to be read-only (like
Class.getXXX(); man, I miss me some const).
• DDMS is your tool to name and blame.
• Better Java engineers than I might be able to supplement
existing frameworks with non-allocating implementations.

メモリーの確保に関係するJAVAのゆがみ

C++のように、JAVAを扱っている

多くのJAVAのユーティリティーオブジェクトは、メモリーを確保している。

イテレータそうであるように、コレクションもアウトしている。

enums これは、わすれてください。(これらは、とても重いです。いずれにせよ。)

Arrays.sort() and と類似の関数

読み専用である必要がある文字列を返すあらゆるもの(たとえば、Class.getXXX();)

DDMSは、あなたのツールになります。名前をつけるためと、文句をいうため。

私よりましなJAVAプログラマは、すでにあるフレームワークの修正・補いを、メモリー確保をしない
実装によってなしとげることができるでしょう。

Step Two: Don’t Call Functions
• Ok, that’s extreme. But function calls are not cheap and you
can’t rely on inlining.
• Use static functions whenever possible.
• Don’t call functions through an interface. 30% slower than
regular virtual functions!
• Accessors and Mutators are my bestest friends in C++, but
they have no place in your Java inner loop.
• Be wary of JNI functions.
– In particular: lots of gl.glXX() functions.

ステップ2 関数の呼び出しはやってはダメ


もちろん、これは極論ですが。しかし、関数の呼び出しは、高くつきます。
関数のインライン展開に頼ることもできません。

静的な関数を、なるべく使うようにしましょう。

インターフェイスを通じて、関数の呼び出しをやってはいけません。
仮想関数より、30% 遅くなります。

私が、C++でコードを書いているときは、アクセサーと、ミューテイターはよき友でした。
しかし、JAVAのインナーループにおいては、その出番はありません。

JNIとは、Java言語で開発されたプログラムから、他の言語で開発されたネイティブコード(特定のプラットフォームでそのまま実行可能なプログラム)のプログラムを利用するためのAPIJavaプログラムからプラットフォーム固有の強力な機能を利用することを可能にするが、そのプラットフォームでしか動作しなくなる。
http://www.brpreiss.com/books/opus4/html/page604.html#SECTION0018331000000000000000

たくさんのJNI関数には、注意してください。

特に、gl.glXX() functions.

関数の種類によって、呼び出しにかかる時間が違ってきます。

Use local variables, especially in inner loops.
• Use the final keyword on fields whenever you possibly can.
• Some hardware (like the G1) has no FPU, so avoid float math.
• Always use Log.d() or similar
rather than
System.out.print(). Printing
takes time!
• Use Traceview!

ローカル変数をつかってください。特に、インナーループでは。
フィールドにおいては、なるべく、最後のキーワードを使うようにしてください。
G1という、アンドロイドの携帯電話の端末のように、いくつかのハードウェアにおいては、少数演算ができません。少数をつかった演算は
プログラミングに組み込まないでください。

use Log.d() またはこれに類似したものを、つかうようにしてください。 System.out.print(). Printingこのメソッドは、時間がかかります。

TraceView用ログを/android/sdk/tools/traceviewで開くと、関数の呼び出しシーケンスと、それぞれの関数でどれだけ時間がかかったかをグラフィカルに表示する。これらのログは、donut版のAndroidを載せたZaurusC3000で取得した。ちなみに、このTraceViewの存在は、前回のAndroid勉強会@金沢*2で行われた、おおいしさんのプレゼンで知った。



Traceviewを使うようにしましょう。

Android Drawing Methods
Canvas:
– CPU-based 2D drawing. Used for most of the Android UI.
– Fast for a small number of blits. (~ 10 sprites < 16 ms in my
tests)
– Very straightforward and easy to use.
OpenGL ES
– 2D and 3D drawing.
– Hardware accelerated on some platforms (like the G1).
– Scales to much more complex scenes than Canvas.
– Various 2D drawing methods:
• Quads with orthographic projection
• VBO quads (on supported platforms)
• draw_texture extension (on supported platforms)
– Only OpenGL ES 1.0 is guaranteed.

アンドロイドで、描画をする方法について

キャンバス

CPUをベースにした2次元の描画になります。ほとんどのアンドロイドのアプリケーションのユーザインターフェースにおいて採用されています。

小さな数の転送をするのに、はやい処理ができます。(キャラクターを10個、画面に出力させるのに、16ミリ秒かかりませんでした。)

単刀直入で、使いやすいです。

OpenGL ES

2次元と3次元での描画ができます。

いくつかのプラットフォーム (たとえば、アンドロイドOSを組み込んだ携帯電話端末であるG1)のハードウェアにおいて、加速されています。

Canvasというソフトウェアより、より複雑なスケールに対応しています。

さまざまな2次元の描画が出来ます。

正射影された4個いりの構造

頂点データ等をまとめて描画するのにvertex arrayという機能がありますが、Vertex Buffer Object(VBO)も似た機能

VBO構造になっています。


Only OpenGL ES 1.0 がサポートされています。

Which Method is Best?
• Clearly, OpenGL ES + the draw_texture extension is fastest
for 2D drawing on the G1.
– But that extension isn’t guaranteed to be supported on all
platforms. You MUST check
glGetString(GL10.GL_EXTENSIONS) before using it.
• However, Canvas isn’t bad if...
– You have very few things to draw every frame, or
– You don’t have to draw every frame (puzzle games, etc).
• SpriteMethodTest provides a framework for swapping
between drawing methods (and timing them) based on my
game code.
http://code.google.com/p/apps-for-android/

どの選択肢で、描画、グラフィックにとりかかるのが、最良なのか?

明らかに、OpenGL ES と the draw_texture extensionの組み合わせが、2次元の描画を、G1という携帯電話の端末で
ゲームをやることを想定すると、一番、はやいように思え素。
ただし、この extension は、すべてのプラットフォームをサポートするかどうか、定かではない。
開発にとりかかるまえに、glGetString(GL10.GL_EXTENSIONS)というメソッドをかならず、チェックをしてください。

Canvasもそんなに悪くはありません。
もし、フレームごとに、そんなにたくさんの「絵」が必要でないなら。

または

すべてのフレームに、「絵」が必要ではないなら(たとえば、パズルゲームなどはそうです。)

SpriteMethodTest→これは、私が、作成したゲームのプログラミングの中で、いろいろなメソッドで、描画をしてみたものの
処理速度を比較したものです。

Case Study: Drawing Tiled Backgrounds
• Replica Island uses three background layers: one large static
image, one mid ground tile-map, and the foreground tile
map.
• The tile map layers are regular grids of 32x32 tiles. That
means 150 tiles to draw per layer on any given frame (worst
case).
• More layers would be nice, but drawing the background is
the single most expensive operation in the Replica Island
code.
– Actually, the single static image is quick. It’s just one 512x512
texture.
– It’s the tile maps that eat frame time, either on the CPU or the
GPU, depending on the drawing method.


ゲームの背景画面を作成する。

Replica Islandというゲームでは、3層のレイヤーを使っています。
ひとつの、静的な大きな画像
タイルの地面の背景地図
それと、最前面になる地図です。

タイル地図の層は、32x32枚のタイルで出来上がっています。
つまり、1枚のレイヤーごとに、すべてのフレームに対して、150のタイルを描画しないと
いけないことになります。(最悪の場合)
よりたくさんのレイヤーを使うのは、すばらしいことだと思います。けれども、背景を描画するという
ことは、このゲームのプログラミングにおいて、一番、高くつく、オペレーションになっています。

実際、ひとつの、静的な画像は、はやいです。512x512no
テクスチャーとなります。

タイルの地図が、一番フレームの時間を食うことになります。どの方法で描画するのかということによって、
CPUやGPUの性能にもよりますが。

Graphics Processing Unit(グラフィックス プロセッシング ユニット、略してGPU)とは、パーソナルコンピュータやワークステーション等の画像処理を担当する主要な部品のひとつ。Visual Processing Unit(ビジュアル プロセッシング ユニット、VPU)という名称もある。
コンピュータシステムにおいて画像表示を担当するASICであるグラフィックコントローラから発展したもので、GPUジオメトリエンジンなどの専用ハードウェアによって画像データ処理を行う集積回路をさす。現在の高機能GPUは高速のVRAMと接続され、グラフィックスシェーディングに特化した演算器を複数搭載するマイクロプロセッサとなっている。


CPU(シーピーユー、Central Processing Unit、セントラルプロセッシングユニット)はプログラムによって様々な数値計算や情報処理、機器制御などを行うコンピュータにおける中心的な電子回路である。中央処理装置(ちゅうおうしょりそうち)あるいは中央演算処理装置(ちゅうおうえんざんしょりそうち)とも言われる。

Case Study: Drawing Tiled Backgrounds
• First idea: use a single atlas texture as the tile map, use
draw_texture to draw, and adjust cropping of the texture to
select individual tiles.
– Only one glBindTexture() call needed, which is good.
– Otherwise, this was a terrible idea. glTexParameteriv() is
expensive.
– Remember kids, state change is costly on fixed-function
hardware!

ケース・スタディ タイルの背景画面を描画する。

最初のアイディア タイルの地図として、単一の、大地の形状をなしているテクスチャーを使う。

描画するときの、メソッドはdraw_texture で、こなす。ひとつひとつのタイルを選択することで、
テクスチャーを切り取り、調整をする。

たった1回のglBindTexture() の呼び出しが必要です。これはいいです。
でなければ、これは、ひどいアイディアです。
glTexParameteriv()というメソッドは高くつきます。

みなさん、覚えておいてください。状態の変化は、機能が固定されているハードウェアにおいては、
高くつきます。

Case Study: Drawing Tiled Backgrounds
• Second idea: draw the tiles individually with draw_texture
extension using a bunch of really small textures.
– This actually works pretty well once some easy optimizations
are made (RLE the tile map, etc).
– But it’s still a lot of calls to OpenGL. 400 calls to
glDrawTexfOES() in the worst case, plus lots of superfluous
glBindTexture calls.
– Average case is good: less than 16 ms for the hardware to draw
everything. But the actual submission of tiles to OpenGL is
variable depending on the sparseness of the layer: 2 - 10 ms.
– Worst case is bad: 9 - 13 ms to make GL calls and 19 - 23 ms
to draw. Way unacceptable.


ケーススタディ 
背景画面を描画する。

2番目のアイディア

draw_texture extensionで、タイルの1枚1枚を描画する。
とても小さなテクスチャーのかたまりを使う。

これは、一度、いくつかの、簡単な最適化が、実行されると、とてもうまくいきます。((RLE the tile map, etc).
しかし、OPENGLに対して、たくさんの呼び出しがかかります。最悪の場合、glDrawTexfOES()
に対して、400回の呼び出しがかかります。さらに、無駄のある、glBindTextureの呼び出しもあります。

平均的なケースではうまくいきます。
16ミリ秒より、短い間隔で、ハードウェアに対して、あらゆるものを描画できます。
しかし、タイルを、OPENGLに対して、実際に差し出すのは、とても、変幻自在なものになります。
背景画面のレイヤーがどれだけ、希薄かにもよります。だいたい、2ミリ秒から、10ミリ秒です。

最悪の場合、GLを呼び出すのに9ミリ秒から13ミリ秒かかります。19ミリ秒から23ミリ秒、描画するのにかかります。
これは、ゲームの開発の上ではうけいれられる数字ではないです。

Case Study: Drawing Tiled Backgrounds
• Third idea: Make “meta tiles” out of vertex arrays, uv them to
the atlas texture, and project them using orthographic
projection.
– Initial results were in line with the “basic vert quads” test in
SpriteMethodTest: terrible.
– Switching to VBOs sped things up a lot.
– Lots of advantages to this approach: only one glBindTexture()
call, very few total calls to other GL commands (only four meta
tiles to draw per layer per frame).
– Worst case situation (two layers with no empty tiles) is much
faster than the draw_texture approach. CPU spends only 3 - 5
ms submitting to GL and drawing takes less than 16 ms.
– Average case is the same! This makes it slightly slower than
draw_texture in the average case (most maps are very sparse).

ケーススタディ 3番目

3番目のアイディア 頂点配列から、メタ・タイルを作成する。それを、UVして、
地面のテクスチャーをつくる。そして、それらを、正射影を使う。

まず、最初の結果としては、

SpriteMethodTestをやってみたところ、ひどいものでした。

VBOにきりかえるのに、時間がかかります。

この方法には、いい点もたくさんあります。

glBindTexture()を1回呼び出せばすむということ。

GLのコマンドをほとんど呼び出さなくていいこと。(一枚のフレームごとに、4枚のメタタイルがあれば、描画は
できます。)

2枚のレイヤーを使って、空になったタイルはないという状態、つまり最悪の状態は、the draw_texture の方法より
はやかったです。
CPUは、GLに提出をするのに、3ミリ秒から5ミリ秒、描画にかかる時間も、16ミリ秒を越えることはありませんでした。

平均的なケースにおいては、同じです。draw_textureより、すこし、遅くなります。(ほとんど、地図は、希薄だからです。)

Case Study: Drawing Tiled Backgrounds
• Last ditch idea: pre-render the tile map and cut it up into
meta tile textures, which can be drawn with VBO quads or
draw_texture.
– I haven’t actually implemented this yet.
– Level size will be restricted by total amount of VRAM if I use this
method (unless I dynamically load textures).
– High main memory cost too.
– But, given all available information, drawing this way should be
blazing fast.
– I’m close enough to 60hz now that this probably won’t be
necessary.
• Future improvements to Android’s GL interface (or the G1
GL driver) might render these optimizations unnecessary.


ケーススタディ 4番目
最後にずるいやり方
タイル地図を、あらかじめ、レンダーしてしまい、それを、メタタイルのテクスチャーにかえてしまう。
これは、VBO quadsまたはdraw_textureによる描画を可能にする。
実は、まだこの方法による実装はしていません。

サイズのレベルは、
VRAMの全体の容量によって、制限をうけます。もし、私がこのメソッドが使うとしたら、(私が、動的に、テクスチャーのロードをしなかったとして)

メモリーの確保が高くつきます。

しかし、入手可能なあらゆる情報を、詳細に検討すると、このように描画するのは、おそらく、いちばん、早くなります。

私は、60ヘルツに近いです。だから、これは、不必要なのではないかと思います。

将来、このさき、アンドロイドのGLのインターフェイスが、よくなったとしたら、もしくは、
G1の端末、もしくはGLのドライバがよくなったとしたら、このような、最適化は、不必要になります。

VRAMとは、ディスプレイに表示される内容を保持しているメモリ。昔はメインメモリの一部が割り当てられたが、最近はビデオカードに高速化された専用のRAMが搭載されることが多い。画面の最大解像度や最大同時発色数はVRAMの容量に左右される。

• Touching the screen causes your app to be flooded with
MotionEvents.
– This will kill your framerate.
– Sleep in the onTouchEvent callback to slow the flood. 16 ms is
a good place to start.
• The mechanics of pausing and resuming are complicated
when it comes to OpenGL, as the contents of VRAM are not
always maintained. GLSurfaceView solves this for you.
– GLSurfaceView handles the state machine correctly.
• ATITC texture compression (supported on the G1) can be a
big win if you are bus-bound.
Android 1.0 - 1.5 failed to throw errors if you try to use VBOs
with indirect buffers. Result: unpredictable crashes.
– Solution is to just use direct buffers.

アンドロイドOSを搭載した携帯電話は、タッチスクリーンです。あなたのアプリケーションは、
モーションイベントだらけになります。
これは、ゲームのフレームレートを停止させてしまいます。
モーションイベントだらけをすこしでも、緩和するために、 onTouchEvent callback
を活用すべきです。16ミリ秒は、開始するのに、とてもいいところです。

停止と、再開の、メカニズムは、とりわけ、OPENGLに関しては、複雑になります。なぜなら、VRAMの
内容は、つねに、保持されているわけではないからです。GLSurfaceViewは、
こういった問題に対して、あなたを助けてくれます。

GLSurfaceView は、端末の状態を、正しく、操作してくれます。

ATITC texture の圧縮(G1でサポートされています。)は、大きな助けになります。

Android 1.0 - 1.5 は、エラーをはくことに、失敗します。もしも、VBO(頂点配列)を、間接的なバッファーと一緒に
使おうとした場合。
結果→  予想できないクラッシュ。

バッファは、直接で、つかってください。
それだけが解決方法になります。

Keep your application as small as possible. 2 ~ 3 mb is
ideal.
• Now is the time for competent games. Customers are
hungry for them and the platform is capable!
• As of right now there are already Android devices without a
hardware keyboard (HTC Magic) or trackball (Samsung
i7500). Don’t rely on these input devices for game play (or
support them all).
• The key to success Android Market is quality. Making a
high-quality game is the way to be considered for the
Featured Apps section too. Polish polish polish!
• You have always-on internet at your disposal. Use it!


開発するアプリケーションのサイズは、小さいほうがいいです。2,3メガバイトが理想です。
優秀なゲームだけが、歓迎される時代です。お客さんは、いいゲームに植えています。
プラットフォームの性能は、とてもいいのです。

すでに、アンドロイドを搭載した携帯電話端末においては、キーボードがないものや、
トラックボールがないものも、販売されています。つまり、携帯電話の端末のハード部分に
ついている入力装置をあてにするようなゲーム設計はしないでください。
(もし、そうでなければ、携帯電話の端末ごとにある違いを、きちんとカバーした上で、開発をしてください。)

Android マーケットで成功しようとしたら、品質がもっとも重要になります。
高品質のゲームを開発することは、マーケットでの注目商品になるための、道になります。
磨き上げましょう。

インターネットにある情報は、いつだって、使ってください。