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