烏賊先生のプログラミング道場
ゲーム プログラミング 道場

§ ゲーム製作基本 §

 ダッシュとジャンプ

烏賊先生のプログラミング道場

ピクチャボックスのBackgroundImageに背景を描画し、Imageにキャラクタを描画して、2層のレイヤーを使用して居る。斯うする事に依り、キャラクタの移動に伴う再描画時に、キャラクタを描画して居るグラフィック面をクリアしても、背景の再描画を行わなくても良い。

ダッシュとジャンプを行うには、左右と上下の夫々に移動速度を格納する変数が必要と成る(下記のプログラムでは変数SpとAc)。更に、ジャンプ処理では、ジャンプ中か何うかを示すフラグが必要と成る(下記のプログラムでは変数Jp)。

ダッシュは、ダッシュキー(下記のプログラムでは左シフトキー)が押されて居れば、ループ毎に左右の移動速度(下記のプログラムでは変数Sp)を徐々に増加(インクリメント)させ(但し、上限を設けないと、際限も無く速く成る)、押されて居なければ、左右の移動速度を初期値に戻す。

ジャンプは、ジャンプキー(下記のプログラムではスペースキー)が押されゝば、ジャンプフラグ(下記のプログラムでは変数Jp)を立てゝ、上下の移動速度(下記のプログラムでは変数Ac)を設定する。此の時、ジャンプフラグが立って居ない事(即ち、ジャンプ中でない時)を条件に加えなければ、ジャンプ中に更にジャンプする事に成る。

ジャンプ中は、上下の移動速度(下記のプログラムでは変数Ac)に重力加速度(本来は9.80665m/s2で有るが、其れらしく観える値を使用する)を加え(下記のプログラムでは0.7に仕た)、キャラクタのY座標(下記のプログラムでは変数Cy)に加える。此れに依り、上昇は徐々に減速し、下降は徐々に加速する。

猶、キャラクタをアニメーションさせる為に、キャラクタが左右孰れを向いて居るかを示すフラグ(下記のプログラムでは変数Dr、フラグだがキャラクタ画像の使用部分の位置を算出するのに利用するのでInteger型に仕て居る)とキャラクタ画像の何番目の画像を使用するかを示す序数(下記のプログラムでは変数St)が必要に成る。

亦、キャラクタの停止中にアニメーションさせない為には、左右に移動中か何うかを示すフラグが必要と成る(下記のプログラムでは変数FlとFr)。此のフラグが立って居る時丈、ループカウンタを移動速度に合わせて進めると、停止中はアニメーションしなく成る。

此のプログラムでは、キャラクタを、左右の矢印キーで左右に移動させて、スペースキーでジャンプさせて居る。亦、左シフトキーで移動速度を速めて居る(所謂Bダッシュ)。猶、無限ループを抜けるには、エスケープキーを押す。

Visual Basic 2005/2008/2010
Imports System.Runtime.InteropServices

Public Class dash
  <DllImport("user32")> Shared Function GetAsyncKeyState( _
    ByVal vKey As Keys) As Short
  End Function

  Private Bm, Bp As Bitmap
  Private Gb, Gf As Graphics

  Private Sub dash_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
    Dim P As String = Application.StartupPath
    If Not P.EndsWith("\") Then P &= "\"

    Bm = New Bitmap(P & "map.gif")
    Bp = New Bitmap(P & "char.png")

    With picDisp
      .BackgroundImage = New Bitmap(.Width, .Height)
      .Image = New Bitmap(.Width, .Height)
      Gb = Graphics.FromImage(.BackgroundImage)
      Gf = Graphics.FromImage(.Image)
    End With
    Gb.Clear(Color.LightCyan)
    Gf.Clear(Color.Transparent)

    For I As Integer = 0 To 639 Step 32
      Gb.DrawImage(Bm, New Rectangle(I, 336, 32, 32), New Rectangle(0, 160, 32, 32), _
        System.Drawing.GraphicsUnit.Pixel)
      Gb.DrawImage(Bm, New Rectangle(I, 368, 32, 32), New Rectangle(0, 16, 32, 32), _
        System.Drawing.GraphicsUnit.Pixel)
    Next
  End Sub

  Private Sub btnStart_Click(sender As System.Object, e As System.EventArgs) Handles btnStart.Click
    btnStart.Enabled = False
    Call Game()
    btnStart.Enabled = True
  End Sub

  Private Sub Game()
    Dim Cx As Single = 304.0F ' キャラクタX座標
    Dim Cy As Single = 298.0F ' キャラクタY座標
    Dim Sp As Single = 2.0F   ' 左右移動速度
    Dim Ac As Single = 0.0F   ' 上下移動速度
    Dim Dr As Integer = 0     ' 方向(0:左向き、1:右向き)
    Dim St As Integer = 0     ' 表示キャラクタ(0〜5)
    Dim Fl As Boolean = False ' 左移動中
    Dim Fr As Boolean = False ' 右移動中
    Dim Jp As Boolean = False ' ジャンプ(スイム)
    Dim Cnt As Integer = 0    ' ループカウンタ
    Dim Tm As DateTime        ' タイマカウント(VSYNC相当)

    Do
      Tm = DateTime.Now

      ' Quit
      If GetAsyncKeyState(Keys.Escape) < 0 Then
        Exit Do
      End If

      ' Dash
      If GetAsyncKeyState(Keys.LShiftKey) < 0 Then
        Sp += 0.5F : If Sp > 5 Then Sp = 10.0F
      Else
        Sp = 2.0F
      End If

      ' Left Move
      If GetAsyncKeyState(Keys.Left) < 0 Then
        Fl = True : Dr = 1 : Cx -= Sp : If Cx < 0.0F Then Cx = 0.0F
      Else
        Fl = False
      End If

      ' Right Move
      If GetAsyncKeyState(Keys.Right) < 0 Then
        Fr = True : Dr = 2 : Cx += Sp : If Cx > 608 Then Cx = 608
      Else
        Fr = False
      End If

      ' Jump
      If Not Jp AndAlso GetAsyncKeyState(Keys.Space) < 0 Then
        Jp = True : Ac = -10
      End If

      ' While Jump
      If Jp Then
        Ac += 0.7
        Cy += Ac
        If Cy > 298.0F Then Cy = 298.0F : Jp = False
      End If

      ' Disp Caractor
      Gf.Clear(Color.Transparent)
      Gf.DrawImage(Bp, New Rectangle(Cx, Cy, 32, 48), New Rectangle(St * 32, Dr * 48, 32, 48), _
        System.Drawing.GraphicsUnit.Pixel)
      picDisp.Refresh()

      ' Loop Counter
      If Fl OrElse Fr Then Cnt += (Sp + 1)
      If Cnt > 10 Then St += 1 : Cnt = 0 : If St > 5 Then St = 0

      ' Loop Cycle Adjust
      Do
        Application.DoEvents()
      Loop While Tm.AddMilliseconds(50) > DateTime.Now
    Loop
  End Sub
End Class

ダウンロード