Delphiでゲーム作成

戦闘画面を作成


Delphiでゲームを作りますが、DirectXとかは使いません。
というより使い方を知りませんので、通常の命令と、WindowsAPIで、
作成していくつもりです。

Delphiは、VBを少しでもやったことがあればそれほど難しくないです。
それでは説明します。

1.Delphi6手に入れる。

  Borlandのサイトからダウンロードしてください。

2.処理内容

 今回は、「10×10のマップをプレイヤーが移動する」という処理作成します。

 ・マップサイズは、縦10マス×横10マスにする。
 ・実際に画面に表示するマップは、プレイヤーを中心とした、 縦5マス×横5マスにする。
 ・↑↓←→の矢印キーでプレイヤーを移動させる。
 ・壁は通り抜けられない。

3.処理手順

 ・初期処理
 @マップデータを読み込む。
 Aマップを表示する。

 ・キー入力があった場合
 @矢印キーが押された場合、プレイヤーを移動させる。
 Aプレイヤーを移動させた場合 、マップを再描画する。

4.フォームを作成します。

 

  Imageコンポーネントを、フォームに貼る。
  MainMenuコンポーネントを、フォームに貼る。

TImage
NameimgMap

TImage
NameimgwkMap

TImage
NameimgData

TMainMenu
NameMainMenu1

5.メニューを作成します。

 MainMenuコンポーネントを、ダブルクリックすると、メニュー作成ウィンドウが開くので、
 次のように設定します。

TMenuItem
Captionファイル(&F)
NameFile1

TMenuItem
Caption終了(&X)
NameExit1

 

6.プログラムソース全体

unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
 jpeg, ExtCtrls, Menus;

type
 TForm1 = class(TForm)
  imgwkMap: TImage;
  imgData: TImage;
  MainMenu1: TMainMenu;
  File1: TMenuItem;
  Exit1: TMenuItem;
  imgMap: TImage;

  Procedure FormCreate(Sender: TObject);
  Procedure FormKeyDown(Sender: TObject; var Key: Word;
   Shift: TShiftState);
  Procedure Exit1Click(Sender: TObject);

 private
  { Private 宣言 }
  PlayX : Integer; // プレイヤX位置
  PlayY : Integer; // プレイヤY位置

  // ***** マップ画像設定処理 ***** //
  Procedure MapSet(
   Cvs : TImage;
   ImgNo: Integer;
   X  : Integer;
   Y  : Integer
  );

  // ***** マップ表示 ***** //
  Procedure MapDSP(
   PX  : Integer;
   PY  : Integer
  );

 public
  { Public 宣言 }
  MapData : Array [0..9] of String;

 end;

var
 Form1: TForm1;

implementation

{$R *.DFM}
Const
 MAP_YUKA  = 0;  // 床
 MAP_KABE  = 1;  // 壁
 MAP_PLAYER = 2;  // プレイヤ
 MAP_PLY_MS = 3;  // プレイヤ(マスク画像)

Const
 HEX_SIZE  = 40; // マスのサイズ(pixel)
 MAP_MAX_X = 10; // マップバッファサイズ 横幅(マス)
 MAP_MAX_Y = 10; // マップバッファサイズ 縦幅(マス)
 DSP_SIZE_X = 5;  // 表示マップサイズ 横幅(マス)
 DSP_SIZE_Y = 5;  // 表示マップサイズ 縦幅(マス)
 DSP_X   = 2;  // プレイヤ表示 X位置(マス)
 DSP_Y   = 2;  // プレイヤ表示 Y位置(マス)

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

 PlayX := 0; // プレイヤ初期X位置
 PlayY := 0; // プレイヤ初期Y位置

 // ***** 画像データ読み込み ***** //
 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;

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);

End;


//************************************************************
//    メニュー【終了】処理
//************************************************************
Procedure TForm1.Exit1Click(Sender: TObject);
Begin
 Close;
End;


//------------------------------------------------------------
//       ユーザー関数
//------------------------------------------------------------

//************************************************************
//    マップ画像設定処理
//************************************************************
Procedure TForm1.MapSet(
 Cvs : TImage;  // 画像を書き込むイメージキャンバス
 ImgNo: Integer;  // 画像番号
 X  : Integer;  // 書き込みX位置
 Y  : Integer  // 書き込みY位置
);
Begin

 BitBlt( Cvs.Canvas.Handle    // 転送先デバイスコンテキスト
     ,HEX_SIZE *X       // 転送先X座標
     ,HEX_SIZE *Y       // 転送先Y座標
     ,HEX_SIZE        // 転送先横の幅
     ,HEX_SIZE        // 転送先縦の幅
     ,imgData.Canvas.Handle  // 転送元デバイスコンテキスト
     ,HEX_SIZE *ImgNo     // 転送元X座標
     ,0            // 転送元Y座標
     ,SRCCOPY         // ラスタオペレーションコード
    );

End;

//************************************************************
//    マップ表示処理
//************************************************************
Procedure TForm1.MapDSP(
 PX  : Integer;  // プレイヤX位置
 PY  : Integer  // プレイヤY位置
);
var
 X,Y : Integer;
 XX,YY,WW,HH : Integer;
Begin

 // ***** 表示マップクリア ***** //
 For X := 0 To DSP_SIZE_X -1 Do
  Begin

   For Y := 0 To DSP_SIZE_Y -1 Do
    Begin
     MapSet( imgMap, MAP_KABE, X, Y);
    End;

  End;

 XX := DSP_X - PX;
 If XX < 0 Then XX := 0;

 WW := (MAP_MAX_X + DSP_X - DSP_SIZE_X) - PX;
 If WW > 0 Then WW := 0;
 WW := DSP_SIZE_X - WW;

 YY := DSP_Y - PY;
 If YY < 0 Then YY := 0;

 HH := (MAP_MAX_Y + DSP_Y - DSP_SIZE_Y) - PY;
 If HH > 0 Then HH := 0;
 HH := DSP_SIZE_Y - HH;

 // ***** マップ画像転送 ***** //
 BitBlt( imgMap.Canvas.Handle
     ,HEX_SIZE *XX
     ,HEX_SIZE *YY
     ,HEX_SIZE *WW
     ,HEX_SIZE *HH
     ,imgwkMap.Canvas.Handle
     ,HEX_SIZE *(PX + XX - DSP_X)
     ,HEX_SIZE *(PY + YY - DSP_Y)
     ,SRCCOPY);

 // ***** プレイヤマスク画像転送 ***** //
 BitBlt( imgMap.Canvas.Handle
     ,HEX_SIZE *DSP_X
     ,HEX_SIZE *DSP_Y
     ,HEX_SIZE
     ,HEX_SIZE
     ,imgData.Canvas.Handle
     ,HEX_SIZE *MAP_PLY_MS
     ,0
     ,SRCERASE);

 // ***** プレイヤ画像転送 ***** //
 BitBlt( imgMap.Canvas.Handle
     ,HEX_SIZE *DSP_X
     ,HEX_SIZE *DSP_Y
     ,HEX_SIZE
     ,HEX_SIZE
     ,imgData.Canvas.Handle
     ,HEX_SIZE *MAP_PLAYER
     ,0
     ,SRCINVERT);

 // ***** 表示画像再描画 ***** //
 imgMap.Repaint;

End;

End.

7.キャラクタ画像を作成

MapData.bmp

 40×40ピクセルの画像を4つ作成。
 左から、床、壁、プレイヤ、プレイヤ(マスク画像)になります。
 ソースファイルと同じフォルダにおいてください。    

8.イベントプロシージャの設定

TForm1
CaptionDelphiでゲームを作成
NameForm1
OnCreateFormCreate
OnKeyDownFormKeyDown

TMenuItem
Caption終了(&X)
NameExit1
OnClickExit1Click

9.動作確認

 

 こんな感じになっていればOKです。

 ソースファイルはコレです。

 次回は、敵が出現した時の戦闘画面を作成します。