F# メモ XNA Framework
F#でも XNA が使用できます。
ただし .NET Framework 4.0 ではビルドできませんでした。3.5 なら問題なくビルドできます。
おそらく、 XNA Game Studio 4.0 がリリースされれば .NET Framework 4.0 でもビルドできるようになると思われます。
BasicComponents.fs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | namespace Siki open System open System.Collections.Generic open Microsoft.Xna.Framework module BasicComponents = /// 秒を表す単位 [<Measure>] type sec = static member Unit v = v * 1.0<sec> static member Unit v = v * 1<sec> /// フレームを表す単位 [<Measure>] type frame = /// 1フレームを表す static member Unit v = v * 1.0<frame> static member Unit v = v * 1<frame> /// 1秒あたりの描画フレーム数を計算するコンポーネント type FpsComponent(game, syncv, fixedStep, targetFps) = inherit DrawableGameComponent(game) // フィールド let m_interval = 1.0<sec> let mutable m_fps = 0.0<frame/sec> let mutable m_sec = 0.0<sec> let mutable m_framecount = 0.0<frame> let mutable m_lastupdate = 0.0<sec> // メインコンストラクタ do let graphics = game.Services.GetService(typeof<IGraphicsDeviceManager>) :?> GraphicsDeviceManager graphics.SynchronizeWithVerticalRetrace <- syncv game.IsFixedTimeStep <- fixedStep game.TargetElapsedTime <- TimeSpan.FromSeconds(1.0 / targetFps) /// カスタムコンストラクタ new(game) = new FpsComponent(game, false, false, 1.0 / game.TargetElapsedTime.TotalSeconds) new(game, syncv) = new FpsComponent(game, syncv, false, 1.0 / game.TargetElapsedTime.TotalSeconds) new(game, targetFps) = new FpsComponent(game, true, true, targetFps) /// 現在のFPS値を取得する member x.Fps with get() = m_fps /// 現在のFPSを整数に丸めた値を取得する member x.RoundFps with get() = x.Fps |> float |> Math.Round |> int /// 初期化メソッド override x.Initialize() = base.Initialize() /// 更新メソッド override x.Update(gametime) = base.Update(gametime) /// 描画メソッド override x.Draw(gametime) = let elapsed = gametime.ElapsedGameTime.TotalSeconds |> sec.Unit m_framecount <- m_framecount + 1.0<frame> m_sec <- m_sec + elapsed if m_sec > m_interval then m_fps <- m_framecount / m_sec x.Game.Window.Title <- sprintf "%d fps" x.RoundFps m_framecount <- 0.0<frame> // カウンタリセット m_sec <- m_sec - m_interval base.Draw(gametime) |
Program.fs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | namespace Siki open System open System.Collections.Generic open Microsoft.Xna.Framework open Microsoft.Xna.Framework.Graphics open Siki.BasicComponents module Main = /// ゲームクラス type Game1() as x = inherit Game(IsMouseVisible=true, IsFixedTimeStep=false) // フィールド let m_rand = new Random() let m_graphics = new GraphicsDeviceManager(x) let m_fpscomponent = new FpsComponent(x) let mutable m_num = 0 let mutable m_bgc = new Color(80uy, 80uy, 80uy) let mutable m_rd = -1 let mutable m_gd = -1 let mutable m_bd = -1 // メインコンストラクタ do x.Window.Title <- "FPSを表示します" /// 初期化メソッド override x.Initialize() = x.Components.Add(m_fpscomponent) base.Initialize() /// 更新メソッド override x.Update gametime = m_num <- m_num + 1 base.Update gametime /// 描画メソッド override x.Draw gametime = match m_rand.Next(0, 5) with | 0 -> m_bgc.R <- m_bgc.R + (m_rd |> byte) if (m_bgc.R = 0x00uy || m_bgc.R = 0xffuy) then m_rd <- m_rd * -1 | 1|2 -> m_bgc.G <- m_bgc.G + (m_gd |> byte) if (m_bgc.G = 0x00uy || m_bgc.G = 0xffuy) then m_gd <- m_gd * -1 | 3|4|5 -> m_bgc.B <- m_bgc.B + (m_bd |> byte) if (m_bgc.B = 0x00uy || m_bgc.B = 0xffuy) then m_bd <- m_bd * -1 | _ -> () m_graphics.GraphicsDevice.Clear( m_bgc ) base.Draw gametime /// プログラムのエントリポイント [<EntryPoint>] let main(args:string[]) = use game = new Game1() game.Run() 0 |
FPSを計算するだけの簡単なサンプルです。
Update()、Draw()が呼ばれていることを確認するために、少しずつ背景色を変えています。

rei@sikios.com
コメントはまだありません。