我正在嘗試使用F#和Silverlight編寫遊戲,並且正在努力嘗試一些不變性。使用F#和Silverlight的遊戲:避免可變狀態
我想從視圖中分離一點遊戲,所以我把它放在一個模塊中,並使其更新函數返回一個新的世界狀態實例,從而提供了不變性。
視圖(AppControl)負責繪製世界。
但是,我認爲沒有辦法讓世界變成視圖中的參考單元格。
現在,我認爲可變狀態是足夠本地的,不會引起任何問題(如果我錯了,請糾正我),我只是好奇,如果有人可以想辦法完全避免可變狀態?
這裏的應用程序的輪廓,我試着把減少問題的實質:
open System
open System.Windows
open System.Windows.Controls
open System.Windows.Media
module Game =
type World = { State : int }
let init() =
{ State = 0 }
// immutable update loop
let updateWorld world =
{ State = world.State + 1 }
type AppControl() =
inherit UserControl()
let canvas = new Canvas()
let textBlock = new TextBlock()
let world = Game.init() |> ref // mutable world
let drawWorld (world : Game.World) =
textBlock.Text <- world.State.ToString()
// mutating game loop
let gameLoop world =
world := Game.updateWorld !world
drawWorld !world
()
do
canvas.Children.Add(textBlock)
base.Content <- canvas
CompositionTarget.Rendering.Add (fun _ -> gameLoop world)
type App() as this =
inherit Application()
let main = new AppControl()
do this.Startup.Add(fun _ -> this.RootVisual <- main)
正是我在找的東西,非常感謝!我打算使用異步工作流進行輸入處理(正如我從你的書中學到的,順便說一句,這真是太棒了!),但是我也沒有想過用它來更新狀態。 – bknotic 2011-04-27 16:19:40
我有點新F#,在你的例子中,'let! _'有一個特殊的含義,或者你可以用'do!'離開嗎? – R0MANARMY 2011-04-28 16:29:18
@ R0MANARMY @bknotic你實際上必須使用'let! _ ='當你調用的函數返回一些結果。 'do!'只能用於沒有返回值的異步工作流('Async')。所以,'做! ...'是'let的簡寫! ()= ...'。 –
2011-04-28 22:44:25