首页 > 解决方案 > Issue Running Monogame in F#

问题描述

I am experimenting a bit with F# and I am wanted to see if I could do some simple stuff with Monogame in F#. I figured the translation from C# to f# would be straightforward but it has not been so far. The code I have so far is just a simple empty project which should run. Or at least it would in C#. However running this in F# yields a

Unhandled exception. System.InvalidOperationException: No Graphics Device Service

The code I have is this, which really does not do anything crazy. I was forced to use a mutable val for the spritebatch as you must instantiate it in LoadContent for whatever reason. Anyone have any pointers to what I am doing wrong? I would be most grateful.

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

标签: .netf#monogame

解决方案


Asti 是正确的,你不想GraphicsDeviceManager重复创建一个新的。

这是一些对您所做的更改最少的工作代码。请注意,要在构造函数时定义值,您需要()在类型名称之后。在这种情况下使用mutableforSpriteBatch很丑陋但很常见,并且您不需要将其设为成员:

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 // 

随意看看我的这个 repo,它给出了一个使用 MonoGame 和 F# 的工作示例(尽管它现在可能有点过时了),包括基本的内容管道。


推荐阅读