当ページのリンクには広告が含まれています。

ゲーム開発で挫折した人必見!生成AI ChatGPT&VBAでプチゲーム開発しませんか?(第5話)

当ページのリンクには広告が含まれています。
  • URLをコピーしました!

前回はセル移動周りの処理を解説&修正を行いました。

今回はセル移動周りの後半戦です。

次にやらないといけないのがいよいよ各種セル毎のイベント実行です。

ここがゲームの肝の部分なので細かく解説していきたいと思います。

目次

前回のおさらい

前回はプレイヤーの移動処理前半部分のソースを解説&修正を行いました

プロシージャ名も以下のように変更しています。

Sub MovePlayer()

Sub Worksheet_SelectionChange()

セルの移動処理をしてもらうためにどうしても必要だったので止む無く…。

今回はSub Worksheet_SelectionChange()の後半戦でセルのイベント処理を解説と実際に動かしてとりあえず遊んでみるのパートになります。

3.移動 Worksheet_SelectionChange で各種イベントを実行!?(後半)

後半のソースはイベントの実行処理部分ですね。移動した結果そのセル(配列)にあるイベントが実行される処理が書かれています。

移動処理後半のソースはこちら
   ' 移動先のセルの内容によって処理を分岐
    Select Case grid(newX, newY)
        Case GridCell.Empty
            ' 空のセルなら何もしない
        Case GridCell.Enemy
            ' 敵がいるセルなら攻撃する
            AttackEnemy()
        Case GridCell.Item
            ' アイテムがあるセルなら取得する
            PickupItem()
        Case GridCell.Pitfall
            ' 落とし穴があるセルならダメージを受ける
            TakeDamage(3)
        Case GridCell.Door
            ' 扉があるセルなら鍵を持っているか確認して開ける
            If playerHasKey Then
                ' 扉を開けてクリア
         MsgBox "クリア!"
          Else
              MsgBox "鍵が必要です。"
          End If
End Select
' 移動先に移動する
playerX = newX
playerY = newY
End Sub

上記のソースは配列にセットされているイベントの内容をCase文で読み取り、イベントを実行する仕組みです。

【図】イベントごとの処理

因みに…以下の変数名は変更しました。

Case GridCell.Empty

Case GridCell.Emp

第2話でも書きましたが、Emptyは予約語なので使えません。なので、Empに直しておきましょう。

基本的には図解の通りの処理をするだけなので、難しいことはありません。

最後にPlayer位置を最新の値に変更しています。

' 移動先に移動する
playerX = newX
playerY = newY

さて、問題はここからなのです。肝心のイベントの中身が書かれていない箇所が何か所かあります。

以下のAttackEnemy()とPickItem()は移動した先のソースコードは空っぽなので、現時点では何も起きません。

        Case GridCell.Enemy
            ' 敵がいるセルなら攻撃する
            AttackEnemy()
        Case GridCell.Item
            ' アイテムがあるセルなら取得する
            PickupItem()

因みにAttackEnemy()PickItem()の後ろの()は削除しないとエラーが出るので今回は削除しておきます。

AttackEnemy()→ AttackEnemy
PickItem()→ PickItem

さて、もう二か所修正しておきましょう。それはPitfallです。

Pitfall(落とし穴)に落ちた時に分かるようにする

落とし穴に落ちたらメッセージを出したい!

Pitfallはちゃんと動作するのですが、落とし穴に落ちても見た目でダメージを受けたことが分かりません

なのでソースに以下の記述を追加します。

MsgBox “落とし穴に落ちた。プレイヤーは3のダメージ!”

追記する箇所はCase GridCell.PitfallにあるTakeDamage(3)の下に追記すればOKです。

  Case GridCell.Pitfall
            ' 落とし穴があるセルならダメージを受ける
            TakeDamage(3)
       MsgBox "落とし穴に落ちた。プレイヤーは3のダメージ!"

これで落とし穴に落ちたときにダメージを受けたことがわかります。

あと、もう一つ直さないといけないところがあります。

鍵を取得した際のイベントを作る

実はこのソースコードないんですよ。なので、Case文の中に以下のコードを追記しました。

Case GridCell.Key
            '鍵を取得する
             playerHasKey = True
             MsgBox "鍵を手に入れた"

鍵を手に入れないと永遠にクリアできないので、この記述は必須です。

これで少なくともゲームが最低限出来る状態が整いました。

ChatGpt RPGゲームの第5話時点のソースコード

さて、以下が現時点でのソースコードです。

そう言いながら…何か所か修正してしまった箇所もあるので、そこも少し説明します。

ソースコードはこちら
Option Explicit
' グリッドの幅と高さを定義
Const GRID_WIDTH As Integer = 10
Const GRID_HEIGHT As Integer = 10
' グリッドのセルごとに定義する内容
Enum GridCell
    Emp
    Enemy
    Item
    Pitfall
    Door
    Key
End Enum
' キャラクターの初期位置
Dim playerX As Integer
Dim playerY As Integer
' キャラクターの状態
Dim playerHP As Integer
Dim playerHasKey As Boolean
Dim playerAttackPower As Integer
' グリッドの内容を保持する配列
Dim grid(GRID_WIDTH, GRID_HEIGHT) As GridCell
' 初期化処理
private Sub Init()
    ' グリッドの内容をランダムに設定
    Dim x As Integer, y As Integer
    For x = 1 To GRID_WIDTH
        For y = 1 To GRID_HEIGHT
            Dim randValue As Integer
            randValue = Int(Rnd() * 4) ' 0-3のランダムな整数を生成
            grid(x, y) = randValue
       Cells(x, y).Interior.ColorIndex = 20
        Next y
    Next x

'鍵の配置
    randValue = Int(Rnd() * 9 + 1)  ' 1-10のランダムな整数を生成
    x = randValue
    randValue = Int(Rnd() * 9 + 1)  ' 1-10のランダムな整数を生成
    y = randValue
    grid(x, y) = 5

'扉の配置
    Do
        randValue = Int(Rnd() * 9 + 1) ' 1-10のランダムな整数を生成
        x = randValue
        randValue = Int(Rnd() * 9 + 1) ' 1-10のランダムな整数を生成
        y = randValue
    Loop While grid(x, y) = 5 ' 鍵の位置と重なる場合はやり直す
    grid(x, y) = 4

    ' キャラクターの初期位置を設定
    playerX = 1
    playerY = 1
    Sheet1.Cells(playerY, playerX).Activate
    
    ' キャラクターの初期状態を設定
    playerHP = 10
    playerHasKey = False
    playerAttackPower = 1
End Sub

'  ワークシートのセル上をキャラクターが移動する
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    If Not Intersect(Target, Range("A1:J10")) Is Nothing Then
        ' セルが10x10のマップの範囲内である場合
        Dim moveX As Integer
        Dim moveY As Integer
        moveX = 0
        moveY = 0
        Select Case True
            ' 上キー
            Case Target.Row > playerY
                moveY = 1
            ' 下キー
            Case Target.Row < playerY
                moveY = -1
            ' 左キー
            Case Target.Column < playerX
                moveX = -1
            ' 右キー
            Case Target.Column > playerX
                moveX = 1
        End Select
        playerY = playerY + moveY
        playerX = playerX + moveX
        Sheet1.Cells(playerY, playerX).Activate
     Cells(playerY, playerX).Interior.ColorIndex = 35
    End If
    

' キャラクターの配列上の移動判定処理
Dim newX As Integer
    newX = playerX
    If newX < 1 Or newX > GRID_WIDTH Then
      ' 移動先がグリッド外なら何もしない
      Exit Sub
    End If
Dim newY As Integer
    newY = playerY
    If newY < 1 Or newY > GRID_HEIGHT Then
      ' 移動先がグリッド外なら何もしない
      Exit Sub
    End If
    
    ' 移動先のセルの内容によって処理を分岐
    Select Case grid(newX, newY)
        Case GridCell.Emp
            ' 空のセルなら何もしない
        Case GridCell.Enemy
            ' 敵がいるセルなら攻撃する
            AttackEnemy
        Case GridCell.Item
            ' アイテムがあるセルなら取得する
            PickupItem
        Case GridCell.Pitfall
            ' 落とし穴があるセルならダメージを受ける
            TakeDamage (3)
             MsgBox "落とし穴に落ちた。プレイヤーは3のダメージ!"
        Case GridCell.Door
            ' 扉があるセルなら鍵を持っているか確認して開ける
            If playerHasKey Then
                ' 扉を開けてクリア
                  MsgBox "クリア!"
            Else
                MsgBox "鍵が必要です。"
    Case GridCell.Key
            '鍵があるなら取得する
            playerHasKey = True
            MsgBox "鍵を手に入れた"
        End If
End Select
' 移動先に移動する
playerX = newX
playerY = newY
End Sub
' 敵と戦う
Sub AttackEnemy()
' 敵にダメージを与える
' この部分は実装してください
End Sub
' アイテムを取得する
Sub PickupItem()
' アイテムの種類に応じて効果を適用する
' この部分は実装してください
End Sub
' ダメージを受ける
Sub TakeDamage(damage As Integer)
' ダメージを受けてHPを減らす
playerHP = playerHP - damage
If playerHP <= 0 Then
' HPが0以下になったらゲームオーバー
MsgBox "ゲームオーバー"
End If
End Sub

実は以下の図で言うところの「7」のこのままだと使えない処理ですが、全く役に立たないソースだったため削除しています。

一番したのプロシージャ…ですらな無い部分

そこはごっそり消しました。今時点だとあってもエラーの原因になるだけで何も役に立ちません。

Sub Init() を Private Sub Init()に修正

タイトルの通りなんですが、第三話で解説しているSub Init()(初期化処理のプロシージャ)のヘッダ部を変更しています。

Sub Init() → Private Sub Init()

このように直しておかないと、プロシージャからプロシージャへ移動する際に変数を引き継いでくれません。

そのため、ここは修正しています。

プレイヤーの「セル」の初期位置を指定

ゲームスタートで赤枠の位置に移動

後、初期化処理の「キャラクターの初期位置を設定」部分に以下を追記しました。

Sheet1.Cells(playerY, playerX).Activate

    ' キャラクターの初期位置を設定
    playerX = 1
    playerY = 1
    Sheet1.Cells(playerY, playerX).Activate

こんな感じですね。こうしないとゲーム開始時にフォーカスが初期位置(セル:A1)に移動してくれないので、追加しました。

セルに色を付ける処理の追加

移動時にセルに色をつけたい

後、移動したセルは別の色に変わらないとかなり微妙です。

そこでセルの移動処理の最後に以下のソースを足しました。

Cells(playerY, playerX).Interior.ColorIndex = 35

プレイヤーがいるセルを指定の色(35は黄緑)にするコードを以下に追記しました。

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Not Intersect(Target, Range(“A1:J10”)) Is Nothing Then
~ 省略  ~
Sheet1.Cells(playerY, playerX).Activate
Cells(playerY, playerX).Interior.ColorIndex = 35
End If

セルの移動処理が終わった直後に配置しています。

後、もう一行コードを追加します。

ゲームのリスタート時に元の色に戻したいですよね?

そのため、Init(初期化)の際にセルに数値をセットしているForループ分にもセルの色指定のコードを混ぜました。

Cells(playerY, playerX).Interior.ColorIndex = 20

Private Sub Init()
‘ グリッドの内容をランダムに設定
Dim x As Integer, y As Integer
 For x = 1 To GRID_WIDTH
  For y = 1 To GRID_HEIGHT
   Dim randValue As Integer
   randValue = Int(Rnd() * 4) ‘ 0-3のランダムな整数を生成
   grid(x, y) = randValue
   Cells(x, y).Interior.ColorIndex = 20
Next y

これでゲームリスタート時に元のセルの色に戻してくれます。

これで敵やアイテムが出現しないもののクリアはできるゲームが完成しました。

RPGゲームをとりあえず動かしてみる

お待たせいたしました。第5話目にして初めてゲームを動かすことができます。

ということで、最後に少し設定をしてゲームで遊んでみましょう。

ゲームスタートボタンにマクロを登録する

STEP
ゲームスタートボタンにマクロを登録

第二話で作成しておいた「ゲームスタート」ボタンにマウスを移動させます。右クリックしてメニューが開いたら、「マクロの登録」を選択します。

STEP
ボタンにマクロを登録して完了です。

①のマクロの部分に以下のように記入してください。

Sheet1.Init

②「OK」ボタンを押下でマクロ登録完了です。

これによって、ゲームスタートをすると「Init(初期化処理)」を呼び出します。

  • 10×10の配列にイベントをセットする
  • 10×10のセルに青色を付ける
  • 鍵と扉を配列に1つずつセットする
  • ゲームプレイヤーを初期位置(1,1)に移動
  • プレイヤーのHP10をセットする
  • プレイヤーの鍵を非所持にする
  • プレイヤーの攻撃力を1でセットする

ということで、初期化してゲームが開始できる状態にしてくれます。

因みに自分で設定するのすら面倒…という方は第5話までの内容を反映したエクセルを以下よりダウンロードできますのでよろしければお使いください。尚、怪しいことは一切していませんが、ダウンロードは自己責任でお願いいたします。

\ クリックでダウンロード /

さあ、VBA RPGゲームを遊んでみよう!

ということで、動画をとってみましたのでプレイシーンを見てみましょう

ブハハハッこれは酷い

折角、セルにHPや鍵などのステータスがあっても変化しませんし、HPが0になってゲームオーバーでもゲーム続けられちゃうし。

まだまだ、楽しめるほどのゲームではありませんが、なんとなくInocchiQuestの片りんは感じてもらえたのではないでしょうか?

ソースがシンプルなので、手を加えられそうなところは是非弄ってみてください。

ということで今回はここまで。

次回は「攻撃する」、「アイテムを使う」を追加したいと思います。

残念パパことイノッチでした!

では、また

この記事が気に入ったら
フォローしてね!

シェアお願いします!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメント一覧 (4件)

  • F*ckin’ tremendous things here. I’m very glad to look your post. Thank you a lot and i’m taking a look forward to touch you. Will you kindly drop me a e-mail?

  • Throughout this great pattern of things you secure an A with regard to effort. Exactly where you actually confused us was first in your specifics. As people say, the devil is in the details… And it couldn’t be much more true right here. Having said that, let me inform you just what did work. The article (parts of it) is actually incredibly engaging which is possibly the reason why I am taking an effort in order to comment. I do not really make it a regular habit of doing that. Secondly, whilst I can certainly notice the leaps in reason you make, I am not necessarily confident of just how you appear to unite your details which in turn help to make the final result. For right now I will subscribe to your position but trust in the near future you link your dots much better.

  • Wow that was strange. I just wrote an extremely long comment but after I clicked submit my comment didn’t show up. Grrrr… well I’m not writing all that over again. Anyhow, just wanted to say wonderful blog!

コメントする

目次