Javaにおける2Dゲーム描画設計 (キャラクタータスクにビットマップ情報を持たせる)
前回は言語を意識しない2D描画の設計を検討しましたが、今回より具体的にJava言語に絞って説明をしてみたいと思います。
今回は1/22に説明した、「キャラクタータスクに描画属性を持たせた設計」の描画情報の一つであるビットマップの説明をメインに行いたいと思います。
◇ ◇ ◇
さて、キャラクタータスクに描画属性を持たせた設計では、
【2Dゲームの開発の場合の情報】
・ビットマップ(これは1枚〜n枚)
・アニメーション情報(現在何枚目を示しているか等)
ということを説明しましたが、このビットマップをJavaで実現する場合には、「Imageクラス」を用いることができます。ImageクラスはJavaの標準ライブラリで実装されてる高機能なビットマップ情報を保持するクラスとなります。
次にキャラクタータスクより派生したタスクにてアニメーションが行われることを考える場合、このビットマップ情報が複数必要になるので、以下の二つのアプローチが考えられます。
【アニメーションにおけるビットマップの保持方法】
1.ビットマップファイルをアニメーションパターン分作成して、その分のImageクラスを配列で持つ。
長所:プログラミングとは離れたレベルでアニメーションの管理を行いやすい。
短所:「2.」に比べてパフォーマンスが良くない。
2.ビットマップファイルを一枚のみ作成し、この中にアニメーション分のパターンを描いておき、
Imageクラスを1つ持つ。
長所:「1.」に比べてパフォーマンスが良い。
短所:アニメーションが追加された場合など、ビットマップの修正が場合により大変になる。

インターネットにて検索すると「2.」の方式を取るケースをが多く見受けられますが、これには長所/短所や好みがあるので、ここでは話がシンプルにしやすい「1.」の方式で話を進めて行きたいと思います。
(ゲーム上の表現にて大量の計算やメモリを必要とする場合にて、パフォーマンス優先するという場合には、「2.」の方法は必須と思います)
これをプログラムソースで表すと以下のようになります。
【単純なコーディング例(Java) 】
この中の"m_images"がアニメーション用のビットマップとなります。
実際に描画を行う対象のImageクラスはメンバ変数"m_image"が、対象となることに注意してください。
これはアニメーションを行わないタスクの場合を考慮してこのように設計しています。

まずはここで説明を一区切りとして、次回はこのImageクラスにビットマップファイルを設定する説明をしたいと思います。
実際に画面に描画されるまで道のりはまだまだですが、一つずつ説明していきたいと思います。
今回は1/22に説明した、「キャラクタータスクに描画属性を持たせた設計」の描画情報の一つであるビットマップの説明をメインに行いたいと思います。
◇ ◇ ◇
さて、キャラクタータスクに描画属性を持たせた設計では、
【2Dゲームの開発の場合の情報】
・ビットマップ(これは1枚〜n枚)
・アニメーション情報(現在何枚目を示しているか等)
ということを説明しましたが、このビットマップをJavaで実現する場合には、「Imageクラス」を用いることができます。ImageクラスはJavaの標準ライブラリで実装されてる高機能なビットマップ情報を保持するクラスとなります。
次にキャラクタータスクより派生したタスクにてアニメーションが行われることを考える場合、このビットマップ情報が複数必要になるので、以下の二つのアプローチが考えられます。
【アニメーションにおけるビットマップの保持方法】
1.ビットマップファイルをアニメーションパターン分作成して、その分のImageクラスを配列で持つ。
長所:プログラミングとは離れたレベルでアニメーションの管理を行いやすい。
短所:「2.」に比べてパフォーマンスが良くない。
2.ビットマップファイルを一枚のみ作成し、この中にアニメーション分のパターンを描いておき、
Imageクラスを1つ持つ。
長所:「1.」に比べてパフォーマンスが良い。
短所:アニメーションが追加された場合など、ビットマップの修正が場合により大変になる。

インターネットにて検索すると「2.」の方式を取るケースをが多く見受けられますが、これには長所/短所や好みがあるので、ここでは話がシンプルにしやすい「1.」の方式で話を進めて行きたいと思います。
(ゲーム上の表現にて大量の計算やメモリを必要とする場合にて、パフォーマンス優先するという場合には、「2.」の方法は必須と思います)
これをプログラムソースで表すと以下のようになります。
【単純なコーディング例(Java) 】
| public class CharacterTask extends Task { // 画像集合(アニメーション対応) public ArrayList<Image> m_images = new ArrayList<Image>(); // 現在の画像(この画像が描画対象となります) public Image m_image; // アニメーション画像インデックス(現在どのアニメーションを差しているか) public int m_animeIndex = 0; // アニメーション画像待ち時間(何フレーム後にアニメーションを切り替えるか) public int m_animeWait = 0; public int m_workAnimeWait = 0; } |
この中の"m_images"がアニメーション用のビットマップとなります。
実際に描画を行う対象のImageクラスはメンバ変数"m_image"が、対象となることに注意してください。
これはアニメーションを行わないタスクの場合を考慮してこのように設計しています。

まずはここで説明を一区切りとして、次回はこのImageクラスにビットマップファイルを設定する説明をしたいと思います。
実際に画面に描画されるまで道のりはまだまだですが、一つずつ説明していきたいと思います。
コメント
No title
アプローチは色々とありますよね〜
PUSHさん、どうもです(^^)
BufferedImageいいですよね。ビットマップが直接いじれる感があっていいと思います。
「2.」の方式ですが、JavaがImageクラスで内部に管理する情報が一つで済む分、パフォーマンスが良いのと、ファイルの読み込みが一回で済むということや、他のタスクのビットマップと全て混同すれば、描画の際に「タスク毎のイメージの参照→描画」のループシーケンスが、「一つのビッットマップ内の座標毎の描画」と、ほんの少しですが、処理が高速になる(かも知れません)と思います。
これは描画ルーチンの実装次第…という感じですが、よくフリーでソースコードを公開している人のゲームのビットマップを見ると、1イメージ=複数のキャラクターアニメーションとかを見かけるので、全キャラクターのビットマップ描画座標集合だけを配列で持っていれば、描画のループは1イメージに対してこの配列を回すだけなので、アクセスはそれなりに速くはなるとは思いました。(故意に考えなくてもGCが発生しづらくなりますし)
しかし、これはその分メモリにオンキャッシュなので、広大なスケールのゲームには向いていない方式とも思いますし、結局のところ、処理が自分の考えているfpsに間に合えばいいだけの話なので、好みという感じでしょうね。
でわ〜♪
BufferedImageいいですよね。ビットマップが直接いじれる感があっていいと思います。
「2.」の方式ですが、JavaがImageクラスで内部に管理する情報が一つで済む分、パフォーマンスが良いのと、ファイルの読み込みが一回で済むということや、他のタスクのビットマップと全て混同すれば、描画の際に「タスク毎のイメージの参照→描画」のループシーケンスが、「一つのビッットマップ内の座標毎の描画」と、ほんの少しですが、処理が高速になる(かも知れません)と思います。
これは描画ルーチンの実装次第…という感じですが、よくフリーでソースコードを公開している人のゲームのビットマップを見ると、1イメージ=複数のキャラクターアニメーションとかを見かけるので、全キャラクターのビットマップ描画座標集合だけを配列で持っていれば、描画のループは1イメージに対してこの配列を回すだけなので、アクセスはそれなりに速くはなるとは思いました。(故意に考えなくてもGCが発生しづらくなりますし)
しかし、これはその分メモリにオンキャッシュなので、広大なスケールのゲームには向いていない方式とも思いますし、結局のところ、処理が自分の考えているfpsに間に合えばいいだけの話なので、好みという感じでしょうね。
でわ〜♪
コメントの投稿
« 昔のゲームの想い出 [0010] 「メタルソルジャーアイザックII」 [タイトー] [1985] [アーケード] l Home l 昔のゲームの想い出 [0009] 「魔城伝説II ガリウスの迷宮」 [コナミ] [1987] [MSX] »
> (ゲーム上の表現にて大量の計算やメモリを必要とする場合にて、
> パフォーマンス優先するという場合には、「2.」の方法は必須と思います)
知らなかったです。ちなみにSTAGE-1では「1.」の方式で
GraphicsConfiguration.createCompatibleImageで生成した
BufferedImageを使用しています。
VRAM上にイメージが生成される(はず)ので「1.」方式でも
大丈夫かと思っていました。
今後、もしまたJavaで作る機会があれば試してみたいですね。