無題
ここ数年のプログラムのソースファイルが全て消えました・・・。
大したものは作っていないとはいえ、かなりショック。
これを機にWeb上にもバックアップをとっておこうか。
投稿者のアーカイブ
ここ数年のプログラムのソースファイルが全て消えました・・・。
大したものは作っていないとはいえ、かなりショック。
これを機にWeb上にもバックアップをとっておこうか。
フォームアプリケーションでは使う機会は少ないけれども、用意しておくと便利かもしれない。
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 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 | namespace Siki.Libra [<AutoOpen>] module WinUser = type WM = | WM_NULL = 0x0000 | CREATE = 0x0001 | DESTROY = 0x0002 | MOVE = 0x0003 | SIZE = 0x0005 | SETFOCUS = 0x0007 | KILLFOCUS = 0x0008 | ENABLE = 0x000A | SETREDRAW = 0x000B | SETTEXT = 0x000C | GETTEXT = 0x000D | GETTEXTLENGTH = 0x000E | PAINT = 0x000F | CLOSE = 0x0010 | QUERYENDSESSION = 0x0011 | QUIT = 0x0012 | QUERYOPEN = 0x0013 | ERASEBKGND = 0x0014 | SYSCOLORCHANGE = 0x0015 | ENDSESSION = 0x0016 | SHOWWINDOW = 0x0018 | WININICHANGE = 0x001A | DEVMODECHANGE = 0x001B | ACTIVATEAPP = 0x001C | FONTCHANGE = 0x001D | TIMECHANGE = 0x001E | CANCELMODE = 0x001F | SETCURSOR = 0x0020 | MOUSEACTIVATE = 0x0021 | CHILDACTIVATE = 0x0022 | QUEUESYNC = 0x0023 | PAINTICON = 0x0026 | ICONERASEBKGND = 0x0027 | NEXTDLGCTL = 0x0028 | SPOOLERSTATUS = 0x002A | DRAWITEM = 0x002B | MEASUREITEM = 0x002C | DELETEITEM = 0x002D | VKEYTOITEM = 0x002E | CHARTOITEM = 0x002F | SETFONT = 0x0030 | GETFONT = 0x0031 | SETHOTKEY = 0x0032 | GETHOTKEY = 0x0033 | QUERYDRAGICON = 0x0037 | COMPAREITEM = 0x0039 | GETOBJECT = 0x003D | COMPACTING = 0x0041 | COMMNOTIFY = 0x0044 | WINDOWPOSCHANGING = 0x0046 | WINDOWPOSCHANGED = 0x0047 | POWER = 0x0048 | COPYDATA = 0x004A | CANCELJOURNAL = 0x004B | NOTIFY = 0x004E | INPUTLANGCHANGEREQUEST = 0x0050 | INPUTLANGCHANGE = 0x0051 | TCARD = 0x0052 | HELP = 0x0053 | USERCHANGED = 0x0054 | NOTIFYFORMAT = 0x0055 | CONTEXTMENU = 0x007B | STYLECHANGING = 0x007C | STYLECHANGED = 0x007D | DISPLAYCHANGE = 0x007E | GETICON = 0x007F | SETICON = 0x0080 | NCCREATE = 0x0081 | NCDESTROY = 0x0082 | NCCALCSIZE = 0x0083 | NCHITTEST = 0x0084 | NCPAINT = 0x0085 | NCACTIVATE = 0x0086 | GETDLGCODE = 0x0087 | SYNCPAINT = 0x0088 | NCMOUSEMOVE = 0x00A0 | NCLBUTTONDOWN = 0x00A1 | NCLBUTTONUP = 0x00A2 | NCLBUTTONDBLCLK = 0x00A3 | NCRBUTTONDOWN = 0x00A4 | NCRBUTTONUP = 0x00A5 | NCRBUTTONDBLCLK = 0x00A6 | NCMBUTTONDOWN = 0x00A7 | NCMBUTTONUP = 0x00A8 | NCMBUTTONDBLCLK = 0x00A9 | NCXBUTTONDOWN = 0x00AB | NCXBUTTONUP = 0x00AC | NCXBUTTONDBLCLK = 0x00AD | INPUT_DEVICE_CHANGE = 0x00FE | INPUT = 0x00FF | KEYFIRST = 0x0100 | UNICHAR = 0x0109 | KEYLAST = 0x0109 | IME_STARTCOMPOSITION = 0x010D | IME_ENDCOMPOSITION = 0x010E | IME_COMPOSITION = 0x010F | IME_KEYLAST = 0x010F | KEYDOWN = 0x0100 | KEYUP = 0x0101 | CHAR = 0x0102 | DEADCHAR = 0x0103 | SYSKEYDOWN = 0x0104 | SYSKEYUP = 0x0105 | SYSCHAR = 0x0106 | SYSDEADCHAR = 0x0107 | INITDIALOG = 0x0110 | COMMAND = 0x0111 | SYSCOMMAND = 0x0112 | TIMER = 0x0113 | HSCROLL = 0x0114 | VSCROLL = 0x0115 | INITMENU = 0x0116 | INITMENUPOPUP = 0x0117 | GESTURE = 0x0119 | GESTURENOTIFY = 0x011A | MENUSELECT = 0x011F | MENUCHAR = 0x0120 | ENTERIDLE = 0x0121 | MENURBUTTONUP = 0x0122 | MENUDRAG = 0x0123 | MENUGETOBJECT = 0x0124 | UNINITMENUPOPUP = 0x0125 | MENUCOMMAND = 0x0126 | CHANGEUISTATE = 0x0127 | UPDATEUISTATE = 0x0128 | QUERYUISTATE = 0x0129 | CTLCOLORMSGBOX = 0x0132 | CTLCOLOREDIT = 0x0133 | CTLCOLORLISTBOX = 0x0134 | CTLCOLORBTN = 0x0135 | CTLCOLORDLG = 0x0136 | CTLCOLORSCROLLBAR = 0x0137 | CTLCOLORSTATIC = 0x0138 | MOUSEFIRST = 0x0200 | MOUSEMOVE = 0x0200 | LBUTTONDOWN = 0x0201 | LBUTTONUP = 0x0202 | LBUTTONDBLCLK = 0x0203 | RBUTTONDOWN = 0x0204 | RBUTTONUP = 0x0205 | RBUTTONDBLCLK = 0x0206 | MBUTTONDOWN = 0x0207 | MBUTTONUP = 0x0208 | MBUTTONDBLCLK = 0x0209 | MOUSEWHEEL = 0x020A | XBUTTONDOWN = 0x020B | XBUTTONUP = 0x020C | XBUTTONDBLCLK = 0x020D | MOUSEHWHEEL = 0x020E | MOUSELAST = 0x020E | PARENTNOTIFY = 0x0210 | ENTERMENULOOP = 0x0211 | EXITMENULOOP = 0x0212 | NEXTMENU = 0x0213 | SIZING = 0x0214 | CAPTURECHANGED = 0x0215 | MOVING = 0x0216 | POWERBROADCAST = 0x0218 | MDICREATE = 0x0220 | MDIDESTROY = 0x0221 | MDIACTIVATE = 0x0222 | MDIRESTORE = 0x0223 | MDINEXT = 0x0224 | MDIMAXIMIZE = 0x0225 | MDITILE = 0x0226 | MDICASCADE = 0x0227 | MDIICONARRANGE = 0x0228 | MDIGETACTIVE = 0x0229 | MDISETMENU = 0x0230 | ENTERSIZEMOVE = 0x0231 | EXITSIZEMOVE = 0x0232 | DROPFILES = 0x0233 | MDIREFRESHMENU = 0x0234 | TOUCH = 0x0240 | IME_SETCONTEXT = 0x0281 | IME_NOTIFY = 0x0282 | IME_CONTROL = 0x0283 | IME_COMPOSITIONFULL = 0x0284 | IME_SELECT = 0x0285 | IME_CHAR = 0x0286 | IME_REQUEST = 0x0288 | IME_KEYDOWN = 0x0290 | IME_KEYUP = 0x0291 | MOUSEHOVER = 0x02A1 | MOUSELEAVE = 0x02A3 | WTSSESSION_CHANGE = 0x02B1 | TABLET_FIRST = 0x02c0 | TABLET_LAST = 0x02df | CUT = 0x0300 | COPY = 0x0301 | PASTE = 0x0302 | CLEAR = 0x0303 | UNDO = 0x0304 | RENDERFORMAT = 0x0305 | RENDERALLFORMATS = 0x0306 | DESTROYCLIPBOARD = 0x0307 | DRAWCLIPBOARD = 0x0308 | PAINTCLIPBOARD = 0x0309 | VSCROLLCLIPBOARD = 0x030A | SIZECLIPBOARD = 0x030B | ASKCBFORMATNAME = 0x030C | CHANGECBCHAIN = 0x030D | HSCROLLCLIPBOARD = 0x030E | QUERYNEWPALETTE = 0x030F | PALETTEISCHANGING = 0x0310 | PALETTECHANGED = 0x0311 | HOTKEY = 0x0312 | PRINT = 0x0317 | PRINTCLIENT = 0x0318 | APPCOMMAND = 0x0319 | THEMECHANGED = 0x031A | CLIPBOARDUPDATE = 0x031D | DWMCOMPOSITIONCHANGED = 0x031E | DWMNCRENDERINGCHANGED = 0x031F | DWMCOLORIZATIONCOLORCHANGED = 0x0320 | DWMWINDOWMAXIMIZEDCHANGE = 0x0321 | DWMSENDICONICTHUMBNAIL = 0x0323 | DWMSENDICONICLIVEPREVIEWBITMAP = 0x0326 | GETTITLEBARINFOEX = 0x033F | HANDHELDFIRST = 0x0358 | HANDHELDLAST = 0x035F | AFXFIRST = 0x0360 | AFXLAST = 0x037F | PENWINFIRST = 0x0380 | PENWINLAST = 0x038F | USER = 0x0400 | APP = 0x8000 |
全シーンクリアしました。
総プレイ時間は約30時間。
やっぱりフィルムの巻きが早い分、2周目は簡単でしたね。(10-4を除く)
ちなみに初成功時枚数が多いのは、
EX-5 天儀「オーレリーズソーラーシステム」(文)866枚
8-6 星符「巨星堕つ」(文)548枚
12-7 「スターソードの護法」(文)488枚
9-7 想起「うろおぼえの金閣寺」(文)430枚
8-7 酔歩「キャットランダムウォーク」(文)349枚
でした。
前回の文花帖はまだクリアできないシーンがあるので、ダブルスポイラーの方が易しいようですね。
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()が呼ばれていることを確認するために、少しずつ背景色を変えています。
C#でいうNullable型のようなもので、値を持たないことも表せるようになる。
引数 x が自然数なら x を、負の数なら None (値を持たない) を返す。
| Option.get ‘a option -> ‘a |
Option型 は Some (値を持っている) か None (値を持たない) のいずれかを表し、
Some の場合は値を取得できる。
None に対し Option.get を行うと例外が発生する。
| Option.isSome ‘a option -> bool |
引数が Some なら true を、None なら false を返す。
| Option.isNone ‘a option -> bool |
引数が Some なら true を、None なら false を返す。
| 関数 関数の型 |
簡単な説明 |
| List.length ‘a list -> int |
要素の数を取得する |
| List.head ‘a list -> ‘a |
先頭の要素を取得する |
| List.tail ‘a list -> ‘a list |
先頭の要素を除いたリストを取得する |
| List.exists (‘a -> bool) -> ‘a list -> bool |
条件に合う要素が存在するか調べる |
| List.rev ‘a list -> ‘a list |
順番を逆にしたリストを取得する |
| List.tryFind (‘a -> bool) -> ‘a list -> ‘a option |
条件に合う要素を取得する 存在しない場合はNoneを返す |
| List.zip ‘a list -> ‘b list -> (‘a * ‘b) list |
2つのリストの要素を組み合わせ、 タプルのリストを作成する |
| List.filter (‘a -> bool) ‘a list -> ‘a list |
条件に合う要素のみを含むリストを作成する |
| List.partition (‘a -> bool) -> ‘a list -> (‘a list * ‘a list) |
条件に合う要素のみを含むリストと それ以外のリストのタプルを作成する |
他にも多数あります。msdn
リストなどのコレクションには個々の要素に対して何らかの操作を行う関数が多数用意されている。
| List.map (‘a -> ‘b) -> ‘a list -> ‘b list |
‘a -> ‘b 変換関数をすべての要素に適用し、’b list を作成する。
例:整数のリストを基に、文字列のリストを作成する。
| List.reduce (‘a -> ‘a -> ‘a) ->’a list -> ‘a |
リストの要素を辿りながら ‘a 型のアキュムレータを構築していく関数。
(‘a -> ‘a -> ‘a) の部分は現在のアキュムレータとリストの要素を引数とし、新たなアキュムレータを作成する関数。
例:1から5までの整数の積を求める。(ついでに、アキュムレータの確認を行う)
上の例のように、リストの先頭要素がアキュムレータの初期値となる。
| List.fold (‘acc -> ‘b -> ‘acc) -> ‘acc -> ‘b list -> ‘acc |
リストの要素を辿りながら任意の型のアキュムレータを構築していく関数。
List.reduceを汎用的にしたもの。
アキュムレータの初期値を与える必要がある。
例:リスト中の文字数の合計を取得する
| List.iter (‘a -> unit) -> ‘a list -> unit |
指定された関数を、リストの各要素に対して順次実行する関数。