XNA 虛擬按鍵(Virtual D-Pad)

  • 4693
  • 0

很多動作類型遊戲的操作方式適合用鍵盤操作,而大部分的手機都是沒有配置實體按鍵的,這時我們可以在螢幕上創造虛擬鍵盤
來模擬實際按鍵。

很多動作類型遊戲的操作方式適合用鍵盤操作,而大部分的手機都是沒有配置實體按鍵的,這時我們可以在螢幕上創造虛擬鍵盤來模擬實際按鍵。

 

先看看完成後的樣子

 

接下來我們開始來實作這個範例

首先在專案新增以下三個檔案,包含VirtualDpad.vb類別檔以及按鍵圖片以及我們要移動的瓢蟲圖片 (按這下載)

image

 

新增完畢如下圖所示

image

 

再來把Game1的命名空間改為TouchThumbsticks,也就是把Game1裡的程式碼放入下面程式碼之間。

Namespace TouchThumbsticks
    Public Class Game1
         .
         .
         .
    End Class
End Namespace

 

在Game1裡宣告變數

Public Class Game1
        Inherits Microsoft.Xna.Framework.Game
 
        Private WithEvents graphics As GraphicsDeviceManager
        Private WithEvents spriteBatch As SpriteBatch
 
        Dim thumbstick As Texture2D '按鍵圖片
        Dim LadyBird As Texture2D   '瓢蟲圖片
        Dim position As Vector2 = New Vector2(400, 200) '瓢蟲位置
        Dim Rotation As Double                          '瓢蟲轉動角度
End Class

 

LoadContent()載入圖片

Protected Overrides Sub LoadContent()
        ' 建立可用來繪製紋理的新 SpriteBatch。
        spriteBatch = New SpriteBatch(GraphicsDevice)
 
        ' TODO: 在此使用 Me.Content 載入您的遊戲內容
        thumbstick = Content.Load(Of Texture2D)("Dpad")
        LadyBird = Content.Load(Of Texture2D)("LadyBird")
End Sub

 

Update()撰寫控制程式碼,VirtualPad是一個NotInheritable類別,不需要產生instance就可以直接使用,先用VirtualPad.Update()更新按鍵狀態,再來依據按鍵狀態來轉動跟移動瓢蟲。

Protected Overrides Sub Update(ByVal gameTime As GameTime)
            ' 允許遊戲結束
            If GamePad.GetState(PlayerIndex.One).Buttons.Back = ButtonState.Pressed Then
                Me.Exit()
            End If
 
            ' TODO: 在此新增您的更新邏輯
            VirtualDpad.Update()
 
            If VirtualDpad.RightMoveVector.Length > 0.3F Then
                Rotation = VirtualDpad.RightRotation
            ElseIf VirtualDpad.LeftMoveVector.Length > 0.2F Then
                Rotation = VirtualDpad.LeftRotation
            End If
 
            position += VirtualDpad.LeftMoveVector * 3
 
            MyBase.Update(gameTime)
End Sub

 

Draw()繪製按鍵左鍵、右鍵以及瓢蟲。

 Protected Overrides Sub Draw(ByVal gameTime As GameTime)
            GraphicsDevice.Clear(Color.CornflowerBlue)
 
            ' TODO: 在此新增您的繪圖程式碼
            spriteBatch.Begin()
            If VirtualDpad.LeftTouch Then
                spriteBatch.Draw(thumbstick, VirtualDpad.LeftThumbstickCenter - New Vector2(thumbstick.Width / 2.0F, thumbstick.Height / 2.0F), Color.Green)
            End If
 
            If VirtualDpad.RightTouch Then
                spriteBatch.Draw(thumbstick, VirtualDpad.RightThumbstickCenter - New Vector2(thumbstick.Width / 2.0F, thumbstick.Height / 2.0F), Color.Blue)
            End If
 
            spriteBatch.Draw(LadyBird, New Rectangle(CInt(position.X), CInt(position.Y), CInt(LadyBird.Width / 2), CInt(LadyBird.Height / 2)), Nothing, Color.White, CSng(Rotation), New Vector2(CSng(LadyBird.Width / 2), CSng(LadyBird.Height / 2)), SpriteEffects.None, 0)
 
            spriteBatch.End()
 
            MyBase.Draw(gameTime)
 End Sub

 

程式執行結果如下 (範例下載)

有了虛擬鍵盤,遊戲的互動性便增加了,大家腦子有沒有出現很多Idea想要趕快實作呢 ^_^。

screenshot_11-1-2011_22.21.41.241

 

VirtualDpad.vb類別主要是用到多點觸控,觸控包含三個狀態 Press、Move、Release,當Press按下後會產生一個Id,多點觸控就是認這個Id的。

這個類別可以傳回左右鍵是否按下、左鍵移動的單位向量、右鍵轉動的角度,以下附上完成程式碼給大家參考,寫的不好請包含。

Imports Microsoft.Xna.Framework
Imports Microsoft.Xna.Framework.Input
Imports Microsoft.Xna.Framework.Input.Touch
 
Namespace TouchThumbsticks
    Public NotInheritable Class VirtualDpad
        Const maxThumbstickDistance As Single = 30.0F
 
        Shared LeftTouchId As Integer = -1
        Public Shared LeftTouch As Boolean = False
        Public Shared LeftMoveVector As Vector2       '移動的單位向量
        Public Shared LeftThumbstickCenter As Vector2 '搖桿中心坐標
        Public Shared LeftRotation As Double    '轉動角度(弧度)
        'Public Shared LeftRotation2 As Integer    '轉動角度(度)
 
        Shared RightTouchId As Integer = -1
        Public Shared RightTouch As Boolean = False
        Public Shared RightMoveVector As Vector2
        Public Shared RightThumbstickCenter As Vector2
        Public Shared RightRotation As Double
        'Public Shared RightRotation2 As Integer
 
 
        Public Shared Sub Update()
            Dim touches As TouchCollection = TouchPanel.GetState()
 
            For Each touchLocation As TouchLocation In touches
                If touchLocation.State = TouchLocationState.Pressed Then
                    If LeftTouchId = -1 Then
                        If touchLocation.Position.X < TouchPanel.DisplayWidth / 2 Then
                            LeftTouch = True
                            LeftTouchId = touchLocation.Id
                            LeftThumbstickCenter = touchLocation.Position
                        End If
                    End If
 
                    If RightTouchId = -1 Then
                        If touchLocation.Position.X >= TouchPanel.DisplayWidth / 2 Then
                            RightTouch = True
                            RightTouchId = touchLocation.Id
                            RightThumbstickCenter = touchLocation.Position
                        End If
                    End If
                End If
 
                If touchLocation.State = TouchLocationState.Moved Then
                    If touchLocation.Id = LeftTouchId Then
                        Dim r As Vector2
                        r = (touchLocation.Position - LeftThumbstickCenter) / maxThumbstickDistance
                        If r.LengthSquared > 1 Then
                            LeftMoveVector = Vector2.Normalize(r)
 
                            Dim angle As Double = Math.Atan2(r.Y, r.X)
                            LeftRotation = angle
                            'angle = angle * 180 / Math.PI
                            'LeftRotation2 = CInt(angle)
                        End If
                    End If
 
                    If touchLocation.Id = RightTouchId Then
                        Dim r As Vector2
                        r = (touchLocation.Position - RightThumbstickCenter) / maxThumbstickDistance
                        If r.LengthSquared > 1 Then
                            RightMoveVector = Vector2.Normalize(r)
 
                            Dim angle As Double = Math.Atan2(r.Y, r.X)
                            RightRotation = angle
                            'angle = angle * 180 / Math.PI
                            'RightRotation2 = CInt(angle)
                        End If
                    End If
                End If
 
                If touchLocation.State = TouchLocationState.Released Then
                    If touchLocation.Id = LeftTouchId Then
                        LeftTouchId = -1
                        LeftTouch = False
                        LeftThumbstickCenter = New Vector2(0, 0)
                        LeftMoveVector = New Vector2(0, 0)
                    End If
 
                    If touchLocation.Id = RightTouchId Then
                        RightTouchId = -1
                        RightTouch = False
                        RightThumbstickCenter = New Vector2(0, 0)
                        RightMoveVector = New Vector2(0, 0)
                    End If
                End If
            Next
        End Sub
    End Class
End Namespace