简体   繁体   中英

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

Asti is correct, you don't want to create a new GraphicsDeviceManager repeatedly.

Here is some working code with minimal changes to yours. Note that to define values at constructor-time you need the () after the type name. Using mutable for the SpriteBatch is ugly but common in this case, and you don't need to make it a member:

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

Feel free to take a look at this repo of mine which gives a working example of using MonoGame with F# (although it's probably a bit out-of-date now), including basic content pipelines.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM