作者: Yさ
日時: 2002/7/9(19:49)
 こんばんは、Yさと申します。
 「(疑似)三次元迷路脱出ゲームでも作ろうかい?」講座
 最終回は、ゲームとしての仕上げです。


5.1 ゲームとして動作させるために必要な取り決め
 サンプルスクリプトは以下の考え方で作成しています。
 1)表示
   ・メインの画面は、迷路を(疑似)三次元表示する。
     残り酸素と2Dマップ表示回数(残りエネルギー)を表示する。
   ・2Dマップ表示-メインの画面を上書きする。
     (2Dマップ消去はメインの画面を再表示する事により行なう)
 2)入力
   ・可能な動作は"一歩前へ進む","右を向く","左を向く","後ろを向く"。
     "鍵を拾う","出口を出る"のも、その場所へ"一歩前へ進む"とする。
   ・2Dマップ表示/消去指示


5.2 サンプルスクリプトの遊び方
 実行し、大きさを x*y の形式で指定してください。 指定サイズの迷路を
作成します。 (サイズが偶数だった場合は +1 して調整します。)
 サイズを入力すると迷路が(疑似)三次元表示されます。
 また、画面には以下の情報が表示されます。

  OXY:残り酸素量です。0になるとゲームオーバーです。
  MAP:地図を見ることのできる回数です。迷路のサイズによっては1回も
      見れない場合があります。

 後は酸素がなくなる前に、鍵("$"記号)を拾って出口(EXIT)まで行っ
てください。出口(EXIT)を抜けると得点を表示して終了します。

 [使用キー]
             8:前へ一歩進む
   4:左を向く              6:右を向く
             2:後ろを向く

  Mまたはm:2Dマップ表示。何かキーを押すと(疑似)三次元表示に戻ります

 [2Dマップ表示の意味]
   #:壁です
   S:スタート地点です
   G:出口(EXIT)です。なぜかゴールのGです(^^;)
   $:鍵です
   ↑,→,↓,←:あなたです。それぞれ、地図に対して
   上、右、下、左 向きなことをあらわします


5.3 サンプル
 では、今回の参考用Yさ版スクリプトです。

 <<重要>> 今回のスクリプトだけでは動作しません。
          第二回のスクリプト(MAZE3DM1.000, MAZE3DS1.001)および
          第四回のスクリプト(MAZE3DS2.002, MAZE3DS3.003)
          を編集して追加してください。

 (maze3d.awk と言う名前で編集した場合)
    jgawk -f maze3d.awk -v _NO_TEST=1[ENTER]
   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 などとして、実行してください。

-----^ MAZE3DM2.004 ( date:02-07-01 time:00:00:00 ) --------------< cut here
# 3D迷路脱出Game Main#2 - acction & ending -  written by Yさ
function move(  key,forward,dx,dy)
{ OXY-=TURN;
  if($0=="M" || $0=="m") return 8;  # MAPを表示する
  key=$0+0;  dx=dy=0;
  if(key==2){ NowDir+=2;  if(NowDir>=4) NowDir-=4;}
  if(key==4){ NowDir-=1;  if(NowDir<0)  NowDir=3; }
  if(key==6){ NowDir+=1;  if(NowDir>=4) NowDir=0; }
  if(key==8 || key==0){ dx=XMove[NowDir];  dy=YMove[NowDir];}
  forward=Mtbl[NowXPos+dx,NowYPos+dy];
  if(forward==0 || forward==4 || forward==3 && KeyXPos==-1){
    NowXPos+=dx;  NowYPos+=dy;  OXY-=MOVE;
    if(forward==4){ Mtbl[KeyXPos,KeyYPos]=0;  KeyXPos=-1;}  # 鍵を拾う
  } if(OXY<=0 && forward!=3){ OXY=0;  return 9;}            # 酸素切れ
  return forward;}
function putStat(){printf("** OXY:%d MAP:%d **  ", OXY, int(ENG/MAP));}
_NO_TEST{
  forward=move();  # 入力判別
  if(forward==9 || forward==3 && KeyXPos==-1) exit;     # 酸素切れorゴール
  if(forward==8){                                       # 2D MAP表示
    if(int(ENG/MAP)<=0){ printf("... Can't searching.");}
    else{ ENG-=MAP;  dispMaze(); putStat();}
    printf(" [PUSH ENTER]");  getline tmp < "/dev/stdin";
  } put3D();  putStat();
  if(forward==1) printf(" Ouch! ... Are you sure?");    # 壁
  if(forward==2) printf(" Get a key and go to EXIT.");  # 入口
  if(forward==3) printf("... You have no key.");        # 出口(鍵無し)
  if(forward==4) printf(" You get a key.");             # 鍵
  printf("\nCOMMAND?>");}
END{ putStat();
  if(forward==9){  # 酸素切れ
    printf("... No OXYGEN.\n");
    printf(" You are DEAD.\n");}
  if(forward==3){  # ゴール
    printf(" Congratulations !!\n");
    printf(" Size : %d*%d\n", Xsize, Ysize);
    printf(" Left OXYGEN : %d\n", OXY);
    printf(" BONUS       : %d\n", ENG);
    printf(" Your score is %d\n", OXY*10+ENG);
} }
-----$ MAZE3DM2.004 ( lines:40 words:193 bytes:1742 ) ------------< cut here

 複雑な判定は分離するのが良い手です(^_^)b 
 (サンプルでは関数 move() として分離しました)
 なお、2byte文字が化ける場合は、前回、前々回を参考にしてスクリプト
を修正して下さい。


  ...長くなりましたが「(疑似)三次元迷路脱出ゲームでも作ろうかい?」
はこれで終わります。 いかがでしたか? 何かのお役に立ちましたか?
 それでは、いつかまた(^o^)/ Yさ