第9回.連載でJavaゲーム作っちゃいます弐
Masa: いゃー皆さん。Long time no see です。
ほるえ: えっと・・・・どちら様でした?(ぽかっ)いったーい。ちょっとしたお茶目なのに。
Masa: いやー個人的にとっても忙しくて。あと、プログラムもかなりすごいことになって、同じような処理を作っちゃったりして。やっぱり、ばたばたしている時にあんまり複雑な処理をつくるのは、いけません(^-^;
ほるえ: あと、思いつきで作るのもね。
Masa: そうそうって、なんやと。
ほるえ: べっ。

追加部分
1.町を占領,2.移動可能エリア表示のグラフィック化,3.コンピュータ側移動処理


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


←キャラクタグラフィックは、こちらからお借りしています。
注意)まだ、つくりかけの物です。雰囲気だけお楽しみください。

デバックソフトの動作
【相手キャラクタ】
 1)街を目指して移動します。ピクシーは町を占領(右表参照)します。
 2)全キャラクタが移動し終わると自分キャラクタの移動に移ります。
 3)人間キャラクタが攻撃位置にあると、攻撃をします。(ここが、まだいまいち・・・)
 4)キャラクタが重なると気持ち悪いので、重ならないように処理を入れました。(10/16)


【自分キャラクタ】
 1)中央のマップの右側に各キャラのステータス表示があります。クリックすると各キャラをマップ画面の中央に持ってくることが出来ます。
 2)中央マップに表示された敵キャラについては、左側にステータス表示が出ます。
 3)選択したキャラの上で右クリックするとポップアップメニューが出ます。
 4)’MOVE’を選択しすると、キャラ周囲の移動可能部分以外がグレイになります。(10/10変更部分)
 5)移動したいところをクリックすると、移動します。

【全体的な変更】
キャラの移動可能位置の表示部分を、□の枠からグレイスケールにしました。

未占領の町
人間占領
エルフ占領



Masa: 初物の処理が多くて、仕様を決めるのに一苦労です。こうすればいいと思って作ってみても、あらぬ動きをしてしまったりして・・・こうなると、プログラム製作って言うよりは、アルゴリズムの勉強です。おかげで、配列のソート系のプログラムの経験値が増えました。
ほるえ: レベルアップはしてませんけどね。
Masa: (まだ、すねてんのか。) 
で今回は、キャラの移動先を決めている処理を紹介します。中で使用されている、idou()とpathserch()については、第3回と第7回を参照してください。手段として、
@idou()の検出範囲を広く取って一点ごとに、pathserch()で移動先までの配列を作成。
Aその配列内の場所に何があるかを一点ずつ確認して評価点を出す。
としてもいいのですが・・・・・
ほるえ: めちゃめちゃ時間がかかることがわかって断念したんですよね。
Masa: そうそう。(機嫌直ったか。ほっ) である程度の距離までは、全点検出を行っておいて、それ以上になったら移動先の評価点マップを参照して移動先を決めることにします。

「キャラ移動について2」

動作:
 他の処理で作成されたto_point[]:移動先候補配列の中からもっとも評価点の高い場所を選択する。
前提条件:
 to_point[]:移動先候補配列が作成されていること。

手順
 1.移動先候補配列から一点を読み込み、idou()とpathserch()を用いて、そこまでの工程path[][]を作成する。
 2.作成した、path[][]位置にあるものを調べ、評価点を割り振る。
 3.目標地点の評価点をさらに加える。
 4.to_point[]配列の最後まで、この処理を行い評価点の最も高い位置を返す。

Tips.評価点マップについて
 評価点マップの目的は、エルフキャラをマップ上で動かしたい方向へ誘導することです。ですので、地形が同じだからといってポイントが一緒にはしていません。


ソース解説(詳細)

to_point配列に読み込まれた位置と、そこまでの工程を、指定された行動に基づき評価点として出力します。

public int[] cheak_path(int select){

int point[] = new int[4];point[0]=-1000;

int acup=0; int pc;pc=topc-1;//ポインタ位置を調整

push();

while(pc>=1){
 pop();

 int a=to_point[pc][0];
 int b=to_point[pc][1];
 int hai= pathNo(a,b);

 int c=character[count].getPointX();int d=character[count].getPointY();
 int s_x=a;int s_y=b;int s_l=tansaku[hai][3];

 rest_tanpc();
 rest_path();

 idou(c,d,character[count].getChr(),s_l);
 pathserch(c,d,s_x,s_y,s_l);
 pc--;

///////////////////////////////
//占領用評価
///////////////////////////////

if (select == ocup) {

 for (int i = 0; i < pathhai; i++) {
  if (path[i][4] % 10 == man_city) {acup = acup + 100;} //人間の町
  if (path[i][4] % 10 == city) {acup = acup + 100;} //町
  if (path[i][4] % 10 == man_castle) {acup = acup + 150;} //人間の城
  if (path[i][4] == man) {acup = acup - 10;} //人がいる
  if (path[i][4] == elf) {acup = acup + 10;} //エルフがいる

  int x=path[i][0];int y=path[i][1];
  acup=acup+map[x][y].getpoint();
}

  if (path[0][4] % 10 == man_city) {acup = acup + 1000;} //人間の町
  if (path[0][4] % 10 == city) {acup = acup + 1000;} //町
  if (path[0][4] % 10 == man_castle) {acup = acup + 1500;} //人間の城

  if (acup > point[0]) {
   point[0] = acup;point[1] = s_x;point[2] = s_y;point[3] = s_l;

   acup=0;
  }
 }

 pop();//tansaku[][]をpopする。
 return point;
}
select:行動
占領 int ocup=10
攻撃 int attack=11
撤退 int tetai=12
回復 int heal=13

push()は、tansaku[][]配列を一時保管します。


pop()は、保管したtansaku[][]配列を書き出します。

pathNo()は、tansaku配列の中からVP,HPと等しい配列番号をピックアップし配列数を返す

目標地点をpath[][]から読み取ります。
目標地点までの距離を読み込みます。

・配列tansaku[][]をリセットします。
・配列path[][]をリセットします。

目標地点までの工程路をpath[][]に作成します。




占領用の評価値のみを記入


selectがocup(占領)ならば、この処理へ

目標地点までの工程にあるものを評価します。






map[][].getpoint()は場所(地形ではない)の評価値がはいっています。


移動先の評価ポイントを足します。



評価ポイントが、記録してある評価ポイントの最高値より大きければ、評価した場所を目標地点にします。




tansaku[][]配列を元に戻し、point[]配列を戻します。


独り言)
 シミュレーションゲームというバーチャルな世界でキャラを動かすだけでも、相当大変です。ロボットなんかをやっている人って相当優秀なんだろうなっておもう最近です。



Masa: というわけで、9月中の更新を目指したんですが、10月に入ってしまいました。m(_ _)mごめんなさい。
ほるえ: 反省の心がこもっていない。(うりうり)
Masa: ううっ。今度はがんばりまーす。
でも、10月も忙しいんだよなー。

Copyright (C) 錬金術師Masa
新規:2005年10月1日
更新:2005年10月16日