XNA 多重捲軸 (Parallax scrolling)

  • 4382
  • 0

多重捲軸就是利用幾張不同層的圖片,背景圖捲動的較慢,前景圖捲動的較快,進而達到景深類似3D的視覺效果。

多重捲軸就是利用幾張不同層的圖片,背景圖捲動的較慢,前景圖捲動的較快,進而達到景深類似3D的視覺效果。

 

我們準備三張背景圖片開始實作多重捲軸效果。

image

 

在Game1宣告變數包含圖片、位置、捲動速度

Public Class Game1
    Inherits Microsoft.Xna.Framework.Game
 
    Private WithEvents graphics As GraphicsDeviceManager
    Private WithEvents spriteBatch As SpriteBatch
    '三張背景圖片
    Dim ground As Texture2D
    Dim mountain As Texture2D
    Dim cloud As Texture2D
    '三張背景圖位置
    Dim groundPosition As Vector2 = New Vector2(0, 0)
    Dim mountainPosition As Vector2 = New Vector2(0, 0)
    Dim cloudPosition As Vector2 = New Vector2(0, 0)
    '三張背景圖捲動速度
    Dim groundVelocity As Vector2 = New Vector2(-8, 0)
    Dim mountainVelocity As Vector2 = New Vector2(-2, 0)
    Dim cloudVelocity As Vector2 = New Vector2(-1, 0)
 
    Dim screenSizeX As Vector2 = New Vector2(800, 0)
End Class

 

LoadContent()載入圖片資源

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

 

在Update()撰寫捲動程式碼,直線運動可參考此範例

Protected Overrides Sub Update(ByVal gameTime As GameTime)
        ' 允許遊戲結束
        If GamePad.GetState(PlayerIndex.One).Buttons.Back = ButtonState.Pressed Then
            Me.Exit()
        End If
 
        ' TODO: 在此新增您的更新邏輯
        '直線運動 S=Vt
        groundPosition += groundVelocity
        mountainPosition += mountainVelocity
        cloudPosition += cloudVelocity
 
        '捲動超過手機螢幕
        If groundPosition.X < -800 Then
            groundPosition.X = 0
        End If
 
        If mountainPosition.X < -800 Then
            mountainPosition.X = 0
        End If
 
        If cloudPosition.X < -800 Then
            cloudPosition.X = 0
        End If
 
        MyBase.Update(gameTime)
End Sub

 

Draw()繪製出三張背景圖,每張背景圖要繪製兩次位置關係如下圖,這邊要注意因為有層深的關係要設定SpriteSortMode.BackToFront,spriteBatch.Draw()最後一個參數就是層深排列順序(範圍0~1,數字越大越下層)。

image

Protected Overrides Sub Draw(ByVal gameTime As GameTime)
        GraphicsDevice.Clear(Color.CornflowerBlue)
 
        ' TODO: 在此新增您的繪圖程式碼
        spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend)
 
        spriteBatch.Draw(ground, New Rectangle(CInt(groundPosition.X), CInt(groundPosition.Y), ground.Width, ground.Height), Nothing, Color.White, 0, Nothing, SpriteEffects.None, 0.1)
        spriteBatch.Draw(ground, New Rectangle(CInt((screenSizeX + groundPosition).X), CInt((screenSizeX + groundPosition).Y), ground.Width, ground.Height), Nothing, Color.White, 0, Nothing, SpriteEffects.None, 0.1)
 
        spriteBatch.Draw(mountain, New Rectangle(CInt(mountainPosition.X), CInt(mountainPosition.Y), mountain.Width, mountain.Height), Nothing, Color.White, 0, Nothing, SpriteEffects.None, 0.2)
        spriteBatch.Draw(mountain, New Rectangle(CInt((screenSizeX + mountainPosition).X), CInt((screenSizeX + mountainPosition).Y), mountain.Width, mountain.Height), Nothing, Color.White, 0, Nothing, SpriteEffects.None, 0.2)
 
        spriteBatch.Draw(cloud, New Rectangle(CInt(cloudPosition.X), CInt(cloudPosition.Y), cloud.Width, cloud.Height), Nothing, Color.White, 0, Nothing, SpriteEffects.None, 0.3)
        spriteBatch.Draw(cloud, New Rectangle(CInt((screenSizeX + cloudPosition).X), CInt((screenSizeX + cloudPosition).Y), cloud.Width, cloud.Height), Nothing, Color.White, 0, Nothing, SpriteEffects.None, 0.3)
 
        spriteBatch.End()
 
        MyBase.Draw(gameTime)
End Sub

 

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

以前任天堂的紅白機還沒有雙重捲軸,而現在硬體及軟體開發平台是如此的進步,很容易的就做出這種效果了。

screenshot_10-30-2011_22.54.58.200