1 // ここにサンプルプログラムをペーストしてください 2 // 初期状態ではサウンドノベル風文字列描画サンプルが入力されています。 3 // べつのサンプルプログラムを実行する場合は以下のプログラムをすべて 4 // 削除して、新たにコピー&ペーストしてください。 5 module windows_sample.app; 6 7 8 version (Windows): 9 10 import core.stdc.math; 11 import core.sys.windows.windef; 12 import core.sys.windows.winnt; 13 import dxlib_d.dxdatatype; 14 import dxlib_d.dxfunctionwin; 15 import dxlib_d.dxlib; 16 17 // サウンドノベル風文字列描画、テキストバッファ使用バージョン 18 19 // 文字のサイズ 20 enum MOJI_SIZE = 24; 21 22 //画面の幅と高さ 23 enum WIDTH = 640; 24 enum HEIGTH = 480; 25 26 // 仮想テキストバッファの横サイズ縦サイズ 27 enum STRBUF_WIDTH = 24; 28 enum STRBUF_HEIGHT = 20; 29 30 // 仮想テキストバッファ 31 core.sys.windows.winnt.TCHAR[(.STRBUF_WIDTH * 4) + 1][.STRBUF_HEIGHT] StringBuf; 32 33 // 仮想画面上での文字表示カーソルの位置 34 int CursorX; 35 int CursorY; 36 37 // 参照する文字列番号と文字列中の文字ポインタ 38 int SP; 39 int CP; 40 int CursorX_CP; 41 42 // 終了フラグ 43 int EndFlag; 44 45 // ボタン押し待ちフラグ 46 int KeyWaitFlag; 47 48 // フレームカウンタ 49 int Count; 50 51 //Dxlibの関数に渡される文字列の終端は'\0'でなければならないことに気をつける。 52 version (Unicode) { 53 //正常に動作するかは未確認 54 static assert(false); 55 56 //UTF-16 文字列 57 static immutable wchar[256][] String = 58 [ 59 " ゲームプログラムを習得するための一番の近道はとにかく沢山プログラムを組む", 60 "ことである。B", 61 "@ プログラムの参考書にはゲームのプログラムの方法なんて何も書かれていない、B", 62 "変数、B配列、B関数、Bループ、B条件分岐…Bこれらすべての説明はゲームで何に使うか", 63 "なんてどこにも書いていない、Bせいぜい住所録を題材にした例がある程度である。B", 64 "C プログラムは習うより慣れろなのでプログラムを組むに当たって少しでも知識が", 65 "つけば後はそこからは掘り下げ、広げていけば良いわけで、Bプログラムの参考書を", 66 "読んでいて少しでも何か出来るような気がしたらそこでとにかくプログラム", 67 "を打ってみることが大事である。E", 68 ]; 69 } else { 70 version (all) { 71 //UTF-8文字列 72 //Dxlibの関数に文字列を渡す場合、DxLib_Initの前にSetUseCharCodeFormat(DX_CHARCODEFORMAT_UTF8)としないと、UTF-8ではなくSHIFT-JIS文字列と認識されてしまう 73 static immutable char[256][] String = 74 [ 75 " ゲームプログラムを習得するための一番の近道はとにかく沢山プログラムを組む", 76 "ことである。B", 77 "@ プログラムの参考書にはゲームのプログラムの方法なんて何も書かれていない、B", 78 "変数、B配列、B関数、Bループ、B条件分岐…Bこれらすべての説明はゲームで何に使うか", 79 "なんてどこにも書いていない、Bせいぜい住所録を題材にした例がある程度である。B", 80 "C プログラムは習うより慣れろなのでプログラムを組むに当たって少しでも知識が", 81 "つけば後はそこからは掘り下げ、広げていけば良いわけで、Bプログラムの参考書を", 82 "読んでいて少しでも何か出来るような気がしたらそこでとにかくプログラム", 83 "を打ってみることが大事である。E", 84 ]; 85 } else { 86 //SHIFT-JIS 文字列 87 static immutable char[256][] String = 88 [ 89 "\x81\x40\x83\x51\x81\x5B\x83\x80\x83\x76\x83\x8D\x83\x4F\x83\x89\x83\x80\x82\xF0\x8F\x4B\x93\xBE\x82\xB7\x82\xE9\x82\xBD\x82\xDF\x82\xCC\x88\xEA\x94\xD4\x82\xCC\x8B\xDF\x93\xB9\x82\xCD\x82\xC6\x82\xC9\x82\xA9\x82\xAD\x91\xF2\x8E\x52\x83\x76\x83\x8D\x83\x4F\x83\x89\x83\x80\x82\xF0\x91\x67\x82\xDE", 90 "\x82\xB1\x82\xC6\x82\xC5\x82\xA0\x82\xE9\x81\x42\x42", 91 "\x40\x81\x40\x83\x76\x83\x8D\x83\x4F\x83\x89\x83\x80\x82\xCC\x8E\x51\x8D\x6C\x8F\x91\x82\xC9\x82\xCD\x83\x51\x81\x5B\x83\x80\x82\xCC\x83\x76\x83\x8D\x83\x4F\x83\x89\x83\x80\x82\xCC\x95\xFB\x96\x40\x82\xC8\x82\xF1\x82\xC4\x89\xBD\x82\xE0\x8F\x91\x82\xA9\x82\xEA\x82\xC4\x82\xA2\x82\xC8\x82\xA2\x81\x41\x42", 92 "\x95\xCF\x90\x94\x81\x41\x42\x94\x7A\x97\xF1\x81\x41\x42\x8A\xD6\x90\x94\x81\x41\x42\x83\x8B\x81\x5B\x83\x76\x81\x41\x42\x8F\xF0\x8C\x8F\x95\xAA\x8A\xF2\x81\x63\x42\x82\xB1\x82\xEA\x82\xE7\x82\xB7\x82\xD7\x82\xC4\x82\xCC\x90\xE0\x96\xBE\x82\xCD\x83\x51\x81\x5B\x83\x80\x82\xC5\x89\xBD\x82\xC9\x8E\x67\x82\xA4\x82\xA9", 93 "\x82\xC8\x82\xF1\x82\xC4\x82\xC7\x82\xB1\x82\xC9\x82\xE0\x8F\x91\x82\xA2\x82\xC4\x82\xA2\x82\xC8\x82\xA2\x81\x41\x42\x82\xB9\x82\xA2\x82\xBA\x82\xA2\x8F\x5A\x8F\x8A\x98\x5E\x82\xF0\x91\xE8\x8D\xDE\x82\xC9\x82\xB5\x82\xBD\x97\xE1\x82\xAA\x82\xA0\x82\xE9\x92\xF6\x93\x78\x82\xC5\x82\xA0\x82\xE9\x81\x42\x42", 94 "\x43\x81\x40\x83\x76\x83\x8D\x83\x4F\x83\x89\x83\x80\x82\xCD\x8F\x4B\x82\xA4\x82\xE6\x82\xE8\x8A\xB5\x82\xEA\x82\xEB\x82\xC8\x82\xCC\x82\xC5\x83\x76\x83\x8D\x83\x4F\x83\x89\x83\x80\x82\xF0\x91\x67\x82\xDE\x82\xC9\x93\x96\x82\xBD\x82\xC1\x82\xC4\x8F\xAD\x82\xB5\x82\xC5\x82\xE0\x92\x6D\x8E\xAF\x82\xAA", 95 "\x82\xC2\x82\xAF\x82\xCE\x8C\xE3\x82\xCD\x82\xBB\x82\xB1\x82\xA9\x82\xE7\x82\xCD\x8C\x40\x82\xE8\x89\xBA\x82\xB0\x81\x41\x8D\x4C\x82\xB0\x82\xC4\x82\xA2\x82\xAF\x82\xCE\x97\xC7\x82\xA2\x82\xED\x82\xAF\x82\xC5\x81\x41\x42\x83\x76\x83\x8D\x83\x4F\x83\x89\x83\x80\x82\xCC\x8E\x51\x8D\x6C\x8F\x91\x82\xF0", 96 "\x93\xC7\x82\xF1\x82\xC5\x82\xA2\x82\xC4\x8F\xAD\x82\xB5\x82\xC5\x82\xE0\x89\xBD\x82\xA9\x8F\x6F\x97\x88\x82\xE9\x82\xE6\x82\xA4\x82\xC8\x8B\x43\x82\xAA\x82\xB5\x82\xBD\x82\xE7\x82\xBB\x82\xB1\x82\xC5\x82\xC6\x82\xC9\x82\xA9\x82\xAD\x83\x76\x83\x8D\x83\x4F\x83\x89\x83\x80", 97 "\x82\xF0\x91\xC5\x82\xC1\x82\xC4\x82\xDD\x82\xE9\x82\xB1\x82\xC6\x82\xAA\x91\xE5\x8E\x96\x82\xC5\x82\xA0\x82\xE9\x81\x42\x45", 98 ]; 99 } 100 } 101 102 extern (Windows) 103 nothrow @nogc 104 int WinMain(core.sys.windows.windef.HINSTANCE hInstance, core.sys.windows.windef.HINSTANCE hPrevInstance, core.sys.windows.winnt.LPSTR lpCmdLine, int nCmdShow) 105 106 do 107 { 108 //WIDTH × HEIGTH, 色ビット深度 16 109 dxlib_d.dxlib.SetGraphMode(WIDTH, HEIGTH, 16); 110 111 //全画面表示にしない 112 dxlib_d.dxfunctionwin.ChangeWindowMode(dxlib_d.dxdatatype.TRUE); 113 114 version (ANSI) { 115 version (all) { 116 //UTF-8にする 117 dxlib_d.dxlib.SetUseCharCodeFormat(dxlib_d.dxlib.DX_CHARCODEFORMAT_UTF8); 118 } 119 } 120 121 // DXライブラリ初期化処理 122 if (dxlib_d.dxlib.DxLib_Init() == -1) { 123 // エラーが起きたら直ちに終了 124 return -1; 125 } 126 127 scope (exit) { 128 // DXライブラリ使用の終了処理 129 dxlib_d.dxlib.DxLib_End(); 130 } 131 132 // 描画位置の初期位置セット 133 .CursorX = 0; 134 .CursorX_CP = 0; 135 .CursorY = 0; 136 137 // 参照文字位置をセット 138 139 // 1行目の 140 .SP = 0; 141 142 // 0文字 143 .CP = 0; 144 145 // フォントのサイズセット 146 dxlib_d.dxlib.SetFontSize(.MOJI_SIZE); 147 148 // フォントの太さを変更 149 dxlib_d.dxlib.SetFontThickness(1); 150 151 // フォントのタイプをアンチエイリアスフォントに変更 152 dxlib_d.dxlib.ChangeFontType(dxlib_d.dxlib.DX_FONTTYPE_ANTIALIASING_EDGE_8X8); 153 154 // 描画先を裏画面にセット 155 dxlib_d.dxlib.SetDrawScreen(dxlib_d.dxlib.DX_SCREEN_BACK); 156 157 // フレームカウンタ初期化 158 .Count = 0; 159 160 //文字コード形式の取得 161 version (Unicode) { 162 immutable int code = dxlib_d.dxlib.Get_wchar_t_CharCodeFormat(); 163 } else { 164 immutable int code = dxlib_d.dxlib.GetUseCharCodeFormat(); 165 } 166 167 // ループ 168 while ((dxlib_d.dxlib.ProcessMessage() == 0) && (dxlib_d.dxlib.CheckHitKey(dxlib_d.dxlib.KEY_INPUT_ESCAPE) == 0)) { 169 // サウンドノベル風文字列描画処理を行う 170 // ただし終了フラグが1だった場合は処理をしない 171 if (.EndFlag == 0) { 172 // ボタン押し待ちフラグがたっていた場合はボタンが押されるまでここで終了 173 if (.KeyWaitFlag == 1) { 174 if ((dxlib_d.dxlib.ProcessMessage() == 0) && (dxlib_d.dxlib.CheckHitKeyAll() != 0)) { 175 // ボタンが押されていたら解除 176 .KeyWaitFlag = 0; 177 } 178 } else { 179 // 文字の描画 180 core.sys.windows.winnt.TCHAR Moji = String[.SP][.CP]; 181 182 switch (Moji) { 183 // 改行文字 184 case '@': 185 // 改行処理および参照文字位置を1つ進める 186 .Kaigyou(); 187 .CP++; 188 189 break; 190 191 192 // ボタン押し待ち文字 193 case 'B': 194 // ボタンが離されるまで待つ 195 while ((dxlib_d.dxlib.ProcessMessage() == 0) && (dxlib_d.dxlib.CheckHitKeyAll() != 0)) { 196 } 197 198 // ボタン押し待ちフラグをたてる 199 .KeyWaitFlag = 1; 200 .CP++; 201 202 break; 203 204 // 終了文字 205 case 'E': 206 // 終了フラグを立てるおよび参照文字位置を1つ進める 207 .EndFlag = 1; 208 .CP++; 209 210 break; 211 212 // クリア文字 213 case 'C': 214 // 仮想テキストバッファを初期化して描画文字位置を初期位置に戻すおよび参照文字位置を1つ進める 215 for (size_t i = 0; i < .StringBuf.length; i++) { 216 for (size_t j = 0; j < (StringBuf[i - 1].length - 1); j++) { 217 .StringBuf[i][j] = 0; 218 } 219 } 220 221 .CursorY = 0; 222 .CursorX = 0; 223 .CursorX_CP = 0; 224 .CP++; 225 226 break; 227 228 // その他の文字 229 default: 230 int code_length = GetCharBytes(code, &(String[.SP][.CP])); 231 assert(code_length != -1); 232 233 version (Unicode) { 234 code_length = code_length / 2; 235 } 236 237 // 1文字テキストバッファに代入 238 for (size_t i = 0; i < code_length; i++) { 239 .StringBuf[.CursorY][.CursorX_CP + i] = String[.SP][.CP + i]; 240 } 241 242 // 参照文字位置を1文字分進める 243 .CP += code_length; 244 .CursorX_CP += code_length; 245 246 // カーソルを1文字分進める 247 .CursorX++; 248 249 // テキストバッファ横幅からはみ出たら改行する 250 if (.CursorX >= .STRBUF_WIDTH) { 251 .Kaigyou(); 252 } 253 254 break; 255 } 256 257 // 参照文字列の終端まで行っていたら参照文字列を進める 258 if (String[.SP][.CP] == '\0') { 259 .SP++; 260 .CP = 0; 261 } 262 } 263 } 264 265 // 画面のクリア 266 dxlib_d.dxlib.ClsDrawScreen(); 267 268 // 背景エフェクトの描画 269 { 270 int Color = cast(int)(core.stdc.math.sin((.Count / 100.0) * 80.0) + 125.0); 271 dxlib_d.dxlib.DrawBox(0, 0, WIDTH, HEIGTH, dxlib_d.dxlib.GetColor(Color, 0, 0), dxlib_d.dxdatatype.TRUE); 272 .Count++; 273 } 274 275 // テキストバッファの描画 276 for (size_t i = 0; i < .StringBuf.length; i++) { 277 dxlib_d.dxlib.DrawString(8, cast(int)(i * .MOJI_SIZE), &(.StringBuf[i][0]), dxlib_d.dxlib.GetColor(255, 255, 255)); 278 } 279 280 // 裏画面の内容を表画面に反映させる 281 dxlib_d.dxlib.ScreenFlip(); 282 } 283 284 // ソフトの終了 285 return 0; 286 } 287 288 // テキストバッファの改行処理関数 289 nothrow @nogc 290 void Kaigyou() 291 292 do 293 { 294 // 描画行位置を1つ下げる 295 .CursorY++; 296 297 // 描画列を最初に戻す 298 .CursorX = 0; 299 .CursorX_CP = 0; 300 301 // もしテキストバッファ縦幅からはみ出るならテキストバッファを縦スクロールさせる 302 if (.CursorY >= .StringBuf.length) { 303 for (size_t i = 1; i < .StringBuf.length; i++) { 304 for (size_t j = 0; j < (StringBuf[i - 1].length - 1); j++) { 305 .StringBuf[i - 1][j] = .StringBuf[i][j]; 306 } 307 } 308 309 // 描画行位置を1つあげる 310 .CursorY--; 311 } 312 }