XNA 遊戲存檔 (IsolatedStorage)

  • 3156
  • 0

在Windows Phone 7要儲存資料,需要使用IsolatedStorage來將資料儲存到每個程式的隔離儲存區內,而遊戲存檔一般是儲存人物等級、分數、關卡…而這些資料可以存成文字檔、XML檔或是用可序列化物件,這裡要示範的是存成一個文字檔,我們先設計一個可以拖曳的小方塊,程式離開時將小方塊位置存檔,下次再開啟程式時載入上次的小方塊位置。

在Windows Phone 7要儲存資料,需要使用IsolatedStorage來將資料儲存到每個程式的隔離儲存區內,而遊戲存檔一般是儲存人物等級、分數、關卡…而這些資料可以存成文字檔、XML檔或是用可序列化物件,這裡要示範的是存成一個文字檔,我們先設計一個可以拖曳的小方塊,程式離開時將小方塊位置存檔,下次再開啟程式時載入上次的小方塊位置。

 

使用IsolatedStorage類別先要先引用System.IO.IsolatedStorage命名空間。

Imports System.IO.IsolatedStorage

 

在Game1宣告變數,包括小方塊、拖曳時要用到的旗標和測試用文字。

Public Class Game1
    Inherits Microsoft.Xna.Framework.Game
 
    Private WithEvents graphics As GraphicsDeviceManager
    Private WithEvents spriteBatch As SpriteBatch
 
    Dim isDown As Boolean                   '是否按下
    Dim isDragging As Boolean               '是否拖曳中
    Dim texture As Texture2D                '紅色方塊圖形
    Dim texturePosition As Vector2          '紅色方塊圖形的座標
    Dim dPosition As Vector2                '按下位置與紅色方塊圖形的座標的差
 
    Dim txt As String = ""                  '文字
    Dim font As SpriteFont
End Class

 

在New()啟用手勢監聽

Public Sub New()
        graphics = New GraphicsDeviceManager(Me)
        Content.RootDirectory = "Content"
 
        'Frame rate is 30 fps by default for Windows Phone.
        TargetElapsedTime = TimeSpan.FromTicks(333333)
 
        'Extend battery life under lock.
        InactiveSleepTime = TimeSpan.FromSeconds(1)
 
        '啟用FreeDrag與DragComplete手勢監聽
        TouchPanel.EnabledGestures = GestureType.FreeDrag Or GestureType.DragComplete
 End Sub

 

在LoadContend()載入圖片並且讀入存檔,把存檔的座標位置設給圖片 (存檔內容格式: 100,400)。

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
        texture = Content.Load(Of Texture2D)("red")      '載入紅色方塊
        font = Content.Load(Of SpriteFont)("spriteFont1") '載入文字資源
      
        Dim savegame As IsolatedStorageFile
 
        savegame = IsolatedStorageFile.GetUserStoreForApplication()
        If savegame.FileExists("mygame.sav") Then
            Dim fs As IsolatedStorageFileStream = Nothing
 
            Try
                fs = savegame.OpenFile("mygame.sav", System.IO.FileMode.Open)
            Catch ex As Exception
 
            End Try
 
            If fs Is Nothing Then
            Else
                Dim saveBytes(256) As Byte
                Dim count As Integer
 
                count = fs.Read(saveBytes, 0, 256)
 
                If count > 0 Then
                    txt = System.Text.Encoding.UTF8.GetString(saveBytes, 0, count - 1)
 
                    Dim arr() As String
                    arr = txt.Split(","c)
 
                    texturePosition.X = CSng(arr(0))
                    texturePosition.Y = CSng(arr(1))
                    fs.Close()
                End If
 
            End If
        Else
            texturePosition.X = 50
            texturePosition.Y = 50
        End If
End Sub

 

在Update()撰寫拖曳圖片主程式,並在 GamePad.GetState(PlayerIndex.One).Buttons.Back = ButtonState.Pressed 程式要離開時將圖片位置寫入mygame.sav檔案。

Protected Overrides Sub Update(ByVal gameTime As GameTime)
        ' Allows the game to exit
        If GamePad.GetState(PlayerIndex.One).Buttons.Back = ButtonState.Pressed Then
            Dim savegame As IsolatedStorageFile
            Dim fs As IsolatedStorageFileStream
            Dim txtPosition As String
 
            savegame = IsolatedStorageFile.GetUserStoreForApplication()
            fs = savegame.OpenFile("mygame.sav", IO.FileMode.Create)
            txtPosition = texturePosition.X & "," & texturePosition.Y
 
            If fs Is Nothing Then
            Else
                fs.Write(System.Text.Encoding.UTF8.GetBytes(txtPosition), 0, txtPosition.Length)
                fs.Close()
            End If
            Me.Exit()
        End If
 
        ' TODO: Add your update logic here
        While (TouchPanel.IsGestureAvailable)
            Dim gesture As GestureSample
            gesture = TouchPanel.ReadGesture
 
            '儲存按下位置與紅色方塊圖形位置座標的差
            '拖曳時紅色方塊位置等於手勢位址減去差
            If gesture.GestureType = GestureType.FreeDrag Then
                If Not isDragging Then
                    If gesture.Position.X > texturePosition.X And gesture.Position.X < texturePosition.X + texture.Width And gesture.Position.Y > texturePosition.Y And gesture.Position.Y < texturePosition.Y + texture.Height Then
                        If Not isDown Then
                            dPosition.X = gesture.Position.X - texturePosition.X
                            dPosition.Y = gesture.Position.Y - texturePosition.Y
 
                            isDown = True
                            isDragging = True
                        End If
                    End If
                Else
                    texturePosition.X = gesture.Position.X - dPosition.X
                    texturePosition.Y = gesture.Position.Y - dPosition.Y
                End If
            ElseIf gesture.GestureType = GestureType.DragComplete Then
                If isDragging Then
                    isDown = False
                    isDragging = False
                End If
            End If
        End While
        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(texture, texturePosition, Color.White)
        spriteBatch.DrawString(font, txt, Vector2.Zero, Color.Red)
        spriteBatch.End()
 
        MyBase.Draw(gameTime)
 End Sub

 

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

screenshot_11-15-2011_21.55.28.670