在F#中运行Monogame的问题

5
我正在尝试使用 F# 并想看看是否可以在 F# 中使用 Monogame 进行一些简单的操作。我认为从 C# 到 F# 的转换应该是直接的,但到目前为止并非如此。我目前所拥有的代码只是一个简单的空项目,应该可以运行。或者至少在 C# 中可以。然而,在 F# 中运行这个代码会产生一个


Unhandled exception. System.InvalidOperationException: No Graphics Device Service

我现在的代码如下,其实并没有什么特别的。由于必须在“LoadContent”中实例化spritebatch,所以我不得不使用可变val来表示它。有没有人能指出我做错了什么?我将不胜感激。

type GameState = 
    inherit Game
    new() =  { inherit Game(); Sb = null;  }
    member this.Gfx : GraphicsDeviceManager = new GraphicsDeviceManager(this)
    val mutable Sb : SpriteBatch 

    override this.Initialize() = 
        this.Content.RootDirectory <- "Content"
        this.IsMouseVisible <- false
        base.Initialize ()

    override this.LoadContent () =
        this.Sb <- new SpriteBatch(this.Gfx.GraphicsDevice)
        base.LoadContent ()

    override this.UnloadContent () = 
        base.UnloadContent ()

    override this.Update (gameTime : GameTime) = 
        base.Update (gameTime)

    override this.Draw (gameTime : GameTime) = 
        this.Gfx.GraphicsDevice.Clear (Color.CornflowerBlue)
        this.Sb.Begin()
        //draw here
        this.Sb.End()
        base.Draw (gameTime)

[<EntryPoint>]
let main argv =
    let gs = new GameState()
    gs.Run()
    0 // return an integer exit code

1
这里的 member this.Gfx = new GraphicsDeviceManager(this) 每次访问 this.Gfx 都会创建一个新的 GraphicsDeviceManager。这可能不是一个好的做法。 - Asti
1个回答

4
Asti是正确的,您不希望重复创建新的GraphicsDeviceManager
以下是一些能正常工作且与您的代码有最小更改的代码。请注意,在构造函数时定义值,需要在类型名称后面加上()。在这种情况下,使用mutableSpriteBatch是丑陋的但很常见,而且您不需要将其设置为成员变量:
open Microsoft.Xna.Framework
open Microsoft.Xna.Framework.Graphics

type GameState() as this = 
    inherit Game()
    let gfx = new GraphicsDeviceManager(this)
    let mutable sb = Unchecked.defaultof<SpriteBatch>

    override this.Initialize() = 
        this.Content.RootDirectory <- "Content"
        this.IsMouseVisible <- false
        base.Initialize ()

    override this.LoadContent () =
        sb <- new SpriteBatch(gfx.GraphicsDevice)
        base.LoadContent ()

    override this.UnloadContent () = 
        base.UnloadContent ()

    override this.Update (gameTime : GameTime) = 
        base.Update (gameTime)

    override this.Draw (gameTime : GameTime) = 
        gfx.GraphicsDevice.Clear (Color.CornflowerBlue)
        sb.Begin()
        //draw here
        sb.End()
        base.Draw (gameTime)

[<EntryPoint>]
let main argv =
    let gs = new GameState()
    gs.Run()
    0 // 

欢迎查看我的这个仓库,其中提供了使用F#与MonoGame的可工作示例(尽管现在可能有点过时),包括基本内容管道。


谢谢,F#的类对我来说仍然非常令人困惑,使用起来似乎很笨拙。我也会查看你的存储库以获得灵感! - kiooikml
没问题。我发现在 F# 中大多数情况下根本不需要使用类,但显然 MonoGame 在这里需要一个。 - Mark Pattison

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接