XNA 2D碰撞偵測

  • 6611
  • 0

碰撞偵測在遊戲中常被使用到,例如判斷子彈是否射中目標、人物是否撞到東西,碰撞偵測有好幾種方法:

碰撞偵測在遊戲中常被使用到,例如判斷子彈是否射中目標、人物是否撞到東西,碰撞偵測有好幾種方法:

list_b 邊界檢測法

list_b 中心檢測法

list_b 像素檢測法

 

邊界檢測法 - 當兩個邊界有重疊時表示發生碰撞,此法最簡單但不是很精準。

image

 

中心檢測法 - 當兩個中心點的距離小於某值時表示發生碰撞,此法適合圖像是圓形。

image

 

像素檢測法 - 圖像重疊部分像素的alpha值不等於0的時候表示碰撞,此法最精準也最耗硬體資源。

image

 

今天程式要實作的是最簡單的邊界檢測法,來偵測兩球的碰撞,並在碰撞後彈開。

image

 

首先還是一樣將我們可愛的小球加到專案裡   ball

 

在Game1宣告變數,包括兩個小球,小球的矩形邊界,小球移動的速度。

Public Class Game1
    Inherits Microsoft.Xna.Framework.Game
 
    Private WithEvents graphics As GraphicsDeviceManager
    Private WithEvents spriteBatch As SpriteBatch
 
    Dim aBall As Texture2D       'A球
    Dim bBall As Texture2D       'B球
    Dim aBallRect As Rectangle   'A球圖片矩形
    Dim bBallRect As Rectangle   'B球圖片矩形
    Dim aVelocity As Vector2     'A球移動速度
    Dim bVelocity As Vector2     'B球移動速度
End class

 

LoadContent()載入小球資源,初始化變數,New Rectangle四個參數分別是矩形的X坐標,Y坐標,寬,長。

Protected Overrides Sub LoadContent()
        ' Create a new SpriteBatch, which can be used to draw textures.
        spriteBatch = New SpriteBatch(GraphicsDevice)
 
        ' TODO: use Me.Content to load your game content here
        aBall = Content.Load(Of Texture2D)("ball")
        bBall = Content.Load(Of Texture2D)("ball")
 
        aBallRect = New Rectangle(0, 240, aBall.Width, aBall.Height)
        bBallRect = New Rectangle(770, 240, bBall.Width, bBall.Height)
 
        aVelocity = New Vector2(5, 0)
        bVelocity = New Vector2(-5, 0)
 End Sub

image

 

Update()裡有直線運動的程式碼及碰撞判斷,當偵測到碰撞產生反彈,將速度*(-1)即改變方向,

這裡的碰撞偵測使用Retengle類別的Intersects方法,傳入一個矩形,當兩矩形有重疊傳回True

Protected Overrides Sub Update(ByVal gameTime As GameTime)
        ' Allows the game to exit
        If GamePad.GetState(PlayerIndex.One).Buttons.Back = ButtonState.Pressed Then
            Me.Exit()
        End If
 
        ' TODO: Add your update logic here
        aBallRect.X += CInt(aVelocity.X)             '直線運動
        bBallRect.X += CInt(bVelocity.X)
 
        If aBallRect.Intersects(bBallRect) Then     '判斷矩形重疊
            aVelocity = -aVelocity
            bVelocity = –bVelocity                  '反彈
        End If
 
        MyBase.Update(gameTime)
End Sub

 

Draw()繪製小球

Protected Overrides Sub Draw(ByVal gameTime As GameTime)
        GraphicsDevice.Clear(Color.CornflowerBlue)
 
        ' TODO: Add your drawing code here
        spriteBatch.Begin()
        spriteBatch.Draw(aBall, aBallRect, Color.White)
        spriteBatch.Draw(bBall, bBallRect, Color.White)
        spriteBatch.End()
        MyBase.Draw(gameTime)
End Sub

 

程式執行結果如下,接下來是觸控及手勢操作喔! (範例下載)

screenshot_10-28-2011_0.12.31.324