トップページgamedev
1001コメント390KB

ゲームにおけるデータ構造・クラス設計・パターン

■ このスレッドは過去ログ倉庫に格納されています
0001名前は開発中のものです。2006/08/10(木) 20:27:06ID:BnvyxuCB
具体的なゲーム名を挙げて、
どのようにクラス設計をすればよいか、
継承・委譲関係はどのようにすればよいか、
使えそうなパターンは何かなど語るのもよし。
自作ゲームの内容とクラス図を書いて
改善案を聞くもよし。
設計に関して困ったことを質問するもよし。

関数の具体的な実装内容やゲーム内容に関しては他スレに譲る。
大いに語れ。
0737名前は開発中のものです。2008/02/09(土) 02:03:34ID:Be1sC8H8
まぁゲームで new とか使わんな。ポインタも殆ど使わん。
0738名前は開発中のものです。2008/02/09(土) 15:46:31ID:Rmj5T+sL
そんなプログラムはゴミ箱へ
0739名前は開発中のものです。2008/02/09(土) 17:21:52ID:Ktk+EzAJ
プログラマもゴミ箱へ。
0740名前は開発中のものです。2008/02/09(土) 18:50:29ID:5eO+wULN
ゴミ箱はリサクル。
0741名前は開発中のものです。2008/02/19(火) 22:44:36ID:sVjxRGgG
なるべく一般性の高いゲームの骨作りをしたいんだけど
みんなどうしているんだろう…
CGやBGMのロード、キーチェックをどこで実施すべきか悩んでしまう
↓だいたいこんな感じで組んでいるけど変?
//----main.cpp----
int WINAPI WinMain( ... ){
GameFrame *game = new GameFrame();
game->doMainLoop();
delete game;
}
//---gameframe.cpp---
void GameFrame::doMainLoop();{
loadCG();//ここ?
loadBGM();//ここ?
while(ProcessMessage()==0 && ...){
switch(gameState){
case GAME_DEMO : drawGameDemo ();break;
case GAME_TITLE : drawGameTitle();break;
case GAME_MAIN : drawGameMain ();break;
...
}
...
}

void GameFrame::drawGameMain(){
checKey();//どこに入れよう?
drawBG();
drawEnemy();
drawPlayChara();
drawHoge();
}
0742名前は開発中のものです。2008/02/19(火) 22:58:48ID:kk7YgASy
class Task { public: virutal ~Task() {} virtual void exec() = 0; virtual void draw() const = 0; virutal bool needGC() const = 0; };

void GameFrame::doMainLoop() {
 // シングルトン系の処理実行
 g_pad.exec(); // パッド入力処理
 g_file_loader.exec(); // ファイル非同期読み込み処理
 // その他の処理実行
 std::for_each(m_task_list.begin(), m_task_list.end(), boost::bind(&Task::exec, ::_1));
 std::for_each(m_task_list.begin(), m_task_list.end(), boost::bind(&Task::draw, ::_1));
 m_task_list.remove_if(boost::bind(&Task::needGC, ::_1));
}

こんな感じだと思うが。ファイルの読み込みは Task 派生クラスの exec の中で

TestTask1::exec() {
  switch (m_state) {
  case INIT:
    g_loader.load("file1.arc");
    ++m_state;
    break;
  case LOADING:
    if (g_loader.isLoaded("file1.arc"))
      ++m_state;
    break;
  case MAIN:
    ...
}

って感じで。マジメに作るとファイルは事前にアーカイブ&圧縮しておいて、ロード時に
展開するとか、そもそも名前ではなく #define シンボルで扱えるようにして下らないバグを
出さないようにするとか、断片化防ぐためにメモリのセグメント分割するとか、いろいろ
あるけど。
0743名前は開発中のものです。2008/02/19(火) 23:21:10ID:sVjxRGgG
>>742
過疎っている思ったのに光速レス有難う。
なんかタスク管理とか高度でかっこいいですね。
デザパタとboostをもうちょい勉強してみます。
自分のはなんかCでやってたことをクラスに詰め込んだだけっぽい。
0744名前は開発中のものです。2008/02/19(火) 23:24:49ID:kk7YgASy
タスクというと、タスク原理主義者の襲撃受けるのでアレだがw

直接 m_task_list に突っ込むのは、いわゆるシーンオブジェクトぐらいに
しておいたほうが良い。個々のキャラクターとかエフェクトの類は、派生
クラス (TastTask1 とか) のメンバ変数で持たせる。

m_task_list は見て分かるように exec, draw 両方とも引数ないので、
これだと相互作用するようなインスタンスをうまく扱えないので。
0745名前は開発中のものです。2008/02/20(水) 00:09:11ID:mhKVjbwn
>>706とかでもありましたけど
タスクにキューをためるような処理の仕方が一般的なんですね。
自分はそういうスタイルで組もうとしたことがないので色々と勉強しないと…
0746名前は開発中のものです。2008/02/20(水) 00:09:55ID:mhKVjbwn
に×
を○
0747名前は開発中のものです。2008/02/21(木) 01:33:19ID:y49BO0DL
>>741-742
いきなり、スレタイ否定だが、
本気で一般性の高いのを目指すなら、
ここで聞くより、ソースが見られるゲームエンジン見た方が100倍いい。
力がつくよ。
俺もいろんなソースみて力つけてきた
0748名前は開発中のものです。2008/02/21(木) 08:24:03ID:f3J60D7j
>>747
どのエンジンが勉強に良かったか教えてくれ。
0749名前は開発中のものです。2008/02/21(木) 14:29:42ID:J9L5jpws
言語の講座は大量にあるけど
設計の講座はさっぱり見当たらないな。
実装部分の詳細はよくみつかるけど
0750名前は開発中のものです。2008/02/21(木) 15:15:43ID:zstakQXs
>>747
俺も聞きたい。どんなエンジンを見てきたの?
0751名前は開発中のものです。2008/02/21(木) 16:09:59ID:J9L5jpws
>>747
>>741のようなCの延長的な書き方でクラスで関数を纏めただけじゃん
みたいにしか組めない俺もききたい。
0752名前は開発中のものです。2008/02/21(木) 20:26:16ID:Okox727g
yaneSDKとかw
0753名前は開発中のものです。2008/02/23(土) 23:46:58ID:DDpK+Okk
             . ィ
.._ .......、._    _ /:/l!
 :~""''.>゙' "~ ,、、''‐'、|         _
゙、'、::::::ノ:::::::_,.-=.  _〜:、         /_.}'':,
 ``、/:::::::::__....,._ `゙'Y' _.ェ-、....._ /_゙''i゙ノ、ノ
 ,.--l‐''"~..-_'.x-='"゙ー 、`'-、 ,:'  ノ゙ノブ
"   .!-'",/  `'-‐'') /\ `/ でノ-〈
 .-''~ >'゙::    ‐'"゙./  ヽ.,'   ~ /
   //:::::       ',    /    ,:'゙
0754名前は開発中のものです。2008/02/25(月) 00:12:54ID:zZm6FQuH
マジレスすると「ゲームデザイン」の中の人最強だろ
0755名前は開発中のものです。2008/02/25(月) 03:05:17ID:0uW9SKNN
ゲームデザインでググって一番上に来る人のことですよね?
そうじゃなければ自演乙
0756名前は開発中のものです。2008/02/25(月) 12:02:29ID:zZm6FQuH
間違えた。
ゲームデザインの方じゃなくてABA Games最強だろ。

なんか俺の脳内で一緒になっていた
0757名前は開発中のものです。2008/02/26(火) 15:08:24ID:xLe52R9Z
>>753がマスターシャーフーに見えたw
0758名前は開発中のものです。2008/02/26(火) 15:52:10ID:PSiNRJla
ご冗談をw
0759名前は開発中のものです。2008/02/26(火) 19:15:30ID:tRWcfCXW
首があるから「ネコ〜」じゃないよ。
0760名前は開発中のものです。2008/02/26(火) 20:11:44ID:i0RtjL2w
カリンさまだろ?
0761名前は開発中のものです。2008/02/26(火) 23:56:46ID:76zWC3a3
ゲームのHPとかMPみたいにMAX値を超えたり0を下回ると困る数字の処理って
一般的にはどうしているんでしょう?
↓みたいな感じでやっているんですけど

class MyFunc{
public:
       //上限を超える、0を下回るときの処理
       static float trimZeroMax( float val, float val_max ){
              if ( val > val_max ) { val = val_max; }
              if ( val < 0 ) { val = 0; }

              return val;
       }
};

//使うとき(ダメージ処理、回復処理の後)
hp = MyFunc::trimZeroMax( hp, hp_max );
0762名前は開発中のものです。2008/02/26(火) 23:59:37ID:gnaVpqJX
プロパティが使えない言語なのか
0763名前は開発中のものです。2008/02/27(水) 00:07:04ID:5as5SRvU
>>761
それで数値がMAXまで行ってクリッピングされた時に
音を鳴らしたい場合どうする?
ポインタ渡しの引数増やすのも気持ち悪いし
GetLastError() みたいな別関数で状態を取得するのも気持ち悪い

0764名前は開発中のものです。2008/02/27(水) 00:07:18ID:oXng1J4U
見るからにC++だからなぁ。

俺なら数字っぽく扱えるクラスを書いて、
operator+()の中で範囲チェックするかなー。
07657642008/02/27(水) 00:09:34ID:oXng1J4U
追記
>>763みたいな要求にこたえるときは、
作ったクラスにコールバックの仕組みを追加する、とかの方法で実現できる。
クラスのクライアントに対しては修正いらないはずだし。
0766名前は開発中のものです。2008/02/27(水) 00:30:52ID:TisTOwvT
プロパティが何だか分からなくて心が折れた。
0767名前は開発中のものです。2008/02/27(水) 00:32:46ID:FtdPv/Qb
要はgetHPとsetHPのこと
0768名前は開発中のものです。2008/02/27(水) 00:35:39ID:TisTOwvT
…VBとかの機能か。
0769名前は開発中のものです。2008/02/27(水) 00:46:29ID:vyFLiqpq
>>761
言語がHSPなので参考になるかわからんが、

isover(val, min, max) //溢れ判定
irange(val, min, max) //上限下限
itorus(val, min, max) //ループ
ibound(val, min, max) //跳ね返り

の4つでだいたい足りている。
0770名前は開発中のものです。2008/02/27(水) 00:47:14ID:FtdPv/Qb
>>761にプロパティを使うのは不適切だね
プロパティは外から見てフィールドのように振舞うべき
101をセットして1が返ってくるのは直感的じゃない
0771名前は開発中のものです。2008/02/27(水) 00:47:21ID:ICP6u2PI
java使いの俺も泣けてきた。プロパティの仕様でカオスってる。
アクセッサメソッドでいいじゃん。getter/setter。
0772名前は開発中のものです。2008/02/27(水) 00:49:46ID:eBwcQsVt
プロパティを使うときの一番ありふれた事例が
上限下限のコントロールかと思ってた……

まあ1人で開発するから問題にはなんないけど
0773名前は開発中のものです。2008/02/27(水) 01:11:23ID:L4S10xjM
max(0, min(val_max, val));
0774名前は開発中のものです。2008/02/27(水) 01:29:41ID:ICP6u2PI
その程度の計算にしては高価じゃない
0775名前は開発中のものです。2008/02/27(水) 01:31:42ID:vyFLiqpq
デバッグで失われる時間のほうが高価なので
どんどん怠けましょう。
07767612008/02/27(水) 02:08:49ID:g7Py3Pl9
getter/setterとかのメソッド≒プロパティというんでしょうか?

プレイキャラクターのクラスにダメージやら回復やらを処理させるメソッド内で
件の自作関数を呼び出しています。同じような処理ばかりあちこちにガリガリ書いていたもんで…

↓みたいにクラス化してしまう方が一般的ですかね
class LimitFloat{
//.なんか勝手に良い感じにしてくれる処理

};

class PlayChara{
LimitFloat hp;
LimitFloat mp;

};
0777名前は開発中のものです。2008/02/27(水) 02:36:41ID:oXng1J4U
>>776
直接的なプロパティへのアクセスを許可すると
情報隠匿の観点からマズイので、getter/setterを噛ませるってだけ。
プロパティ自体は
http://e-words.jp/w/E38397E383ADE38391E38386E382A3.html
こんな感じ。
文字列なら、文字列長や、文字エンコーディング。
mp3ならアーティスト名とか曲名。
0778名前は開発中のものです。2008/02/27(水) 02:41:28ID:RhgcvCBo
いやプロパティはアクセス時にgetter/setterが呼ばれる変数みたいなもんだろ。
プロパティが言語仕様にある言語て何があったっけ?

esのプロパティはスロットだし
0779名前は開発中のものです。2008/02/27(水) 06:06:32ID:VPWpT54e
触ったことある言語の中だとC#にはあったな。
0780名前は開発中のものです。2008/02/27(水) 07:04:41ID:9e3rMNMJ
>>761
bool add_ubound(float& x, float xmax, float add)
{
  assert(x > 0);
  assert(add > 0);
  asert(xmax > 0);
  assert(x <= xmax);

  x += add;
  if (x > xmax) {
    x = xmax;
    return true;
  }
  return false;
}

>>763
if (add_ubound(hp, MAX_HP, 10)) {
  playSound();
}

ベタだけど、こんな感じで処理してる。あと >>769 みたく上限加減とか
ループとか扱う関数をいくつか用意。
0781名前は開発中のものです。2008/02/27(水) 12:56:18ID:ITfjdhQA
C#には、getter/setter関数を、通常とは異なる文法の関数1つにまとめて記述できる文法があってそれがプロパティ。
代入演算の左に来ればsetterが、それ以外ならgetterが呼ばれるから結果的にグローバル変数のように使用できる。

個人的にはプロパティの用途は以下のようだと思ってるのでプロパティで処理するのはありだとおも。
>>772、インターフェイスのメンバにして多態性、getterのみ。

それにしてもRPGっぽいステータス管理って結構複雑だな。
今ぱっと考えただけじゃクラスが作れん。
0782名前は開発中のものです。2008/02/27(水) 19:16:26ID:ww8Aojqq
値を上限・下限内に丸めるのとアサートによる契約プログラミングは別問題じゃないか?
単にセッタ内で丸めるという処理が目的だろこの場合。
アサートは条件に違反があった場合に吠えることが目的だろ?
違反があるかないか以外に影響しちゃだめだろアサートは。
07837612008/02/27(水) 19:30:12ID:g7Py3Pl9
>>780有難うございます。参考にして改造しました。
static U_BOUND_RESULT add_ubound ( float& val, float val_max, float add ) {
    if ( val < val_max ) {
      val += add;
      if ( val >= val_max ) { val = val_max; return MOMENT_FULL; }
      val -= add;
    }
    if ( val >= val_max ) {
      val += add;
      if( val >= val_max ) { val = val_max; return ALREADY_FULL; }
      val -= add;
    }
    if ( val <= 0 ){
      val += add;
      if( val <= 0 ) { val = 0; return ALREADY_DEAD; }
      val -= add;
    }
    if ( val > 0 ){
      val += add;
      if(val <= 0) { val = 0; return MOMENT_DEAD; }
      val -= add;
    }
    val += add ;
    return NORMAL ;
  }
} ;
>>763
if ( MOMENT_FULL == MyFunc::add_ubound (hp, MAX_HP, 10) ) {
  playSound ( ) ;
}
満タンになった瞬間だけ音が鳴るようにしてみたんですがえらく冗長に…
0784名前は開発中のものです。2008/02/27(水) 23:19:17ID:9e3rMNMJ
>>783
C++ なら、せっかくだから関数テンプレートにしとこうか。
07857612008/02/28(木) 00:50:13ID:fsbSiynp
関数テンプレート化頑張ってみます。
CからC++に移行したばかりで手間取りそうですが…

>>783の条件分岐の記述はもうちょっとスマートに処理できそうな気がするんですが
良い方法が思いつかず…
0786名前は開発中のものです。2008/02/28(木) 00:53:56ID:aMmxfMJe
アサートが何なのかわからなくて検索してしまったぜ。
要するに本来はデバッグ検出用の関数なのね
0787名前は開発中のものです。2008/02/28(木) 00:56:28ID:gTDbrfGi
まあHPならfloatで決め打ちでもそんなに困らない気がしないでもない
将来のための勉強にはなるかな
0788名前は開発中のものです。2008/02/28(木) 02:04:32ID:UDo8JFjd
HPとかステータス値は普通整数じゃね?
0789名前は開発中のものです。2008/02/28(木) 02:06:57ID:gTDbrfGi
表示するときは整数でも実数で保持しておいたほうが便利なことがあるかもしれない
MOTHER2みたいにダメージ受けても減少するまで時間がかかるとか……
0790名前は開発中のものです。2008/02/28(木) 02:44:14ID:fsbSiynp
時間とともにちょっとずつ回復みたいなことをやるなら実数の方がいいかなと。
ドラクエとかって最初から整数なのかな…
1ポイント前後のダメージって強制的に1ポイントダメージに補正されている感じだし
内部的に実数で0.1fずつ喰らったダメージが蓄積して1ポイントダメージになったりはしてなさそう
0791名前は開発中のものです。2008/02/28(木) 07:23:54ID:71Ai97aI
>>786
俺は assert() が入っていおらず、かつ UnitTest も書かれていない関数は
信用しない。
0792名前は開発中のものです。2008/02/28(木) 07:41:00ID:cET+1oWo
どうせリリース時には消えるしな
0793名前は開発中のものです。2008/02/28(木) 08:43:52ID:TTiCigMJ
>>789
固定小数でググれ
0794名前は開発中のものです。2008/02/28(木) 09:17:18ID:payXug97
アサートっていうかイベントだな
0795名前は開発中のものです。2008/02/28(木) 14:13:32ID:gTDbrfGi
floatと書いておけば何も考えなくてもいいのに比べて
今どき固定少数で処理するのってメリット少なくない?

処理速度の面でも遜色ないし使用するメモリも
そこまでケチる時代じゃないしコードも固定少数の
ほうがいくらか読みづらくなるでしょ
0796名前は開発中のものです。2008/02/28(木) 16:35:34ID:cET+1oWo
固定小数点数のメリットは論じても仕方ないので置いておくとして、
floatなら何も考えなくていいってのは違うので気をつけよう
値の比較や、演算誤差・丸め込みに注意を払う必要がある

int main() {
 float a = 0.0f;
 for (int i = 0; i < 100; ++i) {
  a += 0.01f;
 }
 std::cout << a << std::endl;
 return 0;
}

手元の環境だと結果は0.999999になる
あとゲームではよく使う % での剰余も出来ないので、代わりにfmod()を使う必要がある

例がFAQすぎてすまん
0797名前は開発中のものです。2008/02/28(木) 18:26:26ID:TilB203v
言ってることは別に間違ってないけど、float値の比較に「==」とか使うような奴は
ゲーム以前に計算機リテラシー欠乏者なのでこのスレでは無視していい存在では?
0798名前は開発中のものです。2008/02/28(木) 18:46:41ID:C0ktJ0ww
このスレではThe art of computer programmingは既読が前提ということか
質問しようと思ったけど出直すわ
0799名前は開発中のものです。2008/02/28(木) 19:23:14ID:TilB203v
ヘソ曲げ乙
別にそんな鈍器を買わんでも、その辺の理工学書コーナーに売ってる
薄っぺらい数値計算法の初歩本(教科書)を一冊借りて読んどけばいいよ
情報工学系大学1年次の基礎教養レベルの話なんだからさ
0800名前は開発中のものです。2008/02/28(木) 21:18:29ID:gTDbrfGi
まあHPとかのステータス値を%で剰余出す計算することは少ないだろうし
>>796の問題でバグ出すケースも少ないだろうな……

ステータスアップや次のレベルに必要な経験値テーブルなんかに
アクセスすることが多いLVは整数型にするだろうけど、
その場合は値を丸める処理がHPと同じじゃまずいし
0801名前は開発中のものです。2008/02/28(木) 21:56:42ID:u9i/69wo
リテラシー(笑)
0802名前は開発中のものです。2008/02/29(金) 00:50:23ID:scJliyMv
>>795
すまん
単にMOTHER2だとかドラクエだとか
DC/PS2以前のゲーム機で浮動小数なんて使わないよということが
言いたかっただけなんだw

何でもかんでもfloatにしたら配列の添え字にも使えないわ、単純な比較は出来ないわ
論理演算は出来ないわ
余計に面倒な気がするけど。
0803名前は開発中のものです。2008/02/29(金) 00:55:40ID:pZqyzh8s
>>802
HPを配列の添え字には使わんでしょう。ま、どっちでも良いんじゃない?
0804名前は開発中のものです。2008/02/29(金) 01:11:33ID:1a1vCA3e
浮動小数はゆとりにはいいんじゃね?
およそ3とか。
0805名前は開発中のものです。2008/02/29(金) 01:20:16ID:mi6een0V
オッサンは(笑)の使いどころが微妙だな
0806名前は開発中のものです。2008/02/29(金) 03:04:41ID:Su9zU3dq
そんなに気に障ったのか……
0807名前は開発中のものです。2008/02/29(金) 03:05:47ID:Yy6nmC7D
オッサンと言われるだけでカチンと来たら
気をつけないといけない年齢だぜ。。。
0808名前は開発中のものです。2008/02/29(金) 03:44:01ID:4Kq/g52z
これは酷い
0809名前は開発中のものです。2008/02/29(金) 13:05:12ID:MAKYfqWf
>>785
こんなのダメ?
    float a = val + add;
    float b = val;
    if ( a >= val_max ) {
      val = val_max;
      if ( b < val_max ) return MOMENT_FULL;
      return ALREADY_FULL;
    }
    略

ところで>>789みたいな例ってブレゼンハムぽいことすれば固定少数必要ないんじゃない?
浮動少数も>>796を理解しててもついうっかりってのがあるしかもしれないし
0810名前は開発中のものです。2008/02/29(金) 13:16:40ID:s07vVVTE
見えない小数部分を利用なんてしないで、
別にタイマーでも持った方がいいと思う
0811名前は開発中のものです。2008/02/29(金) 13:35:10ID:er34P6sc
誰にタイマー持たせるの?
0812名前は開発中のものです。2008/02/29(金) 14:40:49ID:dte27yiX
ついうっかりどころか、>>789はそのまんま>>796をやらかすに違いない。
合計10減らしたはずなのに9.999999しか減ってないとかな。
ま、このスレでは無視していい存在らしいしどうでもいいんじゃね?
0813名前は開発中のものです。2008/02/29(金) 15:47:54ID:Yy6nmC7D
何をそうカリカリしているんだ
0814名前は開発中のものです。2008/02/29(金) 17:28:29ID:JGbETmbf
>>809
有難うございます。
かなりスマートになりました。
ローカル変数に退避させておけばよかったんですね。
0815名前は開発中のものです。2008/03/01(土) 20:59:06ID:ESvEWD62
>>778
Delphiとか?C++Builderは言語仕様つーより、独自拡張ですね

>>802
も前のマシンはいつからDSに?

>>796-797
その後、「なんで、0.999999になるの?」って質問が出てこないから大丈夫かとw
0816名前は開発中のものです。2008/03/01(土) 21:19:01ID:dqQWYIvh
最近RPGの設計話増えたな
0817名前は開発中のものです。2008/03/01(土) 21:58:24ID:sBXIWwoH
そろそろ卒業なんじゃね?
もう3月だし、さすがにそれはないかw
0818名前は開発中のものです。2008/03/02(日) 03:32:21ID:LsA47iDE
卒業製作なら去年の夏ごろから死んでると思う
0819名前は開発中のものです。2008/03/02(日) 21:49:31ID:Hbr0sFHK
さすがに一ヶ月未満で作ろうとは思わんよなあ
0820名前は開発中のものです。2008/03/07(金) 18:18:38ID:1kJAWqPN
STGでボタン1を普通のショット、ボタン2を溜めショット用にしようとしているんですけど
この溜めている量は
自機クラスのメンバ変数に持たすべきでしょうか?
それともキー管理クラスを作って
jiki.shot2 ( joypad1.getCharge ( BTN2 ) )
みたいな感じで処理すべきでしょうか?
0821名前は開発中のものです。2008/03/07(金) 18:25:22ID:cRszUD3e
俺だったら、自機の基底クラスである(例えば)機体クラスで管理する。

理由は、機体クラスの派生クラスで敵機クラスを作れば、
敵機の溜めショットの実装が楽になる。
0822名前は開発中のものです。2008/03/07(金) 19:30:11ID:ZcSmZqCn
おおむね>821に同意しつつ、自分なら、キーの押しっぱなし時間も同時に保持しておくかな。
溜めショット以外にも使うこと多そうだし。

カーソルとか、ポンと押した場合は1つ進むだけだけど、押しっぱなしにすると自動的にカーソルが動くとか、
そんな類の処理に流用できそう。
0823名前は開発中のものです。2008/03/07(金) 19:36:59ID:i2RlFGNS
>>820
void 機体クラス::update()
{
 if (joypad1.getOnf() & BTN2) // getOnf() はボタン押し下げてれば真
  m_shot2.Charge();
}

俺なら、こうするかなぁ。機体クラスのメンバ変数に溜めショット用の
メンバ変数を持たせる。

キー管理クラスというのが何を意図してるのかわからんけど、汎用の
パッド入力処理関数として

enum { BTN1 = 0x1, BTN2 = 0x2, BTN3 = 0x4, BTN4 = 0x8, ... };

getOnf(); // 押し下げボタンの論理和が返る
getTrg(); // 直前まで放されてて、このフレームに初めて押し下げられたボタンの論理和
getRep(); // 一定時間以上押しっぱなしのボタンの論理和

ぐらいは用意しておいた方が便利だよ。
08248202008/03/07(金) 23:07:06ID:1kJAWqPN
>>821-822
有難うございます。その方向でちょっと作ってみます。
08258202008/03/07(金) 23:26:54ID:1kJAWqPN
>>823実は自作で汎用のパッド入力処理関数のようなものを作ってあったんですが
ちょっと出来に難があります。
1回のメインループで2回使用、例えばKEY_DOWNとKEY_UPの2種類を検出しようと
したりすると1種類目の呼び出ししか有効でなかったり。
enum BTN_STATE{ NO_PUSH, KEY_DOWN, KEY_PUSH, KEY_UP };
//「押されていない」「押下げた瞬間」「押されている状態」「押上げた瞬間」
class JoyPad{
 int isPushDown[2][8];//[パッド1P、2P][ボタン数] (各ボタン押されているか否か)
public:
 BTN_STATE getBtnState(int pad_num, int btn_num );
}

BTN_STATE JoyPad::getBtnState (int pad_num, int btn_num ){
  int btn = ボタンが押されているか?関数( pad_num, btn_num );
  if ( btn == 1 ) {//ボタンが押されていたら
    if ( isPushDown[pad_num][btn_num] == 0){
    isPushDown[pad_num][btn_num] = 1;
    return KEY_DOWN;//「押下げた瞬間」
    }else{
    return KEY_PUSH;//「押されている状態」
    }
  }
  if ( btn == 0 ) {//ボタンが押されてなければ
    if(isPushDown[pad_num][btn_num] != 0){
    isPushDown[pad_num][btn_num] = 0;
    return KEY_UP;//「押上げた瞬間」
    }
  }
return NO_PUSH; //「押されていない
}
0826名前は開発中のものです。2008/03/07(金) 23:36:57ID:6HaqHq5U
状態を管理する部分と、管理されてる情報を参照する部分を分ければいいんじゃね?
0827名前は開発中のものです。2008/03/07(金) 23:39:41ID:cRszUD3e
Win系ならWindowメッセージかDirectX使え。
0828名前は開発中のものです。2008/03/07(金) 23:54:13ID:2OqKUBaL
>>825
>>826も言ってるが
それぞれの状態について保存しておいて、それを参照すればいいじゃん

現在の状態をcurrentに0,1で保存するとして
押下した瞬間 on_trigger = (on_trigger ^ current) & ~current
離した瞬間 off_trigger = off_trigger ^ (^current & last)
過去の状態 last = current
08298202008/03/07(金) 23:56:56ID:1kJAWqPN
>>826
ちょっと考えて見ます
>>827
使っているのが「DXライブラリ」というDirectX用ライブラリなんですが押している状態しか
チェックできなくて難儀しています。
直接DirectXガリガリした経験がないのでわかりませんがWindowメッセージの
WM_KEYDOWN, WM_KEYUPに相当するものがあればその方が楽できそうですね…
0830名前は開発中のものです。2008/03/08(土) 00:15:59ID:XxYr3Sol
DXライブラリってのは名前くらいしか知らんが、
1フレーム内にon/offがあった場合検知できないのかねぇ?
(FPSを上げれば解決できそうな問題だと思うけど)

DirectXは(デバッガで止めるなどして)1フレーム内に複数の入力あっても、
全部取得できると思った。でもDirectXはその性質上最低レベルAPIだから、
DXで済ませるならDXでやったほうがいいんじゃないかな…
0831名前は開発中のものです。2008/03/08(土) 08:33:18ID:L6W8V7J1
stateパターンか
0832名前は開発中のものです。2008/03/08(土) 09:13:25ID:S4+z8pGt
DXライブラリの中の人もチラと言ってたけど、そのまま使わずに、自分でラップして使った方がいいんじゃないかな?
低レベルな部分を隠すだけ、って割り切っちゃう。
0833名前は開発中のものです。2008/03/13(木) 01:35:23ID:+x1fkFDE
>>828
横レスすまん。
たぶん俺が根本的に何かを勘違いしているんだろうけど、
どう考えても意図がわからない。

押下した瞬間 on_trigger = current & ~last
離した瞬間 off_trigger = ~current & last
ほんとはこう?

「C,C++じゃねーよ」ってのならごめん。他の言語はわからない。
0834名前は開発中のものです。2008/03/13(木) 10:23:04ID:QxqUuAIc
素直にifを使うっていうのはどうだろうか。
0835名前は開発中のものです。2008/03/13(木) 22:39:59ID:Bu/r75Um
そういうことだな
0836名前は開発中のものです。2008/03/17(月) 12:58:49ID:bgIcAWWo
最近デザインパターンを覚え始めたんだが、
oopのコンポジション集約と、デザインパターンのコンポジットは全然別なことと、
デザインパターンのファザードがコンポジション集約と似た効果/構造してて戸惑った。

この違和感は普通にそのうち無くなるもの?
0837名前は開発中のものです。2008/03/17(月) 14:16:30ID:hf8pDjO+
デザインパターンか…
そろそろ俺も覚えないと不味いな
■ このスレッドは過去ログ倉庫に格納されています