イメージマップの考え方


たとえば、RPGのようにマップを移動するようなゲームを作ろうと思ったとき、どうやって表示を作成していけばいいでしょうか。普通に考えると、表示用のイメージと、表示するデータに関する配列を用意しておいて、繰り返しを使って配列の値を元にイメージを1つずつずらして描画していく……というようなやり方になるでしょう。

が、特にゲーム関係などを作成するとき、こうした「小さいイメージを縦横に敷き詰めて大きなマップ状の盤面を作る」ということはよく行います。実際に、簡単なサンプルを作ってやってみましょう。

ここでは、「images.gif」というファイル名でイメージファイルを作成しましょう。大きさは、横100×縦25ドット。25×25の大きさのマップイメージを4つ横に並べた形にしておきます。それぞれは、ここでは例としてこういうイメージにしておきました。

1つ目――一般的な平野のイメージ。
2つ目――荒地のイメージ。
3つ目――海や川などの水のイメージ。
4つ目――道路のイメージ。

25×25のイメージを4つ横に並べる。

このイメージから、表示したい部分を切り出して並べていけばいいわけですね。では、実際に簡単なサンプルを作成してみましょう。

import com.nttdocomo.ui.*;

public class SampleIApp extends IApplication {

  public void start() {
    Display.setCurrent((Frame)(new MainCanvas()));
  }

}

class MainCanvas extends Canvas {
  private int[] data;
  Image map;

  MainCanvas() {
    setSoftLabel(SOFT_KEY_1, "END");
    setBackground(Graphics.getColorOfName(Graphics.WHITE));
    data = new int[]{
        2,2,2,2,3,0,0,
        2,2,3,3,3,3,3,
        2,2,3,0,0,0,1,
        2,0,3,0,0,1,1,
        0,0,3,0,1,1,1,
        0,0,3,0,1,1,1,
        0,0,3,0,0,1,1
    };
    try {
      MediaImage mi =MediaManager.getImage("resource:///images.gif");
      mi.use();
      map = mi.getImage();
    }catch(Exception e){}
  }

  public void paint(Graphics g) {
    g.lock();
    g.clearRect(0, 0, Display.getWidth(), Display.getHeight());
    int col = 7;
    int row = 7;
    int dx = 10;
    int dy = 10;
    int w = 25;
    int h = 25;
    for(int i = 0;i < col * row;i++){
      g.drawImage(map,dx + i % col * w,dy + i / col * h,data[i] * w,0,w,h);
    }
    g.unlock(true);
  }

  public void processEvent(int type, int param) {
    switch(type){
    case Display.KEY_RELEASED_EVENT:
      switch(param){
      case Display.KEY_SOFT1:
        (IApplication.getCurrentApp()).terminate();
        break;
      }
      break;
    }
  }

}