第5回.連載でJavaゲーム作っちゃいます弐
Masa: 実は、いきなり訂正があります。第3回で解説した移動ルーチンに若干のバグがあって、そのせいでキャラの移動量が足らなくなっていました。
今回のプログラムは修正されています。解説の修正は、またやっておきますが、とりあえずごめんなさい。
ほるえ: そうですよ。いつもプログラムは充分見直すように、言っているのに・・・
Masa: ていうか、寝てたろおまえ。
ほるえ: (あさっての方向をみて)そ、そんなことある訳ないじゃないですか!そんなことより今回は大丈夫なんですか?
Masa: うーん。多分OK

「キャラクタステータス表示とキャラ毎の移動指定」

キャラクタグラフィックは、こちらからお借りしています。


デバックソフトの動作
 1)中央のマップの右側に各キャラのステータス表示をつけました。この表示部分をクリックすることで各キャラをマップ画面の中央に持ってくることが出来ます。
 2)中央マップに表示された敵キャラについては、左側にステータス表示が出ます。
 3)キャラ周囲に出る□をクリックすることで移動します。
 4)移動が終了すると動作移動済みになります。



サンプルが表示されない場合は、Java環境がインストールされていない可能性があります。
SUNホームページから、J2SE v 1.4.2_07 JRE以上のバージョンをダウンロードしてください。

Masa: まあ、自分側の移動についてはこんなものかな?
ほるえ: でも、攻撃とかはないんですか?
Masa: これから、作るよ。ただ、ウインドウ上の場所を使いきっているから、マルチウインドとかにしないと・・
ほるえ: そうですね。このページもフレーム内に入りきっていないし。
Masa: まあね。その辺も含めてちょっと調べないとね。うまい方法を知っている方は、掲示板への書き込みよろしく。
ほるえ: ほんとに他力本願ですね。

移動可能場所サーチの変更について

前回のものと今回の修正版を比較しました。前回のものは、落ち物ゲームのルーチンを再利用したので、2重カウント防止のためのチェックが入っていました。
今回のシミュレーションでは、同じ場所でも道の進み方によっては、残りの移動力に差がありますが、これが2重カウント防止に引っかかって、移動力が残っているのに移動できないというバグが発生していました。

今回の修正でこれについては対策をしています。


前回(間違い) 今回(修正版+更新)
while (mitanpc > 0) {
//未探索領域の読み込み
  V = mitansaku[mitanpc][0];
  H = mitansaku[mitanpc][1];
  IDOU = mitansaku[mitanpc][2];
  mitanpc--;
//マスの上側をチェックする。
//自分の残り移動量で移動できるか?
  if (IDOU >= map[V - 1][H].GetCost()) {
    flag = true;

//探索済みを探していないか?
    for (int i = 0; i <= tanpc; i++) {
      if ( (tansaku[i][0] == V - 1)
            & (tansaku[i][1] == H)) {
        flag = false;break;
      }}
//未探索を2度探していないか?
    for (int i = 0; i <= mitanpc; i++) {
      if ( (mitansaku[i][0] == V - 1)
            & (mitansaku[i][1] == H)) {
        flag = false;break;
      }}


//良ければ、未探索スタックに格納
    if (flag) {
      mitanpc++;
      mitansaku[mitanpc][0] = V - 1;
      mitansaku[mitanpc][1] = H;
      int ido_zan
     = IDOU - map[V - 1][H].GetCost();
      mitansaku[mitanpc][2] = ido_zan;
    }}
while (mitanpc > 0) {
//未探索領域の読み込み
V = mitansaku[mitanpc][0];
H = mitansaku[mitanpc][1];
IDOU = mitansaku[mitanpc][2];
length = mitansaku[mitanpc][3];
mitanpc--;

//マスの上側をチェックする。
if (IDOU >= map[V - 1][H].GetCost()) { //自分の残り移動量で移動できるか?
flag = true;

//良ければ、未探索スタックに格納
if (flag) {
mitanpc++;
mitansaku[mitanpc][0] = V - 1;
mitansaku[mitanpc][1] = H;
int ido_zan = IDOU - map[V - 1][H].GetCost();
mitansaku[mitanpc][2] = ido_zan;
mitansaku[mitanpc][3] = length + map[V - 1][H].GetCost();
}
}

この下で、移動力の残りをチェックするところを入れました。
////////////////////////////////
flag = true;
for (int i = 0; i <= tanpc; i++) {
  if ( (tansaku[i][0] == V) & (tansaku[i][1] == H)) {
   flag = false;
    if(length<tansaku[i][3]){//ここを修正(9/16)
      tansaku[i][0] = V;tansaku[i][1] = H;
      tansaku[i][2] = IDOU;tansaku[i][3] = length;
      tansaku[i][4] = cheakpoint(V,H);
    }

}}
if (flag) {
tansaku[tanpc][0] = V;tansaku[tanpc][1] = H;
tansaku[tanpc][2] = IDOU;
tansaku[tanpc][3] = length;
tansaku[tanpc][4]=cheakpoint(V,H);//追加分
tanpc++;
}
}

//選択場所に何があるかを調べて戻り値を返す。
//-1:何もない,10:自分キャラ,20:相手キャラ,1:町,2:自分の町,3:相手の町,4:自分の城,5:相手の城
//地形にキャラが重なっている場合は、足した数になる。
//地形関係 8:町,9:自分の町,10:敵の町,11:自分の城,12:敵の城
public int cheakpoint(int VP,int HP){
 int point = 0;
 switch (map[VP][HP].getGeo()){
  case 8:
   point = 1;break;
  case 9:
   point = 2;break;
  case 10:
   point = 3;break;
  case 11:
   point = 4;break;
  case 12:
   point = 5;break;
  }
  for(int i=0;i<20;i++){
    int charX=character[i].getPointX();
    int charY=character[i].getPointY();
    if ((charX==VP)&(charY==HP)){
      if(i<10){point=point+20;}else{point=point+10;}
      }
    }
  return point;
}
9/10 tansaku[][4]に、そのポイントの情報を追加しました。
9/16 配列が重複している部分を修正しました。

Masa: てなかんじで、移動についての修正は完了したと思うので、後は他の行動、攻撃とかを組んでいくことになるな。
あと、敵キャラも動かさんとつまらないしね。
ほるえ: あと、出来るだけバグを出さないようにてですね。
Masa: (グサッ)そうそうこんなバグはださんよ。ただ結構チャレンジングなことをすれば間違いもあるってことで・・・・
ほるえ: ま、そのときは転地爆裂か、ドラグスレイブをぶちかましておきますので、皆さんお楽しみに。
Masa: そんなん、楽しみにされても・・・

Copyright (C) 錬金術師Masa
新規:2005年08月20日
更新:2005年09月18日