スプライトの考え方
ゲームなどのプログラムでは、背景の上にキャラクタが重なって表示され、それがぐりぐりと動いている、というようなことをよくやっています。こうした「キャラクタを動かす」という処理はどうやっているのでしょう。
まず、誰もが思いつくのは、「キャラクタのImageをインスタンス変数などで保持し、その描画位置を変更しながら描きなおす」ということでしょう。毎回、背景を描いて、その上にキャラクタを描く、という処理を行っていけば、キャラクタの位置を自由に動かすことはできそうですね。
ただし、このやり方は、キャラクタの数が増えてくるとかなり煩雑になってきます。すべてのImageと、それを表示する場所をあらかじめ変数などで用意しておき、描画の際にそれを使って描いていくわけですから。もう少しすっきりとしたやりかたはないのか?と誰しも感じることでしょう。
また、こうしたキャラクタ利用のプログラムでは、ただ表示するだけで済むことは稀です。多くの場合、「衝突判定」というものが必要になります。これは、2つのキャラクタが衝突(接触)したかどうかを調べるものです。こうしたことまで手作業ですべて計算しないといけないとなると、これは少々やっかいですね。
こうした「キャラクタの表示と操作」を行うとき、非常に便利な機能がDoJaには用意されてます。それが「スプライト」と呼ばれるものです。とりあえず、実際に簡単なサンプルを動かしてみましょう。まず、表示するキャラクタのイメージ(縦横50ドットの大きさ、「char.gif」というファイル名)を、iappliToolプロジェクトの「res」フォルダに入れてください。そして以下のようにソースコードを作成しましょう。
import com.nttdocomo.ui.*;
public class SampleIApp extends IApplication {
public void start() {
Display.setCurrent((Frame)(new MainCanvas()));
}
}
class MainCanvas extends Canvas {
Image charImg;
Sprite[] sprites;
SpriteSet set;
MainCanvas() {
setSoftLabel(SOFT_KEY_1, "END");
setBackground(Graphics.getColorOfName(Graphics.WHITE));
try {
MediaImage mi = MediaManager.getImage("resource:///char.gif");
mi.use();
charImg = mi.getImage();
sprites = new Sprite[2];
sprites[0] = new Sprite(charImg);
sprites[1] = new Sprite(charImg);
sprites[0].setLocation(50,50);
sprites[1].setLocation(100,100);
set = new SpriteSet(sprites);
}catch(Exception e){}
}
public void paint(Graphics g) {
g.lock();
g.clearRect(0, 0, Display.getWidth(), Display.getHeight());
g.drawSpriteSet(set);
g.unlock(true);
}
public void processEvent(int type, int param) {
switch(type){
case Display.KEY_RELEASED_EVENT:
int x = sprites[0].getX();
int y = sprites[0].getY();
switch(param){
case Display.KEY_SOFT1:
(IApplication.getCurrentApp()).terminate();
break;
case Display.KEY_UP:
sprites[0].setLocation(x,y - 10);
break;
case Display.KEY_DOWN:
sprites[0].setLocation(x,y + 10);
break;
case Display.KEY_LEFT:
sprites[0].setLocation(x - 10,y);
break;
case Display.KEY_RIGHT:
sprites[0].setLocation(x + 10,y);
break;
}
repaint();
}
}
}