game.cpp
1    //ゲーム処理のソースファイル
2    
3    #include "game.h"
4    #include "System/font.h"
5    #include "geometory.h"
6    #include "Game/Ball.h"
7    #include "System/key.h"
8    #include "System/mouse.h"
9    #include "System/music.h"
10   #include "Game/Block.h"
11   #include "System/Button.h"
12   #include "System/fps.h"
13   
14   //ゲームシーン
15   enum E_GameScene NowGameScene;	//現在のゲームシーン
16   
17   RECT GameWindow;            //ゲームウィンドウの矩形
18   HWND GameHandle;	            //ゲームのウィンドウハンドル
19   
20   bool Isfade;    //フェード中かどうか
21   int ScreenFadeInMillTime;       //フェードインの時間
22   int ScreenFadeInMillTimeMax;    //フェードインの最大時間
23   int ScreenFadeOutMillTime;      //フェードアウトの時間
24   int ScreenFadeOutMillTimeMax;   //フェードアウトの最大時間
25   
26   
27   //ゲームシーンの名前
28   const char GameSceneName[GAME_SCENE_COUNT][GAME_SCENE_TEXT_MAX] =
29   {
30       "タイトル画面",
31       "プレイ画面",
32       "リザルト画面"
33   };
34   //スタートボタンの作成
35   Button startButton= {RECT{(GAME_WIDTH/2)-100, (GAME_HEIGHT/2)+150,
36       (GAME_WIDTH/2)+100,(GAME_HEIGHT/2)+200},
37       Color{255,0,0},"Start",fontDotSmall};
38   
39   //リスタートボタンの作成
40   Button restartButton= {RECT{(GAME_WIDTH/2)-250, (GAME_HEIGHT/2)+150,
41       (GAME_WIDTH/2)-50,(GAME_HEIGHT/2)+200},
42       Color{255,0,0},"Restart",fontDotSmall};
43   
44   //タイトルボタンの作成
45   Button titleButton= {RECT{(GAME_WIDTH/2)+50, (GAME_HEIGHT/2)+150,
46       (GAME_WIDTH/2)+250,(GAME_HEIGHT/2)+200},
47       Color{255,0,0},"Title",fontDotSmall};
48   
49   //終了ボタンの作成
50   Button endButton= {RECT{(GAME_WIDTH/2)-100, (GAME_HEIGHT/2)+250,
51       (GAME_WIDTH/2)+100,(GAME_HEIGHT/2)+300},
52       Color{255,0,0},"Quit",fontDotSmall};
53   
54   
55   // ゲーム初期化関数
56   void InitGame()
57   {
58       //ゲーム画面ハンドルを取得
59       GameHandle = GetMainWindowHandle();
60   
61       //ゲームウィンドウの矩形を取得
62       GameWindow = GetRect(0,0,GAME_WIDTH,GAME_HEIGHT);
63       
64       //最初のシーンを設定
65       NowGameScene = E_GameScene::TitleScene;
66   
67       //ボールとブロックの初期化
68       ball.Ball_Init();
69       block.Block_Init();
70       
71   }
72   
73   //ゲームとDxLibの終了処理
74   void GameAndDxLibAllEnd()
75   {
76       //フォントの終了処理
77       FontEnd();
78   
79       //Musicの終了処理
80       MusicEnd();
81   	
82       //DxLib終了する
83       DxLib_End();
84   }
85   
86   // ゲームハンドル取得
87   HWND GetGameHandle()
88   {
89       return GameHandle;
90   }
91   
92   // ゲームウィンドウ取得
93   RECT GetGameWindow()
94   {
95       return GameWindow;
96   }
97   
98   /// 初期化関数
99   /// @param scene シーンの種類
100  void InitScene(E_GameScene scene)
101  {
102      //ブレンドモードの設定
103      SetDrawBlendMode(DX_BLENDMODE_ALPHA, 255);
104      //デバッグモードが有効なら
105      if (GAME_DEBUG_MODE == TRUE)
106      {
107          //初期化中のシーン名を表示
108          DrawFormatString(GAME_WIDTH - 200, 0, GetColor(255, 255, 255),
109              "%s%s", GameSceneName[static_cast<int>(scene)], "初期化");
110      }
111  
112      //該当シーンになったときの初期化処理
113      switch (scene)
114      {
115          
116      case E_GameScene::PlayScene:
117          // プレイシーンでブロックの初期化
118          break;
119      }
120  }
121  
122  /// 制御関数
123  /// @param scene シーンの種類
124  void CtrlScene(E_GameScene scene)
125  {
126      ProcScene(scene);
127      DrawScene(scene);
128  }
129  
130  /// 処理関数
131  /// @param scene シーンの種類
132  void ProcScene(E_GameScene scene)
133  {
134  
135      //該当シーンになったときの処理
136      switch (scene)
137      {
138      case E_GameScene::TitleScene:
139          // タイトルシーンの処理
140              //音楽を再生
141                  MusicPlay(titleBGM);
142          //スタートボタンが押されたら
143          startButton.CollButtonToMouseClick(MOUSE_INPUT_LEFT);
144              
145          //スタートボタンの処理部分
146          if(startButton.IsOnceClick())
147          {
148              //スタートボタンを無効化する
149              startButton.SetActive(false);
150              //BGMのフェードアウト
151              FadeOutPlayMusic(&titleBGM,1000);
152              if (FadeInScene(1000)==true)
153              {
154                  //スタートボタンを有効化する
155                  startButton.ResetOnceClick();
156                  startButton.SetActive(true);
157                  //音楽を停止
158                  MusicStop(&titleBGM);
159                  NowGameScene = E_GameScene::PlayScene;
160                  //初期化
161                  InitScene(NowGameScene);
162                  //もしPlaySceneがゲーム終了後なら
163                  if(GameEnd()==true)
164                  {
165                      //ボールとブロックを再設置
166                      ball.Ball_Init();
167                      block.Block_Init();
168                  }
169              }
170          }
171  
172          //終了ボタンの処理部分
173          endButton.CollButtonToMouseClick(MOUSE_INPUT_LEFT);
174          if(endButton.IsOnceClick())
175          {
176              //終了ボタンを無効化する
177              endButton.SetActive(false);
178              //BGMのフェードアウト
179              FadeOutPlayMusic(&titleBGM,1000);
180              if (FadeInScene(1000)==true)
181              {
182                  //終了ボタンを有効化する
183                  endButton.ResetOnceClick();
184                  endButton.SetActive(true);
185                  //音楽を停止
186                  MusicStop(&titleBGM);
187                  //ゲームとDxLibの終了処理
188                  GameAndDxLibAllEnd();
189              }
190          }
191          break;
192          
193      case E_GameScene::PlayScene:
194          // プレイシーンの処理
195              //音楽を再生
196                  MusicPlay(playBGM);
197  
198          //タイトルボタンの位置
199          titleButton.SetPosition(RECT{(GAME_WIDTH/2)+50, (GAME_HEIGHT/2)+150,
200      (GAME_WIDTH/2)+250,(GAME_HEIGHT/2)+200});
201          
202          //ゲームオーバーになったらブロックとボールを再設置
203          if(GameEnd()==true)
204          {
205              //リスタートボタンをを押したか
206              restartButton.CollButtonToMouseClick(MOUSE_INPUT_LEFT);
207              //タイトルボタンを押したか
208              titleButton.CollButtonToMouseClick(MOUSE_INPUT_LEFT);
209              //バーを動かなくする
210              block.SetBarMove(false);
211              //ボールのスピードを0にする
212              ball.SetSpeed(0,0);
213              
214              //リスタートボタンが一度でも押されたらボールとブロックを再設置
215              if(restartButton.IsOnceClick())
216              {
217                  ball.Ball_Init();
218                  block.Block_Init();
219                  //リスタートボタンを有効化する
220                  restartButton.ResetOnceClick();
221              }
222              //タイトルボタンが一度でも押されたら
223              if(titleButton.IsOnceClick())
224              {
225                  //titleButtonを無効化
226                  titleButton.SetActive(false);
227                  
228                  //BGMのフェードアウト
229                  FadeOutPlayMusic(&playBGM,1000);
230                  if (FadeInScene(1000)==true)
231                  {
232                      //タイトルボタンを有効化する
233                      titleButton.ResetOnceClick();
234                      titleButton.SetActive(true);
235                      //音楽を停止
236                      MusicStop(&playBGM);
237                      NowGameScene = E_GameScene::TitleScene;
238                      //初期化
239                      InitScene(NowGameScene);
240                  }
241              }
242          }
243          //ブロックの計算
244          block.Block_Cal();
245          //ボールの計算
246          ball.Ball_Cal();
247  
248          //ゲームクリアになったら
249          if(IsGameClear()==true)
250          {
251              //BGMのフェードアウト
252              FadeOutPlayMusic(&playBGM,1000);
253              if (FadeInScene(1000)==true)
254              {
255                  //音楽を停止
256                  MusicStop(&playBGM);
257                  NowGameScene = E_GameScene::ResultScene;
258                  //初期化
259                  InitScene(NowGameScene);
260              }
261          }
262          //デバッグ用
263          if(GAME_DEBUG_MODE)
264          {
265              //スペースキーを押したらシーンの移動
266              if (KeyDown(KEY_INPUT_SPACE))
267              {
268                  //BGMのフェードアウト
269                  FadeOutPlayMusic(&playBGM,1000);
270                  if (FadeInScene(1000)==true)
271                  {
272                      //音楽を停止
273                      MusicStop(&playBGM);
274                      NowGameScene = E_GameScene::ResultScene;
275                      //初期化
276                      InitScene(NowGameScene);
277                  }
278              }
279          }
280          
281              break;
282          case E_GameScene::ResultScene:
283              // リザルトシーンの処理
284              //音楽を再生
285              MusicPlay(resultBGM);
286  
287          //タイトルボタンの位置
288          titleButton.SetPosition(RECT{(GAME_WIDTH/2)-100, (GAME_HEIGHT/2)+150,
289      (GAME_WIDTH/2)+100,(GAME_HEIGHT/2)+200});
290          
291          //タイトルボタンを押したか
292          titleButton.CollButtonToMouseClick(MOUSE_INPUT_LEFT);
293          //タイトルボタンが一度でも押されたら
294          if(titleButton.IsOnceClick())
295          {
296              //titleButtonを無効化
297              titleButton.SetActive(false);
298                  
299              //BGMのフェードアウト
300              FadeOutPlayMusic(&resultBGM,1000);
301              if (FadeInScene(1000)==true)
302              {
303                  //タイトルボタンを有効化する
304                  titleButton.ResetOnceClick();
305                  titleButton.SetActive(true);
306                  //音楽を停止
307                  MusicStop(&resultBGM);
308                  NowGameScene = E_GameScene::TitleScene;
309                  //初期化
310                  InitScene(NowGameScene);
311              }
312          }
313  
314          //終了ボタンの処理部分
315          endButton.CollButtonToMouseClick(MOUSE_INPUT_LEFT);
316          if(endButton.IsOnceClick())
317          {
318              //終了ボタンを無効化する
319              endButton.SetActive(false);
320              //BGMのフェードアウト
321              FadeOutPlayMusic(&resultBGM,1000);
322              if (FadeInScene(1000)==true)
323              {
324                  //終了ボタンを有効化する
325                  endButton.ResetOnceClick();
326                  endButton.SetActive(true);
327                  //音楽を停止
328                  MusicStop(&resultBGM);
329                  //ゲームとDxLibの終了処理
330                  GameAndDxLibAllEnd();
331              }
332          }
333              break;
334      }
335     
336  }
337  
338  /// 描画関数
339  /// @param scene シーンの種類
340  void DrawScene(E_GameScene scene)
341  {
342  
343      switch (scene)
344      {
345          // タイトルシーンの場合
346          case E_GameScene::TitleScene:
347              // 背景色を設定
348              DrawBox(0, 0,GAME_WIDTH,GAME_HEIGHT, GetColor(178, 216, 255), TRUE);
349              // タイトル文字の描画
350              DrawFormatStringToHandle(GAME_WIDTH / 2-170, GAME_HEIGHT/2-200, GetColor(255, 255, 255),
351              fontDotLarge.Handle,"ブロック崩し");
352              // スタートボタンの描画
353              startButton.Button_Draw();
354              startButton.SetText("Start",fontDotSmall);
355              //終了ボタンの描画
356              endButton.Button_Draw();
357              endButton.SetText("Quit",fontDotSmall);
358              break;
359          
360          // プレイシーンの場合
361          case E_GameScene::PlayScene:
362              // 背景色を設定
363              DrawBox(0, 0,GAME_WIDTH,GAME_HEIGHT, GetColor(210, 105, 30), TRUE);
364              // ブロックの描画
365              block.Block_Draw();
366              ball.Ball_Draw();
367              //ゲームオーバーになったらブロックとボールを再設置
368              if(GameEnd()==true)
369              {
370                  //リスタートボタンの描画
371                  restartButton.Button_Draw();
372                  restartButton.SetText("Restart",fontDotSmall);
373  
374                  //タイトルボタンの描画
375                  titleButton.Button_Draw();
376                  titleButton.SetText("Title",fontDotSmall);
377              }
378          break;
379  
380          // リザルトシーンの場合
381          case E_GameScene::ResultScene:
382              // 背景色を設定
383              DrawBox(0, 0,GAME_WIDTH,GAME_HEIGHT, GetColor(211, 211, 211), TRUE);
384              // クリア文字の描画
385              DrawFormatStringToHandle(GAME_WIDTH / 2 - 170, GAME_HEIGHT/2 - 200, GetColor(255, 255, 255),
386              fontDotLarge.Handle,"Game Clear!!");
387              //タイトルボタンの描画
388              titleButton.Button_Draw();
389              titleButton.SetText("Title",fontDotSmall);
390              //終了ボタンの描画
391              endButton.Button_Draw();
392              endButton.SetText("Quit",fontDotSmall);
393              break;    
394          }
395  
396          // デバックモードが有効なら
397          if(GAME_DEBUG_MODE)
398          {
399              // シーン名を表示
400              DrawFormatStringToHandle(GAME_WIDTH - 200, 0, GetColor(255, 255, 255),
401                  fontDotSmall.Handle,
402                  "%s%s", GameSceneName[static_cast<int>(scene)], "描画中");
403          }
404      
405  }
406  
407  // ゲームオーバーの処理
408  bool GameEnd()
409  {
410      bool endFlag = false;
411  
412      //ボールが落ちてしまった場合
413      if (ball.GetCircle().pt.y > GAME_HEIGHT)
414      {
415          endFlag = true;
416      }
417      
418      return endFlag;
419  }
420  
421  // ゲームクリアの処理
422  bool IsGameClear()
423  {
424      bool endFlag = true;
425      // ゲームオーバーの処理
426      for (int y=0;y<BLOCK_NUM_Y;y++)
427      {
428          for (int x=0;x<BLOCK_NUM_X;x++)
429          {
430              // 一つでもブロックがある場合ゲームを続ける
431              if (block.GetBlock(x,y).isAlive == true)
432              {
433                  endFlag = false;
434                  break;
435              }
436          }
437      }
438      
439      return endFlag;
440  }
441  
442  // シーン切り替え関数
443  void SwitchScene()
444  {
445      CtrlScene(NowGameScene);
446  }
447  
448  /// 
449  /// @param fadeInFrame フェードに使う時間(1000=1秒)
450  /// @return true フェードイン終了 false フェードイン中
451  bool FadeInScene(int fadeInFrame)
452  {
453      //初めてフェードインを行う
454      if (!Isfade)
455      {
456          //フェードイン時間を設定
457          ScreenFadeInMillTime = 0;
458          ScreenFadeInMillTimeMax = (fadeInFrame/1000.0f) * GAME_FPS;
459          SetDrawBlendMode(DX_BLENDMODE_ALPHA, 255);
460          //フェードイン開始
461          Isfade = true;
462      }
463  
464      //フェードイン中
465      if(Isfade)
466      {
467          if(ScreenFadeInMillTime <= ScreenFadeInMillTimeMax)
468          {
469              //フェードイン時間をカウントアップ
470              ScreenFadeInMillTime++;
471              
472              //ブレンドモードを設定(255 - 経過時間/最大時間 * 最大アルファ値)
473              SetDrawBlendMode(DX_BLENDMODE_ALPHA,255 - (float)ScreenFadeInMillTime/ScreenFadeInMillTimeMax * 255 );
474              
475          }
476          else if(ScreenFadeInMillTime >= ScreenFadeInMillTimeMax)
477          {
478              //フェードイン終了
479              Isfade = false;
480              return true;
481          }
482      }
483      return false;
484  }
485  
486  ///
487  /// @param fadeOutFrame フェードに使う時間(1000=1秒)
488  /// @return true フェードアウト終了 false フェードアウト中
489  bool FadeOutScene(int fadeOutFrame)
490  {
491      //初めてフェードインを行う
492      if (!Isfade)
493      {
494          //フェードイン時間を設定
495          ScreenFadeInMillTime = 0;
496          ScreenFadeInMillTimeMax = (fadeOutFrame/1000.0f) * GAME_FPS;
497          SetDrawBlendMode(DX_BLENDMODE_ALPHA, 255);
498          //フェードイン開始
499          Isfade = true;
500      }
501  
502      //フェードイン中
503      if(Isfade)
504      {
505          if(ScreenFadeInMillTime <= ScreenFadeInMillTimeMax)
506          {
507              //フェードイン時間をカウントアップ
508              ScreenFadeInMillTime++;
509              
510              //ブレンドモードを設定(経過時間/最大時間 * 最大アルファ値)
511              SetDrawBlendMode(DX_BLENDMODE_ALPHA, (float)ScreenFadeInMillTime/ScreenFadeInMillTimeMax * 255 );
512              
513          }
514          else if(ScreenFadeInMillTime >= ScreenFadeInMillTimeMax)
515          {
516              //フェードイン終了
517              Isfade = false;
518              return true;
519          }
520      }
521      return false;
522  }
523