戦闘画面を作成  

Delphiでゲーム作成


1.処理内容

 ・プレイヤーを移動していると一定の確率で敵が出現する。
 ・敵が出現すると戦闘画面(ウィンドウ)を表示。
 ・プレイヤーと敵に体力を設定し、0になるとゲームオーバーにする。

2.処理手順

 ・プレイヤーが移動した場合
 @敵が現れるかどうかランダム値を取得
 Aランダム値が敵出現値の場合、戦闘画面を表示する。

3. プロジェクトにフォーム(戦闘画面用)を追加する。

 ファイル(F) ⇒ フォームの新規作成(F) で、フォームを追加します。

 

  Imageコンポーネントを、フォームに貼る。
  ButtonImageコンポーネントを、フォームに貼る。
  Labelコンポーネントを、フォームに貼る。
  Memoコンポーネントを、フォームに貼る。
  Panelコンポーネントを、フォームに貼る。
  ProgressBarコンポーネントを、フォームに貼る。
  Timerコンポーネントを、フォームに貼る。

4.プロパティ&イベントプロシージャの設定

TForm
BorderStylebsDialog
Caption戦闘画面
NameForm2
PositionpoDesktopCenter
Height225
Width300
OnShowFormShow

TPanel
BevelInnerbvLowered
BevelOuterbvLowered
ColorclWhite
NamePanel1
Left6
Top8
Height105
Width280

TTimer
NameTimer1
EnabledTrue
OnTimerTimer1Timer

TImage (Panel1に貼付)
NameimgEnemy
Left6
Top45
Height50
Width50

TImage (Panel1に貼付)
NameimgDoka
Height50
Width50

TImage (Panel1に貼付)
NameimgPlayer
Left205
Top45
Height50
Width50

TLabel
Caption体力
NameLabel1
Left6
Top120

TLabel
Caption/
NameLabel2
Left245
Top120

TLabel
NamelblHP
Left217
Top120

TLabel
NamelblMaxHP
Left257
Top120

TButton
Caption攻撃
NamebtnAtc
Left8
Top136
Height25
Width48
OnClickbtnAtcClick

TButton
Caption逃走
NamebtnRun
Left8
Top168
Height25
Width48
OnClickbtnRunClick

TProgressBar
NameProgressBar1
SmoothTrue
Left35
Top117
Height16
Width174

TMemo
NameMemo1
ReadOnlyTrue
ScrollBarsssVertical
Left60
Top136
Height57
Width223

5.プログラムソース(追加分)

Unit1.pas (追加部分)

//************************************************************
// 初期処理
//************************************************************
Procedure TForm1.FormCreate(Sender: TObject);
var
X,Y : Integer;
Begin

 Randomize;

 PlayX := 0;   // プレイヤ初期X位置
 PlayY := 0;   // プレイヤ初期Y位置
 iMaxHP := 1200;  // 体力(最大値)
 iHP   := iMaxHP; // 体力


 // ***** 画像データ読み込み ***** //
 imgData.Picture.LoadFromFile('MapData.bmp');

 // ***** マップデータ ***** //
 MapData[0] := '0000010000';
 MapData[1] := '0111111110';
 MapData[2] := '0100000010';
 MapData[3] := '0101101010';
 MapData[4] := '0001001010';
 MapData[5] := '0110011010';
 MapData[6] := '0000100010';
 MapData[7] := '1110011110';
 MapData[8] := '0111001000';
 MapData[9] := '0000000010';

 // ***** マップ表示サイズ設定 ***** //
 imgMap.Width  := HEX_SIZE * DSP_SIZE_X;
 imgMap.Height  := HEX_SIZE * DSP_SIZE_Y;
 imgMap.Top   := 10;
 imgMap.Left   := 15;

 imgwkMap.Width := HEX_SIZE * MAP_MAX_X;
 imgwkMap.Height := HEX_SIZE * MAP_MAX_Y;

 // ***** マップ画像データを設定 ***** //
 For X := 0 To MAP_MAX_X -1 Do
  Begin

   For Y := 0 To MAP_MAX_Y -1 Do
    Begin
     MapSet( imgwkMap, StrToInt(Copy(MapData[Y],X+1,1)), X, Y);
    End;

  End;

 // ***** マップ表示 ***** //
 MapDSP(PlayX,PlayY);

End;

//************************************************************
//    キー入力判定処理
//************************************************************
Procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
 Shift: TShiftState);
var
 PlayX_BK : Integer;
 PlayY_BK : Integer;
 iRnd    : Integer;
 Menus  : HMENU;

Begin

 // ***** プレイヤ現在位置退避 ***** //
 PlayX_BK := PlayX;
 PlayY_BK := PlayY;

 // ***** キー入力判定 ***** //
 Case Key of
  VK_LEFT : PlayX := PlayX -1;
  VK_RIGHT: PlayX := PlayX +1;
  VK_UP  : PlayY := PlayY -1;
  VK_DOWN : PlayY := PlayY +1;
 Else
  Exit;
 End;

 // ***** 移動先が範囲外座標にならないようにする ***** //
 If PlayX < 0     Then PlayX := 0;
 If PlayX >= MAP_MAX_X Then PlayX := MAP_MAX_X -1;
 If PlayY < 0     Then PlayY := 0;
 If PlayY >= MAP_MAX_Y Then PlayY := MAP_MAX_Y -1;

 // ***** 移動先が壁の場合、移動をキャンセル ***** //
 If StrToInt(Copy(MapData[PlayY],PlayX+1,1)) = MAP_KABE Then
  Begin
   PlayX := PlayX_BK;
   PlayY := PlayY_BK;
  End;

 // ***** マップ表示 ***** //
 MapDSP(PlayX,PlayY);

 iRnd := Random(100);
 If iRnd < 5 Then
  Begin

   // ***** 閉じるボタン無効処理 ***** //
   Menus := GetSystemMenu(Form2.Handle,False);
   EnableMenuItem(Menus,SC_CLOSE,MF_BYCOMMAND or MF_GRAYED);
   DrawMenuBar(Form2.Handle);

   Form2.pHP  := iHP;
   Form2.pMaxHP := iMaxHP;
   Form2.ShowModal; // Form2を閉じるまで先に進めないようにする

   iHP  := Form2.pHP;
   iMaxHP := Form2.pMaxHP;

   If Form2.iStatus = 9 Then Close;

  End;

End;


Unit2.pas

unit Unit2;

interface

uses
 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
 ExtCtrls, StdCtrls, ComCtrls;

type
 TForm2 = class(TForm)
  Panel1: TPanel;
  btnAtc: TButton;
  btnRun: TButton;
  Memo1: TMemo;
  imgEnemy: TImage;
  imgPlayer: TImage;
  Label1: TLabel;
  lblHP: TLabel;
  ProgressBar1: TProgressBar;
  lblMaxHP: TLabel;
  Label2: TLabel;
  imgDoka: TImage;
  Timer1: TTimer;

  procedure btnRunClick(Sender: TObject);
  procedure FormShow(Sender: TObject);
  procedure Timer1Timer(Sender: TObject);
  procedure btnAtcClick(Sender: TObject);

 private
  { Private 宣言 }
  iHP_E,iMaxHP: Integer; // 敵の体力
  bWait : Boolean;    // 時間待ち処理用

  procedure EnemyTurn;
  procedure btnEnabled(iEna: Boolean);
  procedure Wait(imSec: Integer);

 public
  { Public 宣言 }
  pHP,pMaxHP : Integer;  // 体力
  iStatus  : Integer;

 end;

var
 Form2: TForm2;

implementation

//Uses Unit1;

{$R *.DFM}

Const
 C_ENEMY_X = 25;  // 敵の初期位置
 C_PLAYER_X = 205; // プレイヤーの初期位置

//************************************************************
//    初期処理
//************************************************************
procedure TForm2.FormShow(Sender: TObject);
begin

 imgPlayer.Picture.LoadFromFile('Player.bmp');
 imgEnemy.Picture.LoadFromFile('Enemy.bmp');
 imgDoka.Picture.LoadFromFile('Doka.bmp');

 Memo1.Text := '悪党にからまれた!!';
 iMaxHP := 300;
 iHP_E := iMaxHP;
 iStatus := 0;

 lblMaxHP.Caption := IntToStr(pMaxHP);
 ProgressBar1.Max := pMaxHP;

 lblHP.Caption     := IntToStr(pHP);
 ProgressBar1.Position := pHP;

 imgDoka.Visible  := False;
 imgPlayer.Visible := True;
 imgEnemy.Visible := True;

 Memo1.Lines.Add('プレイヤーのターンです。');
 btnEnabled(True);

end;


//************************************************************
//    【攻撃】処理
//************************************************************
procedure TForm2.btnAtcClick(Sender: TObject);
Var
 szMsg :String;
 iDmg,J :Integer;
begin

 btnEnabled(False);

 Memo1.Lines.Add('プレイヤーの攻撃!!');

 J := C_PLAYER_X;
 While J > (C_ENEMY_X +60) Do
  Begin
   J := J -5;
   imgPlayer.Left := J;
   Wait(20);
  End;

 iDmg := 100 + Random(10);
 imgDoka.Left := C_ENEMY_X;
 imgDoka.Visible := True;
 Wait(500);

 szMsg := '悪党は、' + intToStr(iDmg) + 'ポイントのダメージ!';
 Memo1.Lines.Add(szMsg);
 imgDoka.Visible := False;

 iHP_E := iHP_E - iDmg;

 J := C_ENEMY_X +60;
 While J < C_PLAYER_X Do
  Begin
   J := J +5;
   imgPlayer.Left := J;
   Wait(20);
  End;

 If iHP_E <= 0 Then
  Begin
   imgEnemy.Visible := False;
   ShowMessage('悪党をやっつけた。');
   iStatus := 1;  // 敵をたおした(1)
   Close;
  End

 Else
  Begin
   EnemyTurn;
  End;

end;


//************************************************************
//    【逃走】処理
//************************************************************
procedure TForm2.btnRunClick(Sender: TObject);
Var
 iRnd :Integer;
begin

 btnEnabled(False);

 Memo1.Lines.Add('プレイヤーは逃げ出した・・・');
 Wait(1000);

 iRnd := Random(100);
 If iRnd < 50 Then
  Begin
   imgPlayer.Visible := False;
   ShowMessage('逃げ切れた。');
   Form2.ModalResult := 2;
   Close;
  End

 Else
  Begin
   ShowMessage('逃げようとしたら捕まった。');
   EnemyTurn;
  End;

end;


//************************************************************
//    敵の行動処理
//************************************************************
procedure TForm2.EnemyTurn;
Var
 szMsg :String;
 iDmg,J :Integer;
begin

 Memo1.Lines.Add('悪党のターンです。');
 Memo1.Lines.Add('悪党の攻撃!!');

 J := C_ENEMY_X;
 While J < (C_PLAYER_X -60) Do
  Begin
   J := J +5;
   imgEnemy.Left := J;
   Wait(20);
  End;

 iDmg := 100 + Random(10);
 imgDoka.Left := C_PLAYER_X;
 imgDoka.Visible := True;
 Wait(500);

 szMsg := 'プレイヤーは、' + intToStr(iDmg) + 'ポイントのダメージ!';
 Memo1.Lines.Add(szMsg);
 imgDoka.Visible := False;

 pHP := pHP - iDmg;
 If pHP < 0 Then pHP := 0;

 lblHP.Caption := IntToStr(pHP);
 ProgressBar1.Position := pHP;

 J := C_PLAYER_X -60;
 While J > C_ENEMY_X Do
  Begin
   J := J -5;
   imgEnemy.Left := J;
   Wait(20);
  End;

 If pHP <= 0 Then
  Begin
   imgPlayer.Visible := False;
   Memo1.Lines.Add('プレイヤーはやられた。');
   ShowMessage('ゲームオーバー');
   iStatus := 9;  // ゲームオーバー(9)
   Close;
  End;

 Memo1.Lines.Add('プレイヤーのターンです。');
 btnEnabled(True);

end;


//************************************************************
//    ボタン有効/無効処理
//************************************************************
procedure TForm2.btnEnabled(iEna: Boolean);
begin
 btnAtc.Enabled := iEna;
 btnRun.Enabled := iEna;
end;


//************************************************************
//    時間待ち処理
//************************************************************
procedure TForm2.Wait(imSec: Integer);
begin

 bWait := True;
 Timer1.Interval := imSec;
 Timer1.Enabled := True;
 While bWait Do Application.ProcessMessages;

end;

procedure TForm2.Timer1Timer(Sender: TObject);
begin
 Timer1.Enabled := False;
 bWait := False;
end;

end.

6.戦闘画面用のキャラクタ画像を用意する。

Doka.bmp
Player.bmp
Enemy.bmp

ソースはコレです。

次回は、プレイヤーにステータスを付け加えて、敵を倒していくと、
強くなる処理を追加します。