前回のVBAの解説をしていきたいと思っています。
まず最初!
Declare Sub Sleep Lib "kernel32" (ByVal ms As Long)
プログラムを一時的に止める処理です。
ゲームでいうところのフレームとして扱います。
'グローバル変数' Dim f As Double
Startメソッドと Changeメソッド両方で使っているので
両方で使えるように変数指定を外に出します。
Sub Start() Dim t As Long Dim pos As Double Dim ra As Integer f = 0.2 v = 0# pos = 6# t = 6 Randomize '初期設定' Cells.ClearContents ActiveWindow.ScrollRow = 6
変数指定と初期設定です。
Cells.ClearContents
シート内の値を全削除します。
ActiveWindow.ScrollRow = 6
スクロールバーを6行目に持っていきます
'障害物配置' For obst = 50 To 1000 Step 50 ra = Int(Rnd() * 80) For x = 1 To 100 If (Not (ra < x And x < ra + 20)) Then Cells(obst + 50, x) = "■" End If Next x Next obst
50行ごとに障害物を設置します。
ゲームの幅が100列あるため、
ランダムに数字を1~80を選び
20マス分通り道を作ります。
(数字が36のとき 36列~56列が通り道)
'3秒待機' DoEvents Sleep 3000
スタートボタン押してすぐゲームがスタートするとあわただしいので
3秒猶予を持たせます
'オイラー法' v = v + f pos = pos + v
UNITY でいうところの Rigidbody.AddForce の処理をおこなっています。
正直、ここ自分の得意分野です。
今回、物理の運動方程式 ma = F を基本として使っているんですけど、
このゲームでは運動方程式を解いて1回ループするたびにどれだけ進むかを求めています。
大学の物理シミュレーションで4次のルンゲクッタ法というのを使ったのですが
それの精度が悪い代わりに軽い計算方法と思ってください。
本当はこってり解説したいんですけど、こちらをご覧ください。
'ゲームオーバー処理' If (pos < 1 Or pos > 101) Then MsgBox "GAME OVER" End End If
画面端になったらゲームオーバーと表示します。
If (Cells(t, Int(pos)) = "■") Then MsgBox "GAME OVER" End End If
障害物に当たったらゲームオーバーと表示します。
'現在の場所を記入' Cells(t, Int(pos)) = "○"
オイラー法で求めた自分の位置を入力します。
'クリア処理' If (1020 < t) Then MsgBox "CLEAR" End End If
1020行進めたらゲームクリアと表示します。
'更新する' t = t + 1
時間 t を更新します。
'画面スクロールを行う' If (t > 30) Then ActiveWindow.SmallScroll Down:=1 End If
画面をスクロールさせます。
最初からスクロールさせると、自分が画面上部で動くことになってしまうので、
30ループさせてからスクロールを行うようにしています。
'更新待機処理' DoEvents Sleep 20
1フレームは 1/60秒 = 0.0166 秒 = 16ms
なので約1フレームに設定しています。
20にしたのは特に理由はありません。16で大丈夫です。(^^;)
処理が追いついてない場合は遅くするといいと思います。
Sub Change() '加速度の変更' f = f * -1# End Sub
Clickボタンを押したときの処理です。
UNITYでいうところの Rigidbody.AddForce の符号を変えます。
力を与えている方向を逆転させます
以上です。
画面スクロールがちょっと重いですね、
もしかしたら、スクロールさせずに、画面を行を追加、削除したり、セルの文字を入力、削除
して動かした方が軽いのかもしれないですね
また、検証してみたいと思います。
今 UNITYで物理演算はチェック入れるだけで出来ますから
こうやって初心に帰ることすごく重要だと思うんですね。
というか、自分が楽しいだけですが(笑
コメント