低所得の青色申告個人事業主のブログ

開業から経験で得た情報をお知らせしていきたいと思います。

= グローバル ナビゲーション =

【第8回】VBA で単純な倉庫番ゲームにチャレンジ


[ スポンサー リンク ]

Amazonのアソシエイトとして、当メディアは適格販売により収入を得ています

その昔 倉庫番 というゲームがありました。

Excelで完全に再現することは不可能ですが、できるだけ再現してみたいと思います。

ゲームプログラミングを勉強したい方には、あまり参考にならないと思います。

しかし、VBAの学習に多少寄与できるよう無駄なことをしながら挑戦してみます。

途中で挫折するかもしれませんので、ご承知ください。

 

ゲームクリアの実装

前回記事の続きです。

定数の追加です。

Const C_NUM_REST_INIT   As Integer = 3      'ゲーム開始時点での残数

Macro2クリア条件を反映させて、名前も Macro2 から StartGame に変更します。

Sub StartGame()
                
    Dim objRangePrsn As Range   '倉庫作業者のセル
    
    Worksheets("Sokoban").Select
    
    '初期化
    Set objRangePrsn = fnRefresh(Worksheets("Sokoban"))
    
    m_intRest = C_NUM_REST_INIT
    
    Do Until m_intRest = 0
        ' 上矢印
        If GetAsyncKeyState(vbKeyUp) <> 0 Then
            Set objRangePrsn = _
                fnExecByCursorKey(ActiveSheet, objRangePrsn, "上")
        End If
        ' 右矢印
        If GetAsyncKeyState(vbKeyRight) <> 0 Then
            Set objRangePrsn = _
                fnExecByCursorKey(ActiveSheet, objRangePrsn, "右")
        End If
        ' 下矢印
        If GetAsyncKeyState(vbKeyDown) <> 0 Then
            Set objRangePrsn = _
                fnExecByCursorKey(ActiveSheet, objRangePrsn, "下")
        End If
        ' 左矢印
        If GetAsyncKeyState(vbKeyLeft) <> 0 Then
            Set objRangePrsn = _
                fnExecByCursorKey(ActiveSheet, objRangePrsn, "左")
        End If
        ' 「HOME」ボタン リトライ
        If GetAsyncKeyState(vbKeyHome) <> 0 Then
            If MsgBox("最初からやり直します", vbOKCancel) = vbOK Then
                Set objRangePrsn = fnRefresh(ActiveSheet)
            End If
        End If
        ' 「END」ボタン 終了
        If GetAsyncKeyState(vbKeyEnd) <> 0 Then
            If MsgBox("ゲームを終了します", vbOKCancel) = vbOK Then
                '画僧クリア
                Call sbClearShapes(ActiveSheet)
                Exit Sub
            End If
        End If
        DoEvents
        Sleep 100
    Loop
    
    MsgBox "Good job !" & vbCrLf & vbCrLf & _
                                        "ゲームを終了します", vbOKOnly
    
End Sub

クリアするとプログラムを終了します。

ループを抜け出し、プログラムを終了する

 

 

どのようにプログラムを呼び出すか

これで完全に完成したのですが、今回コマンドボタンを使用せずどのようにゲームを開始するかという課題があります。

マクロの開始によって実行してもいいのですが、ファイルを開くと同時に実行するように設定します。

ThisWorkbookモジュールにて、WorkbookOpenするイベントでメインルーチンであるStartGameを呼び出します。

Workbook_Openイベントでゲームを開始する



 

 

 

 

 

振り返って

振り返りの前に、やたらとシートオブジェクトを引数(パラメータ)にしてるけど何の意味があるの?と疑問に思われた方も多いと思いますが、何の意味もありません

シートはひとつだけなので、すべて ActiveSheet で大丈夫です。

最初に書いておくべきでしたが、無視してください。

作り終えて、テトリスを再現する人が多い理由が分かりました。

テトリスをやりたくなかった理由として、タイマーイベントを使いたくなかったのですが、結果的にタイマーイベントこそ使いませんでしたが、APIを使いまくる結果になりました。

また、カクカクした動きになることは予想していたのですが、予想以上にイライラする動きの悪さでした。

画像を使わないテトリスならこんなこともないでしょう。

低品質なコードと宣言していますが、こちらも想像した以上の分かりにくいコードとなってしまいました。

特に構造体とクラスを行ったり来たりするところは自分でも混乱するくらいでした。

改めて、コード作成前にきちんと構成を決めて思いつきで書かないことが重要だと認識しました。

 

 


ご質問は下の 「コメントを書く」 からお願いします。

ExcelVBA全般に関わる質問で、比較的簡単にお答えできるものはできる限り回答したいと思います。

回答を公開でなくメールでやり取りしたいという場合は、その旨記載していただければ非公開で回答することも可能です。

有償での作業依頼は非公開にしますので、条件等をお知らせください。