質問するログイン新規登録

質問編集履歴

2

コードの追加

2021/02/16 07:20

投稿

sinigami
sinigami

スコア6

title CHANGED
File without changes
body CHANGED
@@ -28,7 +28,156 @@
28
28
  KEY_INPUT_J, // Jキー取得
29
29
  KEY_INPUT_I // Iキー取得
30
30
  };
31
+
32
+ struct MUGIC_DATA
33
+ {
34
+ double bpm = 120; // BPMが指定されていなければ120に設定
35
+ double offset = 0; // ノーツが出現する時間が指定されていなければ
36
+ char song_name[MAX_READ] = "shinigamitowaltz.mp3"; // 曲名
37
+ char music_file_path[MAX_READ]; // ファイルのパス名
38
+ double perfect_times[LANE_NUM][NOTE_NUM] = { 0 }; // 判定ラインにノーツが到達する時刻
39
+ int perfect_time_size[LANE_NUM] = { 0 }; // 初期化処理の0と入ってくる0とを区別する
40
+ };
41
+
42
+ // #STARTより上の情報を読み込む
43
+ bool loadHumenOptions(MUGIC_DATA* music_data, FILE* fp)
44
+ {
45
+ char str[MAX_READ], *next_token = NULL, tstr[MAX_READ];
46
+ while ((fgets(str, MAX_READ, fp)) != NULL)
47
+ {
48
+ strncpy_s(tstr, MAX_READ, str, 6);
49
+ if (strcmp(tstr, "#START") == 0)
50
+ {
51
+ return true;
52
+ }
53
+
54
+ char* first = strtok_s(str, ":", &next_token);
55
+ if (first == NULL) continue;
56
+
57
+ if (strcmp(first, "BPM") == 0) // BPM読み込み
58
+ {
59
+ char* second = strtok_s(NULL, ":", &next_token);
60
+ music_data->bpm = atof(second);
61
+ }
62
+ else if (strcmp(first, "OFFSET") == 0) // OFFSET読み込み
63
+ {
64
+ char* second = strtok_s(NULL, ":", &next_token);
65
+ music_data->offset = atof(second);
66
+ }
67
+ else if (strcmp(first, "TITLE") == 0) // TITLE読み込み
68
+ {
69
+ char* second = strtok_s(NULL, "\n", &next_token);
70
+ strcpy_s(music_data->song_name, second);
71
+ }
72
+ else if (strcmp(first, "WAVE") == 0) // WAVE読み込み
73
+ {
74
+ char* second = strtok_s(NULL, "\n", &next_token);
75
+ strcpy_s(music_data->music_file_path, second);
76
+ }
77
+ }
78
+ return false;
79
+ }
80
+
81
+ // 譜面データを読み込む
82
+ void loadHumen(MUGIC_DATA* music_data, FILE* fp)
83
+ {
84
+ char line[MAX_READ], *next_token = NULL, delim[4] = ", \n";
85
+
86
+ for (int col = 0; col < LANE_NUM; col++)
87
+ {
88
+ music_data->perfect_time_size[col] = 0;
89
+ }
90
+
91
+ for (int row = 0; (fgets(line, MAX_READ, fp)) != NULL; row++)
92
+ {
93
+ char* str = strtok_s(line, delim, &next_token);
94
+ if (str == NULL) continue;
95
+
96
+ for (int col = 0; str != NULL; col++)
97
+ {
98
+ int length = strlen(str);
99
+ for (int i = 0; i < length; i++)
100
+ {
101
+ if ('1' <= str[i] && str[i] <= '9')
102
+ {
103
+ music_data->perfect_times[col][music_data->perfect_time_size[col]++] =
104
+ 60.0 * 4 * (row + (double)i / length) / music_data->bpm - music_data->offset;
105
+ }
106
+ }
107
+ str = strtok_s(NULL, delim, &next_token);
108
+ }
109
+ }
110
+ }
111
+
112
+ // 譜面データファイルのopen/closeをする処理
113
+ bool loadHumenData(MUGIC_DATA* music_data, const char* file_name)
114
+ {
115
+ FILE* fp;
116
+
117
+ if ((fopen_s(&fp, file_name, "r")) != 0 || fp == 0)
118
+ { // "fpが0である可能性があります"というエラー対策
119
+ return false; // boolはC++
120
+ }
121
+
122
+ bool loadable = loadHumenOptions(music_data, fp);
123
+
124
+ if (loadable) loadHumen(music_data, fp);
125
+
126
+ fclose(fp);
127
+ return true;
128
+ }
129
+
130
+ // ノーツの構造体
131
+ struct NOTE
132
+ {
133
+ bool flag = false;
134
+ float x = 0.0f;
135
+ float y = 0.0f;
136
+ };
137
+
138
+ // ノーツ初期化処理
139
+ void initNotes(int perfect_time_size[LANE_NUM], NOTE notes[LANE_NUM][NOTE_NUM])
140
+ {
141
+ for (int col = 0; col < LANE_NUM; col++)
142
+ {
143
+ int lane_length = perfect_time_size[col];
144
+
31
- ----------------------------------------------
145
+ for (int row = 0; row < lane_length; row++)
146
+ {
147
+ notes[col][row].flag = true;
148
+ notes[col][row].x = 200.0f + 150.0f * col;
149
+ }
150
+ }
151
+ }
152
+
153
+ // ノーツ更新処理
154
+ void updateNotes(double current_time, double perfect_times[LANE_NUM][NOTE_NUM], NOTE notes[LANE_NUM][NOTE_NUM])
155
+ {
156
+ // ノーツ座標更新
157
+ for (int col = 0; col < LANE_NUM; col++)
158
+ {
159
+ for (int row = 0; row < NOTE_NUM; row++)
160
+ {
161
+ if (notes[col][row].flag)
162
+ notes[col][row].y = JUDGE_Y * (float)(current_time - perfect_times[col][row]) / 2 + JUDGE_Y;
163
+ }
164
+ }
165
+
166
+ // 画面外かつ判定範囲外に出たノーツを削除
167
+ for (int col = 0; col < LANE_NUM; col++)
168
+ {
169
+ for (int row = 0; row < NOTE_NUM; row++)
170
+ {
171
+ if (notes[col][row].flag
172
+ && WIN_H + NOTE_HEIGHT < notes[col][row].y
173
+ && 0.3 < current_time - perfect_times[col][row])
174
+ {
175
+ notes[col][row].flag = false; // ノーツを削除
176
+ }
177
+ }
178
+ }
179
+ }
180
+
32
181
  // ノーツ判定処理
33
182
  void judgeNotes(double current_time, double perfect_times[LANE_NUM][NOTE_NUM], NOTE notes[LANE_NUM][NOTE_NUM], char buf[256])
34
183
  {
@@ -39,14 +188,185 @@
39
188
  {
40
189
  if (buf[KEYS[col]] == 1 // KEYS[4] = E,F,J,Iが押されている
41
190
  && notes[col][row].flag // ノーツが存在している
42
- && -0.01 < current_time - perfect_times[col][row] // -0.01...判定線より上の判定時間
191
+ && -0.03 < current_time - perfect_times[col][row] // -0.03...判定線より上の判定時間
43
- && current_time - perfect_times[col][row] < 0.01) // 0.01...判定線より下の判定時間
192
+ && current_time - perfect_times[col][row] < 0.03) // 0.03...判定線より下の判定時間
44
193
  {
45
194
  notes[col][row].flag = false; // ノーツを削除
46
195
  }
47
196
  }
48
197
  }
49
198
  }
199
+
200
+ // ノーツ描画処理
201
+ void drawNotes(NOTE notes[LANE_NUM][NOTE_NUM])
202
+ {
203
+ for (int col = 0; col < LANE_NUM; col++)
204
+ {
205
+ for (int row = 0; row < NOTE_NUM; row++)
206
+ {
207
+ if (notes[col][row].flag) // ノーツが存在している
208
+ {
209
+ DrawBoxAA(notes[col][row].x,
210
+ notes[col][row].y - NOTE_HEIGHT / 4, // / 2,
211
+ notes[col][row].x + NOTE_WIDTH,
212
+ notes[col][row].y + NOTE_HEIGHT / 4, // / 2,
213
+ GetColor(255, 0, 0), // ノーツの色指定(Red,Green,Blue : 0~255)
214
+ TRUE);
215
+ //DrawCircleAA(notes[col][row].x, // 円の中心座標x
216
+ // notes[col][row].y - NOTE_HEIGHT / 2, // 円の中心座標y
217
+ // 20, // 円の半径(大きさ)
218
+ // 20, // 円の角の数(多いほど滑らかな円になるが処理が重くなる)
219
+ // GetColor(255, 0, 0), // ノーツの色指定(Red,Green,Blue : 0~255)
220
+ // TRUE); // 円の内部まで塗りつぶすか(TRUEで塗りつぶし)
221
+ }
222
+ }
223
+ }
224
+ }
225
+
226
+ // 処理を変更したい場合、WINAPIも変更する
227
+ // 上で行った処理を呼び出す
228
+ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
229
+ {
230
+
231
+ MUGIC_DATA music_data;
232
+ NOTE notes[LANE_NUM][NOTE_NUM];
233
+ char buf[256]; //キー押下状態格納用配列
234
+
235
+ SetMainWindowText("KeyBorder"); //ウインドウのタイトルを設定
236
+ ChangeWindowMode(TRUE); //ウィンドウモードで起動
237
+ SetGraphMode(WIN_W, WIN_H, 32); //画面の解像度指定
238
+ SetWindowSizeChangeEnableFlag(FALSE); //画面サイズ変更不可
239
+ if (DxLib_Init() == -1) { return -1; } //DxLib初期化処理
240
+ SetDrawScreen(DX_SCREEN_BACK); //描画先を裏画面に設定
241
+
242
+ loadHumenData(&music_data, "test.txt"); // 譜面データ読み込み
243
+
244
+ initNotes(music_data.perfect_time_size, notes); // ノーツ初期化処理
245
+
246
+ int bgmHandle = LoadSoundMem(music_data.music_file_path);
247
+ PlaySoundMem(bgmHandle, DX_PLAYTYPE_BACK);
248
+
249
+ LONGLONG start_count = GetNowHiPerformanceCount();
250
+
251
+ //while(裏画面を表画面に反映, メッセージ処理, 画面クリア)
252
+ while (ScreenFlip() == 0 && ProcessMessage() == 0 && ClearDrawScreen() == 0)
253
+ {
254
+
255
+ GetHitKeyStateAll(buf);
256
+ if (buf[KEY_INPUT_ESCAPE] == 1) // ESACAPEキーが押された時
257
+ {
258
+ break; // 終了
259
+ }
260
+
261
+ LONGLONG now_count = GetNowHiPerformanceCount();
262
+ double current_time = (now_count - start_count) / 1000000.0;
263
+
264
+ // ノーツの更新処理
265
+ updateNotes(current_time,
266
+ music_data.perfect_times,
267
+ notes);
268
+
269
+ // ノーツの判定処理
270
+ judgeNotes(current_time,
271
+ music_data.perfect_times,
272
+ notes, buf);
273
+
274
+ // 判定線表示
275
+ DrawLine(
276
+ 0,
277
+ JUDGE_Y,
278
+ WIN_W,
279
+ JUDGE_Y,
280
+ GetColor(0, 0, 255) // 判定線のRGB指定
281
+ );
282
+
283
+ // 境界線表示
284
+ // 1レーン目
285
+ DrawLine(
286
+ 200, // 第一X(右)方向座標 X方向への境界線表示位置1
287
+ 0, // 第一Y(上)方向座標 Y方向への境界線表示位置1
288
+ 200, // 第二X(右)方向座標 X方向への境界線表示位置2
289
+ 500, // 第二Y(上)方向座標 Y方向への境界線表示位置2
290
+ GetColor(0, 255, 0) // 境界線のRGB指定
291
+ );
292
+
293
+ DrawLine(
294
+ 270, // 第一X(右)方向座標 X方向への境界線表示位置1
295
+ 0, // 第一Y(上)方向座標 Y方向への境界線表示位置1
296
+ 270, // 第二X(右)方向座標 X方向への境界線表示位置2
297
+ 500, // 第二Y(上)方向座標 Y方向への境界線表示位置2
298
+ GetColor(0, 255, 0) // 境界線のRGB指定
299
+ );
300
+
301
+ // 2レーン目
302
+ DrawLine(
303
+ 350, // 第一X(右)方向座標 X方向への境界線表示位置1
304
+ 0, // 第一Y(上)方向座標 Y方向への境界線表示位置1
305
+ 350, // 第二X(右)方向座標 X方向への境界線表示位置2
306
+ 500, // 第二Y(上)方向座標 Y方向への境界線表示位置2
307
+ GetColor(0, 255, 0) // 境界線のRGB指定
308
+ );
309
+
310
+ DrawLine(
311
+ 420, // 第一X(右)方向座標 X方向への境界線表示位置1
312
+ 0, // 第一Y(上)方向座標 Y方向への境界線表示位置1
313
+ 420, // 第二X(右)方向座標 X方向への境界線表示位置2
314
+ 500, // 第二Y(上)方向座標 Y方向への境界線表示位置2
315
+ GetColor(0, 255, 0) // 境界線のRGB指定
316
+ );
317
+
318
+ // 3レーン目
319
+ DrawLine(
320
+ 500, // 第一X(右)方向座標 X方向への境界線表示位置1
321
+ 0, // 第一Y(上)方向座標 Y方向への境界線表示位置1
322
+ 500, // 第二X(右)方向座標 X方向への境界線表示位置2
323
+ 500, // 第二Y(上)方向座標 Y方向への境界線表示位置2
324
+ GetColor(0, 255, 0) // 境界線のRGB指定
325
+ );
326
+
327
+ DrawLine(
328
+ 570, // 第一X(右)方向座標 X方向への境界線表示位置1
329
+ 0, // 第一Y(上)方向座標 Y方向への境界線表示位置1
330
+ 570, // 第二X(右)方向座標 X方向への境界線表示位置2
331
+ 500, // 第二Y(上)方向座標 Y方向への境界線表示位置2
332
+ GetColor(0, 255, 0) // 境界線のRGB指定
333
+ );
334
+
335
+ // 4レーン目
336
+ DrawLine(
337
+ 650, // 第一X(右)方向座標 X方向への境界線表示位置1
338
+ 0, // 第一Y(上)方向座標 Y方向への境界線表示位置1
339
+ 650, // 第二X(右)方向座標 X方向への境界線表示位置2
340
+ 500, // 第二Y(上)方向座標 Y方向への境界線表示位置2
341
+ GetColor(0, 255, 0) // 境界線のRGB指定
342
+ );
343
+
344
+ DrawLine(
345
+ 720, // 第一X(右)方向座標 X方向への境界線表示位置1
346
+ 0, // 第一Y(上)方向座標 Y方向への境界線表示位置1
347
+ 720, // 第二X(右)方向座標 X方向への境界線表示位置2
348
+ 500, // 第二Y(上)方向座標 Y方向への境界線表示位置2
349
+ GetColor(0, 255, 0) // 境界線のRGB指定
350
+ );
351
+
352
+ DrawFormatString(
353
+ 10,
354
+ 10,
355
+ GetColor(255, 255, 255),
356
+ "t:%f\nbpm:%f\noffset:%f\n%s\n%s",
357
+ current_time,
358
+ music_data.bpm,
359
+ music_data.offset,
360
+ music_data.song_name,
361
+ music_data.music_file_path
362
+ );
363
+
364
+ // ノーツの表示
365
+ drawNotes(notes);
366
+ }
367
+ DxLib_End(); //DxLibの終了処理
368
+ return 0; //正常終了
369
+ }
50
370
  ```
51
371
 
52
372
  ----------------------------------------------

1

コードの挿入で見やすく改善

2021/02/16 07:20

投稿

sinigami
sinigami

スコア6

title CHANGED
File without changes
body CHANGED
@@ -7,6 +7,7 @@
7
7
  キーを長押ししているとその間ノーツが削除されてしまう。
8
8
 
9
9
  ### 該当のソースコード
10
+ ```
10
11
  C++, dx.lib
11
12
  ----------------------------------------------
12
13
  #include "DxLib.h"
@@ -46,6 +47,8 @@
46
47
  }
47
48
  }
48
49
  }
50
+ ```
51
+
49
52
  ----------------------------------------------
50
53
  ### 試したこと
51
54