MMDゲーム化計画@wiki

フレームワーク

最終更新:

mmdgame

- view
だれでも歓迎! 編集

技術指南/フレームワーク

ここではゲームを作るにあたって共通して使われるコンポーネント?要素技術について紹介します。
ただ,ここに上げる要素技術は作る人によって違いどれが正解とも言えないです。まさに十人十色。
今回は実装の一例として紹介します。これを元に自分の使いやすいクラスを作るべきだともいます。

※ただしここにあるソースは一部開発中もモノも含まれていますので利用する場合は適宜調整をお願いします




FPSクラス
まずなんといってもゲームにはFPSの管理が必要です
FPS(Frames Per Second)で一秒あたりの画面更新回数みたいなもんです
大抵のゲームはFPS60とかですが一部処理が重いものはFPS30まで制限しているものもあります
MMDゲームを作る場合はFPS30になることが多いと思います。単純にMMDモデルが重いからです。
FPSには大体2通りあると思います。ひとつは固定型,もう一つは可変型です。
固定型は処理落ちしない限りそのFPSで回り、正確にゲーム内の処理Stepで処理したいときに適する
可変長は処理落ちするとそれに合わせてゲーム内の移動距離を変えてしまい安定しているように見せる

  • ソース(固定FPSタイプ)
    • Fps.h
+ ...
  1. #pragma once
  2. #include "dxlib.h"
  3. #define FLAME_MAX 60*10
  4. class Fps
  5. {
  6. private:
  7. int fps_count,count0t;//fpsのカウンタ、60フレームに1回基準となる時刻を記録する変数
  8. int f[FLAME_MAX];//平均を計算するため60回の1周時間を記録
  9. double ave;//平均fps
  10. int color[9];//表示用色
  11. int flame_0 ;
  12. int term_0;
  13. int max_fps;//設定された瞬時値最大FPS
  14. public:
  15. Fps();
  16. ~Fps();
  17. void fps_wait(int FLAME);//FPSの処理:FLAME=設定するFPS(ex.60)
  18. void draw_fps(int x, int y);//x,y座標にFPSを表示
  19. };
  20.  

    • Fps.cpp
+ ...
  1. #include "Fps.h"
  2. Fps::Fps(void)
  3. {
  4. //fpsのカウンタ、60フレームに1回基準となる時刻を記録する変数
  5. fps_count =0;
  6. count0t =0;
  7. ave =0;//平均fps
  8. color[0] = GetColor(255,255,255);//白
  9. color[1] = GetColor( 0, 0, 0);//黒
  10. color[2] = GetColor(255, 0, 0);//赤
  11. color[3] = GetColor( 0,255, 0);//緑
  12. color[4] = GetColor( 0, 0,255);//青
  13. color[5] = GetColor(255,255, 0);//黄色
  14. color[6] = GetColor( 0,255,255);//青緑
  15. color[7] = GetColor(255, 0,255);//紫
  16. color[8] = GetColor(100, 100,100);//灰色
  17. }
  18.  
  19. Fps::~Fps(void)
  20. {
  21. }
  22.  
  23. void LC_Fps::fps_wait(int FLAME)
  24. {
  25. this->flame_0 = FLAME;
  26. this->max_fps = FLAME;
  27. int term,i,gnt;
  28. static int t=0;
  29. if(fps_count==0){//FLAMEフレームの1回目なら
  30. if(t==0)//完全に最初ならまたない
  31. term=0;
  32. else//前回記録した時間を元に計算
  33. term=count0t+1000-GetNowCount();
  34. }else{//待つべき時間=現在あるべき時刻-現在の時刻
  35. term = (int)(count0t+fps_count*(1000.0/FLAME))-GetNowCount();
  36. }
  37. this->term_0 = term;
  38. if(term>0)//待つべき時間だけ待つ
  39. Sleep(term);
  40. gnt=GetNowCount();
  41. if(fps_count==0)//60フレームに1度基準を作る
  42. count0t=gnt;
  43. f[fps_count]=gnt-t;//1周した時間を記録
  44. t=gnt;
  45. //平均計算
  46. if(fps_count==FLAME-1){
  47. ave=0;
  48. for(i=0;i<FLAME;i++)
  49. ave+=f[i];
  50. ave/=FLAME;
  51. }
  52. fps_count = (++fps_count)%FLAME ;
  53. }
  54.  
  55. void LC_Fps::draw_fps(int x, int y)
  56. {
  57. if(ave!=0){
  58. if(1000/ave <this->max_fps*0.5f){//半分以下赤
  59. DrawFormatString(x, y,color[2],"[%.1f/%d]",1000/ave,this->max_fps);
  60. }else if(1000/ave <this->max_fps*0.85f){//85%のFPS黄色
  61. DrawFormatString(x, y,color[5],"[%.1f/%d]",1000/ave,this->max_fps);
  62. }else{ //通常の安定時緑
  63. DrawFormatString(x, y,color[3],"[%.1f/%d]",1000/ave,this->max_fps);
  64. }
  65. }
  66. return;
  67. }
  68.  

  • 使い方
  1. Fps fps;//定義
  2. ・・・中略
  3. fps.fps_wait(60);//60フレームで処理
  4. fps.draw_fps(0,460);//[0,460]の座標に表示
  5.  


PAD入力クラス
PADからの入力を処理するクラスについてです
ゲームだと,連射のように毎フレーム取得するものと押された瞬間など立ち上がりを検知する必要があります
以下のソースでは
  • 今の状態を取得するNow系関数(now_stickなど)
  • 押されたフレーム時にtrueとなるEdge系関数(edge_buttonなど)
の二種類が使えます
コマンドなどの処理もあるのですが個人的あまり使う機会がなかったので今はなしとします

  • ソース
    • Padinput.h
+ ...
  1. #pragma once
  2. #include "dxlib.h"
  3. class Padinput
  4. {
  5. private:
  6. int NowInput[5] ;//!< 現在の入力@[人数]
  7. int EdgeInput[5] ;//!< 現在のフレームで押されたボタンのみビットが立っている入力値
  8. int PadNumber; //!<1p@2p@3p@4p ?? 0==key
  9. int PadKnd[5];
  10. int MouseX , MouseY ;//!<マウス座標
  11. int M_NowInput, M_EdgeInput, M_NowRot , M_EdgeRot; //!<マウス入力
  12. int Input_histerisis[5][60];//!< 60フレーム分の履歴
  13. //
  14. bool check_button(int in , int num);//!<ボタン入力監視関数
  15. bool check_stick(int in , int num);//!<スティック監視関数@テンキー配置
  16. public:
  17. Padinput(void);
  18. ~Padinput(void);
  19. void input_Process();//!<周期入力監視関数
  20. void input_config();//!<キーボード割り当て
  21.  
  22. bool now_button(int id,int button_num);//!<現在のボタン入力取得
  23. bool edge_button(int id,int button_num);//!<現在入力されたボタン取得
  24. bool now_stick(int id,int stick_num);//!<現在のスティック取得
  25. bool edge_stick(int id,int stick_num);//!<現在入力されれたスティック取得
  26. //
  27. int get_NowInput(int num);
  28. };
  29.  

    • Padinput.cpp
+ ...
  1. #include "Padinput.h"
  2. Padinput::Padinput(void)
  3. {
  4. M_NowRot =0;
  5. M_EdgeRot =0;
  6. this->PadKnd[0] = DX_INPUT_KEY_PAD1;
  7. this->PadKnd[1] = DX_INPUT_PAD1 | DX_INPUT_KEY;//PAD1&キーボード@[0]と同じかも?
  8. this->PadKnd[2] = DX_INPUT_PAD2 | DX_INPUT_KEY;
  9. this->PadKnd[3] = DX_INPUT_PAD3;
  10. this->PadKnd[4] = DX_INPUT_PAD4;
  11. for(int i=0;i<5;i++)
  12. {
  13. for(int s= 0;s<60;s++)
  14. {
  15. this->Input_histerisis[i][s] =0 ;
  16. }
  17. }
  18. }
  19.  
  20. Padinput::~Padinput(void)
  21. {
  22. }
  23. bool Padinput::check_button(int in , int num)//!<ボタン入力監視関数
  24. {
  25. int f=0;
  26. switch(num)
  27. {
  28. case 0: f = (in>0)?1:0;//なにかの入力あり.
  29. case 1: f=in&PAD_INPUT_A;break;
  30. case 2: f=in&PAD_INPUT_B;break;
  31. case 3: f=in&PAD_INPUT_C;break;
  32. case 4: f=in&PAD_INPUT_X;break;
  33. case 5: f=in&PAD_INPUT_Y;break;
  34. case 6: f=in&PAD_INPUT_Z;break;
  35. case 7: f=in&PAD_INPUT_L;break;
  36. case 8: f=in&PAD_INPUT_R;break;
  37. case 9: f=in&PAD_INPUT_START;break;
  38. case 10: f=in&PAD_INPUT_M;break;
  39. }
  40. return (f>0? true:false);
  41. }
  42. bool Padinput::check_stick(int in , int num)//!<スティック監視関数@テンキー配置
  43. {
  44. int f=0;
  45. switch(num)
  46. {
  47. case 0: f=(in&PAD_INPUT_UP || in&PAD_INPUT_DOWN || in&PAD_INPUT_LEFT || in&PAD_INPUT_RIGHT);break;//何かの入力あり
  48. case 1: f=(in&PAD_INPUT_DOWN)*(in&PAD_INPUT_LEFT);break;
  49. case 2: f=in&PAD_INPUT_DOWN;break;
  50. case 3: f=(in&PAD_INPUT_DOWN)*(in&PAD_INPUT_RIGHT);break;
  51. case 4: f=in&PAD_INPUT_LEFT;break;
  52. case 5: f=!(in&PAD_INPUT_UP || in&PAD_INPUT_DOWN || in&PAD_INPUT_LEFT || in&PAD_INPUT_RIGHT);break;//ニュートラル判定
  53. case 6: f=in&PAD_INPUT_RIGHT;break;
  54. case 7: f=(in&PAD_INPUT_UP)*(in&PAD_INPUT_LEFT);break;
  55. case 8: f=in&PAD_INPUT_UP;break;
  56. case 9: f=(in&PAD_INPUT_UP)*(in&PAD_INPUT_RIGHT);break;
  57. }
  58. return (f>0? true:false);
  59. }
  60. void Padinput::input_Process()//!<周期入力監視関数
  61. {
  62. int Old ;
  63. // ひとつ前のフレームの入力を変数にとっておく
  64. for(int i=0;i<5;i++)
  65. {
  66. for(int s= 60-1-1;s>0;s--)
  67. {
  68. this->Input_histerisis[i][s] = this->Input_histerisis[i][s-1] ;
  69. }
  70. //
  71. Old = NowInput[i] ;
  72. // 現在の入力状態を取得
  73. NowInput[i] = GetJoypadInputState( this->PadKnd[i]/*DX_INPUT_KEY_PAD1*/ ) ;
  74. // 今のフレームで新たに押されたボタンのビットだけ立っている値を Edgepnput に代入する
  75. EdgeInput[i] = NowInput[i] & ~Old ;
  76. //
  77. this->Input_histerisis[i][0] = NowInput[i];
  78. }
  79. Old = M_NowInput;
  80. // マウスの位置を取得
  81. GetMousePoint( &MouseX , &MouseY ) ;
  82. M_NowInput = GetMouseInput() ;
  83. M_EdgeInput = M_NowInput & ~Old ;
  84. // 前回 GetMouseWheelRotVol が呼ばれてから今回までの回転量を足す
  85. M_EdgeRot = GetMouseWheelRotVol() ;
  86. M_NowRot += M_EdgeRot;
  87. }
  88. void Padinput::input_config()//!<キーボード割り当て
  89. {
  90. /*this->PadKnd[0] = DX_INPUT_KEY_PAD1;
  91. this->PadKnd[1] = DX_INPUT_PAD1 | DX_INPUT_KEY;//PAD1&キーボード@[0]と同じかも?
  92. this->PadKnd[2] = DX_INPUT_PAD2 | DX_INPUT_KEY;
  93. this->PadKnd[3] = DX_INPUT_PAD3;
  94. this->PadKnd[4] = DX_INPUT_PAD4;*/
  95. //// パッド1の十字ボタンの対応を変更
  96. SetJoypadInputToKeyInput( DX_INPUT_PAD1, PAD_INPUT_UP, KEY_INPUT_UP, -1, -1, -1 );
  97. SetJoypadInputToKeyInput( DX_INPUT_PAD1, PAD_INPUT_DOWN, KEY_INPUT_DOWN, -1, -1, -1 );
  98. SetJoypadInputToKeyInput( DX_INPUT_PAD1, PAD_INPUT_LEFT, KEY_INPUT_LEFT, -1, -1, -1 );
  99. SetJoypadInputToKeyInput( DX_INPUT_PAD1, PAD_INPUT_RIGHT, KEY_INPUT_RIGHT, -1, -1, -1 );
  100.  
  101. SetJoypadInputToKeyInput( DX_INPUT_PAD1, PAD_INPUT_A, KEY_INPUT_Z, -1, -1, -1 );
  102. SetJoypadInputToKeyInput( DX_INPUT_PAD1, PAD_INPUT_B, KEY_INPUT_X, -1, -1, -1 );
  103. SetJoypadInputToKeyInput( DX_INPUT_PAD1, PAD_INPUT_C, KEY_INPUT_C, -1, -1, -1 );
  104. SetJoypadInputToKeyInput( DX_INPUT_PAD1, PAD_INPUT_X, KEY_INPUT_A, -1, -1, -1 );
  105. SetJoypadInputToKeyInput( DX_INPUT_PAD1, PAD_INPUT_Y, KEY_INPUT_S, -1, -1, -1 );
  106. SetJoypadInputToKeyInput( DX_INPUT_PAD1, PAD_INPUT_Z, KEY_INPUT_D, -1, -1, -1 );
  107. SetJoypadInputToKeyInput( DX_INPUT_PAD1, PAD_INPUT_L, KEY_INPUT_Q, -1, -1, -1 );
  108. SetJoypadInputToKeyInput( DX_INPUT_PAD1, PAD_INPUT_R, KEY_INPUT_W, -1, -1, -1 );
  109. //
  110. SetJoypadInputToKeyInput( DX_INPUT_PAD2, PAD_INPUT_UP, KEY_INPUT_P, -1, -1, -1 );
  111. SetJoypadInputToKeyInput( DX_INPUT_PAD2, PAD_INPUT_DOWN, KEY_INPUT_SEMICOLON, -1, -1, -1 );
  112. SetJoypadInputToKeyInput( DX_INPUT_PAD2, PAD_INPUT_LEFT, KEY_INPUT_L, -1, -1, -1 );
  113. SetJoypadInputToKeyInput( DX_INPUT_PAD2, PAD_INPUT_RIGHT, KEY_INPUT_COLON, -1, -1, -1 );
  114.  
  115. SetJoypadInputToKeyInput( DX_INPUT_PAD2, PAD_INPUT_A, KEY_INPUT_B, -1, -1, -1 );
  116. SetJoypadInputToKeyInput( DX_INPUT_PAD2, PAD_INPUT_B, KEY_INPUT_N, -1, -1, -1 );
  117. SetJoypadInputToKeyInput( DX_INPUT_PAD2, PAD_INPUT_C, KEY_INPUT_M, -1, -1, -1 );
  118. SetJoypadInputToKeyInput( DX_INPUT_PAD2, PAD_INPUT_X, KEY_INPUT_H, -1, -1, -1 );
  119. SetJoypadInputToKeyInput( DX_INPUT_PAD2, PAD_INPUT_Y, KEY_INPUT_J, -1, -1, -1 );//st
  120. SetJoypadInputToKeyInput( DX_INPUT_PAD2, PAD_INPUT_Z, KEY_INPUT_K, -1, -1, -1 );//st
  121. SetJoypadInputToKeyInput( DX_INPUT_PAD2, PAD_INPUT_L, KEY_INPUT_U, -1, -1, -1 );//st
  122. SetJoypadInputToKeyInput( DX_INPUT_PAD2, PAD_INPUT_R, KEY_INPUT_I, -1, -1, -1 );//st
  123. }
  124.  
  125. bool Padinput::now_button(int id,int button_num)//!<現在のボタン入力取得
  126. {
  127. return this->check_button(this->NowInput[id] , button_num);
  128. }
  129. bool Padinput::edge_button(int id,int button_num)//!<現在入力されたボタン取得
  130. {
  131. return this->check_button(this->EdgeInput[id] , button_num);
  132. }
  133. bool Padinput::now_stick(int id,int stick_num)//!<現在のスティック取得
  134. {
  135. return this->check_stick(this->NowInput[id] , stick_num);
  136. }
  137. bool Padinput::edge_stick(int id,int stick_num)//!<現在入力されれたスティック取得
  138. {
  139. return this->check_stick(this->EdgeInput[id] , stick_num);
  140. }
  141.  
  142. int Padinput::get_NowInput(int num)
  143. {
  144. return this->NowInput[num];
  145. }
  146.  
  147.  

  • 使い方
  1. Padinput inp;//定義
  2. inp.input_config();//必要ならば
  3. //・・・中略
  4. inp.input_Process();//毎フレーム呼ぶ=更新関数
  5. //・・・中略
  6. if(inp.edge_button(0,1)==true)//ID=0のボタン1がこのフレームで入力されたか@過渡応答
  7. {
  8. //・・・中略
  9. }
  10.  


SEクラス

SAVE/LOADクラス
誰か書いてくれると助かります

Cameraクラス

タグ:

+ タグ編集
  • タグ:

このサイトはreCAPTCHAによって保護されており、Googleの プライバシーポリシー利用規約 が適用されます。

記事メニュー
人気記事ランキング
目安箱バナー