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

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

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

関数の具体的な実装内容やゲーム内容に関しては他スレに譲る。
大いに語れ。
0643名前は開発中のものです。2007/11/17(土) 18:34:11ID:2u92yTvZ
SceneManagerとか定番だな
0644名前は開発中のものです。2007/11/17(土) 18:35:34ID:JxWacONa
javaの立場が・・・
0645名前は開発中のものです。2007/11/17(土) 20:30:54ID:/rbqSJ11
class Referee
{
public:
  Referee(const class Rule& current_rule);

  const bool judge(const class Battle& current_battle);
  void bribe(const int price);

  inline void win(void) { http://youtube.com/watch?v=ubhW9R-F7cM }
};
0646名前は開発中のものです。2007/11/17(土) 21:45:56ID:K5pYaEDh
>>644
0647名前は開発中のものです。2007/11/18(日) 06:00:26ID:D4743XwF
使うなとは誰もいってないよ
0648名前は開発中のものです。2007/11/18(日) 07:27:13ID:mDvA2is2
>>642
俺の場合、Manager って名前は使っちゃうな。ただし Manager クラスで
何でもかんでも処理せずに、分割できるところは別のクラスに切り出して
Manager クラスに集約する。

Facade やね。
0649名前は開発中のものです。2007/11/20(火) 01:41:42ID:Xv2CgjLa
さっきからしょぼいBGMのループがひどいな
2ループもすりゃ十分だろ
0650名前は開発中のものです。2007/11/20(火) 02:00:34ID:B+/JlwAo
>>649
何に対して言ってるのか
0651名前は開発中のものです。2007/11/20(火) 06:51:02ID:x6OdnLNb
B・・・・・GM・・?
0652名前は開発中のものです。2007/11/24(土) 17:27:35ID:5kPj3Eca
シューティング作ってて、敵のクラスと自機のクラスを分けちゃったけど、わけない方がスマートだったかなあ
0653名前は開発中のものです。2007/11/24(土) 17:36:40ID:BsLqDTe0
>>652
一部同じインターフェースを持つことはあるだろうけど、普通に考えてまったく同じクラスに
なるとは思えない。
0654名前は開発中のものです。2007/11/24(土) 19:10:43ID:XdMXhxj/
自分は敵1と敵2とかでもわけてる
0655名前は開発中のものです。2007/11/24(土) 21:09:45ID:vFIasKer
>>654
そりゃ、作るゲームにもよるな。キャラクター数少なくて差異が大きい場合には
クラス分けるが、RPG のように数が多いと基本1クラスでデータ駆動にする。
0656名前は開発中のものです。2007/11/24(土) 22:25:37ID:Y480fdwm
>>652
何シューティングか知らないが、
よくある2Dのシューティングなら自機と敵機で違う処理したほうが、
当たり判定の最適化しやすそうだな。
(同じ基底クラスから派生させるとかいう話はおいといて、
0657名前は開発中のものです。2007/12/23(日) 16:09:31ID:zijTonf7
シューティングでも、データ駆動(簡易スクリプトもしくは、相当するもの)
がお勧め。

俺は、クラス志向でやってたら、敵、弾のクラスが200超えたあたりで、死んだ
0658名前は開発中のものです。2007/12/23(日) 17:43:24ID:j05CibA3
もっと詳しく。
数の多さからの管理の複雑化という問題だとしたら、
データでもクラスでも一緒だと思うんだが。
0659名前は開発中のものです。2007/12/23(日) 17:48:27ID:1bBLAr/H
>>657は敵の動きや弾の速度やダメージなんかを全部
コード中に書いてたんじゃね
0660名前は開発中のものです。2007/12/23(日) 18:00:13ID:Uzvq0eJL
DIO「所詮OOPはゲームプログラミングの亜流!データドリブンに敗北する定めよおおおぉっ!!」
0661名前は開発中のものです。2007/12/23(日) 18:27:09ID:a745ZQah
実際に完成したゲームのデータj構造・クラス設計が王道。
0662名前は開発中のものです。2007/12/23(日) 20:45:04ID:5BsM8MRd
RPGゲームのクラスを作ろうとしているのですが・・・
http://www.kent-web.com/pubc/book/test/uploader/uploader.cgi?mode=downld&no=530
キャラクタークラスや技エフェクトクラスにも画像データを持たせたいのですが、描画処理クラスの下に
キャラクタークラスを置くべきでしょうか?それとも多重継承で描画処理クラスのデータを継承させたほうが良いでしょうか?
描画処理クラスでは画像のデータや実際に描画する関数など描画データを統合して持っています。

他にもこうした方がいいというところがあればお教え下さい。
よろしくお願いしますm(_ _)m
0663名前は開発中のものです。2007/12/23(日) 21:13:08ID:sYkuqm1i
2Dゲームだと仮定すると
キャラクタークラスがコピーする画像の種類、座標と大きさをパラメで持ってればいい
変数5個ぐらいだからあとはそれを描画クラスに渡して描画されるしくみがあればおk

エフェクト関係の位置が微妙に変だと思う
あれは継承?それとも集約(コンポジション)?

あと図の矢印が継承と集約混ざっててわかりにくす
あれが全部継承なら最初から作り直し
0664名前は開発中のものです。2007/12/23(日) 21:20:38ID:zijTonf7
>>659
そのとおり
で、途中からやばいことに気づいて(そら100もクラス作ってたら、気づくわw)
スクリプトで外に出したりしてたら、
かなーりカオスに・・・
0665名前は開発中のものです。2007/12/23(日) 21:22:59ID:zijTonf7
>>662
矢印の関係、向きがグチャグチャだなおいw
UML関連の入門記事をさらっと読んだ方が、いいよ

本まで買って厳密にやることはないが
0666名前は開発中のものです。2007/12/23(日) 21:35:43ID:j05CibA3
>>659
それのどこがやばいのかよく分からないなぁ。

>>664
本当に必要なものならクラス数は増えても良い気がするけど。
0667名前は開発中のものです。2007/12/23(日) 21:38:17ID:1bBLAr/H
.NETだったらコンパイルも早いし、dllに分けてスクリプト言語で書いたりもできるから
派生クラスで全部書いちゃってもいけそうだな
0668名前は開発中のものです。2007/12/23(日) 21:39:00ID:X8aN6eEV
>>664
ふつーは、プレイヤー弾クラス、敵弾クラスとか作って、そいつがパラメタを
ファイルから読み込む or スクリプト駆動にするわな。パラメタ変更では手に
負えないような差異がある場合(バラバラの弾とレーザーとか)は、そこを
クラスに切り出す。

どこまでプログラムで書いて、どこからスクリプト or データ駆動にするかは
センスの問題。何でもかんでもスクリプトで書くと、結局 C++ で書くより手間
かかるだけだしなw
0669名前は開発中のものです。2007/12/23(日) 21:41:05ID:5BsM8MRd
>>663
描画処理にキャラクターのデータを渡すだけでいいのですね。
図は全て継承の意で矢印を書いてしまいました。
継承と集約の相違点と関係を見直してもう一度はじめから考え直してみます。
>>665
確かに書き方が全く成っていませんね・・
ネットでUMLを説明してる所へ行ってみます!

ご指摘ありがとうございました。
大変ためになりました><
0670名前は開発中のものです。2007/12/23(日) 21:42:05ID:4U1OUhJg
このキーワードを出すと荒れそうだけど、やっぱりデザインパターンは
一通りかじった方が良いと思うよ。そうしたら、何が悪いか見えてくる。

あと、基本的に継承しまくるのは良くない。継承よりも委譲で処理した方が
スッキリする場面が多い。
0671名前は開発中のものです。2007/12/23(日) 21:44:24ID:X8aN6eEV
>>662
まずゲーム上の意味を持たず、単純に描画関連の処理だけ行うクラスを作る。
3Dモデル、2Dスプライトとかな。

その上で、次に、3Dならモデルのモーション制御用のクラスと、2Dスプライトなら
テクスチャアニメーションや拡大縮小アニメーションなどを行うクラスを用意する。

最後に、ゲーム的に意味があるクラス(技エフェクトクラスとか)は、上記クラスの
インスタンスをメンバ変数に持たせて使う。間違っても継承するなよ。
0672名前は開発中のものです。2007/12/23(日) 23:44:07ID:5BsM8MRd
>>670
>>671
なんでもかんでも継承すればいいというわけではないのですね・・・
is-a関係とhas-a関係をよく確かめます。
ありがとうございました。
0673名前は開発中のものです。2007/12/24(月) 01:50:39ID:EusYFrXZ
>>672
慣れてくると悟れるようになるけど、
HogeHogeUtil
っていう名前にできるものはオブジェクトにしちゃいかんよ。

StringUtil、DBUtil、CSVUtil、DrawUtil、SpriteUtil、etcetc...

こういう「いつでもどこでも使う」ものは、本質的に
状態を持たない(=オブジェクトにはならない)もの。
これらはスタティックに関数を定義しておけばそれでOK。
初心者はここを勘違いして地獄を見ることになる。

ま、慣れてくれば分かるさ。
0674名前は開発中のものです。2007/12/24(月) 03:14:08ID:vIQmZz28
そういう機能メソッドのstatic化って今までとても気持ち悪く感じていた。
C#の拡張メソッドみたいなものはもっと以前からあって然るべきだった。
0675名前は開発中のものです。2007/12/24(月) 08:33:00ID:IJjsYfw4
どうしてもクラスにしたいならシングルトンパターンだな
0676名前は開発中のものです。2007/12/24(月) 13:19:10ID:1XlkQ3N6
>>657
スクリプトでも下クラスでも同じだろ?

どっちに記述するかの問題だが
IDEサポートある環境ならクラスのほうが見通しやバグがへる
0677名前は開発中のものです。2007/12/24(月) 13:28:54ID:XKsRO39k
>>676
> スクリプトでも下クラスでも同じだろ?
スクリプトとかデータファイルだと、

1) 必要最小限のことしかできないように制限かけておく
2) 少ない記述量で済むようにする

から、量産するときに手間が減る。あとプログラマが一人で全部作る場合は
良いんだが、企画やスクリプタに調整してもらう場合は、開発環境そのまま
渡すのはいろいろコストが高くつく。
0678名前は開発中のものです。2007/12/24(月) 13:38:18ID:z6srLKkd
あとしょぼいとはいえ技術情報だだもれのうえソース持ち逃げ逃亡の可能性もでる(同人の場合)
0679名前は開発中のものです。2007/12/24(月) 14:26:45ID:1XlkQ3N6
>>677
いや、データの一元管理をしたいならクラスにまとめてかいとけばいい
だからどこに書くかどうかという程度の問題だからかわらん
外部ファイルだと整合性が取れない場合とかそういうことも考慮しないと
0680名前は開発中のものです。2007/12/24(月) 14:59:36ID:NAxUuQ7P
>>678
むしろ同人以上に仕事でやってるときのほうがソースの中とか見せたら危険すぎだね…

>>657
ま、そのくらいの規模になったらデータ化したほうがいいっすな。
0681名前は開発中のものです。2007/12/24(月) 15:11:02ID:XKsRO39k
>>679
> 外部ファイルだと整合性が取れない場合とかそういうことも考慮しないと
外部ファイルも事前にコンバートするから、そこで整合性担保するでしょ。

テキストで書いておいて、ツール使って実行時環境の構造体に直接マッピング
できる形に変換。実行時にテキストパーするなんて、エラーチェックの意味でも
実行効率の点でもありえんので。

開発効率に関してはたとえば、

 ATK=100,THROUGH=1

とか書くのと、

struct Shot1 : IShot {
  virtual int getAttackPoint() const { return 100; }
  virtual bool canThrough() const { return true; }
};

とするのと、どっちが楽かって話だよな。プログラマならともかく、それ以外の人間に
後者はありえんと思う。
0682名前は開発中のものです。2007/12/25(火) 00:11:32ID:AryQ9OX5
技術者以外でコードさわらせることってある?
その程度がかけない人を使う場合はツールつかうでしょ
0683名前は開発中のものです。2007/12/25(火) 07:00:22ID:kU76M/LQ
>>682
> 技術者以外でコードさわらせることってある?
ない。

人数増えると、開発環境をセットアップ・メンテナンスしたり、ソフトウェアの
ライセンス費用だけでも馬鹿にならんし。
0684名前は開発中のものです。2007/12/27(木) 14:55:37ID:IZhCMn6z
アクションゲームのプレイヤーキャラクター、エネミーの状態遷移はどう管理するべき?
タスクシステムとか使うんでしょうか?
0685名前は開発中のものです。2007/12/27(木) 18:41:38ID:WHA23eKG
Cならタスクシステムで良いと思うけどOOPでタスクシステムは勝手が悪いだけだぞ。

というかタスクシステムの話は荒れるからやめれ。
0686名前は開発中のものです。2007/12/27(木) 18:43:32ID:AMPsIlOq
>>684
単純に書くなら、プレイヤーとかエネミークラスのメンバ変数として状態変数を持たせる。

class Enemy
{
  enum STATE { STATE_INIT, STATE_LOAD, STATE_ATTACK, STATE_DOWN } m_state;
public:
  void exec() {
    switch (m_state) {
    case STATE_INIT:
       // 必要な処理。状態遷移は m_state の値を上書きすることで行う。
       break;
    case STATE_LOAD:
       break;
    }
  }
};

入退場動作を記述したいとか、状態遷移が複雑で手に負えなくなったら、
XML なり CSV なりで書いた状態遷移表から C++ のコードを自動生成する
トランスレータ書くとか、階層化状態をサポートするライブラリ (有名どころ
だと Boost Statechart とか) を入手して使う。
0687名前は開発中のものです。2007/12/27(木) 18:51:03ID:68c9oLh7
関連でboost FSMって言うのがあるんだけど
ゲームならこちらの方がいいかも
(state_chartと違ってコストがポインタ経由の関数呼び出しと同等程度)
0688名前は開発中のものです。2007/12/29(土) 19:02:05ID:51LlsxT5
>>684
こちらへどうぞ

タスクシステム総合スレ part2
http://pc11.2ch.net/test/read.cgi/gamedev/1196711513/
0689名前は開発中のものです。2007/12/29(土) 19:05:56ID:51LlsxT5
>>686
前に作ってたプロジェクトで、
30個くらい状態ができて、exec相当の関数が長くなりすぎ、
関数内関数にしたものの、死にそうに。

こういうときは、やっぱり、データ駆動にすべきなんかね
0690名前は開発中のものです。2007/12/29(土) 20:33:51ID:V6gceCEb
俺だったらまず階層化を考えるかな。
>>686の状態列挙子を

  enum STATE { STATE_INIT, STATE_LOAD, STATE_ALIVE, STATE_DEAD, } m_state;

と変更して、STATE_ALIVEのとき

  enum ACT_STATE { STATE_MOVE, STATE_ATTACK, STATE_DOWN, } m_act_state;

を参照するとかね。
0691名前は開発中のものです。2007/12/31(月) 13:37:37ID:abjuzRp8
>>689
関数の作成単位を処理毎 (exec(), draw()) から状態毎 (_stateAlive(),
_stateDead()) にして、各関数の中に exec, draw なんかの処理を
書くよう逆転させるとメンテナンスが楽になるよ。

実装はこんな感じ。
ttp://gameobj.issei.org/trac/wiki/HSM

それでも複雑になってきたら、更に状態ごとにスクリプトを貼り付ける。
状態遷移の入場動作でスクリプトを読み込み VM を設定、exec 相当の
処理ではスクリプトの VM を実行するように書く。

どこまで C++ で書いて、どこからスクリプトにするかは、一律の答えが
ないので難しい。作業を一人でやるか分担するかにもよるし、仕様変更を
どこにどれだけ見込むかにもよる。ただリソース(メモリとかテクスチャとか)の
確保・解放が絡んだら、経験上、そこは C++ で処理した方がトラブル少ない。
0692名前は開発中のものです。2008/01/02(水) 03:34:31ID:JuBEjuNy
実は、>>689の後のプロジェクトでは、苦肉の策で、
簡単な非階層型の状態遷移クラスを作って対処してた。

状態ごとに派生クラス作ると、しんどかったので(これもかなりやってた)
結局、できるだけ、簡易的にするために、
draw、exec はメソッドポインタにして、状態遷移クラスに持たせ、
状態遷移クラスのdraw、execでそれらを呼び出すことに。
これなら、派生クラスを大量に作る必要がなく、気が楽(笑)

呼びたい entity に、1状態につき、initialize_hoge、draw_hoge、exec_hoge メソッドを作り、
状態遷移時に(initialize_hoge内で)、状態遷移クラスにメソッドポインタを割り当て、遷移させてた。

まあ、結局、entityのメソッドが増えるのと、階層化ができないのがキズ。
階層化は、状態遷移クラスをさらに持たせて、実現してたけど
0693名前は開発中のものです。2008/01/02(水) 06:36:13ID:JuBEjuNy
>>691
ありがとう。

あー、逆の発想か・・・
ナルホ・・・

HSMは、(・∀・)イイ! って聞いてたけど、実際の実装を見たことがなかったので、
参考になります。
じっくり見てみる。

しかし、勉強セナあかんな・・・
0694名前は開発中のものです。2008/01/02(水) 20:15:35ID:chyomhKK
>>692
> これなら、派生クラスを大量に作る必要がなく、気が楽(笑)
GoF のステートパターンよろしく、状態ごとにクラスを作るか
それともクラス一つで済ませるかも場合によるよね。

AIとかシーンのように、各状態がそれなりに複雑で個別のメンバ
変数を大量に持つような場合は、状態ごとにクラス分けた方がいい。
アクションゲームのキャラクタ程度だと、クラス分けるとクラス間の
データ受け渡しの手間がかかりすぎ。
0695名前は開発中のものです。2008/01/05(土) 01:21:42ID:fugzpZ90
(゚Д゚)
0696名前は開発中のものです。2008/01/05(土) 01:23:01ID:fugzpZ90
(・∀・)
0697名前は開発中のものです。2008/01/11(金) 13:18:44ID:0lOBaoZM
age
0698名前は開発中のものです。2008/01/25(金) 11:38:57ID:J9K9o4zc
保守
0699名前は開発中のものです。2008/01/25(金) 20:32:41ID:cpC7cqhh
^^
0700名前は開発中のものです。2008/01/25(金) 20:33:24ID:cpC7cqhh
随分漏れのIDにCが多いな。
0701名前は開発中のものです。2008/01/25(金) 20:37:13ID:h6GX/EGa
VIAのCPUがいる
0702名前は開発中のものです。2008/02/02(土) 14:42:47ID:mI6LOL9z
ム板のクラス名・変数名に迷ったら書き込むスレ。Part11でメソッド名を質問している内に
設計を見直したくなったので誘導に従い引越して来ました。

C++で練習用にドラクエモドキ作っているんですが

class PlayChara{
int hp;
int mp;

public:
void receiveAttack(ATTACK_TYPE atk_type, ATTACK_POINT atk_point);
}

プレイキャラクラス自身に敵からのダメージを与える為のメソッドで
(攻撃のタイプと攻撃力の引数を受け取る)receiveAttackってのを検討したんですけど
設計そのものを見直したほうがいいでしょうか?

・攻撃者が.attackメソッドを持って引数に被攻撃者のパラメータを渡す
・攻撃用のクラスそのものを作る
0703名前は開発中のものです。2008/02/02(土) 14:49:42ID:nEhdyqU2
戦闘管理クラスみたいなので上からまとめてやっちゃう
0704名前は開発中のものです。2008/02/02(土) 14:53:31ID:72phXJxx
なんでそんな小難しく考えるのかわからん。
0705名前は開発中のものです。2008/02/02(土) 15:03:58ID:eaarCO+A
hp/mpをprivateにしてメソッドで操作するメリットは、
それらを操作するコードを制限できる点で、メンテナンス性向上を期待できる。

でも、ちゃんと管理できればpublicでも全く問題ないので、
このやり方で良いとも言えるし、このやり方でなくても良いと言えるけどねw
0706名前は開発中のものです。2008/02/02(土) 16:16:27ID:sj8x5kQa
>>702
ドラクエならダメージの計算はキャラによらず一律だし、ダメージが
発生するタイミングや順序も明確だから、他の人が言ってる様に
計算式を実装するのはプレイヤークラスではなく、戦闘の進行
管理やってるクラス。

キャラクターごとに持っているパラメタが全然違って計算式が
異なるとか、キャラクタの内部状態によってダメージあり/なしが
変わる、またリアルタム進行でダメージ判定などタイミングが
シビアな場合には、プレイヤークラス内部で計算した方が
やりやすい。対戦格闘とか一部のアクション RPG とか。

ただ、その場合は receiveAttack() というように攻撃専用の
メッセージにせず、回復やらダメージやら全部含めた汎用の
メッセージクラスを一つ用意して、

void sendMessage(Msg const* pMsg);

で送りつけてやったほうが良い。あと、メッセージは即処理せず
キューにためておいて、あとでプレイヤークラスのほうで都合が
良いようにソートしたりしてから処理するとか、インスタンスの
ポインタ直接使わずにハンドル管理にするとかした方が良い。
0707名前は開発中のものです。2008/02/02(土) 17:20:36ID:09h7GmI7
receiveAttack(ATTACK_TYPE atk_type, ATTACK_POINT atk_point)

damage(DAMAGE_TYPE dmg_type, DAMAGE_POINT dmg_point)
に改名すれば謎は全て解ける
0708名前は開発中のものです。2008/02/02(土) 19:05:26ID:NHG8vmrt
俺なら戦闘進行クラスに行動のプライオリティキュー持たせてコマンドパターン突っ込んでキャラクラスにキュー見せるかな。
でキャラクラスはストラテジーパターンで行動処理を分けると・・・。
キャラクラスはキャラごとにインスタンス化して行動処理はストラテジーに分離。

ぱっと思いついたがこんなもんか。
0709名前は開発中のものです。2008/02/02(土) 19:08:36ID:NHG8vmrt
忘れてた。
↑のコードをスクリプト言語内蔵してハードコーディングしないようにする。
0710名前は開発中のものです。2008/02/02(土) 19:11:17ID:sj8x5kQa
>>709
ドラクエだと、コアロジックのスクリプト化は要らん気がするなぁ。

俺ならスクリプト指定にするのは、エフェクトとか SE 再生とかの種類・
タイミング制御と、あとはパラメタの定数設定ぐらいか。
0711名前は開発中のものです。2008/02/02(土) 19:48:03ID:KbmRx+Ru
スクリプト化するかどうかとかは開発において本質的な部分じゃないし
今回の実装方法の話は好きにしろとしかいえんね
07127022008/02/02(土) 21:06:24ID:mI6LOL9z
>>706
有難うございます。

なるべく他のアクションゲームとかにも流用できる汎用性の高い作りにしようと
思っていたのでリアルタイムに仕様変更があっても対応できるように後者のような感じ
でやってみようと思います。

取り合えずクラス候補としてこんな感じでいこうかと。

・プレイキャラ(敵キャラ含む)
・成長管理
・戦闘管理
・シナリオ進行管理
・コマンドメニュー
・アイテム(装備品含む)
・ステージ(街、ダンジョン、フィールド含む)
・ショップ
・酒場(キャラ登録、出し入れ管理)
0713名前は開発中のものです。2008/02/02(土) 21:25:25ID:sj8x5kQa
>>712
ふつーのRPGにするなら、まずシステム全体を
・戦闘
・フィールド
・デモ(イベント)
に分割して、それぞれの間のツナギを緩やかにしておく(直接インスタンス
参照せずに、パラメタ渡して立ち上げるようにする)、さらにサブシステムを
切り替えるときには画面ブラックアウトさせるようにしておくのが敷居低いよ。

装備品や戦闘中に利用できるアイテムに関しては戦闘システムに密に
絡むので、装備品のパラメタとして何をどう持たせるかなどは戦闘システム
中心で考える。

プレイヤーに関しても、戦闘で利用するプレイヤークラスとフィールドで利用
するプレイヤークラスは別にしとく。戦闘側プレイヤークラスではアイテムの
戦闘中効果や使用可/不可の管理なども要るけど、フィールドだと個数や
値段だけ管理しとけば良いから、必要な情報が全然違う。
0714名前は開発中のものです。2008/02/02(土) 22:11:59ID:RVYU4pub
俺今Java MEのMIDP上に汎用のゲームミドルウェアとほかのライブラリに組み込んで使う
AVGエンジン作ってるが設計は使ってる言語とプラットフォームによると思う。

たとえばCだとOOPが言語仕様にあるわけじゃないから再利用性のあるライブラリは作りにくいと思うし、
MIDPみたいなリソースが限られてる環境上だと制限多いし。
0715名前は開発中のものです。2008/02/02(土) 23:15:59ID:ld1ta0/w
>>713
> プレイヤーに関しても、戦闘で利用するプレイヤークラスとフィールドで利用
> するプレイヤークラスは別にしとく。

あ、それでいいんだ。
現にそうやってRPGのクラス設計してたけど、もしかしたらマズイやり方なんだろうかと
不安になってたとこ。これで前進できるよ〜。
0716名前は開発中のものです。2008/02/02(土) 23:17:36ID:sj8x5kQa
>>714
> たとえばCだとOOPが言語仕様にあるわけじゃないから再利用性のあるライブラリは作りにくいと思うし、
それはない。ただ設計が OOA/OOD じゃなくなるだけ。

むしろソース非公開でライブラリ配る場合は C++ より C の方がバイナリ
互換性を維持するの楽だし。C++ だとメンバ変数ひとつ加えただけで
バイナリ互換性崩れるから COM のようにインターフェースと実装を厳密に
分離するような細工が必要になってくる。

社内ライブラリとかでも公開 API は extern "C" してあって、中が C++
なんてのは未だに良くある。
0717名前は開発中のものです。2008/02/02(土) 23:22:17ID:sj8x5kQa
中身も全部 C っつーのも、もちろん良くある。
0718名前は開発中のものです。2008/02/03(日) 02:15:42ID:nv4LC70S
見てる人自体は結構いるんだなとしみじみ感じた。
0719名前は開発中のものです。2008/02/03(日) 15:45:30ID:nX/UP8ww
全部ベターCってのもまだいるな
0720名前は開発中のものです。2008/02/05(火) 01:04:17ID:EmCkbq3D
さすがにそれは設計だのライブラリ配布だの以前の
0721名前は開発中のものです。2008/02/05(火) 15:29:46ID:jyHjb4Ol
C++でオブジェクト指向を生かすにはゲームはちょっときつい
フラグメントの問題が面倒だしな

PCのようにリソースが多い場合はJava等でOpenGLベースで作ったほうが楽かも
0722名前は開発中のものです。2008/02/05(火) 17:47:40ID:gWVvLPR2
VGAドライバーのバグがどうしても回避できないからイマイチ安定しないよ、JOGL。
fpsはかなり出るんだが。
0723名前は開発中のものです。2008/02/05(火) 20:50:19ID:jyHjb4Ol
>>722
具体的に

JOGL単体だと不具合はまずでない
0724名前は開発中のものです。2008/02/05(火) 21:18:49ID:njRVzy5T
>>721
> C++でオブジェクト指向を生かすにはゲームはちょっときつい
PS2 の頃から、ゲーム部分はほとんど C++ だよ。
0725名前は開発中のものです。2008/02/06(水) 01:01:34ID:15llbTQ/
C++ に GC 付きの軽量スクリプト載せるのが主流じゃね?
フラグメントがどうとか言ってメモリのやりくり縛ってるような人は、
GC 付き言語は絶対導入しないってことなんだろうか?
0726名前は開発中のものです。2008/02/06(水) 01:37:49ID:imNHr76c
>>273
GF7600GTと特定のドライバで出る。ドライバのバグだといっただろJOGLの問題じゃない。
後はググレ
0727名前は開発中のものです。2008/02/06(水) 02:46:02ID:G+IyjTNG
>>725
コンシューマとかサーバーとかは普通に気にするだろ
だから、素の状態だと使えん
GCつきなら問題はないが、フットプリント大きくなるからコンシューマでは採用しにくい

>>726
そんな特定のドライバで動かないといったらそんなのは大量にあるわけだが
0728名前は開発中のものです。2008/02/06(水) 06:22:47ID:8gln52JP
>>727
> コンシューマとかサーバーとかは普通に気にするだろ
メモリに関しては断片化と使用量の問題がある。

断片化はモデル・テクスチャ・モーションといった数百KB単位の
リソースデータと C++ インスタンスのようなせいぜい数KB程度の
データを混在させると問題になる。最初からヒープ領域を分けて、
リソースに関しては
・事前に複数ファイルをアーカイブして1つにまとめておく
・ファイル読み込み領域を階層化して管理
・用途によっては固定長で
とすることで解決できる。

使用量は頑張れとしか…

>>725
GCつきの言語は使ってないなぁ。lua とか悪くないとは思うんだが。

メモリ使用量やCPU消費が読めないのと、そもそもスクリプタに
高度なロジック書かせない方針なので、そこまで高機能な言語は
要らなかった。

ストラテジー系のゲームで AI とかスクリプト化するとなると、Lisp
系言語を使うかもしれん。実装簡単だし。
0729名前は開発中のものです。2008/02/06(水) 16:16:10ID:G+IyjTNG
>>728
だから、素の状態では使えないと書いた
固定長とかしばってるとC++らしいオブジェクト指向のコードが書けなくなる

結局クラスが名前空間程度のベターCでおわってしまう
0730名前は開発中のものです。2008/02/06(水) 19:03:53ID:P+v/9YuT
D言語で良いんじゃね?
バグだらけだが
0731名前は開発中のものです。2008/02/06(水) 21:38:48ID:8gln52JP
>>729
> 固定長とかしばってるとC++らしいオブジェクト指向のコードが書けなくなる
断片化が問題になるのはリソースデータだから、そっちだけ固定長とか
縛り入れる。

他は気にせず new しても、ヒープ多めにとっておけば大丈夫だよ。
0732名前は開発中のものです。2008/02/07(木) 02:50:44ID:Q4eXpMLP
>>731
newとdelete繰り返しているとフラグメントがぐちゃぐちゃに
0733名前は開発中のものです。2008/02/07(木) 04:12:05ID:jx59zphN
つプールかスラブ
0734名前は開発中のものです。2008/02/07(木) 08:58:00ID:iWwJi06c
>>732
ゲームの場合はたいていインスタンスの寿命が入れ子状になってて、
寿命がやたらに長いインスタンスが不定期のタイミングで作成される
ことは少ない。

delete されたときに、積極的に前後のアドレスの空きスペースと融合
するたいぷのメモリアロケータ使ってれば、そんなに酷いことには
ならんよ。

これがサーバ系だと、また話が変わって来るんだが。
0735名前は開発中のものです。2008/02/07(木) 09:25:32ID:vAX6bai3
>>706
702じゃないけど、なんか目からうろこだわ。Thanks!!
0736名前は開発中のものです。2008/02/07(木) 16:22:59ID:YGBnt0cR
new を使わなければすべて解決
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 シンボルで扱えるようにして下らないバグを
出さないようにするとか、断片化防ぐためにメモリのセグメント分割するとか、いろいろ
あるけど。
■ このスレッドは過去ログ倉庫に格納されています