■迷路の定義と表示

迷路の中をキャラクタが移動するタイプのゲームは色々あります。この迷路をJavaでどう表現するかを考えてみます。
ここでは、迷路の一こま毎にClassを持たせてキャラの進む方向の判定をする事にしました。


↑元ネタファイルはこちら

STEP.1 迷路の定義

final int[][] maze_pattan 迷路パターンが入っている配列です。
NUMBER_OF_X X方向の配列数です。
NUMBER_OF_Y Y方向の配列数です。
WIDTH_OF_MAZE 迷路1コマの横幅です。
HEIGHT_OF_MAZE 迷路1コマの縦幅です。

 迷路配列を初期化します。

 maze = new Maze[NUMBER_OF_X][NUMBER_OF_Y];

  迷路のインスタンス化します。ここで呼び出しているMazeクラスは、STEP.2で説明します。

 for(int j=0; j < NUMBER_OF_Y; j++){
   for(int i=0; i < NUMBER_OF_X; i++){
      int px_maze = (int) (i*WIDTH_OF_MAZE);
      int py_maze = (int) (j*HEIGHT_OF_MAZE);
      maze[i][j]
      = new Maze(maze_pattan[i][j],WIDTH_OF_MAZE, HEIGHT_OF_MAZE,px_maze, py_maze,this);
   }
 }



STEP.2 Mazeクラスの示します。

 class Maze{
  private int kabe, width, height;
  private int px, py;
  pack pack;

 Maze(int kabe, int width, int height, int px, int py,Applet applet){
  this.kabe = kabe;
  this.width = width;
  this.height = height;
  this.px = px;
  this.py = py;
  pack = (pack)applet;
 }

// 壁データの設定
 public void setKabe(int kabe){
  this.kabe = kabe;
 }

// 壁データの取得
 public int getKabe(){
  return kabe;
 }

// 本体描画
public void paint(Graphics g){

壁の表示部分です。

  if(kabe == 0){
    g.setColor(new Color(0,0,255)); // 色の設定
    g.fillRect(px,py,width,height);
  }

ドットの表示部分です。

  if(kabe == 1){
    g.setColor(new Color(255,255,255)); // 色の設定
    g.fillOval(px+(int)(width/2),py+(int)(height/2),2,2);
  }

パワーエサはちょっと大きいので、中心を気にしています。

  if(kabe == 3){
    g.setColor(new Color(255,255,255)); // 色の設定
    g.fillOval(px+(int)(width/2)-5,py+(int)(height/2)-5,10,10);
  }

ボーナスフルーツ発生条件が満たされると、配列に'4'を書き込みます。

  if(kabe >= 4){
    g.drawImage(pack.BonusImage[kabe-4],px,py,pack);
  }
 }
}



STEP.3 進行方向の状態を検出します。

 パックマンを動かしているpack()を説明します。

mmx,mmy マウスのX軸位置とY軸位置
packman.getPointX() PackmanのX軸位置
packman.getPointY() PackmanのY軸位置
pack_x,pack_y Maze配列上のPackmanの位置
pvx,pvy Mazeコマ上のPackman位置
shift_pack Packmanの移動量
dir Packmanの向いている方向

 Packmanはマウスカーソルを追っていく様に作ってありますので、そちら側に障害物が
 ないことを確認しています。

 マウス位置とPackmanの位置を比較して移動方向を決めています。
 但し、迷路まの壁の中をとおったりしないように、X方向はpvyが零、Y方向はpvxが零の時のみ
 移動できるようにしています。

  int dist_x = packman.getPointX()-mmx;
  int dist_y = packman.getPointY()-mmy;

  if((dist_x < 0)&(pvy == 0)){
    if(maze[pack_x+1][pack_y].getKabe() != 0){
      pvx=pvx+shift_pack;
      dir = 3;
    }
  }

 pvx,pvyが規定値を超えたら配列上の位置をずらします。
 但し、X軸方向にはワープゾーンがあるのでY方向に比べると処理が大きくなっています。

  if (pvx >= WIDTH_OF_MAZE){
    if(pack_x >= NUMBER_OF_X-2){
      pack_x=1;
      } else {
      pack_x++;
    }
    pvx=0;
  }

  if (pvx <= -1*WIDTH_OF_MAZE){
    if(pack_x <= 1){
      pack_x= NUMBER_OF_X-2;
    } else {
    pack_x--;
    }
    pvx=0;
  }

  if (pvy >= HEIGHT_OF_MAZE){
    pack_y++;
    pvy=0;
  }

  if (pvy <= -1*HEIGHT_OF_MAZE){
    pack_y--;
    pvy=0;
  }

 また、ドットに付いても同じような処理でします。但し、食べた後にドットが残ってはまずいので、
 maze.setKabe()で何もない状態にしています。(パワーエサやボーナスも同じです。)

 if(maze[pack_x][pack_y].getKabe() == 1){
   maze[pack_x][pack_y].setKabe(2) ;
   score++;
   counter++;
 }


STEP3.表示部です。この表示は比較的処理が軽いので、paint(Graphics gc)の中で毎回実施しています。

 ちらつき防止に、イメージ領域uraを宣言します。

 Image ura;   //イメージ領域「ura」の宣言
 Graphics gc2; //Graphics オブジェクトを宣言
ura= createImage(300,400); //裏のイメージ領域「ura」のサイズを決める
gc2= ura.getGraphics(); //裏のイメージ領域「ura」に絵を描けるようにする

 ここで作ったイメージ領域に、MazeClassのmaze.paintで表示グラフィックデータなどを書き込んでいきます。
 それぞれの位置に表示するもの(ドット、壁など)は、MazeClass内であらかじめ設定しています。

 public void paint(Graphics gc){
    for(int j=0; j < NUMBER_OF_Y; j++){
      for(int i=0; i < NUMBER_OF_X; i++){
        maze[i][j].paint(gc2);
      }
    }
 }
迷路は基本ですが、それだけに変な動きがあるとがっかりしてしまうので、がんばって作りましょう。
Copyright (C) 錬金術師Masa
更新:2005年05月10日
http://www.katch.ne.jp/~mh524-1997/