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

§ ゲーム製作基本 §

 レイヤーと歩行

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

パネルのBackgroundImageプロパティに背景画を設定し、其の中に、BackColorプロパティをTransparentに設定したピクチャボックスを配置して、パネルのBackgroundImageとピクチャボックスのBackgroundImage、Imageで、3層のレイヤーを実現して居る。

ゲーム作成では、イベント駆動(Event Driven)型のプログラミングでは、充分なスピードが得られないので、ポーリング(Polling)型のプログラミングを行うのが一般的で有る。即ち、初期設定等以外の総てのコードを無限ループの中に記述する方式で有る(勿論、ゲームオーバーやゲームクリア時には無限ループを抜ける事に成る)。

其の為、キー入力をKeyPressやKeyDown/KeyUpのイベントで受け取れない為、コードが実行された瞬間にキー入力の判定を行うAPI関数GetAsyncKeyStateを使用する(イベントで処理出来ない訳では無いが、リアルタイム性に欠ける為、アクションゲーム等のスピードが要求されるゲームでは用いない)。

猶、ポーリング方式では、コンピュータの性能(特に処理速度)に依り、実行スピードが大きく左右される為、ループを一定のサイクルに調整する必要が有る(ニンテンドー3DSのSmile BASICのVSYNCに相当)。

此のプログラムでは、中層に描画されたキャラクタを、左右の矢印キーで移動させて居る。猶、無限ループを抜けるには、エスケープキーを押す。

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

Public Class layer
  <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 layer_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 & "foreground.png")
    Bp = New Bitmap(P & "person.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.Transparent)
    Gf.Clear(Color.Transparent)

    Gf.DrawImage(Bm, 0, picDisp.Height - Bm.Height)
    Gb.DrawImage(Bp, 300, picDisp.Height - Bp.Height)
  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    ' キャラクタX座標
    Dim Cy As Single    ' キャラクタY座標
    Dim Tm As DateTime  ' タイマカウント(VSYNC相当)

    Cx = 300 : Cy = picDisp.Height - Bp.Height

    Do
      Tm = DateTime.Now

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

      ' Left Move
      If GetAsyncKeyState(Keys.Left) < 0 Then
        Cx -= 5 : If Cx < 0 Then Cx = 0
      End If

      ' Right Move
      If GetAsyncKeyState(Keys.Right) < 0 Then
        Cx += 5 : If Cx > picDisp.Width - Bp.Width Then Cx = picDisp.Width - Bp.Width
      End If

      ' Disp Caractor
      Gb.Clear(Color.Transparent)
      Gb.DrawImage(Bp, Cx, Cy)
      picDisp.Refresh()

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

ダウンロード