// SLG Move Test // Programmed by. 鷹月ぐみな(ishigami@campus.ne.jp) unit move; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, TGameB, MPlayer, MMSystem; type TForm1 = class(TForm) GW1: TGW; MediaPlayer1: TMediaPlayer; procedure GW1_0_Create(Sender: TObject); procedure GW1_1_TitleInit(Sender: TObject); procedure FormCreate(Sender: TObject); procedure GW1_2_TitleJob(Sender: TObject); procedure GW1_3_MainInit(Sender: TObject); procedure GW1_4_MainJob(Sender: TObject); procedure MediaPlayer1Notify(Sender: TObject); private { Private 宣言 } public { Public 宣言 } procedure Arch(px,py,mv,di: integer; mway: String); end; var Form1: TForm1; mx,my,cx,cy,px,py,cur,mv,goflag,golast,tog: integer; mvrec: Packed array[0..255,0..255] of String; Epath: String; implementation {$R *.DFM} // --- 起動時設定等(マップのロード他) procedure TForm1.GW1_0_Create(Sender: TObject); begin // マップデータの読みこみ GW1.BG_ChipDataRead(0,'mapdata.dat'); mx:=10; my:=10; // mx,my は、マップの表示開始位置(+9,+7が中心地) cx:=2; cy:=2; // cx,cy は、画面内カーソル表示位置 px:=20; py:=20; /// px,py は、主人公の絶対位置 mv:=6; // 移動許可単位距離 goflag:=0; golast:=0; // アニメーション移動中かどうかの判定フラグ tog:=0; // トグル // BGM起動処理 MediaPlayer1.FileName:=Epath+'tikai.mid'; MediaPlayer1.Open; MediaPlayer1.Play; end; procedure TForm1.GW1_1_TitleInit(Sender: TObject); begin // --- 実際はタイトルではなく、メイン読み出し用 end; // メインルーチン procedure TForm1.GW1_2_TitleJob(Sender: TObject); var zx,zy:integer; begin // スペースキーを押すと、キャラクターの移動範囲計算処理へ if (tog=0) and (GW1.boolButtonLeft) then begin if (mx+cx=px) and (my+cy=py) then begin SndPlaySound(PChar(Epath+'set.wav'),SND_ASYNC); GW1.Goto_MainInit; end; end; if (tog=1) and not (GW1.boolBUttonLeft) then tog:=0; // カーソル移動 if (GW1.boolKeyLeft) then begin SndPlaySound(PChar(Epath+'move.wav'),SND_ASYNC); if cx<1 then dec(mx) else dec(cx); end else if (GW1.boolKeyRight) then begin SndPlaySound(PChar(Epath+'move.wav'),SND_ASYNC); if cx>17 then inc(mx) else inc(cx); end; if (GW1.boolKeyUp) then begin SndPlaySound(PChar(Epath+'move.wav'),SND_ASYNC); if cy<1 then dec(my) else dec(cy); end else if (GW1.boolKeyDown) then begin SndPlaySound(PChar(Epath+'move.wav'),SND_ASYNC); if cy>12 then inc(my) else inc(cy); end; // 画面デバッグ情報の表示 // キャラクター表示 zx:=px-mx; zy:=py-my; GW1.putZ(Epath+'girl',1+(cur div 5),zx*32+16,zy*32-16,200); GW1.putZ(Epath+'girl',3+(cur div 5),zx*32+16,zy*32+16,200); // マップ表示およびカーソル表示 GW1.FloaterBGput(Epath+'bgchip2',0,mx*32,my*32,1); GW1.put(Epath+'Cur',(cur div 5)+1,cx*32+16,cy*32+16); cur:=cur+1; if cur>=10 then cur:=0; end; // --- アプリケーションが最初に呼び出すルーチン procedure TForm1.FormCreate(Sender: TObject); begin Epath:=ExtractFilePath(Application.ExeName); end; // --- キャラクターの移動範囲を計算するルーチンはここです procedure TForm1.GW1_3_MainInit(Sender: TObject); var i,j:integer; begin // フィルターを全解除 for i:=0 to 255 do for j:=0 to 255 do begin GW1.BGF[1,i,j]:=1; mvrec[i,j]:=''; end; // 主人公の位置から、移動距離 mv 分への再帰探索をはじめる Arch(px,py-1,mv,1,'1'); Arch(px+1,py,mv,2,'2'); Arch(px,py+1,mv,3,'3'); Arch(px-1,py,mv,4,'4'); end; procedure TForm1.Arch(px,py,mv,di: integer; mway: String); var num,down:integer; begin // すでに地点情報が書きこまれている場所は無視する事 if (mvrec[px,py]<>'') and (Length(mway) > Length(mvrec[px,py])) then exit; // まず、その場所の地形情報を調べる。downは、地形を移動するために必要な距離数 down:=0; num:=GW1.BGf[0,px,py]; // 仮決定部 if (num>=1) and (num<=15) then down:=1; if num>=16 then down:=10; // 本決定部 if num=0 then down:=10; if (num=3) or (num=12) or (num=15) then down:=2; if (num=2) then down:=3; if (num=21) then down:=6; if mv-down<0 then begin // 移動できない事が分かりました。もう調べてもムダですね exit; end; // すくなくとも移動はできるようなんで、マークして次へ GW1.BGF[1,px,py]:=0; mvrec[px,py]:=mway; if di<>3 then Arch(px,py-1,mv-down,1,mway+'1'); if di<>4 then Arch(px+1,py,mv-down,2,mway+'2'); if di<>1 then Arch(px,py+1,mv-down,3,mway+'3'); if di<>2 then Arch(px-1,py,mv-down,4,mway+'4'); end; procedure TForm1.GW1_4_MainJob(Sender: TObject); var zx,zy:integer; sr:String; begin if goflag=0 then begin // ----- アニメーションフラグ=0の時の処理はここから // スペースキーで移動開始します(大変かも……) if (GW1.boolButtonLeft) and (GW1.BGf[1,mx+cx,my+cy]=0) then begin if not ((px=mx+cx) and (py=my+cy)) then begin // アニメーション距離のセット goflag:=1; golast:=Length(mvrec[mx+cx,my+cy]); end; end; // リターンキーを押すと、先の画面に戻ります if (GW1.boolButtonRight) then GW1.Goto_TitleInit; // カーソル移動 if (GW1.boolKeyLeft) then begin SndPlaySound(PChar(Epath+'move.wav'),SND_ASYNC); if cx<1 then dec(mx) else dec(cx); end else if (GW1.boolKeyRight) then begin SndPlaySound(PChar(Epath+'move.wav'),SND_ASYNC); if cx>17 then inc(mx) else inc(cx); end; if (GW1.boolKeyUp) then begin SndPlaySound(PChar(Epath+'move.wav'),SND_ASYNC); if cy<1 then dec(my) else dec(cy); end else if (GW1.boolKeyDown) then begin SndPlaySound(PChar(Epath+'move.wav'),SND_ASYNC); if cy>12 then inc(my) else inc(cy); end; end; // ------ アニメーションフラグ=0の処理はここまで if goflag>0 then begin // ----- アニメーションフラグ>=1の時の処理はここから sr:=mvrec[mx+cx,my+cy]; if copy(sr,goflag,1)='1' then dec(py); if copy(sr,goflag,1)='2' then inc(px); if copy(sr,goflag,1)='3' then inc(py); if copy(sr,goflag,1)='4' then dec(px); inc(goflag); if goflag>golast then begin goflag:=0; tog:=1; GW1.Goto_TitleInit; end; end; // ------ アニメーションフラグ>=1の処理はここまで // 画面デバッグ情報の表示 // キャラクター表示 zx:=px-mx; zy:=py-my; GW1.putZ(Epath+'girl',1+(cur div 5),zx*32+16,zy*32-16,200); GW1.putZ(Epath+'girl',3+(cur div 5),zx*32+16,zy*32+16,200); // マップ表示およびカーソル表示 GW1.FloaterBGput(Epath+'bgchip2',0,mx*32,my*32,1); GW1.FloaterBGput(Epath+'filter',1,mx*32,my*32,20); GW1.put(Epath+'Cur',(cur div 5)+1,cx*32+16,cy*32+16); cur:=cur+1; if cur>=10 then cur:=0; end; procedure TForm1.MediaPlayer1Notify(Sender: TObject); begin If MediaPlayer1.Mode=mpPlaying then exit; MediaPlayer1.Previous; MediaPlayer1.Play; end; end.