[表示 : 全て 最新50 1-99 101- 201- 301- 401- 501- 2chのread.cgiへ]
Update time : 07/21 13:53 / Filesize : 166 KB / Number-of Response : 549
[このスレッドの書き込みを削除する]
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧] [類似スレッド一覧]


↑キャッシュ検索、類似スレ動作を修正しました、ご迷惑をお掛けしました

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



1 名前:名前は開発中のものです。 [2008/05/23(金) 21:10:59 ID:8M1gqhPX]
具体的なゲーム名を挙げて、
どのようにクラス設計をすればよいか、
継承・委譲関係はどのようにすればよいか、
使えそうなパターンは何かなど語るのもよし。
自作ゲームの内容とクラス図を書いて
改善案を聞くもよし。
設計に関して困ったことを質問するもよし。

関数の具体的な実装内容やゲーム内容に関しては他スレに譲る。
大いに語れ。

前スレ
pc11.2ch.net/test/read.cgi/gamedev/1155209226/

テンプレ追加事項あったらよろすく

501 名前:名前は開発中のものです。 mailto:sage [2009/03/18(水) 23:45:50 ID:1sOkzJT6]
デバイスに直接アクセスする処理ってどこに書いてる?
今まであちこちに散らばって状態で書いてたんだけどなんか扱いづらい。
下みたいな感じで一箇所にまとめた方がいいのかな。

今:あちこちでデバイスにアクセス
void draw_landform(void) {
  ...
  lpD3DDEV->draw(...);
}
void draw_menu(void) {
  ...
  lpD3DDEV->draw(...);
}

案:デバイスアクセスは1箇所。デバイスに渡すデータをあちこちで作る。
const DrawData *draw_landform(void) {
  ...
  return ...;
}
const DrawData *draw_menu(void) {
  ...
  return ...;
}
void main_loop(void) {
  draw_data.push(draw_landform(), ...);
  draw_data.push(draw_menu(), ...);
  lpD3DDEV->draw(draw_data, ...);
}

もし既に案の方法でやってる人いたら使い勝手教えて!

502 名前:名前は開発中のものです。 mailto:sage [2009/03/19(木) 04:54:27 ID:KYbRBn+z]
久々に答え甲斐のありそうな相談が来たな
だが俺はモーションインデックスとベクトルをリストに投げて後で一気に処理する方法だから答えられそうに無い
お前らに任せたぜっ!

503 名前:名前は開発中のものです。 mailto:sage [2009/03/19(木) 05:21:17 ID:XLj1eEa+]
描画能力のあるオブジェクトをリストなりグラフなりに登録しておいて、デバイスハンドルはビジターで渡す、とか。

504 名前:名前は開発中のものです。 mailto:sage [2009/03/19(木) 19:28:19 ID:ALN5WhPj]
俺はこの案では無いなぁ…てかどうせなら
lpD3DDEV->draw(draw_data, ...);

draw_data.draw(...);
みたいにしてlpD3DDEVに直接アクセスしない方が…

505 名前:501 mailto:sage [2009/03/20(金) 00:10:41 ID:/TREybMM]
レスありがとう。

>>502
「案」の方に似たやり方だよね? draw_dataがリスト相当で。
やっぱやってる人いたか。採用してるってことは使いやすいんだろうか

>>503
void LandForm::draw(LPDIRECT3DDEVICE9 lpD3DDEV) {
  ...
  lpD3DDEV->draw(...);
}
みたいな感じ?
デバイスに直接アクセスする処理が複数のクラスに散らばるのはOKという判断?
この方が使いやすいってことかな? うーん。。。

>>504
Draw_data::draw(...) {
  this->lpD3DDEV->draw(this->draw_data, ...);
}
こんな感じ? ラッパー作れって話?
「案」ではないってことは 503 さん宛てのコードと同じ感じでやってるのか

うーん、デバイスクラスに依存するクラスが増えると身動き取りづらくなると思うんだけど
気になる人って少ないんだろうか。
0人では無かったけれど。


506 名前:名前は開発中のものです。 mailto:sage [2009/03/20(金) 02:39:39 ID:D2lp0Ec4]
まずはMVCを試みてみるのはどうだろうか

507 名前:名前は開発中のものです。 mailto:sage [2009/03/20(金) 04:52:36 ID:09EDEaYz]
struct Visitor;
struct Element { // 訪問される側の基底クラス
    virtual void accept(Visitor&) = 0;
};
class Landform : Element {
public:
    virtual void accept(Visitor& x) { x.visit(*this); }
    Data* getLandData();
private:
    ...
};
class Menu : Element {
public:
    virtual void accept(Visitor& x) { x.visit(*this); }
    Data* getMenuData();
private:
    ...
};

struct Visitor { // 訪問する側の基底クラス
    virtual void visit(Landform&) = 0;
    virtual void visit(Menu&) = 0;
};
class DrawingVisitor : Visitor { // 各要素を訪れて描画を行うクラス
public:
    DrawingVisitor(LPDIRECT3DDEVICE9 p) : pDevice(p) {}
    virtual void visit(Landform& x) { pDevice->draw(x.getLandData()); }
    virtual void visit(Menu& x) { pDevice->draw(x.getMenuData()); }
private:
    LPDIRECT3DDEVICE9  pDevice;
};
続く…

508 名前:名前は開発中のものです。 mailto:sage [2009/03/20(金) 04:53:53 ID:09EDEaYz]
…続き
elementList.push_back(landform);
elementList.push_back(menu);

void mainLoop() {
    DrawingVisitor visitor(lpD3DDEV);
    for(ElementList::iterator i = elementList.begin(); i != elementList.end(); ++i) {
        i->accept(visitor);
    }
}

うーむ…。

509 名前:501 mailto:sage [2009/03/21(土) 12:54:05 ID:Y4F/PoMw]
>>506
今回の話ではModelとControllは関係なくて、Viewの枠内だけで完結する話だと思ってる

>>507
複雑すぎて俺の頭では完全には理解できないけど、
>    virtual void visit(Landform& x) { pDevice->draw(x.getLandData()); }
>    virtual void visit(Menu& x) { pDevice->draw(x.getMenuData()); }
ここを見るとデバイスに直接アクセスする処理を1クラス内、複数関数にまとめたって感じかな

うーん…、複数の関数にデバイスアクセス処理が分散してるとこがあまりうれしくないかな。
(俺には複雑過ぎるのはさておき)


俺が扱いづらいと思ってるところは、
pDeviceさえあればdraw()以外にもbegin_render()とかset_camera()とかいろいろ
デバイスに対して変更加えることができちゃうわけで、
それをばら撒くってことはいつどこでデバイスに変更が加わるか、例えばいつどこで何回begin_render()されてるのか
とかが追跡しづらくなる。これは1週間後の自分に優しくない。

こんな感じでデバイスに直接アクセスする処理をどう管理したもんかと考えて
ひとつの対策案としてデバイスアクセス処理を1関数内に限定しちゃえってのが >>501 の「案」。
だから例えば複数の関数に同一デバイスへのアクセス処理が分散してるのは自分的には問題が解決していないと感じる。



510 名前:名前は開発中のものです。 mailto:sage [2009/03/22(日) 03:32:29 ID:O7e3N6nq]
描画するにはデバイスに対して様々なパラメータを設定しなけりゃならんわけだが
>>501だとそこをどう処理するのかがよく分からない。
各オブジェクトには描画スクリプトみたいのを作らせておいて、draw()がそれを解釈して描画とか?
そうじゃないなら、結局デバイスをやりとりしなきゃならなくなるような。

511 名前:501 mailto:sage [2009/03/23(月) 00:38:25 ID:/nVLLFvd]
>>510
確かに。描画スクリプトかー、どうしよう。
ポリゴンの描画順番の最適化とかやり始めたら必要になりそうな気もするけど
今の自分のプログラムでは大げさすぎるかなぁ。今のところ2D的にしか使ってないし。
あとデバイスってサウンドとか入力装置とかもあるけど、それらもおんなじ感じで取り扱いたいし。

デバイスにアクセスする処理が関数1個の中に「ひとまとまりで」収まってればOKとするなら
下のように書いて済ませられるかな?
void dev_state1(void) {
  lpD3DDEV->BeginScene();
  lpD3DDEV->set_parameter(...);
  lpD3DDEV->draw(draw_landform(), ...);
  lpD3DDEV->set_parameter(...);
  lpD3DDEV->draw(draw_menu(), ...);
  lpD3DDEV->EndScene();
}

ひとまとまりってのは1フレーム分のデバイスアクセス処理全部。
描画内容を大きく変えたい時はdev_state2()とかをまた別に作っておいて、
ゲームのステートに応じてどれを実行するか切り替える。


なんか描画スクリプトの方が夢があるな。
外部GUIツールで描画内容を設計して
吐き出した描画スクリプトをゲームで解釈して表示とかおもしろそう。
でも描画システムの根幹過ぎて汎用的に作るのめんどくさそう。。。

うーん、とりあえず簡単に済ませたいからdev_state1()みたいにベタ書きで
どこまでいけるかやってみるかな。






[ 続きを読む ] / [ 携帯版 ]

前100 次100 最新50 [ このスレをブックマーク! 携帯に送る ] 2chのread.cgiへ
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧]( ´∀`)<166KB

read.cgi ver5.27 [feat.BBS2 +1.6] / e.0.2 (02/09/03) / eucaly.net products.
担当:undef