1 :
名前は開発中のものです。 :
2006/08/10(木) 20:27:06 ID:BnvyxuCB 具体的なゲーム名を挙げて、 どのようにクラス設計をすればよいか、 継承・委譲関係はどのようにすればよいか、 使えそうなパターンは何かなど語るのもよし。 自作ゲームの内容とクラス図を書いて 改善案を聞くもよし。 設計に関して困ったことを質問するもよし。 関数の具体的な実装内容やゲーム内容に関しては他スレに譲る。 大いに語れ。
2 :
名前は開発中のものです。 :2006/08/10(木) 20:45:47 ID:X/dQa2Wp
はっ、意味不明
設定提案とヲチと批判しかできないこの過疎板で 技術を語れるかが見物だ。
4 :
名前は開発中のものです。 :2006/08/10(木) 22:23:22 ID:BnvyxuCB
抽象的過ぎたからひとまずお題を挙げておくか。 ⊃「パックマン」 敵に関しては、敵の抽象クラスを継承したサブクラスで 移動アルゴリズムをオーバーライドするよりも、 アルゴリズムを別のクラスで用意して それに対する参照を敵のクラスに持たせる方がいいのかな?
+-----------------------+ | CEnemy | +-----------------------+ | move() | | (strategy->execute()) | +-----------<>----------+ | strategy | | +-----V-----+ | Strategy | +-----------+ | execute() | +-----A-----+ | +------+---------+----------+ | | +------+-------+ +------+------+ |AkabeeStrategy| |PinkyStrategy| +--------------+ +-------------+ | execute() | | execute() | +--------------+ +-------------+ クラス図で書くとこうなるのか?まあ絶対ズレているだろうがな…。 俺自身は超初心者だから間違いがあったら指摘お願い。
ちょw いくらなんでもズレすぎだ…。
パックマンごときに大げさなパターンはいらねべ。 敵キャラの個別化をしたければテンプレートメソッドパターンぐらいで十分。 好きにすればよい。
>>7 確かにその通りなんだが、
まあいきなり大規模なものを持ってきても
話しづらいかなと思って。
一応
>>5 のズレ直しverを貼っておこう…。
+-----------------------+
| CEnemy |
+-----------------------+
| move() |
| (strategy->execute()) |
+-----------<>----------+
| strategy
|
|
+-----V-----+
| Strategy |
+-----------+
| execute() |
+-----A-----+
|
+------+------------+----------+
| |
+------+-------+ +------+------+
| AkabeeStrategy | | PinkyStrategy |
+--------------+ +-------------+
| execute() | | execute() |
+--------------+ +-------------+
シューティングゲームの敵と敵から打たれるミサイルなんかは、 ファクトリメソッドパターンかな・・・
11 :
名前は開発中のものです。 :2006/08/11(金) 00:24:48 ID:C/hX80Tz
「こういうキャラに対しては何ちゃらパターンが使えるな」 みたいなことは大体わかるのだが、 全体をまとめようとするとうまくいかないのはオレだけか?
同じ方向に話を進めるためには タスクシステムの内容を統一した方がいいんじゃね??
名スレの予感
15 :
名前は開発中のものです。 :2006/08/11(金) 07:46:49 ID:8h85L6qq
ClassのCじゃねぇの。
MFCを知らんのか?
うん、普通に知らない。
charだけあれば他は要らない
Cつけるのはダサいからやめろ。
じゃあ、なにつければいいのさ?
そのクラスを直感的に理解できるよう努力すれば他に何もいらない
Cつけるの癖になってるなぁ。
コードスタイルはクラス設計とは関係ないだろ Cの1文字ぐらい脳内削除できんのかね
大文字で始まる名詞はクラス以外ありえないから、無意味に邪魔なゴミつけるんじゃないよ。 今出回ってる雑誌や書籍、それにオープンソースのコードに Cつけてるものがどれほどあるか見てみろ。 MSなんか、C#では逆にCを「つけるな」と言ってるしな。 >コードスタイルはクラス設計とは関係ないだろ わざわざ変なスタイルを使うやつは、高確率で変なクラス設計をする。 普通にコードを書く気が最初からないんだから。
26 :
名前は開発中のものです。 :2006/08/11(金) 15:37:25 ID:mPv7ZiBt
>>25 コードスタイルについてはごもっともだけど、
>わざわざ変なスタイルを使うやつは、高確率で変なクラス設計をする。
って誰が言ってたのさ。統計とったの?
そうですか、あなたの経験上ですか。では、変なクラス設計の基準はどこに?
>>25 お前の言っていることは間違いではないが、焦点がズレているな
俺が言いたかったことは、
>>9 の敵クラス名がCEnemyだろうがEnemyだろうが
クラス図には何の影響もないということだ
変なスタイルを使う奴は云々という決め付けはいらない
設計がそこに転がっているんだからその優劣を語ればよい
>>25 何でそんなに興奮してるんだ?
コードスタイルは分かりやすさ、第一。
別にコード公開する気もないし。
>>7 Template Methodパターンだと、実行時に移動アルゴリズムを
変更したくなったときに面倒じゃないか?
パックマンがパワー餌を食べたことがMediatorを通して
通知されたとき、strategyを逃げるアルゴリズムに
変更すれば、同じ呼出しで適切な移動が可能。
まあ、オリジナルだと逃げるアルゴリズムは共通だから
それは組み込んでおいて通常移動はオーバーライドでも
問題ないけど、通常移動も動的に変更したいのならStrategyかな。
実際問題、パックマンを作るのにここまで慎重に設計する必要は
ないが、設計スレだし色々探ってみるのがよさそうだ。
>>30-31 SUGEEEEEEE!!!
英語苦手だけど頑張って読んでみるか。
>>31 おぉ、トンクス。参考になりまつ。
やっぱり並列化も次世代機を考慮すると重要なトピックになりつつあるんだなぁ…
シングルコアを使い切る→マルチスレッド マルチコアを使い切る→並列同時実行
お前ら!TCBを格納するのに何使ってる? STLのlist使ってたんだけど、 動的メモリ確保で遅くなるから配列を使った方がいいと聞いて…。 それから単方向ではなく双方向リスト構造にする利点があれば教えてくれ。
やだ
>>29 >Template Methodパターンだと、実行時に移動アルゴリズムを
>変更したくなったときに面倒じゃないか?
フラグのOF/OFFの分岐でいいべ。パックマン程度だったらその方がずっとコード
が分かりやすい。移動パターンが何種類もあると言うんだったら別だが。
ゲームプログラムでMediator使うの微妙じゃね? オブジェクト同士が相互作用しまくりで 処理内容が多岐にわたるゲームの場合、 updateしたよあとよろしくね♪じゃMadiatorの仕事が多すぎる。 結局俺の場合、例えばシューティングで当たり判定をとるんだったら 自機インスタンスへのポインタを敵のクラスのメンバに持たせたり 自機インスタンスをグローバルにしちゃったりする。 よくないことはわかりつつも。何か良い方法はないものかね。
39 :
38 :2006/08/13(日) 02:36:16 ID:o/UAG1nJ
ん?もしかしたら俺は物凄く馬鹿な勘違いをしていたのかもしれん。
今までは、Mediatorクラスが持つ関数は
呼び出し側の参照を引数として取るupdateただひとつだけで、
updateは引数から得られる情報を元に適切な処理を選択し、
適切なオブジェクトに通知するのだと思っていた。が、
Mediatorに複数の関数を持たせて
呼び出す側が選択するというのもありなんだな。
例えば当たり判定処理のためのhitCheckとか。
タスクリストを持つクラスにMediatorを兼任させるのもありか。
ごちゃごちゃするが。
>>35 listのままでおk
この板ですごい久しぶりの良スレ候補だ。
>>38 まぁゲームシステムにもよるだろうなぁ。自機が一機しかなければ
自機クラスにMediatorの仕事やらせてもまず大差ないだろうし。
弾のような飛び道具出すにしても、
自機の敵キャラクタのインスタンス配列をそのまま渡せば
そこまで複雑になるとも思えない。むしろこっちの方が楽そう。
マリオみたいに敵同士の当たり判定がある場合は、
Mediatorみたいなものは必須だと思うけど。
42 :
名前は開発中のものです。 :2006/08/15(火) 01:28:43 ID:mFMpUmTh
デザパタ話か… 昔、GraphicsクラスやらInputクラスやらを シングルトンにしようとしたが、初期化するための引数が多いせいで Graphics.getInstance()なんて簡潔な呼び出しをすることが 不可能だと気づいて泣いたぜ
>>42 initializeメンバ関数を別途用意して最初の方で呼び出せばいいだけの話じゃ?
>>43 それやるくらいなら俺はシングルトンパターンを適用せずに
フィールドを全部staticにする
初回のgetInstance()呼び出しでコッソリ初期化、
表面上は初期化いらずな点がシングルトンの利点だと勝手に思っているから
Monostateパターンか
Mediator処理関数の呼び出すべき順番が決まっているのに 呼び出し側のタスクがその順番で並んでいないときは発狂する。
47 :
名前は開発中のものです。 :2006/08/19(土) 01:00:05 ID:aLDfzS42
48 :
名前は開発中のものです。 :2006/08/19(土) 10:25:32 ID:IzB67zRr
このスレでよく出てくるタスクって何の事?
49 :
名前は開発中のものです。 :2006/08/19(土) 10:59:20 ID:Br4d5o3I
タスクシステムの考え方は海外ではあまり見ない和製概念だね 向こうではDDAやらエンジン単位でのアーキテクチャが主流なのかな
51 :
名前は開発中のものです。 :2006/08/19(土) 12:16:19 ID:IzB67zRr
タスクシステムって要はリストの事なの?
タスクコントロールブロックがリスト構造を成しているとは限らない。
オレはCompositeパターンを使ってTCBをTreeにしている。 こうすると走査が面倒ななるから、必要なTCBだけMediatorに登録。
シューティングゲームなどで、C++タスクシステムにおいて、 敵管理タスクが当たり判定や弾の狙い撃ちをするために、 自機タスクから座標などの情報を取得するにはどうすればいい?
今北お!
モデルの実装は普通にやればいいと思うんだけれども、
たとえば
>>9 のパックマンでキャラ画像情報とかって
どこに持つ?
で、アルゴリズムとどうやって結びつける?
俺はなんかもう面倒くさくなって全部一緒になってんだよねー(最悪)
>>54 多分、自機情報がグローバルにあるんだと思うよ!
57 :
名前は開発中のものです。 :2006/08/23(水) 20:55:16 ID:Y+7SXF19
パックマンクラスかな
>>55 画像情報がビットマップなんかのことだったら殆ど別だな。
ゲーム総まとめクラスから
キャラの座標値、アニメーションインデックス値を吐かせて
それを画像クラスに投げてる。
【敵機(Enemyクラス)が自機(Playerクラス)の座標の取得する場合】 (GetXY()となっているが、XとYを別々に取ってきても構わない) ・そもそもクラスにまとめていない or 自機も敵機もごちゃ混ぜクラス。 自機の座標の取得には苦労しないよ派。 ・Playerのインスタンスplayerがグローバル。 player.GetXY()で座標を取ってくるよ派。 ・PlayerがSingleton。 Player::Instance().GetXY()で座標を取ってくるよ派。 ・PlayerがMonoState。 player.GetXY()もしくはPlayer::GetXY()で座標を取ってくるよ派。 ・Enemyクラスがplayerへのポインタを保持。 player->GetXY()で座標を取ってくるよ派。 ・enemyがMadiatorに自機の座標の取得を要求。 Madiatorがplayerの座標を調べて返してくれるよ派。 ・playerやenemyが属する統括クラス(GameとかTaskListとか)に enemyがアクセス可能。 Game.(->)GetPlayer()->GetXY()で座標を取ってくるよ派。
61 :
名前は開発中のものです。 :2006/08/24(木) 20:19:35 ID:ioVHmuR2
>>59 キャラの座標やアニメーションインデックス自体は、
やっぱり
>>9 でいうCEnemyにあるんだよねぇ?
それを総まとめクラスが集約してるみたいな構造かなぁ。
その設計だと、ダーティ領域を消すための前回のスプライト位置は
画像クラスに持ってるんだろうか?
62 :
名前は開発中のものです。 :2006/08/25(金) 07:38:55 ID:hwdyVz4L
アニメーションインデックスは CEnemyのメンバとして直接持つのではなく、 委譲関係にあるインデックス管理クラスが持った方がいいかな。 インデックス管理クラスはmap<String, list<POINT> >みたいな構造にして、 動作の名前を与えるとPOINT構造体を返してくれるというような。
>>61 総まとめクラスにインデックス値を吐かせてるのは
それがフレーム管理もやってるから。
インデックス値はCEnemyには持たしていない。
毎回背景から再描画してるんで、
前回スプライト位置は保持していない。メンドイし。
>>63 >総まとめクラスにインデックス値を吐かせてるのは
>それがフレーム管理もやっているから
いやそれ全然理由になっていないと思うぞ…。
65 :
63 :2006/08/25(金) 20:56:45 ID:cXY4CALt
あれ?自分で書いておいて訳わかんねw 作ったまとめクラスよく見たらフレーム管理はしてなくて、 1フレーム進めるメソッドがあるだけだった。 んで、そのメソッドを実行するたびに 0〜(アニメーション数-1)までくるくる回す インデックス値のメンバがそこにあった。 数ヶ月前に書いたソースを思い浮かべながら書いたら 記憶があいまいで勘違いしてた。スマソ
66 :
名前は開発中のものです。 :2006/08/26(土) 02:58:51 ID:MLjkH/sO
>>65 それをやると、敵を生成したタイミングにかかわらず
同じ敵が同じ状況で常に同じモーションをとることになるな(行進みたいに)。
俺はモーションをバラにさせたいときは
>>62 みたいなクラスを敵クラスに持たせ、
あえて統一したいときはそれを敵リストクラスに持たせている。
67 :
名前は開発中のものです。 :2006/08/27(日) 01:28:02 ID:AkzK5166
簡単なことを難しくやる典型例みたいな… やっぱしゲームには過度なオブジェクト指向は必要ないかなあ
3Dゲームはオブジェクト指向無しではやってられまへん。
>>67 このスレに書かれているようなクラス設計を
どんな規模のゲームにでも毎回採用している奴はいないだろう。
採用した方がむしろ簡単になったり、差し替えが楽になったり
するようなところに適用すればいい。
パックマンとかシューティングとかは説明例に利用されているだけだし。
ゲームに過度なオブジェクト指向は必要ないというのはちと早計。
72 :
63 :2006/08/27(日) 12:10:26 ID:f+3tvpuV
>>66 まぁ漏れの場合はそこまで凝ったシューティングじゃなかったし。
もっと拘ると最終的にそれに近くなってくるだろうなぁ。
>>67 難しいか?このくらいじゃ慣れの問題でしょ。
大規模なゲーム作るとなると設計をちゃんとしなければ
取り返しがつかなくなって訳若布になる。
それに、そこで作ったコードを再利用するなら
他のゲームも自動的にオブジェクト志向なコードになる。
そこに時間という足かせとのバランスを考慮するんだろ
過度のオブジェクト指向はゲームじゃなくても要らないっしょ。
過度なんだから。
まぁ、でもパックマンに
>>9 ぐらいの設計は全然アリだよね。
CEnemyを直接継承しちゃうかな。俺は。
75 :
名前は開発中のものです。 :2006/08/27(日) 20:51:21 ID:e75LZdTl
ゲーム固有のコード全てを持つクラス の名前ってどんな風に付けますか? Game だと(他のタイトルのコードと)紛らわしいし、ゲームタイトルって選択もあるだろうけど 開発を始めたばかりの頃に気の訊いたタイトルを思いつけるとも限らないし・・・ 参考までに聞かせてください
ゲームのすべてのコードが含まれてるなら後で変更しても問題ないんじゃないの
たとえばJavaならeclipse様の力で名前なんかどうにでもできるんだが、 そういうツールがない場合、開発コード名をつける。
79 :
名前は開発中のものです。 :2006/08/30(水) 08:47:32 ID:nhdG+7sO
良スレだと思うのだがなかなか伸びないな。 やはりこの板は設計論より実装論が先立ってしまう人が多いからだろうか…
単に内容について来られる奴が予想以上にいない説。
スクリプタやプログラム初心者が多いこの板では
このスレでメインに置かれているC++自体がまず敷居高し。
加えてタスクシステムやデザインパターン等の前提知識が必要だし、
ある程度作り慣れた人でないと語られている手法の有用性がわからない。
っていうか
>>2 が端的にこのスレの性格を表している気がしなくもない。
イベント駆動型で作れないかな
パズルゲームとかなら
むしろ糞スレ化せずに80以上のまともなレスがあるのが奇跡だよなぁ。
実装論先行型が多いと思う デザインパターンって人に伝えるために作られたものだと思う 一人で作ってる分には必要ないんでない? あとオブジェクト指向はホント必要、いやまじで、ないと軽く逝ける どこまでやればオブジェクト指向ってのかは謎だけど とりあえずデザインパターンとあまり関係ないんだが クラスの作り方どうやってるか聞きたい 複雑な行動パターンをお手軽に実装できる方法とかない?
C++で、クラス関連の機能から触り始め テンプレートの書き方やSTLライブラリまで一通り勉強したけど デザインパターンにはまだ触れたことがない 今のところ、機能ごとに切り分けたクラスを作りためながら 自前のゲーム用ライブラリを構築するだけで満足してしまってる
どうでもいいことを突っ込まずにはいられない >85 >STLライブラリ 頭痛が痛いです
知ってるがな どうでもいいことには突っ込まずにいてください
プログラムを勉強し始めて間もなく 多くの人が感動したアルゴリズムと同じく、 綺麗なクラス設計を示したのがデザパタだ みたいなことを誰か言ってたな。
83が変なコトいうから微妙な空気が漂ってきた。
90 :
名前は開発中のものです。 :2006/08/31(木) 03:24:35 ID:LuxRambo
デザインパターンの意図については語る必要はない気がする。
こっちは利用する側なんだし。実際このスレではパターン名で疎通が取れているし
パターン自体も色々な使用例が挙げられていて役立っているからそれでいい。
>>84 >複雑な行動パターンをお手軽に実装できる方法とかない?
なんとなく、このスレでは扱わない具体的な実装面に踏み込む内容な気がする。
どちらにしろ具体例を挙げてくれないと意見しにくい。
行動パターンがコロコロ変わるというのであれば
>>9 の方法でいいんじゃないか?
こういうスレは、この板では貴重だと思う。 当たり判定のアルゴリズムはわかっても、 それぞれの物体の座標をどうやって取得するか等を語れるスレは少ないし。
>>90 前にSTG作った時に敵の数を20以上作れと言われた
一つ一つ行動パターンを作っていくのがえらいめんどくさかった
既出ですまそ、そしてありがとうございます
「複雑な行動パターン」ってどういうもん?
キャラの状態が色々あってステートの変化の組み合わせが多い(格ゲー系にありがち)とか、
行動の流れが複雑でプログラムがめんどくさい(シューティングにありがち)とか、
カテゴリはいくらでもありそうだからなぁ
でも大抵はスクリプトを使えば割と面倒なタスク処理が解決すると思うので紹介
タスクを実装するのにvirtual Update() = 0;な関数を用意したクラスを使うのは皆よくやると思うのだが
キャラにとっては一連の流れ(=関数)を一々タイムスライスしてやらなきゃならんのは面倒だ。
そこでスクリプトを使うと結構その辺が簡略化されるよ
例えばシューティングゲームで360度回転しながら弾を撃つ処理を書くときとかが良い例だと思うのだが
class Hoge
{
float m_Angle = 0;
Update() {
m_Angle += AngleVel;
Fire(m_Angle);
if( m_Angle >= 360.0f )
Destroy( this );
}
};
と書くよりは
HogeThread() {
for( float Angle = 0; Angle < 360; Angle += AngleVel; ) {
Fire(m_Angle);
Wait(1);
}
}
と書きたいわけだな。Wiat(1)みたいなのはスクリプトの得意技だ
>>9 の例を使うと、class ScriptStrategyみたいな感じのクラスを作るのがいい感じ。
それにしてもひどい文法エラーだと自分でつくづく思った。
>>93 ゲームプログラムとしては前者のコードの方が自然だから
わざわざ後者にしたいという理由がわからない。
IEnumerator<IAction> GetAction() { for( float Angle = 0; Angle < 360; Angle += AngleVel; ) { yield return new FireAction(m_Angle); } } C#でこういうのどうだろ
>>93 の例は微妙に不適当な気がする。
”複雑な状態遷移をスクリプト(というよりこの場合fiber/coroutine)で処理した方が簡単”
というのは言えると思うが、
”毎フレームUpdateを呼ぶよりもHogeThreadを1回だけ起動する方法にしたい”
なんて思う人はごく稀だと思われる。
この場合、
>>9 のStrategyのサブクラスとしてScriptStrategyを定義して、
excuteが呼ばれるたびにコンテキストを復帰して起動する処理を作る方が自然。
>>95 そんなことは無いですよ。BulletMLはまさしく後者の方法の一種です。
わざわざこのためにpythonのマイクロスレッドを利用する人もいるくらい。
>>96 まさにその考え方です。
ただC#ではIteratorでしかyieldが使えないので…
>>97 なんか表現を誤った気がします。
結局はおっしゃるとおりコルーチンってことです。
99 :
名前は開発中のものです。 :2006/09/01(金) 22:44:26 ID:gcVCkYdV
人それぞれといわれかねない質問だが・・・、 衝突判定は何処で行う? キャラが他のキャラクタと当たるかどうかを各々チェックする? 衝突クラスなるものがキャラと他のキャラとをチェックする?
衝突判定の対象になるキャラを、障害物クラスに登録しておき、 キャラのメソッドで、判定用ベクトルを格納するクラスを生成し、 その判定ベクトルクラスを、障害物クラスに渡している。 障害物クラスで扱うデータは、 オリジナルだったり複数種のFVFだったりするので、 判定そのものはテンプレートにした。
5000個くらいのキャラの衝突を総当りでやってたらうざったいもんな。 キャラの最小サイズを1ピクセルになるようにマップを縮小したものを容易。 キャラを移動させたらその位置を塗り替えるが、その場所が既に塗り替えられてれば衝突、もしくは 詳細の衝突判定を行う。 クラスにするまでもないと思うが。
俺は衝突クラスを作るかな。
実装は
>>101 みたいな感じだけど4分木を使ってもっと大雑把にやる。
まあ実装に関してはこのスレの範囲外だけど。
衝突判定でよく話題になるダブルディスパッチだけれども boost::variant使うと継承無しで実現できちゃうよ。 中身はswitch caseのコンパイル時自動生成してるだけだけど。 継承関係なしで仮想関数の真似事もできるんで、 たまには役に立つかもしれない。
GameObjectは型クラスの概念に近いことが多いから、 ある程度規模が大きくなると、コンパイル時のダブルディスパッチの確定だけじゃ追いつかなくなるんだよね… UnrealEngineではスクリプトに完全に委譲してしまってるみたいだけど。
variant型なんだからもちろん実行時型識別してくれるよ。 具体的には型にid振ってswitch caseしてるだけ。 メモリアロケーションも発生しないからなかなか優秀。 ただオブジェクトサイズが最大のものに揃っちゃうけど。
こんな感じね。↓ #include <boost/variant.hpp> using namespace boost; class visitor : public static_visitor<> { public: void operator () (int n, int m) const {} void operator () (char n, char m) const {} void operator () (char n, int m) const {} void operator () (int n, char m) const {} }; ・・・・ variant<int, char> v0, v1; v0 = int(2); v1 = char(3); apply_visitor(visitor(), v0, v1); v0 = char(2); v1 = char(3); apply_visitor(visitor(), v0, v1);
>>105 いや、突き詰めていくと、同じ型であってもゲーム上で異なる意味を持つ場合がよくあって、
そういう場合は(言語としての)型でのディスパッチだけでは不十分で、
結局、ゲームにあわせたIDなり名前なりで自前のルーチンを組むことになるって話。
特にRTSやFPSみたく、プログラマは基本的な構造とツールを提供するだけで
後はデザイナーの仕事、のように分業されてるゲームではそうなりやすいでしょ。
って書いてて気づいたけど型クラスじゃなくて型オブジェクトだったよ(´・ω・`)スマソ。
それは単に振る舞いを型まで落としきれてないだけでは。 仮に振る舞いが外部設定可能だったとしても 型をパラメータ化したファクトリ作れば良いし。
ああ、”ゲームオブジェクト”のディスパッチでは 足りない、ということであれば同意。 上のは当たり判定オブジェクトを別に作ってそっちで ディスパッチする前提で話してた。
てかここまでくるとスレ違いじゃね?
>>109 そう、そういう意味ですた。
パックマンやテトリスみたく、型とオブジェクトの振る舞いが1:1で対応するようなゲームであれば
boost::variantやLokiのStaticDispatcherで事足りるし、その方が高速なんだけど
ツールでカスタマイズ可能なオブジェクトを導入したとたんに破綻しちゃうんだよね…
普通はどうするもんなんでしょうか。
衝突は悩みますよねー。 まぁ、衝突判定のためのクラスを作って、そこに対象をごっそり addしていくような感じですかね。わたしは。
2Dの衝突判定の話と3Dの衝突判定の話が混在しているから困るw
次元1つ違うだけジャン
判定アルゴリズムを語っているわけではあるまいし、問題ないだろう。
さすがに
>>101 のやり方は3Dじゃやらんだろww
画像だとめんどいけど多次元配列にすればいけるんじゃね?
>>119 普通はAABBのツリー構造にするけどな
グリッドでやるのは現実的じゃないけど、オクツリーなら。
こういう話題も一応『データ構造』の内に入るのかな? レンジ広めな良スレだな。
まとめ ・形状衝突判定とゲームオブジェクト衝突判定の話が混在してて紛らわしいお ・VisitorパターンはAcceptor側の個数が暴発するときには使いづらいお ・挙動をStrategy化すればAcceptorが暴発しにくくなるお ・次元を問わずグリッドよりツリーのほうがお勧めだお
群体を制御するプログラムのいい案ない? 複数の個体で整列したり陣形を作るっていうのが目標 どっちかというとAIの分野に入ると思うけど そこまで複雑な物じゃなくてもいいかなと思ってる
チーム全体の行動を担うダミーエージェントを用意して、 そいつが全エージェントの操作を行うというのが楽なんじゃね? 昔からある多間接キャラとかはこういうタイプなんだろか 個々のエージェントが周囲の状態を見て次の移動地点を決めたりするのは まさしくAIって感じだが果てしなく重くなりそう
>>125 > 個々のエージェントが周囲の状態を見て次の移動地点を決めたりするのは
> まさしくAIって感じだが果てしなく重くなりそう
そうでもない。
今のクラウドシミュレーションの基礎になってるレイノルズの方法では
3つの単純な操作を各個体に適用するだけでリアルな挙動を作り出せる。
これに、基準になる目標点を個々に与えたり、パラメータを調節・追加することで整列や陣形も表現できる。
といっても完璧に意図した陣形にしたければ、予め動きを指定しておくしかないけど。
boidっ言ってちょ。1行目だけ読んで「レイノルズって誰だ?」とか思っちゃった。 ツリー的な構造にしてセパレーション以外の適用範囲を限定したりすると、 複数の集団が扱えるし、(影響力の強くした)ツリーの親で操作できて手軽。
128 :
124 :2006/09/09(土) 11:31:36 ID:c7q33UAv
129 :
名前は開発中のものです。 :2006/09/09(土) 13:29:03 ID:QcPvLvjH
階層ステートマシーンってどんなものか知ってる人いる?
>>129 従来のステートマシン(全てのステートが完全に等価)に
クラスなりパッケージ化で階層を加えて
オブジェクト指向との親和性を高めた物って認識をしてたけど、違うのかな?
魚に吹いたw
strategyのstrategyみたいなもんか。
質問です。 まず、動的にメモリ上に作成されたオブジェクト、AとBがあります。 ある時、オブジェクトBはオブジェクトAへの参照を保持したとします。 しかしその後、オブジェクトAは消失してしまいます。 こういった場合に、オブジェクトBの保持していたオブジェクトAへの参照が 無効になったことが分かる、良い参照構造がありましたら教えてください。 スマートポインタをちょっと調べてみましたが、あれってこういう場合に使うものではないですよね?(むしろ逆のような感じ) 言語はC++です。
>>135 boost 使うなら shared_ptr と weak_ptr 組み合わせて使う。
或いは、非参照オブジェクトに
bool isTerminated() const;
みたいなメンバ変数を持たせて、参照側はスマートポインタで保持。使う前に
if (p->isTerminated())
p = NULL;
みたいなチェックを入れる。私は intrusive_ptr 好き人間なので、後者で統一
してました。
>>135 インスタンスのポインタのポインタ持たせておけばおk。
Aのインスタンス開放時は必ずぬるぽを指定する。
>>136 weak_ptr使ってみました。これは良いですね。
セットされていたshared_ptrが消失すると以降のlock()が無効になる。
これで私の希望は叶ったように思います。
ただ・・これって内部ではどのような処理が行われているのでしょうか?
ソースを読んでみようかと思いましたが・・私にはちょっと難しかったです。
どなたか、簡単に解説していただけませんでしょうか?
intrusive_ptrについては、よく分かりませんでした。
>>137 Bがインスタンスのポインタのポインタを持つとして、
その「インスタンスのポインタ」にあたるデータは
Aが持つのでしょうか?それとも違う者が持つ?または誰も所有しないのでしょうか?
ちょっと具体的なイメージが沸きませんでした。
宜しければサンプルコードみたいなものを書いて頂けるとありがたいです。
>>138 # boostは使ってないけど、weak_ptrの実装に興味あったのでソース見てみた。
# 間違ってたらごめんね。
intrusive_ptrは参照されるオブジェクトに参照カウンタの仕組みが備わっている場合に
使えるスマートポインタ。shared_ptrは参照カウンタをヒープに確保してて何にでも使える
汎用性がある代わりにオーバーヘッドがありゲーム用ならintrusive_ptrが好まれるという
ことだと思われる。
weak_ptrはそのヒープに確保される参照カウンタ(オブジェト)自身の参照カウンタを
上げ下げするもので、weak_ptrが全部消えるとその参照カウンタオブジェクトが
消えるという仕組みのようだね。
# detail/sp_counted_base_w32.hpp
class sp_counted_base
{
long use_count_; // #shared
long weak_count_; // #weak + (#shared != 0)
virtual void destroy() // nothrow
{
delete this;
}
void weak_release() // nothrow
{
if( BOOST_INTERLOCKED_DECREMENT( &weak_count_ ) == 0 )
{
destroy();
}
}
};
>>138 こんな感じだな。インスタンスのポインタは別に誰が持ってても良い。
っつかポインタのポインタ持ってる時点でそれと同義だし。
class clsA;
class clsB;
class clsB
{
int val;
public:
clsB(int v){val=v;}
int getVal(){return val;}
};
class clsA
{
clsB **pb;
public:
clsA(clsB **b)
{pb=b;}
int getVal()
{
if((*pb))
{return (*pb)->getVal();}
else
{return -1;}
}
};
141 :
138 :2006/09/23(土) 20:22:09 ID:gkZ8TjvK
改行が多いって怒られた。 int _tmain(int argc, _TCHAR* argv[]) { clsA *a; clsB *b; int ret; b=new clsB(256); a=new clsA(&b); delete b; b=NULL; ret=a->getVal(); //ret==-1 return 0; }
名前ミスった。気にせんでくれ。
ここで挙げられたパターンや何やらを使っているような、 小規模でわかりやすいサンプルってありますかね? シューティングを作ろうとしているのですが、設計で悩むことが多くて、 参考になるものが欲しくなってきたので、何かあればよろしくお願いします。
145 :
名前は開発中のものです。 :2006/10/31(火) 10:38:39 ID:xPxE7qYC
タスクシステムって本当に有効なのか? 逆にプログラミングが煩雑になりそうな気がするんだが。
>>146 何度か挙がってるネタだな。まず「タスクシステム」を定義しないと、
いつもどおりグダグダになるだろう。
>>147 タスクシステムというのは、
処理関数とワークエリアがセットになったタスクがリスト構造になっていて、
順番にタスクの処理関数を実行していく仕組みだと思ってる。違うかもしれんが。
あるタスクが、ほかのタスクの保持するデータを参照するのが難しそうだ。
>>148 関数とワークエリアがセットって言ったら仮想関数使えばいいだけの話。
あとは抽象クラスへのポインタをコンテナに保持すればできあがり。
システムって名付けるほどのもんでもないよな。
そこで済ませておけばいいものを、なんでもかんでもそのリストを
使ってやろうとすると、バグの温床となる「タスクシステム」ができあがるんじゃないか
と思っている。
実際C++だと必要ないよ。
>150 そうでもない。組み込み方面からもたらされたと思われる非プリエンプティブな スレッドみたいなもうちょっと複雑なものとするなら、C++のみでは無理、 アセンブラが必要。WindowsならCreateFiberを使えるが、NT系で しか使えない。 これからマルチコアが当たり前になると、スレッドをタスクと名づける人が増える かもね、おおややっこしい。
初心者だがレスさせてくろ タスクシステムはビデオ屋でいうポストレンタルシステムではないでしょうか ゲームプログラムにおいてはリアルタイム戦略ゲームのAIに有効かと 例えば自立スレッド型のユニット(目的地を指定すれば、勝手に動いてくれる)をA地点に移動したのち、B地点に移動させるAIを組もうとしたときなど。 ユニットのスレッドが行動リストをもっていて、AIはぼんぼんリストに行動をaddしていけばいい ユニットのスレッドはリストの下から行動を処理する。 このシステムがないとAIはユニットがA地点に到着した情報を取得し、 その後でB地点に池という命令を出さなければならないのでAIの手間が非常にかかる おやすみなさい
>>154 それは
>>148 の言うようなタスクシステムとは全然違う。
コマンドのキューと言えば十分。システムなんて呼ぶほどのものでもない。
「タスクシステム」の共通な定義が無いのが
一番の問題なのかもしれないと思った。
俺様解釈が多すぎていまさら定義も難しい。
156 :
名前は開発中のものです。 :2006/11/07(火) 10:45:17 ID:FxrEUOug
少なくともこのスレでのタスクシステムの共通定義は
>>148 でいいんじゃないの?
今までずっとそれ前提で話が進められていたし、
そうでないと思っているのは的外れな
>>154 だけだと思うんだが。
タスクに親子関係持たせるとか優先度がどうだとかいった細かい部分は
その都度最適なものを選べばよし。
Cでリスト使ってて、 C++に移行したら「それタスクシステムだよ」って言われた。 どうすればいいでしょう?
もうすこしkwsk
160 :
名前は開発中のものです。 :2006/11/10(金) 11:57:52 ID:bWKjGfw+
161 :
160 :2006/11/10(金) 11:58:41 ID:bWKjGfw+
すまね、上げちまった
この板にしては珍しく良スレだな
>>160 >koei.co.jp scei.co.jp square-enix.co.jp みてるんだったら会社いれてよ!!!!!!
お題とは関係ないがこの辺にワロタw
proxyぐらい使いましょうね、大手の皆さんw
>>163 別に問題ないと思うけど。さすがに社内サーバのアドレスを referer で飛ばしてくるのは
どうかと思うが>k社
自意識過剰
んで問題はとかねーの?
>>166 マジメに考えるほどのもんじゃない気がするが。
メモリの断片化や使用量見積もりを考えると、全オブジェクトを必要最小限の寿命で
確保・解放なんてせずに、シーン毎に必要なファイルぶち込んだアーカイブ作って
終わりだし。
コーエーといえば寝るおもしろす事件だなw
>>167 いつ何時どういう顔でどういう武器を持ったアバターが登場するかわからない
MMOとかだとシーンとか生ぬるいこといってられないんじゃない?
>>169 組み合わせが分からないなら、ワーストケースでも対応できるようにする必要があるから、
賢いメモリ管理はしない方が良いと思うが。
10000とか決めうちで適当にアバター(?)放り込む領域とっときゃい〜じゃん。 クライアントで10000人同時表示とかどうせ無理だからw なんかが湧いたとしても、 射程外の見かけ小さく見えるアバターから削除しちまえばOK。
>> 171 その領域のどこに確保されたのかを示すハンドルやポインタはどうすんのよ。
スケーラビリティはガン無視がゲームにおけるデータ構造・クラス設計の常識?
コンシューマならそれでも良いと思うけど、 昨今のPCゲーム開発であればスケーラビリティは必須では? なんせ環境が数倍以上違うことだってあるからね。
> その領域のどこに確保されたのかを示すハンドルやポインタはどうすんのよ。 領域が決めうちでも決めうちでなくても発生する問題。 > スケーラビリティ MMOなんだから、クライアントの更新でスケーラビリティを代替すればいい。 逆にPCの優劣で、プレイヤー間に格差が出るほうが問題と言えば問題。
んで問題はとかねーの?
あれは、クラスデザインで対応すべき問題ではない、っつーのが答え だろうな。
>> 175 だから、それを採用してもその問題が残るんだろ? この問題の本質はそこだろ。どうやってデータへのアクセスを共有させんだ?
いや、エンジン書いてもそれはゲームじゃないからw さっさとゲーム上の具体的なシーンについて見積もりを建てなさい。 領域なんて初期化時に必要な領域全部取ってしまえば問題無い。
>> 179 件のサイトってMMORPG作ってるわけで、 MMORPG開発を前提にした問題を出してるんだがなあ。 シーンなんて簡単なもんじゃ見積もれないって。
↓↓↓ここから見積もれる/見積もれないの一点だけで100年戦争↓↓↓
なんか虎をつかまえてほしいなら虎を屏風からだしてくれみたいな回答だな あきれた
>>180 URL貼った上で「件のサイト」を持ち出すのは、
あまり良くないと思うのだが…
184 :
名前は開発中のものです。 :2007/01/14(日) 05:03:57 ID:gu/ia/06
良スレあげ
シーン・・・ 昔すべてのシーンはスタックのみで再現可能と思ってた時が俺にも有りました。 実際大半はOKだけど、相互に行き来できるような仕組みを作りたい場合 別の方法をとらないといけないし、平行して動かす場合や 一部をストップさせたいときはいっそシーンクラスじゃなく スレッドで動くクラスの方が良いと思えてきました。 まだ研究中。
俺はそれは兄弟関係をコンポジットにして解決しとるよ
コンポジットパターンですか? なるほど。
188 :
名前は開発中のものです。 :2007/01/27(土) 00:03:58 ID:Mwc3VMrB
良スレ発見。 皆様のお知恵をお借りしたい。 効果音、BGM、描画エンジンなどの管理オブジェクト(コンテキストっていうのか?)をどうやって、 キャラクターなどから参照させるかということについてです。 キャラのオブジェクト生成時に、必要なものだけ渡してやるのがベストなんでしょうか? 今は、全部持ったGameクラスっつーのを作って、そのインスタンスのローカル変数一個を どこからでも参照できるようにして、 各キャラクターから参照できるようにしているんだが、 今の流行的に、ローカル変数がイヤンなので、 なんとかしてやりたいのです。 ABAさんのソースとか見ると、生成時に引数で渡しているんだけど、 うちのDelphiだと、各ユニット間の循環参照問題を回避できなくて真似できないんだよね・・・。
ローカル変数?グローバル変数だよね。 その方法がまあ無理なくやれると思う。 グローバル変数がどうしても嫌なら インターフェイス宣言を使えば、循環参照は回避できるよ。
190 :
名前は開発中のものです。 :2007/01/27(土) 00:46:55 ID:Mwc3VMrB
サウンドみたいなものはモロにシングルトンにしてしまって CSoundManager::GetInstance().Play( FX_HOGE ); こんなんでよいのでは
それにゲームエンティティクラスが増えて、継承の階層とかができても ctxの実装は全部の名前に_ctxつけたインターフェイスを全部同時に多重継承するんだろか? ctxにmixinするインタフェイスはゲームエンティティのクラス群の構造に依存しないで 区分けそのものに対する名前をつけてやる方がきれい、というか合理的に思う。 例えばとにかく弾をつくるインタフェイスを公開するctxインターフェイスならICtxShootとか。
195 :
issei :2007/01/27(土) 22:48:39 ID:+PYaC1IQ
>>193 > まったく同じ汎用的なインターフェイスを複数のエンティティへ公開したいとしても
> いちいち別の実装とインターフェイスを設けなくてはならなくなる。
そうですね。
ただ、純粋仮想関数のプロトタイプが同じなら実装は一つで済むから、ヘッダ
ファイルをメンテするのが多少面倒って程度です。
struct ICtxEnemy { virtual void createShot() = 0; };
struct ICtxField { virtual void createShot() = 0; };
class Manager : public ICtxEnemy, public ICtxField { virtual void createShot(); };
// これで実装は両方に提供できる
このスキーム使って仕事で RPG のリアルタイム戦闘を作ってたんだけど、面倒で
手に負えないって状況には至らなかった。むしろインターフェースごとに公開する
関数が限定されていたから、仕様変更時にチェックが短期間で済んだ感じ。細かい
数字を残してないから、具体的に何パーセント改善とは言えないけどさ。
汎用的なインターフェースをどうするかってのは悩みどころだけど、やりたければ
sturct ICtxEnemy { virtual ICtxCommon& getCommonCtx() = 0; };
とかかなぁ。私は汎用インターフェースは結局作らずシングルトンで済ませちゃった
けど。
>188 個別にオブジェクトのアドレスを渡した場合、パラメータの個数が膨大になるのと、 きれいにまとめないとかなり手間がかかるね。 シングルトンで実装して、グローバルアクセスがよいのではとおもう。
>>issei(誰?w) >// これで実装は両方に提供できる 確かにそうだね。書いてみてから気がついた。 具体的に書くコードの量とかの増減をあげつらう批判をしたいわけじゃないだホントは また寝ながら考えたんだけど、要はこれはエンティティクラスの主要なメソッドを使うには このctxインターフェイスを実装しているオブジェクトをなんとかして用意してください。 というエンティティクラスからの表明が主題で、managerが全部を継承して実装するというのは、 たまたま今回採用されたやりかたに過ぎない、別にどうでもいい部分なんだね。 エンティティクラスが継承ツリーをつくるようなときは最上位のクラスのctxに 下位層のクラスが使おうとする純粋仮想関数も書き加えてかなきゃいかんね。 つまり最上位のオブジェクトを以って、主要メソッドを実行しても、 その下位の継承したクラスの機能追加されたものが呼ばれる可能性があるわけなので。 なんで俺が日記の作者も言ってない手法の使い方をまとめてんだ… ぜんぜん関係ないけどcontextってのはあんまり実態にそぐわない名前だと思うなぁ。分かるけど。 relianceとかdependencyとかのがいいような気がする。
198 :
issei :2007/01/28(日) 01:38:40 ID:ViuHLna9
>>197 > >>issei(誰?w)
日記の人です。
> また寝ながら考えたんだけど、要はこれはエンティティクラスの主要なメソッドを使うには
> このctxインターフェイスを実装しているオブジェクトをなんとかして用意してください。
そうそう。
本当のマネージャとは別に、エンティティの単体テスト用とかデバッグ用に ICtx***
インターフェースを実装した別のマネージャーも作ってました。
確か別のプログラマがエフェクト用の対話型エディタを作ってたんだけど、そこで
デザイナからキャラクタにエフェクト乗せて見たいとリクエストがあって、エフェクト
エディタにキャラクタ用のコンテクスト実装してたんじゃなかったかな。もちろん、
大半の仮想関数はダミー(ヒット判定なんかの関数は、常にヒットしないと返す
だけ)だけど。
風呂はいりながら考えたんだけど ようは移植用区画、エンティティクラス、実装を委譲したい関数群、 それぞれをシステム内で1対1対1。ひとまとめにしたいわけだ。それはわかる。 だが無駄に暗黙的な命名の制約を持ち込むvisitorインターフェイスには反対。 contextというが、それらが文脈として差異を持たされるのは結局はプロジェクト全体で複数作られる 実行単位ごとなわけだ。それに対してvisitor風に関数レベルで型への依存を表明するのは 適当だとは思えない。何がどのレベルで変わるのかがきちんと示せてるのがいいコードっすよね。 ついでに実装をまとめるだけが目的の節操のないmixinも反対だ。 俺はこうする。 class Player { public: void exec() { CreateShoot(); } void Method0(); private: static void CreateShoot(); // どこか他のコンパイル単位で定義してやる }; どこか他のシステムへもっていってもstatic関数を定義した.cppの方だけ取り替えれば移植が完了する。
200 :
名前は開発中のものです。 :2007/01/31(水) 00:35:16 ID:NKCnpIjT
>>200 答えでてんじゃん。
ここで何が聞きたいの?
フラグ立ててるだけなのがなー。 削除と同時に最後尾のデータをコピーしちまえ。
>>200 そのアルゴリズムのどこが高速なのか本当に分からない。
フラグを立てて何に使うの?
いや、向うで煙たがられて誘導されたからって、 本当にこっちに来る事もないだろww
今適当に書いたけどフラグなんか使うよりこっちのほうがいいんじゃないか template<typename T,int N> class FixedAllocator { union Block { T Data; Block* pNext; }; Block* m_pGarbage; Block m_Pool[N]; public: FixedAllocator() { m_pGarbage = &m_Pool[0]; for( int i = 0; i < N-1; i++ ) m_Pool[i]->pNext = &m_Pool[i+1]; m_Pool[N-1]->pNext = NULL; } T* Alloc() { Block* pRet = m_pGarbage; m_pGarbage = m_pGarbage->pNext; return &m_pGarbage->Data; } void Free( void* p ) { static_cast<Block*>(p)->pNext = m_pGarbage; m_pGarbage = static_cast<Block*>(p); } };
>>202 フラグ管理より双方向リストでつないどくのが良いと思うけどな。
struct PoolNode
{
struct PoolNode* pn_next;
struct PoolNode* pn_prev;
char pn_padding[8]; //必要なら
char pn_buf[PN_BUFSIZE];
};
static PoolNode nodes[NODENUM];
// 未使用ノードは、こっちにつなぐ
static PoolNode* free_first = &nodes[0];
// 使用中ノードは、こっちにつなぐ
static PoolNode* inuse_first = 0;
現実には、俺なら自前で書かずに STLport の node allocator にお任せして、
STLコンテナ使っちゃうか、boost::pool だけと。
207 :
名前は開発中のものです。 :2007/01/31(水) 01:13:52 ID:NKCnpIjT
boostみて、なんじゃこりゃーな感じだったので、
>>206 とか、見るとわかりやすいですね。
配列でデータは持つんだけど、使用中ノードは、連結リスト風につないでおくっと。
未使用ノードも同じようにもつ。
これだけで、済む話かー。
>>205 それが segregated storage だろ。
210 :
名前は開発中のものです。 :2007/01/31(水) 01:17:52 ID:kxHbC4YN
欲しいのはクラス名だけであって、
>>200 が考案した以外のクラスなんて興味ないんだろw
だって、
>>200 より優れたクラスなんて存在しないんだからwww
つ 【ステフ18クラス】
つ 【次世代コミュクラス】
つ 【バキュンバキュンクラス】
この板ならではのクラス名を授けるから好きなの選べ
そう言うっていうか、boostのクラスなのか。 boost、まだ知らん機能多すぎる…orz
boostは、知ってても使いこなせてないクラスも多いなぁ。fusionとかmplとか。 普段お世話になってるのは、stdafx.h 見るとこんな感じ。 #include <boost/array.hpp> #include <boost/bind.hpp> #include <boost/call_traits.hpp> #include <boost/crc.hpp> #include <boost/cstdint.hpp> #include <boost/function.hpp> #include <boost/format.hpp> #include <boost/intrusive_ptr.hpp> #include <boost/lambda/lambda.hpp> #include <boost/lambda/bind.hpp> #include <boost/lexical_cast.hpp> #include <boost/noncopyable.hpp> #include <boost/ref.hpp> #include <boost/scoped_ptr.hpp> #include <boost/scoped_array.hpp> #include <boost/static_assert.hpp>
213 :
名前は開発中のものです。 :2007/01/31(水) 01:24:55 ID:NKCnpIjT
>>210 変数名つけろスレから着たけど、
いまや、クラス名だけでないです。
>>210 さんが、私のデータ構造を最高!マンセー!他はクズ!
>>200 様に一生従います!
と言ってくださるのは、うれしいのですが、
他に、どんな効率のよい、データ構造があるかというのを知りたいのです。
Delphiには、boostねーよー。うらやましい。
214 :
名前は開発中のものです。 :2007/01/31(水) 01:26:10 ID:NKCnpIjT
>>213 効率はデータの使い方に依存する。で、何に使おうと思ってるの?
もしかしたら、主要なデータ構造を一通り勉強したいってこと? それなら、 まずは(データ構造を処理するアルゴリズムとセットで) ・Cプログラマのためのアルゴリズムとデータ構造 ・珠玉のプログラミング ・プログラム設計の着想 ・プログラミング作法 あたりの書籍を読むのがお薦めだが。
>>213 いや、普通に皮肉だから、無理にレスしなくていいよ。
この板で数少ない有用なスレッドだな
219 :
名前は開発中のものです。 :2007/01/31(水) 15:38:04 ID:CxDF9OMM
>>215 パーティクルや弾幕のように、
追加、削除の頻度が高い場合に使える構造はないかと探していました。
>>216 勉強したいだけ、というわけではないのですが、
参考になります。
弾幕だったら各機で同時に発射しうる最大数に応じた領域確保しちゃうかな。 頂点バッファは1つあれば十分だし。
>>219 パーティクルは出現数の上限を決めて、それを超えたら適当に消すのが常套手段。
多少消えても人間は気づかんから。
メモリ管理自体は PS2 以降のハードなら大した工夫は要らなくて、pool なり STLport の
node allocator なりで十分な性能が出る。それよりベクトル演算効率化することを考えとけ。
>>221 おまいの賢さは分かったが数個前のレスくらい読んでやれ
>>222 同時に発射しうる最大数を確保して超えないことを保証するのと、適当な数を
確保しておいて越えたときに消しちゃえってのは、一見似てるけど使いどころが
違う。
一般にヒット判定があれば前者、単なる見た目だけなら後者。ヒット判定がある
ものを適当に消すと致命的なバグになったり、予期せぬ挙動をすることがある
ので。
224 :
219 :2007/01/31(水) 23:25:03 ID:NKCnpIjT
まあ、実際、別のプロジェクトで、毎回、インスタンス生成しても、 描画の方が圧倒的に遅すぎるというプロファイル結果が出たりしたので、 そんなに神経質になる必要はないんですけどね orz (動作環境は、PCです) 新しいプロジェクトで、 パーティクル一杯出したいから、それぐらいは、pool化したいなって思ったんです。
>>224 シミュレータの場合、速度最優先で描画をしない状況もあるから、
それが免罪符にならない場合もあるんだよね
良スレage
227 :
名前は開発中のものです。 :2007/03/26(月) 06:10:31 ID:mFbF2Qb2
ところで、 キャラクターの構造体は何で取ってる? 今じゃ普通にダブルでとっても問題ないよな。 むしろ、その方が微調節がしやすくって良いよね。 俺は貧乏癖がついててイントでとって微調節がやり辛くなって、 結局後で困ったりしてるんだよね。 皆は何で取ってる?
228 :
名前は開発中のものです。 :2007/03/26(月) 06:11:56 ID:mFbF2Qb2
あ、ゲームは普通の2dのアクションゲームとかです。
doubleでおk 次の話題どうぞ
単純にintのかわりにすると計算誤差で困ることも多いからちゃんと使ってくれ 具体的にはイコールで判定とかやっちゃだめだぞ
>>227 自分で固定小数点数作るのが楽ちんだろ
浮動小数点数の等号問題も出ないし
桁落ちの誤差で困ったことはないなあ。 「本当はセーフだったのに、桁落ちしたせいで等号が成立して 敵に当たったことになって死にました」みたいな状況は あるだろうけど、まず気づかないと思うし。 そのあたりを完璧にしたいのであれば、丸め誤差も考慮に入れて 10進固定小数点数クラスを作らなければならないだろうけど、 そこまでしたくないというのが正直なところ。
>>232 そんなクラス作らなくてもいいんじゃね?
16ビットシフトするだけでゲームの精度的には十分かと。
>>232 なんか勘違いしてるけど、固定小数点数にするのに10進は関係ないぞ。
>>235 10進って言ったのは、丸め誤差を考慮しての話なんだけど。
桁落ちとは関係ない。
10進でも2進でも丸め誤差は出るってば。
238 :
その1 :2007/03/27(火) 06:12:21 ID:6cy45QrY
「キャラの座標の型に関して」 ・整数か小数か -> 断然小数 ・小数の表現方法 -> 浮動小数点数 or 固定小数点数 -> 2進表現 or 10進表現 ・浮動小数点数 ○ 基本型であるので扱いが楽 × 演算速度が遅い △ 非常に近い値同士を比較したときに桁落ちが発生する (桁落ちが発生したところで別段問題がない場合も多々ある) ・固定小数点数(クラス実装) ○ 比較による桁落ちが発生しない ○ 実態は整数型なので演算速度が早い -> × 汎用性の高い実装(シフト数の異なる固定小数点数同士でも演算を 可能にするなど)を行うと、結局浮動小数点数以下の演算速度に × 固定小数点数オブジェクトの生成が頻繁であると遅くなる (特にオペレータ・オーバーロードに注意) △ 小数点以下の精度(桁数)が固定 (ただし、精度が足りなくて困ることはまず無いと思われる)
239 :
その2 :2007/03/27(火) 06:13:22 ID:6cy45QrY
・2進表現 ○ 基本型は2進表現なので扱いが楽 × 10進表現で有限小数となるが2進表現で循環小数になるような値の場合、 表現できない桁が切り捨てられるなどして丸め誤差が発生する ・10進表現 ○ 循環小数に対する丸め誤差が起きない -> × 一般によく使われるであろう加算減算処理では問題ないが、 除算を行うなどすると何進数であろうが丸め誤差は発生する XX 基本型とは程遠い別次元の演算手法が要求される (2進表現で循環小数となるような値を基本型で記述した時点でアウト) × 同じバイト数で表現できる値の範囲が2進表現より狭い 勝手にまとめっぽい形式で書いてみた。 固定小数点数に関してはクラスとして実装した場合を想定した。 個人的に、固定小数点数を素のintで表現して、その都度シフト変換を行うような手法は、 変換方法に依存した関数/クラスを大量発生させるので論外だと思う。
10進表現ってBCDのことだったの? 俺はてっきりintを10^nで割って使う話だと思ってた。
色々書いたけど、結局俺は無難なdoubleを使っちまうかなあ。 試しに固定小数点数クラスを作ってみたけどあんまし早くならなかった。 っていうかコンパイラによって速度が大きく変わりそうな予感。 10進表現での計算は、誤差が出たら切腹必至の 銀行システムとかでのみ使うものだと思っている。 言語的にサポートされていれば話は別だけど。 以上長文&駄レスすまん。
>>240 俺は流れ的にBCDのことだと思ったが…。違ってたらすまん。
243 :
名前は開発中のものです。 :2007/03/27(火) 10:06:48 ID:KORunXqt
昔は、固定小数点使ってたな 今は、さすがに、浮動小数だわ 問題は、環境によっては、リプレイでずれるとかその辺 (D3DXの最適化とか最適化とか最適化とか)
浮動小数点だと0.1ですらがあらわせないからな 表せないのに無理しているのが浮動小数点 あらわせないのなら扱わない、問題が出ないようにするのが固定小数点 0.1を10回たしたら1になるとか思ってるような人は固定小数点つかっとけと
アナログコントローラーとか3D処理やったこと無いのかな
Flashとかだと0.5ずつずらさないと隙間が空くとかあるんだよね
微妙に関連する話題だと思うんだけど、 皆は(無限)多倍長精度整数を使ってたりする?
>>247 固定小数点数使ってたら、上の桁が足りなくて、
仕方なしに64ビット整数を使っちゃったことはある
>>247 そういうのは学術用だと思うよ。
ゲームなら実際問題そんないらんっしょ。
得点計算で使われることもあると思う。 32bit符号なし整数では40億程度しか表せないし。 恐ろしい桁数の得点をガンガン加算させて、 かつ一の位までキッチリ使っちゃうような 血も涙もない鬼の方御用達です。
無限多倍長精度整数って書いてるんだよな。 long longより上だと3倍長で7.9x10の28乗とかになるけど……要るか?
>>249 んなーこたーない。
経営シミュレーションで多倍長な変数を使うことはあるよ。
キャッシュとか資産とかの額で。
まさか、浮動小数点使うわけにはいかんし。
ビルゲイツの資産とか32bitに収まりきらんもんな
そもそもビルゲイツの資産は、株価がちょっと変わるだけで とんでもない額が変動するから、下の方の桁にあまり意味はない。
32bitどころじゃないだろ。 まあ、毎年訳分からん団体に1兆寄付してるおっさんだからな。 寄付してるのは妻の方だけ?
自分の設立した財団じゃないのあれ?
257 :
名前は開発中のものです。 :2007/03/30(金) 00:16:52 ID:xOzIjQQy
Delphiの日付用構造体TDateTimeを馬鹿にするなよ? 日付なのに、不動小数
不動ならいいや('ー`)
MSのAccessも日付はdoubleでもってたような・・・
いいシーン管理方法が思いつかない…。 「シーンはスタックに積む」って話をよく聞くけど、 積みっぱなしでメモリは大丈夫なのかとか、 タイトルシーンやメニューシーンはその都度生成した方が 再初期化の手間いらずで楽なんじゃないかとか、 ロードの際にスタックの中身をいちいち 再現しなきゃいけないんじゃないかとか、色々疑問が残る。
>>260 何が「いい」かは作るプログラムによって違うからな。
疑問に思うんならやってみろとしか言えない。
なるほどそういうときにシリアライズを使うのか
>>260 Gemsの5巻にスタックを使ったシーン管理が載っている。
試してみたら、なかなか使い易かったよ。
>>262 javaのシリアライズの話ならそういう時の為のものじゃないぞ
>>260 作ってるゲームによるでしょ。
シーン切り替えの度にブラックアウト & ロード処理が入るふつーの RPG だと、
シーンは必要な都度 new して作る(ただしテクスチャ・モデル等のリソース類は
事前に割り当て決めておく)、状態遷移はプログラム側でベタに行う…で十分に
管理できる程度だった。
266 :
名前は開発中のものです。 :2007/04/05(木) 20:02:57 ID:53u6wZm0
>>263 Gemsうp!!
って、無理だw
ソースコードだけでも配ってないのか・・・
【警告】 日本はカルト教団に支配されてしまいます。 選挙に行きましょう。
268 :
名前は開発中のものです。 :2007/04/06(金) 16:07:18 ID:+BNVME6N
スタックベースのシーン管理に参考になるページはないですか?
どっかのやねうの昔のサイトに解説がなかったか。
YaneSDK.Netのソース読め
本人がいらっしゃるようなので一言申し上げますが yaneSDK3rdの更新してください>< 2ndからトランジエントビルトを移植しようとしたんですが正直無理です><
無理とか言ってたらなんも成長しないがな。 つか本人が来たとか本気で思ってるのか。
皮肉にマジレスしてどーする
そういや、やねうらおの会社の社員が、やねうらおを訴えた件はどうなったんだろうな。
275 :
名前は開発中のものです。 :2007/04/09(月) 03:25:15 ID:/ygJ9fwS
騙された馬鹿が、ギャーギャー文句言ってただけ
いい加減スレ違い。
277 :
名前は開発中のものです。 :2007/04/09(月) 13:14:13 ID:/ygJ9fwS
スタックベースのシーン管理について質問 つくってみたけど、いまいち利点がわからん・・・ 何が便利なんだろう・・・
スタックみたいな古臭いのじゃなくて デザインパターンでオブジェクト指向的にスッキリと出来ないものなんだろうか
シーンをオブジェクトと見なしてスタックに積むんだから、 十分オブジェクト指向じゃないかと思うんだけど、そういうことではない?
>>277 利点かー。
末端のシーンがどこに戻るか把握しなくていいから、シーンを柔軟に組めるとか、シーンを再利用しやすいとか。
ごめん、思いつきで書いた。
281 :
名前は開発中のものです。 :2007/04/09(月) 20:46:27 ID:d0StE6D+
>>279 うん。
それ自体が定型になるなら、スタックベースのシーン管理というのも
ゲームにおけるデザインパターンといっても過言ではないと思う。
282 :
277 :2007/04/09(月) 20:49:46 ID:d0StE6D+
とりあえず、googleして、定番とおもわれる ・呼び出し(Call) ・移動(GoTo) ・呼び出し側に戻る(Return) をシーン管理オブジェクトに、実装して、シーンを状態遷移してみたりしたんだけど、 これって、シーンを遷移するときって、前のシーンは開放しちゃっていいのか? 開放しちゃうと、 しなかったらしなかったで、リソース圧迫するし クソー、Game Programing Gems 5がほしいZE
283 :
277 :2007/04/09(月) 20:54:13 ID:d0StE6D+
> 開放しちゃうと、 開放しちゃうと、呼び出し(Call)の意味あんのかな?と思うし
ところでシーン間の関係はだれが持つの? シーンクラス?シーン管理クラスとか他のクラス? 分岐のあるゲームだとこれ重要。 次に進めるべきシーンを決める奴が持てばいいのか・・・? シーン遷移管理とシーン関係管理+フラグ管理に分けるとか? >シーンを遷移するときって、前のシーンは開放しちゃっていいのか? javaだとこれ厄介なんだよね。何しようが使ってなかったら勝手に拾われるから。 一応クリーンアップなりシャットダウンなり処理して放置かな。 こういうときにファイナライザ使うもんじゃないしね。
>>277 シーンは最初に全部確保して
最後に全部解放してるよ。
シーンスタックそのものが「アクティブなシーン」のスタックであって、
今アクティブじゃないシーンは別のリストに保管してる。
でスタックに積まれてるものは一通り処理する。
こうすることで移動画面中にメニューも表示して移動もメニュー選択も可とか
裏画面でデモ(通常ゲーム処理)回しながら上にウィンドウ表示とか
出来ますよ って趣旨だったと思う >Gems5
ただ、ウィンドウ関係以外には特に利点は無さそう。
マルチスレッドを実現する手段の一種ということ?
>>285 >でスタックに積まれてるものは一通り処理する。
これ、厳密にはスタックって呼べなくね?
LIFO≠スタック
なんだ、シーンの遷移がスタック的なのかと思ってた。
289 :
285 :2007/04/10(火) 01:26:00 ID:NhbAQuFj
>>287 上にシーンを積んだときにサスペンド処理(シーンクラスのメソッド)を呼ぶようにして
サスペンド中も実行したいシーンはその処理でサスペンド時も実行してねフラグを立てる
とかそんな処理になっていたと思うから 一応一番上に積まれているのが
現在のシーンってことになる。
立ち読みだから細かいことは忘れたw
スタック全体をなめるんだからスタックとは言わないと俺も思う。
290 :
277 :2007/04/10(火) 01:59:26 ID:9N2vtVIw
わかった。
かなり勘違いしていた・・・。
>>288 俺もそう思ってたww
291 :
名前は開発中のものです。 :2007/04/10(火) 09:19:06 ID:xnqcZNCE
これ読んで、久々にパックマン作りたくなったな〜。 アクションゲームは、作ってないけど、デザインパターンを、正しく使うと、プログラムがスッキリするし、大好き。 デザインパターンって、しらない人多いのかな?
292 :
名前は開発中のものです。 :2007/04/10(火) 09:47:11 ID:9N2vtVIw
Large-Scale Stack-Based State Machines James Boer Game Programming Gems 5, 2005.
>>291 > デザインパターンって、しらない人多いのかな?
んなわきゃない
294 :
名前は開発中のものです。 :2007/04/11(水) 05:40:08 ID:6fD2+qm/
スタックベースのシーン管理、結局、状態遷移をスタックベースに作ってしまったw これで、 タイトル画面→(呼び出し)→ゲーム処理→(戻る)→タイトル画面 とか、 タイトル画面→(呼び出し)→リプレイのメニュー→(呼び出し)→ゲーム処理→(戻る)→ リプレイメニュー→(戻る)→タイトル画面 とかできるようになったw スタックベースといったらやっぱりこっちだろw
スタック的に自然な状態遷移しかしないのであれば役に立つだろうけど、 そうではない大部分のゲームにとっては役立たず以外の何物でもないと思う。
スタックというデータ構造を状態遷移を表現するために利用するからには
・次のシーンに移る=push操作
・1つ前のシーンに戻る=pop操作
という対応関係が常に成り立っていて、この操作のみで完結すべきなんだが、
これだけの操作でOKなゲームがどれだけあるかっていうと、ぶっちゃけほとんどない。
スタックにこだわるあまり、データ構造を破壊したり
オブジェクトの役割を破壊したりするような例が後を絶たないのだが、
>>279 と
>>281 のようなやり取りが行われている現状では仕方がないか。
実質が状態遷移ならstateパターンでいいやんって事ですか?
>>297 Stateパターンとか全く関係ないよ。
シーンの遷移をうまく表現するためのデータ構造に関する話。
どこまで理解しているかわからないから基礎から説明する。
Stackというデータ構造は、
・オブジェクトを1つStackに積むpush操作
・最後にStackに入れたオブジェクトを1つ取り出して捨てるpop操作
・最後にStackに入れたオブジェクトを参照するtop操作
を持つ。ここで、
・push操作=次のシーンに移る
・pop操作=1つ前のシーンに戻る
・top操作=現在のシーンを取得する
と対応付けると、これはシーン管理に使えそうだぞってことになる。
これが、今話題に上がっているStackベースのシーン管理。
これをStateパターンにしたところで、Stackの中に入るオブジェクトが
シーンオブジェクトから状態オブジェクトに変わるだけで、
シーン遷移のための操作やベースとなるデータ構造は変化しないってのはわかる?
(続き)
で、何故Stackベースのシーン管理に関して
>>295 と
>>296 (俺)のような批判が出るかって言うと、
>>298 で挙げた3つの操作だけでうまく管理できるような
状態遷移になっているゲームが少ないから。
例えば、Stackの状態が
タイトル <- メニュー <- ゲーム処理 <-
だとして、ゲームオーバーシーンに移りたいとする。そうするとpush操作で
タイトル <- メニュー <- ゲーム処理 <- ゲームオーバー <-
となるが、次にタイトルシーンに移りたくなったときに、
これに対応する操作がない。あくまで与えられている操作は、
次のシーンに移るか、1つ前のシーンに戻るかだけだから。
"ゲームオーバーシーンから戻るときだけは
topがタイトルシーンになるまでpopする"というような特例を
不都合が生じる度に設けると、Stackベースにした意味がなくなる。
これが
>>296 で言った『データ構造の破壊』に相当する。
"Chain of Responsibilityパターンを使ってシーンオブジェクト間で
データをリレーしていけば実現できるよ"って意見をどこかで
見たことがあるのだが、そもそもシーンオブジェクトには
状態遷移を正しく行う責任はないので、オブジェクトの動作的に不自然。
これが
>>296 で言った『オブジェクトの役割の破壊』に相当する。
ここまで神経使うかよって思うのが普通だとは思うけど、
せっかくのデータ構造スレなので色々グダグダと言ってみた。
よさげなデータ構造があれば是非ともそれを利用したいし。
Stackのシーン管理を、必要なところだけ使うようにすればいいんじゃないの。 セーブ画面とか、オプション画面とか。
色々考えて、俺はスタック的な遷移も結構いいんじゃないかと思えてきた。 スタックだと、シーンの遷移の責任は全て親に任せることができる。 キャンペーンモードなのか、単独のマップを遊ぶだけのモードなのかは、自分は 知る必要もなく、遷移する理由(勝利、敗北、キャンセル…etc)だけを伝えれば 次にどのシーンになるかは親が決めてくれる。 各シーンが自分で次のシーンを選んでダイレクトに遷移していくよりは、 親に一任した方がすっきりするね。 スタックそのものでなくても、スタック的な遷移ができることは便利だと思う。
うむ、完全にpush/popに収める必要はないよな。
素直に多方向リンクリストでやれよ。
それは実装・データ構造の話じゃん。
>>302 遷移する理由を伝えることによるシーン遷移ってのはいいね。
が、これは別にスタックに限った恩恵ではない
(っていうのは
>>302 もわかってると思うけど)。
>>304 の言う多方向リストでも可能(っていうか本来はこっち)だし、
イテレータが指すシーンを現在のシーンとする双方向リストでも可能。
多方向リストで工夫して実装すれば、
リソースを食うシーンに移ったときに
前のシーンをいくつか解放するといった処理が行えるし、
シーンを激しく前後するような操作をしても
オーバーヘッドがかからないのでいいかも。
もっとも、ゲーム起動時にリソースを全部先読みしても
全く問題ないようなゲームだったら、
積みっぱなしのスタックで全く問題ないし、
これが一番簡単だと思うけど。
"多方向リンクリスト"に該当するページが見つかりませんでした。
308 :
名前は開発中のものです。 :2007/04/13(金) 01:17:14 ID:FDWvNnME
双方向リンクリストじゃない?
色んな方向につながってるってことは… vectorじゃねぇの?
310 :
名前は開発中のものです。 :2007/04/13(金) 02:13:59 ID:ye+8qT/8
遷移元シーン番号と遷移事由コードで テーブルから遷移先シーン番号(またはシーンオブジェクトの参照)を 引くだけというのはだめだろうか
ヒント:C言語などの関数
状態の保存方法なんて画面にあわせて stack なり queue なり vector なり list なり、適当に作ったツリー構造なりを使えばいいよ。 コンテナ実装するのも一苦労だったアセンブラやCで組む時代じゃないんだから、 全体でどれに統一するか悩む必要なんて無いでしょ。
ログ
参照カウント付きスマートベクトルポインタ使ってシーンの遅延生成や破壊を自動管理したり 夢が広がりまくりんぐ
シーン間の遷移(例えばクロスフェード)とかどうやってる?
俺はシーン別に切り分けてバッファを持っている。
自分は、Viewで処理してて、Modelでのシーン自体は完全に移行済みにしとく。 あくまで、表示(演出)は表示(演出)ときりわけやったほうがいいと思うし、 また、切り分けとくと変更も楽だし、テスト時とか演出要らん場合はさっさと飛ばせるし。
やべ。意味が分からん^^
ちょっと確認させて欲しい。
class IScene {
virtual void update(ISceneContext& ctx);
virtual void draw(ISceneContext& ctx);
};
class SceneStack {
void push(IScene *scene);
void pop();
void call(IScene *scene);
void update(ISceneContext& ctx) { /*登録されたシーンの更新*/ }
void draw(ISceneContext& ctx) { /*登録されたシーンの描画*/ }
};
自分の理解では、こんなのがシーン処理の実装なんだけど、
まずこの解釈はあってる?
当然、シーン変更時はscenestack.call(new_scene)とかやるわけね。
>>317 シーン別にバッファを持ってるってことは、
シーン遷移時の処理はSceneクラスで遷移を行うか、
他の遷移専用クラスがあるってことですか?
>>318 ↑の例でいうと、ISceneまたはSceneStackのdraw内のみで
遷移処理を実行するということですか?
全然分かってないかもです。
理解が足りなくて申し訳ない。
320 :
316 :2007/04/20(金) 18:22:39 ID:NDgAfFd0
やねうら臭がする
322 :
名前は開発中のものです。 :2007/04/21(土) 04:53:19 ID:upqCn/9t
323 :
名前は開発中のものです。 :2007/04/21(土) 09:13:46 ID:jPfR3hGz
沖縄県の方へ(命に関わる注意事項です) 沖縄県での選挙ですが、どうか民主党だけは避けてください。県民の生命に関わる可能性があります。 民主党の最大の公約は一国二制度(※)ですが、一度「一国二制度 沖縄 三千万」等で検索をお願いします。 この際、民主党のHPで調べても良いです。以下の注釈↓と矛盾することは書いてないはずですから… ※一国二制度 簡単に言えば沖縄を中国と日本の共有物にし、そこに3000万人の中国人を入植させます。 (つまり沖縄人口の 96% を中国人にして、実質、沖縄を中国人の居住地とします。) さらに「自主」の名の下、沖縄で有事が起きても自衛隊は干渉できません。 3000万人の中国人が、少数派となった130万人の日本人に何をしても、です。 そして反日教育を受けた中国人の反日感情の強さは、ほとんどの日本人の理解を超えるものです。 今回の選挙で民主党が勝った場合、「自主」「発展」を連呼しつつ段階的に進めていくことになります。 自主と言っても、自主を認めるのが「住人の96%が中国人となった」後だということに気をつけてください。 発展と言っても、新沖縄の少数派となった「少数民族日本人」の発展ではないことに気をつけてください。
324 :
317 :2007/04/23(月) 17:44:03 ID:jyQ0IgwD
>>318 とほぼ同じと思うけど
シーンに関してスタックは使ってないので、並列処理しているとき
それぞれのシーンが自分用の裏画面などを持ってないと都合が悪い
表示(演出)は別クラスにして任意シーンの裏画面を複数使って料理する
ぶっちゃけ、カメラを切り替えている感じ
>>324 なーる。表示用クラスが裏画面(テクスチャだよね?)
を複数使って演出してるわけね。
ありがとう^^
RPGでマップとかイベントはゲームスタート時に全部ファイルから読み込んでメモリに置いておくほうが普通でしょうか? それともマップに入ったときにファイルからロードするほうがいいでしょうか?
普通なら、使いもしないデータを主記憶に展開しておくのは無駄としか思えないが・・・
環境とか開発の容易性とかいろいろ考えた上で全部入れるのはべつにかまわん 重いのは画像や音声だったりするわけでそれがないので別に大丈夫かと 規模によっちゃそれすらもまるごといれてもかまわんけどな 1MBもあればFF4がまるごとはいるわけで
329 :
名前は開発中のものです。 :2007/04/30(月) 14:36:40 ID:rkXlhSNv
動的に読み込むってなかなか難しくて・・・ FF4で1MBなら自分の程度なら全部読み込んでも大丈夫かも。
シームレスは少し難易度高いが、区画ごとに区切っていいなら難しくないんじゃ? あっちこっちでグローバル変数使うような原人は知らん。
最初は難しいことに手を出すよりも、楽なほうでやったほうがいいよ。 後からだんだん発展させていけばいいと思う。 ぐちゃぐちゃになったらリファクタリングで。
クラスが多くなってぐちゃぐちゃになってきたorz RPGって結構複雑ですぐ混乱してくる。 そろそろUMLとか勉強しないときついなと思ってきた。
UMLは構成を抽象化して理解するためのものであって おぬしの想像しているものとは用途が違うぞ
システムの規模が肥大して、クラスを整理するのが大変になってきたら UMLなり何なり書いて一からやり直してもいいんじゃねぇの
リファクタリングとデザインパターンおぼえておけばおけ アクセサとしてpublicなメソッド用意してるだけだとあとでみなおすとききついから フレームワークつくればよろしい
有名そうなライブラリをぱくるとかで
UMLからソースのスケルトンを自動生成する奴とか使って手抜きしたい 一応ヘッダから関数の定義のスケルトンや、標準関数やライブラリの関数のusing宣言を 自動化する程度のツールは自作して使ってるけど
338 :
名前は開発中のものです。 :2007/05/02(水) 23:15:54 ID:waD0m0t1
今までいきなりコーディング始めてたんだけど大規模なゲーム作り始めて設計の重要性を痛感したorz ただUML書いててもちっとも楽しくない。
>>338 おやこんな所に俺がいるじゃないか
早く新人研修のJava教本を読む作業に戻るんだ・・・
俺はUML書いてるだけで楽しいけどなあ
同意 コードに落とす方がかったるい
すげー、良く分かるw コード打ってる時も、デバックしてる時はめんどい加減で止めたくなる。
俺は未だに、コーディングするときは脳内麻薬出まくり。 分かりきった定型的なコードを書いてるときは退屈で死にそうだけど。
人それぞれだなー 自分はキーボードかたかた叩いてちょっとずつ作っていく瞬間が楽しい でも設計できないと先がなさそうorz がんばってUML勉強しよう。
>>344 UMLはそういうものじゃないぞ。基本的にあれは知らなくても十分だし。
(あくまでも、設計の書き方・設計のための言語みたいなもん。
個人か固定少人数でやるなら、適当でもなんとかなるし。)
設計を と思ってるなら、普通にオブジェクト指向系の本がいい。
自分が買って読んだ本で、お勧めは
憂鬱なプログラマのためのオブジェクト指向開発講座―C++による実践的ソフトウェア構築入門
まぁ、あと定番ながら
オブジェクト指向プログラミング入門
デザインパターンとともに学ぶオブジェクト指向のこころ
立ち読みで数ページしかみてないけど、入門の方はC++ 以外の言語(Object-C、Java、Delphi?)まで含めた本。
どれもこれも、値段も高いし・ページ数もやたらとあるしで
趣味でゲームを作るだけならちょっとオーバーワークっぽくも思えるけど、
Programmerとしての教養に読んでみては?
憂鬱本は読んでみたけれど全くオススメできない。 ゲームプログラマなら、遅くともインベーダゲームを例とした説明のところで 頓珍漢なことを言っているのに気づくべき。
JAVAでもいいなら「オブジェクト脳のつくり方」がお勧めだぞ。 UMLの超簡単解説もあるし。 例題が業務システムなのがアレだが、 本質的な部分はC++も同じだから大丈夫かと。
アレコレ言ってもしょうがないんでとりあえずUMLに触れてみて どうやってコレを使ったら自分の助けになるのか 自分なりに理解するのが大切だと思いますよ
>>344 書籍で理論や共通知識を学ぶのも良いけど、ある程度コーディングできるように
なったら、「ホンモノ」のコードを読んでみるのも良い勉強になるよ。
個人的には UNIX V6 のソースコード読んで勉強したクチなんだが、いまどきの
人に薦められるかというと、ちょっと違う気がする。今だと Java, C++ あたりで
良い教材無いかねぇ…
UMLといってもクラス図くらいしか描かねぇ
色んな図あるけど業務でやらない限りは クラス図、アクティビティ図、シーケンス図あたりが限度かねぇ
業務でもそれプラスユースケースくらい
>>351 俺はアクティビティ図を抜いて、代わりにステートチャート図が追加って感じ。
354 :
名前は開発中のものです。 :2007/05/04(金) 13:14:26 ID:ljy2orUl
> 憂鬱なプログラマのためのオブジェクト指向開発講座 これ、全然おもしろくなかた。 わかりにくい。 オブジェクト指向分かってる後によんだのに、わかりにくかった。 「プログラマのための 憂鬱なオブジェクト指向開発講座」に直すべき。
そんな
>>354 のオススメ図書は?
いや、あおりでなしに、その本読んだけど分からなくて、今も分からないままなもんで。教えてくらさい orz
シームレスってどうやんの? 例えば2DのRPGマップをスクロールさせる様なばやいとか
>>356 普通にやれば言いと思うが・・・
どんな状況を言ってるんだ?
>>356 マップをエリアに分割して、自分が今いるエリアの周囲をメモリに読み込んでおく。
移動して自分がいるエリアが変わったら、不要になったエリアの情報を破棄して
必要なエリアの情報を非同期読み込み。
これだけだが、何か疑問が?
359 :
356 :2007/05/04(金) 23:07:32 ID:+e+/DrXO
わかったありがとちん。 作ってみるよ。
360 :
名前は開発中のものです。 :2007/05/05(土) 00:05:52 ID:WcHz0Tx6
>>355 あー、俺は、Delphiを使っているうちに覚えてしまったたちでね・・・。
当時は、標準添付ライブラリのVCL使ったり、ソースとか読んだりして、オブジェクト指向を学んだな。
今なら、.NETのライブラリ使ったり、コンポーネント作って、覚えるようなもんだろうか。
習うより、慣れろって感じでスマソ。
あえて言うなら、実践的なオブジェクト指向ということで、
デザインパターンの言及しているwebページとか、本とかかな?
直接関係ないが、開発技法になっちゃうが、XP(エクストリームプログラミング)関連とかも、
OOP前提が多くて、実践的でためになる。
リファクタリング、ユニットテストなど。
あと、Javaでかかれた本とかページとかは、オブジェクト指向前提で参考になるよ。
なんとなくだが、
>>360 は見栄を張ってる気がする。
“ためになる” “参考になる”とか言いつつも具体的な書籍やHPも挙げないし、
言ってる事も理解へ向けてと言うよりも言葉で煙に巻く感じで(・A・)イクナイ!!
自分なら
>>355 には、 オブジェクト指向プログラミング入門 を推す。
内容にがやや教科書的/板書的過ぎるから普通の読み方じゃなく
章単位の読み方とか多少英語論文的な読み方が求められるけどページ数に合った力がつくと思う。
あと、ここでなんか批判されまくってるが、「憂鬱な」はそんな悪い本じゃないと思うぞ。
まぁちらほら賛成できない部分や論理的におかしい部分は見受けるが、それでもなかなかの良書。
もう一度、読み直してみるのもいいと思うが。
362 :
名前は開発中のものです。 :2007/05/05(土) 02:25:29 ID:WcHz0Tx6
アホか。見栄はりに2chに来てねーよ。
煙に巻くつもりなら、レスしなけりゃいい。
具体的なページを上げられないのは、当時のをブックマークしてないから。
第一、コード書いて、読んで、実地で学んだと言っているのに・・・。
ただ、「デザインパターン」とか「エクストリームプログラミング」とかキーワード上げてるんだからさ・・・
まあ、ググレカスと言いたいところなのだが・・・
■デザインパターン
サルでもわかる 逆引きデザインパターン 第1章 はじめてのデザインパターン はじめに
http://www.nulab.co.jp/designPatterns/designPatterns1/designPatterns1-1.html Amazon.co.jp: オブジェクト指向における再利用のためのデザインパターン: 本: エリック ガンマ,ラルフ ジョンソン,リチャード ヘルム,ジョン ブリシディース,Erich Gamma,Ralph Johnson,Richard Helm,John Vlissides,本位田 真一,吉田 和樹
http://amazon.co.jp/o/ASIN/4797311126/ 流行になった本だが、実例少なく今となっては読みにくい。CDの中身がまとまっていてよい。
Amazon.co.jp: デザインパターンとともに学ぶオブジェクト指向のこころ: 本: アラン・シャロウェイ,ジェームズ・R・トロット,村上 雅章
http://amazon.co.jp/o/ASIN/4894716844/ Amazon.co.jp: 増補改訂版Java言語で学ぶデザインパターン入門: 本: 結城 浩
http://amazon.co.jp/o/ASIN/4797327030/
363 :
名前は開発中のものです。 :2007/05/05(土) 02:26:17 ID:WcHz0Tx6
364 :
名前は開発中のものです。 :2007/05/05(土) 02:33:04 ID:WcHz0Tx6
初心者ならオブジェクト指向狂詩曲がいい。 内容はたいしたことは無いが、OOPの作法みたいなものがわかる。 軽く読めるのでおすすめ。 ところでダックタイピング系の書物でおすすめない?
366 :
名前は開発中のものです。 :2007/05/05(土) 09:36:59 ID:WcHz0Tx6
>>365 ダックタイピングって、Rubyとか、Pythonのアレですか?
C++とかで実装する方法とかってことですか?
そんな局所的な本なんてでてんのかなー。
ェネリックプログラミング系の書物がそれにあたるような気が
368 :
名前は開発中のものです。 :2007/05/23(水) 19:36:40 ID:yFXY+8Zs
たまにネタふり。 2Dゲームなどで使われる オーダーリングテーブル(Ordering Table)は、すでに常識でしょうか。 たぶんローカル用語でしょうけど、大体用語がないので、これですませています。 おれは、弾幕ゲーム作ってるんだ! いちいち、物体ごとに、Zソートしてたら遅くなる!そんな時に使用します。 z値ごとに、ArrayListをもって、バケットソート(バケツソート)するような感じです。 z値が広い場合は、z値を狭めるか(0〜100くらいの定数にしてもいい)、 z値を割って使用します。 図では、こんな感じ。 z値 0 →□→□ 1 2 →□ 3 →□→□ →□→□ 4 →□→□ □は物体。
369 :
名前は開発中のものです。 :2007/05/23(水) 19:39:22 ID:yFXY+8Zs
>大体用語 代替用語
370 :
名前は開発中のものです。 :2007/05/23(水) 20:10:55 ID:yFXY+8Zs
>>368 登録するのを物体ではなく、メソッドポインタなどにすれば、より汎用性が高まると思います。
久々に凄いネタ振りを見た
人いたんだこのスレ
ぶっちゃけZソートで重いって8bitCPUかと
最近知って、自慢したくて仕方なかったのでしょうw 使いどころ違うしw
>>368 > 物体ごとに、Zソートしてたら遅くなる!
今ならZバッファ使えばいいじゃん。PlayStation じゃないんだし。
>>375 画像処理のことなのか?
まぁ、半透明使うならZソートしといたほうがいいけど
>>368 はハッシュとかツリーとか勉強するといいかも
377 :
名前は開発中のものです。 :2007/05/24(木) 14:14:16 ID:MN3OTeQA
>>375 3Dのシーンならそれでいいんですけど、
2D主体で、アルファ付きテクスチャ描画が標準、
アルファブレンドを使うのが当たり前、加算合成などが多めになると、
Zバッファが使えなくないですか?
俺、もしかしたら、基本的なところで、ミスってる?('A`)
>>373 毎フレーム、オブジェクトを数千個ソートするのもそんなには重くはないですけどね。
>>374 実は、昔から(DirectDrawの時代)から使ってるんですが、
使いどころ間違ってるのあk−−−−−マジ教えてくれ
>>376 そうです。半透明が多めなんです。
Hashとかツリーは普通に使います。OTの実装もHashと同じですし
hashとかわかってるならなんでそんなことをココに書き込むのだと小一時間問い詰めたい
・2D主体かつαブレンドを多用 ・z値が整数で適当な範囲に収まる場合 ならその方法がいいのかもね でもゲームによってやり方を変えるのが一番賢いだろうね
>378 最初にネタふりって書いてあるやん
っていうか、2Dのスプライトの場合はZオーダーなんてそう頻繁に 入れ替わるものではないから、前フレームのソート結果を上手く利用すれば、 もっと軽くできると思う。
このスレの90%はネタを振る人間とそれにケチをつける人間でできています
ROM
ROMはいくらいても0%だろう
386 :
名前は開発中のものです。 :2007/06/12(火) 16:35:34 ID:KXWIMOSu
同人の俺は気にするほどのゲーム作らないからなー。 後から基数ソートやらに書き換えるつもりでSTLのsortでZソートしたけど どこにも問題ないのでそのままリリースしたよ。めっちゃ富豪的
>>386 PS2 でも、そんなもんでした。STLport にお任せ。
コールバックってどういうときに使うんですか? タスクシステム(というかハンドラオブジェクト)を使う時の場合において適当な例を教えてください
コールバックする時。 タスクシステムに限らず、メモリの解放を行ってもらうときとか、 進展情報を表示する時によく使うなあ。 とくに前者の場合は、他の開発環境で作ったDLL内でメモリを解放したいときとか。
>>388 オブザーバーパターンは便利だよ。
たとえば敵を倒したときにそいつのはいた弾をすべて消すとか、誘導弾のつけなおしとか
なれてくるとほとんどこれだけでイベントベースでコードが出来上がる。
タイミングが判明する場所と、そのとき行いたい処理との間の結合を 疎にしたいとき使います。 ほとんどこれだけでとか関係なし。必要なところへ必要なだけ使うべし。
>>388 C時代のコードを利用するとき。
C++使えるんならほとんどのコールバックが仮想関数で見た目上は消せるだろう。
つまり仮想関数をCで使いたいときにコールバックが出てくる。
394 :
名前は開発中のものです。 :2007/06/22(金) 08:30:52 ID:njuyTnq1
Xboxのアレは禁断のボゴソートを使ったとしか思えない
カルドセプトサーガの事じゃないの?
そのタイトル名でググってみたが、これは酷いなw サイコロが奇数と偶数が交互に出るとかw
>>398 これ逆にコーディングの手間がかかるだろw
>ボゴソートは、ソートのアルゴリズムの一つ。 >平均的な計算時間はO(n×n!)で、非常に効率の悪いアルゴリズムとして知られている。 >安定ソートではない。 最後の一行のオチで吹いたw
ここでボゴソートを使ったゲームを考えるのがゲームプログラマの努・・・ごめん無理
ボゴソートワロタw
403 :
名前は開発中のものです。 :2007/06/24(日) 05:25:19 ID:zQnoyhbz
ワラタ ソートつーか、バラバラに並び変えるアルゴリズムかとw
>>400 安定ソートの意味知ってるのかよ('ω`)
>>404 安定ソートの意味知ってるのかよ('ω`)
えーっと、同じ順位のアイテム同士はソート前の順番を保つ、であってる?
あってる。 この記事のオチはInfinite monkey theoremだよ。ググレ、笑うから。
411 :
名前は開発中のものです。 :2007/06/25(月) 20:59:14 ID:NaYhg1aV
>>411 既存のゲームにおけるパターンの一端って事で
413 :
名前は開発中のものです。 :2007/07/17(火) 22:54:23 ID:Mh0Ht4Or
このスレ生きてますか? 基本的?なデータの扱いについて意見を聞きたいです データに対応する操作クラス以外から値を書き換えることを禁止するためにこういうクラスを考えました template <typename T> class IData { public: friend class Mutator<T>; typedef T element_type; typedef boost::shared_ptr< element_type > value_type; protected: value_type value; }; template <typename T> class IMutator : public IData<T> { typedef IData<T> data_type; protected: void assign(data_type& target) { value = target.value; } void swap(data_type& target) { boost::swap(value, target.value); } }; 使う際はこいつを継承して class CData : public IData<int> {}; class CMutator : public IMutator<int> {}; のようにすれば CMutatorはIMutatorのassignやswapを使ってCDataのvalueの指すデータを生成から破壊まで自由に扱えるわけです でもこのようにするとCDataの持つ情報が増えた時に class CData : public IData<Param>, IData<Graphic>, IData<Sound>のように 継承しまくりになることとか、shared_ptrの機能によるコストが気になったりします そこでもっと一般的なやり方を知りたいんですが何か良い方法ありませんかね?
template <typename T> class IData { public: boost::shared_ptr<T> value; //!< 漏れ以外勝手に書き換えんなよ! };
いくら防衛策を巡らせても書く人の意思でいくらでも変えられるから そんな事考えるのは無駄だよってことですか 言われてみればそういう気もしますが…(´・ω・`)
多重継承にパフォーマンス(速度・容量の両面で)上の弊害は無いが 役割が酷似した基底(インターフェース)同士を多重継承って嫌過ぎだろ。常考。 衝突避けるためにインターフェース設計の段階でお互い調整しなくちゃいかんし 衝突上等ならキャストだらけの汚ねぇコードになる。俺ならコンポジットにする
いまいち要求が飲みこめんけど、委譲とかプロキシパターンとか アダプタパターンとか、ありもののパターンで十分間に合いそうな希ガス。 経験上、複雑な仕組みはロクなことがない。 Keep it simple stupidですよ。 苦労して得られる利益が少なくて割が合わないパターンでは?
どうも よく考えたらIDataはインターフェースじゃないっすね… 全く異なる型を同士でコンポジットにしてアクセスも上手く制限できる事って出来るんでしょうか 要求としては ・データと動作を分離する事と ・動作をデータに対してではなくゲーム上のオブジェクトに対して書けること ・書き込み専用のクラス以外からのアクセスを制限する事 です 操作されるデータの実体へのポインタを持つIDataと、それを扱うインターフェースIMutatorに分けたのは一番目のため 多重継承したCData経由でデータを扱うのは2番目を実現するため データの実体へのポインタであるIDataのvalueメンバをprotectedにし Mutatorをフレンドにしたのは三番目の為 以上によってゲーム内でのオブジェクトの振舞いは全てIMutator派生クラスのCDataに対しての操作として 書くことが出来て、リソースの確保等のシステム的な動作は外部に一任できる という意図があったんですが、そんなに複雑ですかいね?
・データと動作を分離する事と ・動作をデータに対してではなくゲーム上のオブジェクトに対して書けること ・書き込み専用のクラス以外からのアクセスを制限する事 つまりテンプレートで実装する意味はないよね?
420 :
名前は開発中のものです。 :2007/07/18(水) 00:37:53 ID:9FpPIZ4u
> ・書き込み専用のクラス以外からのアクセスを制限する事 IMutatorを継承すればどんなクラス以外からでもアクセスできる以上、 制限できてるとは言いがたい。 「IMutatorの継承を無闇にするな」と、文書で説明する? ならば、414でいいでしょ。
>>418 > ・動作をデータに対してではなくゲーム上のオブジェクトに対して書けること
「データ」と「ゲーム上のオブジェクト」の違いがよくわかりません。
「動作を〜に対して書ける」ってのもよくわかりません。
「〜を引数とする関数を書くことができる」ってことでしょうか?
なんか奇想天外なことになってるのは
>・データと動作を分離する事と
これのせいだと思う
誰が吹き込んだんだか知らんがまず
>>413 がしなきゃいけないことはこいつを殺すことだ
class CData : public IData<Param>, IData<Graphic>, IData<Sound> {}; こうすると、CData::valueの型は何になるの?
425 :
413 :2007/07/18(水) 19:28:34 ID:xDBgIMCC
>>419 ,
>>420 >つまりテンプレートで実装する意味は無いよね
恐らく既存の構造体を利用するためにこうした筈なんですが
普通にそれらをCDataにスマポで持たせた方がいいじゃんじゃんな気もしてきました
>>421 おっしゃるとおりです
細かいところにとらわれて本質を見失うという悪い例を晒してしまいました…
>>422 >「〜を引数とする関数を書くことができる」ってことでしょうか?
そうです
キャラクタの移動や描画の際は、リソースのハンドラを移動クラスや描画クラスに渡すんでなく
CDataを渡すような形で書きたいわけです
>>423 なんかキャラクタのクラスに座標構造体と移動メソッドを定義してたソースを友人に見せると
値を保持するクラスと操作するクラスは分けろこのスカポンタンとか言われたのでそうするようにしてるんですが
何か思い違いをしてますか…と問うまでもなく明らかにしてますね
>>424 晒したコードでは見事に多重定義のエラーになりました
実際はそれ避けたり多重定義されたIDataのvalueを内部で扱うためにboost::mplとか使って
さらに複雑な事やってるんですが
>>417 氏の言ってる事に繋がりますね
とりあえず苦労して作った車輪は最発明どころかガラクタですらないナニカだったというオチでした
もっかい一から作り直してみますm(_ _)m
>>425 > 値を保持するクラスと操作するクラスは分けろこのスカポンタン
インターフェースと実装を分離するのは一般論としては間違いじゃないが、粒度が違う。
メンバ変数単位ではなく、意味のあるメンバ変数のセットをインターフェースにしろって
意味だと思うよ。
// 衝突判定後に、消灯判定マネージャから衝突回避のために位置をずらされる
struct IMovable {
// 現在位置
virtual void getPosCur(VECTOR3* p) const = 0;
// 移動したい位置
virtual void getPosNext(VECTOR3* p) const = 0;
// 衝突しないようにマネージャがずらした位置
virtual void setPos(VECTOR3 const& v) = 0;
};
class Player : public IMovable { ... };
class CollisionManager { /* こいつは IMovable だけ使用 */ };
こういう話かと。
>>426 s/メンバ変数のセット/メンバ関数のセット/g
>>425 >値を保持するクラスと操作するクラスは分けろこのスカポンタンとか言われたのでそうするようにしてる
なんでそうしなくちゃいけないか理由は分からないの?
プログラムは芸術じゃないんだから外の人のどうしたこうしたで中身が変わったりしないよ?
> 値を保持するクラスと操作するクラスは分けろこのスカポンタンとか言われたのでそうするようにしてるんですが つかこれ自体間違いだろ。
431 :
名前は開発中のものです。 :2007/07/19(木) 05:21:01 ID:5YEt12VO
getterとsetter作って、アクセス管理するくらいしかやったことねえや 触らせたくないなら、関連クラスからのみアクセスとか(C++ならfriend?) それ以上ってコストかかりすぎねえ?
少人数・小規模製作でアクセス制限も糞もないわな
少人数小規模だろうが、 開発期間中に、年単位で空白があったコードを読むこともあるわけで。 そういう場合は、アクセス権は考えといて損はねーですがよ。
アクセス権?になってくるとまた話が変わってきちゃうんだが そんなファイルのパーミッションみたいな機構小規模だろうが大規模だろうがつけたらあかん というか無駄、損がないというか何の得もない
とりあえず理由を
なんでファイルのパーミッションの話になってるんだ
>>432 のアクセス制限って、クラスのメンバーに対することで、
>>433 のアクセス権ってのもそのことだろ?
437 :
436 :2007/07/19(木) 19:27:51 ID:3ArgKadV
変な日本語になった
正しくは、
なんでファイルのパーミッションの話になってるんだ
>>433 のアクセス権って、クラスのメンバーに対することで、
>>432 のアクセス制限ってのもそのことだろ?
「使いたいものを使いたいときに即使えないのはうっとうしい」 ということではなかろうか>ファイルシステムの例え話 個人管理のLinuxなんかだと、最初からrootでログインして使う人もいるくらいだから それはそれで別に当人の自由だと思う。 要はアクセス権限を分ける方がトクか分けない方がトクかは ケースバイケースで判断すればいいってことだけど
>なんでファイルのパーミッションの話になってるんだ おまえがアクセス権なんていうからじゃん
スレタイを百回声に出して読んでくれ
ついでに二人とも正座な
難しく考えすぎ。 他のオブジェクトにアクセスして欲しくないメンバは クラスの中に隠蔽して、プライベートメンバにしておくのがセオリーでは。 アクセス権ってのは本来そうやってコントロールする。 外からオブジェクトにアクセスできるようにしておきながら アクセスできないように制限する仕組みを作るってのがナンセンス。
「する」「しない」の二択にするという話ならその通りだが 特定の状況でのみ●●に大して××させることを許可するとかいう話なら ソースレベルで静的に操作するのは困難
動的にアクセス権を与えたいなら、まずは隠蔽しておいて、 状態に応じてアクセスを許すかどうかを決めればいいのでは。
本当にアクセス制御の問題で困っている人が大勢いるなら、
今頃boostにそれらしいクラスが含まれていると思うけどね。
例えばnoncopyableはオブジェクトのコピーを禁止するクラス。
こんなレベルのものでも有用さが認められればboostに仲間入りできる。
http://www.kmonos.net/alang/boost/classes/noncopyable.html でも今現在boostにアクセス権制御のクラスがないってことは、
需要がないってことでは?
まずはプライベートメンバを使ったシンプルな隠蔽によるアクセス制御で
どこまでできるのか突き詰めてみた方がいいでしょ。
今のところ自分はそれで困ったことはないけどね…。
ナンセンス。この一語に尽きる。
progress_displayがあるのにそんなこと言われても説得力無いなぁ 動的にアクセス権決めるならgetter,setterを隠蔽してfunction使ってアクセス権を与えたいクラスに そのgetter,setterを与えてやるって方法もあるけど functionは1個で40bytes近く食う割と重たい(?)オブジェクトだから無茶かな、無茶だな
448 :
名前は開発中のものです。 :2007/07/21(土) 03:00:31 ID:DMrsrXyJ
動的ってことになってくるとそれは普通にインターフェイス呼び出し時の
認証の機能の話になってしまうんじゃ?RMIとかそーいった話の流れ方向での
静的だと外側の構造も知らん一クラスごときが誰に使われるのが良いだ悪いだ
決めるとか何いい気になってんだって話だ
>>443 >静的に操作するのは困難
困難どうこうより、そのポリシーを決める根拠をどこにも求められないということだよ
適当に決めてしまえば後で直せなくなる
根拠がどこにもないから
>>443 インターフェースを多重継承して、必要な時・相手にアップキャストしたものを渡せば。
簡単な具体例も挙げてくださいお願いします
>>450 struct IFoo { virtual Vec3 getPos(); const = 0; };
struct IBar { virtual setPos(Vec3 const& pos) = 0; };
class CPlayer : IFoo, IBar { ... };
f1(IFoo&);
f2(IBar&);
CPlayer player;
f1(player); // f1には getPos() しかさせない
f2(player); // f2には setPos() でメンバ変数書き換えを許可
>>447 functionって40byteも食うの?
その半分くらいですみそうなんだけどな。
なるほど、呼び出す側にインターフェースを渡すんですね 参考になりましたありがとうございます。
boost::functionって便利だけどむちゃくちゃヒープが汚くなりそう
>>454 小さなオブジェクトが多数 new されそうって意味? 気にしなさんな。
まあ、それが気になって使ってない、という訳じゃないけどねえ。 アロケータ作れば何とかなるだろうし。
457 :
名前は開発中のものです。 :2007/08/05(日) 20:35:16 ID:ki20ixME
javaでTCBを使いたいんだけど、どうしてる?
>>457 ふつーにメンバ変数使えばいいだけでは? Task Control Block なんてのは、アセンブリ時代の名残だから、
C++, Java あたりでは使わんでしょ。
459 :
名前は開発中のものです。 :2007/08/06(月) 00:04:42 ID:Mz0XA0lP
ゲームのデータを独自のフォーマットとかにする場合にヘッダを用意する?
460 :
457 :2007/08/06(月) 00:40:04 ID:wjb80OI1
というかあからさますぎて夜釣りに思えてきた
TCBと言えばRTOSなので ここはeCosに実装されたwabaを紹介してやるのが筋だろうか
ppc arm super wabaなら・・・
>>460 Java だとインターフェースもしくは抽象基底クラス使う。
466 :
457,460 :2007/08/06(月) 22:38:48 ID:dCjdYchV
aを規定クラスにしたb1タスク aを規定クラスにしたb2タスク b1、b2タスクが混在したリストを作成したい。 C/C++なんかだと、関数ポインタnextなどにタスクをつなげてゆけるところだが・・・ javaだと関数ポインタがないので、配列にしてインデックス参照にするしかないのだろうか? インデックス参照だと、個々のタスクごとに属性を割り振って、別々に読み出すか32bit以内に押し込むかなどして値を管理し、switchで分岐 して実行する記述が必要・・・。 C++なら多重継承があるので、b1からb2にたどることもも可能だが、javaには多重継承はないし・・・。 インターフェースは同じインプリメントを保障してくれるだけど、結局タスク切り替えのロジックが必要になるし・・・。 関数ポインタに比べて、これだと積極的に使うにはオーバーヘッドが気になるのと、記述が煩雑でプログラム的にCより退化しているように感じてしまう。 (今はリスト構造にせず、配列でタスクリストを持つ方向性で考慮中・・)
467 :
457,460 :2007/08/06(月) 22:41:30 ID:dCjdYchV
だれか経験豊かなjavaプログラマた通りかかったりしないかなぁ。
Vectorじゃだめなのか
やはり釣りだったか
HSPでOOPをやろうとするのと同じくらい馬鹿げてるな
>>466 ぐちゃぐちゃ言ってないで書いてみろ。あんまりにも考察がめちゃくちゃで
どこから突っ込んでいいのかわからん。ソース晒してみれば突っ込みも入れやすい。
473 :
名前は開発中のものです。 :2007/08/07(火) 03:33:11 ID:jZSDWWPE
なんでみんな冷たいんだwww
476 :
457,460,468 :2007/08/07(火) 07:55:20 ID:8/4fXdca
void (*func) (); これのjavaでの代用法が知りたい。
477 :
457,460,468 :2007/08/07(火) 08:07:53 ID:8/4fXdca
LinkedList .... Thanks! >> 475
>>476 java.lang.Runnable func;
>>466 aを要素にとるコンテナを宣言して
それにb1インスタンスだのb2インスタンスだのを加え、
コンテナを走査して処理メソッドを順に呼び出せばいいだけの話。
データ構造だとかクラス設計だとかいうレベルじゃない。
単にプログラミング言語の勉強が足りていないだけ。
それにお前は多重継承を激しく誤解している。出直して来い。
なんかタスクってGoToやってるような雰囲気があるな
まぁvtableは関数ポインタみたいなもんだけどな。
>>478 Swingでやってハマるとかw
関数ポインタに直感的に一番近いのはjdk7までお預けだな。
javascriptならそのまま
(function(num){ print(num);})(100); //-> 100
だが。
自分が話理解出来てないだけなのに日本語でryとか言ってる奴増えたよね。
>>485 >Swingでやってハマるとか
理解できないのはこの部分だ
Swingがスレッドセーフではないって話かな。 もしそうなら >478 が言いたいのはRunnableのインターフェースだけを 借りることだろうから話が飛躍してるな。
>>476 だから抽象基底クラスかインターフェース使えと。下のサンプルコードは C++ だが、Java でも
ほとんど変わらん。
#include <boost/foreach.hpp>
#include <boost/ptr_container/ptr_list.hpp>
struct ITask {
virtual ~ITask() {}
virtual void exec() = 0;
virtual void draw() const = 0;
};
class TaskManager {
public:
void exec() { BOOST_FOREACH(ITask& task, m_tasks) task.exec(); }
void draw() const { BOOST_FOREACH(ITask const& task, m_tasks) task.draw(); }
private:
boost::ptr_list<ITask> m_tasks;
};
たったこれだけのことなのに さも凄まじいシステムであるかのように タスクシステムと言う人の気がしれない
492 :
488 :2007/08/08(水) 07:51:26 ID:obrNCieZ
>>490 同意。
アセンブリ言語でハードコーディングしていた時代に初めて見たら「やるな」と思うが、
今時だとふつー過ぎて何も言うことがないよね。UNIX V6 のころのデバドラも、既に
こんな作りだし。
自分でコード書くのもいいけど、もっとコード読もうよ、と思う。
今とは比較にならない制限の厳しさの中で TCBを弄り回してた時代のことを知らないんだろね
495 :
457,460,466,476 :2007/08/09(木) 01:21:26 ID:WI6u6LTt
できた。 抽象基底クラスは知っていたが、 仕様上、基底クラスから上位のクラスをたどる必要があったので、 関数ポインタ云々といっていたのだが・・ キャストすればよいだけだった。 javaにはポインタの概念がないから、 javaのクラスは当然キャストできない、というような誤解があったので。
>>495 それなんか設計がおかしくないか?
みんなの意見無視ってところか
>仕様上、基底クラスから上位のクラスをたどる必要があったので、 そんな仕様にするのが悪い。 第一、抽象基底クラスを知っているのならば そんなところで困ったりしない。
初心者には冷たいもんだな
というか言語仕様勉強しろ
キャストってw ポリモフィズムをカケラも理解しとらんじゃないか
自分から質問してきたくせに まともな意見すら無視するような勉強不足君は 鮮やかに放置して、次の話題ドゾー
まともな意見を無視するのと勉強不足なのは関係ないと思うぞw 質問者はどちらの属性も持ってるけど
503 :
457,460,466,476,495 :2007/08/10(金) 20:04:16 ID:aK9bbQO3
失礼。
>>488 解決のヒントになりました。
ただboostライブラリはjavaにはないような気がします。
>>468 Vectorの案内が最初の解決のヒントになりました。
>>503 さんざん情報貰ったんだから、せめてソース晒して恩返ししてみないか?
JavaSEでVectorつかってそーだな・・・
質問すまそん。DXライブラリ&VC++でゲーム製作してます。 例えばRPGで、キャラデータ・アイテムデータ・フラグおよび ゲーム内システムデータ(ゲーム世界での日付とか)は、 それぞれグローバルなデータクラスにしてるんですが、 もうちっとスマートな設計の仕方はないでしょうか? ほぼ全てのインスタンスから参照するデータ(例えばフラグとか)って、 いちいち参照やポインターで格納させるよりか、データクラスとしてグローバルに 展開してメソッド経由でアクセスさせたほうがいいような気がするど素人なんですが、 こんな俺はオブジェクト指向として根本的に間違ってますね?
ちゃんと管理できるなら問題ない
>>506 >>507 に同意
オブジェクト指向をしたいのか、ゲームを作りたいのか。
書き方に明確な規則やルールがあれば、それだけでいいと思うけどね。
でも自分が「オブジェクト指向的」に組むなら、その辺の情報はグローバルにはしないと思う。
必ずシステム内で生成する。何故なら、ゲームシステム≠ゲームの世界と考えてるから。
1.ゲームシステム=ゲームの中の宇宙を作る(ゲームシステム=プログラム本体)
2.宇宙の中に惑星を一個作る。(ゲーム世界(日付等含む))
3.ゲームの世界の中に、登場人物やアイテムを作る。(キャラクターデータ、アイテムデータ)
4、登場人物とアイテムは、状態を所有している。(フラグ)
単純に現実に沿って状態を作る(これがRPG向きか?と言われると、そうではないけど)
データは必ず1→2→3→4の順にアクセスする。面倒くさいけど、一応これにも利点がある。
・ゲーム内での登場人物の役割を切り替えやすい。
・同時に複数キャラが操られても破綻しにくい。(マルチプレイさせやすい)
・同様に、ゲーム世界以下の要素は増やすのが比較的容易。
まとめて言えば、人や物、物事の取り扱いを現実と同じようにできるってことね。
最初に戻ると、規則があるなら君の好きで良いんじゃないってことで。
>>505 標準ライブラリが互換性のために未だに使いまくってるんだが・・・。
んで使い勝手悪いからいい加減JCFに移行しろと叩かれてるじゃないか。
Universe.MilkyWay.SolarSystem.Planets.Earth.Enabled = false;
>>508 > 単純に現実に沿って状態を作る(これがRPG向きか?と言われると、そうではないけど)
単一システムで作るのは、結構つらいなぁ。
俺だと RPG はフィールド&シナリオ、戦闘、デモシーンでシステム完全に切り離して
作っちゃうけど。どーしてもフィールドからシームレスに戦闘に入りたいと言われたら
考えるが、工数は開発もデバッグも倍かさむよって感じ。
>>506 が心配してるようなのって構造化手法の方の話で
オブジェクト指向とはあんまり関係ない気がする
オブジェクト指向言語は結局構造化手法の流れを汲んでるから関係あるっちゃあるんだけど
「オブジェクト指向的」に批判されることはないと思うんよ
>>508 はこの方針でゲーム作ってなんかあったらここへ相談しにきてね
>>513 >>510 みたいなことは流石にやってないけど、マップが複数面あって
自由にキャラクターを選べるのを作ってるから、今のやり方で全く問題なかったりするぜ!
516 :
名前は開発中のものです。 :2007/09/01(土) 13:35:04 ID:+CS1vDDV
チラウラだが .NETの自動生成コードとか見ると
クラス名がネームスペース入りのフルネームで書かれてて
>>510 と比べてもあまり遜色ないくらい長ったらしい記述になってる
>>510 はどこまでが名前空間でどこからがコレクションなんだろ
Universe.、までが宇宙空間
Planetsまでじゃないのか
C#とかだと区切り記号が全部ピリオドだから分かりにくいよなあ
俺ならPlanetsは入らないな。 Universe.MilkyWay.SolarSystem.Earth しかし、こんな話題しかないものか。
いいんじゃない、超光速星間航行を多用するスペースオペラ的ゲームのデータ構造。
>>522 そんなこと言いだしたらjavaのエンクロージング型の完全修飾名は恐ろしいことになる。
外から内部クラスをアクセスすることはほとんどないんじゃね?
527 :
名前は開発中のものです。 :2007/09/04(火) 01:36:58 ID:aBG3sZkW
まあDelphiもC#も、同じヘルスバーグ氏設計の言語だからな 俺は氏の思想は好きだが
どっちもIDEで使うための言語だからそんなに問題にならないでしょ
C#はCLRで使うための言語だろ。 VSがIDEなだけで。
まあ、確かに動的な型変換と型推論は型の決め方が違うから読み辛い。 というかC#は既存言語の枯れたパラダイム てんこもりにしただけのくせに信者が騒ぎだすんだろうなぁw
アンチうぜぇ
信者うぜー
突然何の脈絡もなく言語叩きをしだす馬鹿は放置して次の話題ドゾー
536 :
名前は開発中のものです。 :2007/09/07(金) 00:33:06 ID:B51b23c5
JAVAとかC#とかってキャストないよね タスクシステムのワーク領域のキャストってどうやるのかな
>536 今どきそんなC時代の古典的「タスクシステム」に無理矢理合わせようとしないのが正解。
>>536 だからインターフェース継承しろと。どうせメモリ管理は GC 入ってるんだし。
キャスト自体はあるだろと まぁC++でもそんなコードかいてたら殴り倒すけど
540 :
名前は開発中のものです。 :2007/09/07(金) 10:04:18 ID:puv664XK
>>539 シューティングゲーム プログラミング
松浦 健一郎 (著)
この本ではC++でワーク領域のキャストしてたけど、殴るの?
541 :
名前は開発中のものです。 :2007/09/07(金) 10:07:03 ID:ODKwq4Ib
ワーク領域のキャスト(笑)
それ悪い見本だろ
543 :
名前は開発中のものです。 :2007/09/07(金) 12:02:42 ID:xHXwrHzM
>>542 普通に使ってたよ
本を書いてる人を殴れる程、出来るプログラマーなの?あなたは
松浦 健一郎 (著)、じゃなくて 松浦 健一郎 (笑)の間違いだろ。
MAKKENは殴ってよい
>>540 の本って継承知らない程度の初心者向けの本ってところか?
継承使わずにやるやり方にページ割くくらいならさわり程度でも継承教えたほうがためになりそうだが・・・
547 :
名前は開発中のものです。 :2007/09/07(金) 16:11:07 ID:g09BD/TG
>>543 >>542 が出来るプログラマーかどうかはわからんが、
基本的に日本だと本を出す奴ってのは3流だから
とりあえず本出してる人すごいって認識は改めたほうがいい。
3流は本すら出せんだろ
>>547 三行目に同意
俺も高校まではそういうステレオタイプを持ってた
じゃあ「俺よりは凄い」で。
551 :
名前は開発中のものです。 :2007/09/07(金) 20:37:04 ID:B51b23c5
ここは自称凄い人がたくさんいるスレですね
>>546 一応継承は使ってるみたいだよ
new deleteのオーバロードも使ってるし
だから単に継承を使ったやり方をしらないだけじゃね
最近のライターがコード書けんのは確かだな。
はいはいスレ違い
"Those Who Can't Do, Teach"という言葉があってだな。 シューティングの本? 同人シュー作者の俺がそのうち書いてボコボコにしてやんよ ∧_∧ つ≡つ);:)ω・).,,'; _| ̄ ̄||≡つ=つ ) /旦|――||// /| \ | ̄ ̄ ̄ ̄ ̄| ̄| . |∪ ̄\_) |_____|三|/
>>553 正直、本を書いてもあまり儲からないんだよな……。前に技術書書いたことがあるんだが
印税8%で初版3000部とかだったから、時間単価考えたらコード書いてた方が遥かにマシ
だった。
もう少し幅広く売れる本とか、時間かけずに書けるとか、その後の仕事受注につながる類の
ヤツなら良いんだが。
何系の本なの?ゲーム系?ハード系? それとも普通の言語系?
>>557 ネットワーク系。だいぶ前だけど、当時は翻訳やら執筆やらイロイロやってた。
今じゃすっかりコンサル稼業で、趣味でしかコードかけない人生だけどな……。
技術書って印税8%も来るのか。
>>559 でも 1 冊 2,000 円 x 8% x 3000 冊だと 48 万だぜ。駆け出しのプログラマだった頃は
実質 1.5 ヶ月かけても割に合ったけど、もうダメだ。金以外に何か目的がないと
やってられんよ。
やねうらおさんですか?
562 :
名前は開発中のものです。 :2007/09/15(土) 18:37:54 ID:odGWNMQb
けっこう、計算するとシビアな値段だな・・・ 人生掛けてまでやることじゃない クソ本あろうとしったことか! あ、俺?俺は、情報商材にして、単価上げて(゚Д゚)ウマー
自分の備蓄禄だと思えば良いじゃない。 何ページで執筆に何カ月かけたか知らんが、 コード書けない人間なら数こなせば良い金になるな。 eclipse本なんてコード書かなくても良いしソフトの新版出る度に改定するから副業にはちょうど良いじゃないか。 デザインパターン本なんて同じ内容なのに言語ごとにあるぞ。 コード書いて食ってる人間に本なんて書いてる暇があるかは知らんが・・・。
日本の場合、コード書いても食えない人間ばかりだろ。 だから低レベルな本しか出てない。 そんな本ばかりだから若い人が育たない。 で、その若い人がコードで食えないから、さらに劣化した本を書くというスパイラル。
と、コードを書けもしない人間が申しております
>>564 > 日本の場合、コード書いても食えない人間ばかりだろ。
というか、単価の高いプログラミング仕事がほとんどない。
大手ゲームメーカーでリードプログラマやるより、中小の基幹システム改修
案件の SE やってた方が全然収入がいいという。技術的にもプロジェクト運営の
面でも、ゲーム屋の方が大変なんだが。
しょせん日本のマは末端の土方
568 :
名前は開発中のものです。 :2007/09/16(日) 07:52:57 ID:hBA8iHMq
プログラマなんて、IT土方だからな
>>568 GoogleとかMSだと給料高いけどな。現地ではなく日本採用でも。
570 :
名前は開発中のものです。 :2007/09/16(日) 09:44:24 ID:hBA8iHMq
>>569 プログラムだけできるだけじゃ、入れないところじゃねーか
>>569 M$はともかくgoogleは給料安いんでないの?福利厚生はともかく給料は。
>>571 Google は給与水準公開してないから情報限られるけど、俺が中の人から
聞いた話だと十分高いと思った。
それより株式公開前にストックオプション貰ってた連中は、上場と同時に
億万長者の仲間入りしちゃってるから、それと比べると給与はどうでも
良いっつー話らしいが。
絶望した。上場したてのGoogle株を買って、任天堂に乗り換えれば たった3年で20倍になってる事実に絶望した。 絶対うまいこと乗れたギーク系投機家がどこかにいるはず。
お前ら良いなgoogleが上場とか、俺の頃はまだyahooすらなかった。 CEREN vs NCSAのhttpd戦争終結後くらいか・・・。
みんな、UMLとかdoxygenとか使ってる?
どっちもつかってます
javaだからdoc toolはデフォだな。
色気出してプリプロセッサ・テンプレートメタプログラミングしてると doxygenが酔ってくれるから困る
579 :
名前は開発中のものです。 :2007/09/17(月) 10:46:54 ID:4TcSZ3vD
doxygenはマニュアル作ってくれる事もいいんだけど、コメントの規格を統一できるのもいいよな でも、心がけてくれないチーム員もいるんだよなあ
580 :
名前は開発中のものです。 :2007/09/17(月) 11:33:01 ID:wCNRu3Bd
■□■□■□■□■□■□■□■□■□■□■□■□■□■ □■□■
――――Click Click Click――――
それは、一番クリックした国が優勝するバカバカしくも熱いゲーム!
2ch全板から力を結集して日本を1位にしよう! 日本は過去に8勝(世界最多)しています。
めざすは、台湾の6連勝記録を打ち破ること!
現在日本は3連勝中だけど、猛加速のハンガリーに昨夜逆転されてしまいました。
日本のツールはとても優秀ですが、参加人数が足りません!!
逆転するには、最低でもあと100台のPCが必要です。
専用ツールを落として、ブラウザを起動しておいてくれるだけでOKです!
放置できるので、寝ながら日本の戦力になることができます!
どうか力を貸してください!
【日本2位】一番クリックした国が優勝【版画ksk】
http://wwwww.2ch.net/test/read.cgi/news4vip/1189932725/l50 ※オリジナルのゲーム制作チームがあります。ぜひ力を貸してください。
doxygen で生成したドキュメントは使ってないが、doxygen 用にコメントは 書いてる。(javadoc 形式というべきか) > コメントの規格を統一できるのもいいよな 目的はこっち。
実際のチーム開発の現場って、 コメントだけでなく、ファイル名とかクラス名とか変数名とかのコンベンションも やっぱ決められてるもんなの?
>>582 当然。
ただ汎用ライブラリを持ってくることもあるから、そっちとこっちで
規約が違って一部混在することはある。たとえば STL と DirectX
だと名づけ方大分違うしな。
584 :
名前は開発中のものです。 :2007/09/17(月) 15:33:27 ID:GfeYD8ac
>>575 Delphi使いなんで、Togetherで UMLはコードから自動生成だぜ〜(嘘、使いません
ドキュメント生成ツールは、日本語対応したものがなくて、使ってない orz
doxgenは日本語出せたよ、Delphiに対応してない気が下が
>UMLはコードから自動生成だぜ 普通設計してからコード書かないか? UMLの仕様上は確かにcode2UMLもUML2codeも相互運用可能だけど・・・。
>>586 ネタにマジ(ry
> UMLの仕様上は確かにcode2UMLもUML2codeも相互運用可能だけど・・・。
C++ は code generation に向かない言語だなぁとおもうよ。
集約・コンポジション・関連の区別とかつけにくいし、boost::scoped_ptr で pimpl イディオム
使ってる場合とか、マジメに piml クラスもクラス図に入れると煩雑になりすぎ。
私は設計段階で主要クラスだけ図に書き出して、あとはコードでって感じ。
クラス図は必要があれば更新するけど、あくまでコードが第一の文書に
しちゃってる。
UMLはドキュメントとしてはいいが、コードにそのまま適用されるものではない というのは比較的お堅い業務アプリでの常識なんだが 柔軟性が求められるゲーム開発ならなおのことじゃね? 組込み系が今突撃中
そこでinterface definition languageですよ
IDLでも結局は各言語に落とさなきゃ使えないからやる事はUMLとかわらなくない?
UMLってやっぱEAでやってるの? eclipseでNECのプラグインのを最近使ったんだが
個人的には MagicDraw とホワイトボード。
まず、マインドマップで手書きして頭の中整理してからUML使うな。
紙と鉛筆最強
同意。小型ホワイトボードもいい。
Eclipseのプラグインなんて使うのは、UMLドキュメントも成果物として要求されるような ソフトウェア製作現場くらいじゃないか
そうなんだ・・・eclipseのプラグインでしか良いのないなーって思ってた
それよりeclipseのプラグイン=UMLツールって図なのはどうなのよ? スタンドアローンなUMLツールもちゃんとあるんだからね!?
>>598 > スタンドアローンなUMLツールもちゃんとあるんだからね!?
俺が使ったことあるのは、こんな感じ。結局 MagicDraw の Standard Edition 買って
使ってる。
Visio
・汎用お絵かきツールなので UML 専用ツールとしてみると、かなりイマイチ…
Together 試用版
・ソースコードに特定の形式でコメント埋め込む必要あり。ソースコードと UML の
同期は完璧だが、C++ だとマクロやらテンプレートやらあって逆に足枷に。
Enterprise Architect
・細かいことは忘れたが、値段の割りによくできてた気がする。
Jude竹
・使いづらかった記憶が。Java 前提で C++ だとイマイチ。
MagicDraw
・それなりに自由に図がかけつつ、UML 固有のサポートも十分している(基底クラスの
メソッドをコピーしてくるとか)。サポートしている図の種類も豊富で、開発も順調に
継続中。Pure Java アプリなのでメモリは多めに。
ただ C++ だとソースコードと同期する reverse engeneering, forward engeneering は
制約ありすぎで使い物にならない。
C++ …
なんかC++のマクロが元凶なだけじゃ・・・。 javaにマクロないし。
>>601 スマートポインタ・pimplイディオムあたりも、そのまま図にすると冗長で
ワケわかめ。
javaにスマートポインタなんてないし世代別GCという逸材が組み込まれてる。 とか言ってみて良い? 実際javaでGCが必要になるケースって言語実装する場合だけど、javaのGCに投げれば良いだけだし。
え、いや、だから何?としか・・・
>>603 文面見るだけだと、集約とコンポジションの区別がつかんけどな。関連との区別も
つかないし。
>>603 CでもC++でもライブラリでGC使えるようになるよ
とか言ってみて良い?
デストラクタのタイミングがJavaだと曖昧だから、
確実に呼ぶためには明示的に呼び出す必要あるよね
とか言ってみて良い?
Dispose論争がやりたいなら他でやってくれ
608 :
名前は開発中のものです。 :2007/09/25(火) 01:43:17 ID:cUqDGz0b
共同開発で、Bohemなんか使ったら(ry
Bohemと言えば、吉里吉里3の開発で使っていたような。
と思って調べてみたら、やはりけっこう面倒になことなっているようですね。
ttp://kikyou.info/diary/?200603 C++でGCをするのは、やはりリスクは大きいんでしょうかね。
挙動をきちんと把握していないと、余計なバグを出しまくると。
まさにそれで右往左往してるじゃん。吉里吉里3は。 というか誰のコードが入るか分からんOSSにはBohemGCは向いてないと思う。
> とくにファイナライザ(デストラクタ)が呼ばれるタイミングや、 > そもそも呼ばれるか呼ばれないかすら信用できなくなるというのは痛いです。 これってBohemGCというか、 JavaでもC#でも似たような問題抱えてるような気が。 C#はusingでだいぶ良くなる(というか必須)けどね。
C#でusingを使えるような状況なら、C++でも std::auto_ptrやboost::scoped_ptrが使えるのでは。 まあこの当たりのスコープによる廃棄を使えるのは、データ構造でなくその 呼び出し側のほうになるとは思いますが。 データ構造の内側たるメンバ変数では、結局いポインタwをを使おうとすると、 やはりGCかスマートポインタが(r
ヒープの解放と後片付けは違うぞ
>>611 全然右往左往はしてないので、BohemGCは向いていると思うよ
>>614 java6からはそこらへんもVMの仕事だな。
>>615 一時期、他のコードとの相性で苦戦してただろ。
というか吉里吉里は実質一人開発なのでバザールモデル開発時の問題は無縁かも知れん、
がソースを公開してるので誰がどう使うか分からないのでBohemGCは向いてないだろ。
>java6からはそこらへんもVMの仕事だな。 ?
>>616 よく知らないんだけど、BohemGC特有の問題ってなんなの?
>>812 はBohemGCだけの問題では無いよ。
>>616 w3m も BohemGC 使ってなかったっけ?
俺は C++ だとスマートポインタで十分なケースが多いので、BohemGC は
まず使わないけど。
>>616 ほら、言い直した。
「一時期問題があった」だろ?
それなのに
>>610-611 で2006年から今もずっと右往左往してるかのような印象操作をして、
BohemGCがOSSに向いてないとか、そんな詭弁はやめろ。
お前が古い人間で、よく理解出来ていないガベージコレクションが嫌いなだけなんだろ?
>ソースを公開してるので誰がどう使うか分からないのでBohemGCは向いてない
これとかまったく意味不明。
boostのshared_ptrでも、まったく理解しないで使うと罠がある。
そういう仕組みをまったく使わないで、手作業で開放しても罠がある。
お前の論では、ナニをやろうが向いていないんだよ。
>>619 スクリプト言語の作成は、スマートポインタだけだとしんどいと思う。
var a = [0];
a[0] = a;
これだけでメモリリーク起きるなんて、危なくて使えん。
GCは魅力的だと思うが、まだ”枯れてないから”じぶんは好きくない 技術は何かを実現する手段であって目的ではない
枯れぬなら 枯らしてしまえ ほととぎす
>>620 > スクリプト言語の作成は、スマートポインタだけだとしんどいと思う。
スクリプト言語の仕様にもよるな。
PCのギャルゲーだとスクリプト言語自体をリッチな仕様にして、動的な
メモリ確保なども可能にする(文字列連結とか)場合もあるみたいだけど、
俺はスクリプトでは完全にコンパイル時にメモリ割り当てが確定しちゃう
ようにして、メモリやリソース管理は C/C++ 側のコードでプログラマが
責任を持って行うようにしてる。
スクリプタとプログラマの役割分担どうするかだが、スクリプタ大量投入
するタイプのプロジェクトだと、スクリプトの自由度を下げた方がバグの
発生頻度が小さくなって、結果的に ウマー なことが多いと思う。
なんで
>>620 はエスパーレッテル張りまでして必死なの?
吉里吉里信者?
確かに必死さが伝わってくるな
626 :
名前は開発中のものです。 :2007/09/27(木) 11:33:55 ID:ET62U43b
nanndeこんんあに必至なの?
池沼だから
荒れていても技術的な話題が堪えることのない名スレ でも最近少々荒れ気味だから皆落ち着け
落ち着いてないのは
>>620 くらいじゃ?
元々隔離板の過疎スレだから少数が騒ぐと目立つだけ。
またーりログ読んでるか、生温かい目で見守ってるのが大半じゃない?
言うに事欠いて「必死だな」で切り抜けようと試みる 古典的バカが未だに生き残ってるとは驚きだな
煽っても必死さが正当化されるわけじゃないよ
BohemGCサイコー
「必死さが正当化される」ってのはよく分からないけど・・・
とりあえず、「必死だな」とか言う前に
>>620 を論破してみれば?
例えば、
1,BohemGCだけにある、もしくはJavaやC#のGCでは解決された重要な問題を列挙する
(数値とアドレス値が識別できないという問題はあるけど、確率的にそれが不都合になることはほとんどない)
2,吉里吉里にはBohemGCが向いていないことを示す他のソースを提示する
とかね。
個人的に1はとても興味があるので、問題があるなら教えて欲しかったりする。
>>620 本題からそれるけど、
> スクリプト言語の作成は、スマートポインタだけだとしんどいと思う。
> var a = [0];
> a[0] = a;
> これだけでメモリリーク起きるなんて、危なくて使えん。
スクリプト言語におけるインスタンスの寿命管理と、C++ インスタンスの寿命管理は
別の話だよね。
俺は VM のスタックは C++ のスタックを使わず、C++ で std::vector<> 使って確保した
記憶域を使ってる。でないとスクリプト一時中断する (co-routine 実装) のが難しい
からさ。
当然スタック上にあるスクリプト言語のインスタンスは全部 VM でトラッキングできる
ので、ガベコレできる。C++ 側のメモリ管理が GC 使ってるかどうかとは無関係に。
>>634 ようするに実装がスタックレスってことだな。
つかスタックレスでないVMにコルーチンを実装するのは不可能じゃないか?
>>635 多少制約がつくけど、Cスタックを保存・切り替えできればスタックフル VM でも
コルーチンは実装できます。
ただ、どうやってもポータブルなコードにはならないし、C++ 例外の実装方法に
よっては問題出るから、お勧めしないけど。
>>636 スタック切り替えてまでやるかw
猛烈に処理系依存なコードになりそうだな
638 :
名前は開発中のものです。 :2007/11/17(土) 17:10:37 ID:iMK/PWng
戦闘シーンの進行管理をするクラスって、どういう名前にしたらいいんだろう? BattleManagerかな…でもManagerは使うなって話もあるし。
>>638 Manager 使うなって話は、つまり「管理」というあいまいな言葉を使うなって話。
「戦闘シーンの進行管理をするクラス」の役割を見直さずに名前付けだけ考えてても
無意味。
640 :
名前は開発中のものです。 :2007/11/17(土) 17:45:31 ID:iMK/PWng
>>639 レスありがとう
そう、今プログラム素人の子と話してたんだけど、
漠然と「場」みたいなもので考えるから名づけに迷うんであって、
相撲の行司みたいなのがいると仮定して、
そいつに戦闘の進行管理をさせればいいんじゃない?
という意見をもらった。
そこでまた、「戦闘の進行」っていう、時間を伴ったものを、
その「行司」の中に持たせちゃっていいのかなと迷うんだけど、
その辺りは割り切っちゃったほうがいいの?
OOPド素人丸出しでごめん
戦闘シーン関連の処理に関して、俺が抱いてるイメージとしての「管理」から考えると そのManagerが関連する他のクラスに処理を分配して、それを仲介するようなクラスだとMediatorあたりになるんじゃなかろうか 俺が作ってた「Manager」は上記のものがさらにFacadeの役割も果たすってのが多かった デザパタから借りてるだけで正解とはとても言えんけど、「Manager」よりはマシかな…と
>>640 > そいつに戦闘の進行管理をさせればいいんじゃない?
それじゃ何も解決しないでしょ。「管理」という役割が同じなままなんだから。
「管理って、実際のところ何するの?」と問い、「あれして、これする」っていう
もっと具体的な単位に分解できれば、「あれするクラス」「これするクラス」に分割する
ことが考えられる。それらを組み合わせたものを「戦闘シーン」というクラスにすることも
考えられる。
どうしても「管理」としか呼べないんなら、それを Manager と名付けること自体には
何の問題も無い。
「戦闘の進行」と「行司」という切り分けができるなら、前者を Advance() なんていう
関数、後者を Rule とかいうクラスにすることが考えられる。 Advance() は Rule に
従って処理をする、って感じね。具体的な状況がわからないんで、全然ダメかも
しれないけど。
SceneManagerとか定番だな
javaの立場が・・・
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 }
};
使うなとは誰もいってないよ
>>642 俺の場合、Manager って名前は使っちゃうな。ただし Manager クラスで
何でもかんでも処理せずに、分割できるところは別のクラスに切り出して
Manager クラスに集約する。
Facade やね。
さっきからしょぼいBGMのループがひどいな 2ループもすりゃ十分だろ
B・・・・・GM・・?
652 :
名前は開発中のものです。 :2007/11/24(土) 17:27:35 ID:5kPj3Eca
シューティング作ってて、敵のクラスと自機のクラスを分けちゃったけど、わけない方がスマートだったかなあ
>>652 一部同じインターフェースを持つことはあるだろうけど、普通に考えてまったく同じクラスに
なるとは思えない。
自分は敵1と敵2とかでもわけてる
>>654 そりゃ、作るゲームにもよるな。キャラクター数少なくて差異が大きい場合には
クラス分けるが、RPG のように数が多いと基本1クラスでデータ駆動にする。
>>652 何シューティングか知らないが、
よくある2Dのシューティングなら自機と敵機で違う処理したほうが、
当たり判定の最適化しやすそうだな。
(同じ基底クラスから派生させるとかいう話はおいといて、
657 :
名前は開発中のものです。 :2007/12/23(日) 16:09:31 ID:zijTonf7
シューティングでも、データ駆動(簡易スクリプトもしくは、相当するもの) がお勧め。 俺は、クラス志向でやってたら、敵、弾のクラスが200超えたあたりで、死んだ
もっと詳しく。 数の多さからの管理の複雑化という問題だとしたら、 データでもクラスでも一緒だと思うんだが。
、
>>657 は敵の動きや弾の速度やダメージなんかを全部
コード中に書いてたんじゃね
660 :
名前は開発中のものです。 :2007/12/23(日) 18:00:13 ID:Uzvq0eJL
DIO「所詮OOPはゲームプログラミングの亜流!データドリブンに敗北する定めよおおおぉっ!!」
実際に完成したゲームのデータj構造・クラス設計が王道。
2Dゲームだと仮定すると キャラクタークラスがコピーする画像の種類、座標と大きさをパラメで持ってればいい 変数5個ぐらいだからあとはそれを描画クラスに渡して描画されるしくみがあればおk エフェクト関係の位置が微妙に変だと思う あれは継承?それとも集約(コンポジション)? あと図の矢印が継承と集約混ざっててわかりにくす あれが全部継承なら最初から作り直し
664 :
名前は開発中のものです。 :2007/12/23(日) 21:20:38 ID:zijTonf7
>>659 そのとおり
で、途中からやばいことに気づいて(そら100もクラス作ってたら、気づくわw)
スクリプトで外に出したりしてたら、
かなーりカオスに・・・
665 :
名前は開発中のものです。 :2007/12/23(日) 21:22:59 ID:zijTonf7
>>662 矢印の関係、向きがグチャグチャだなおいw
UML関連の入門記事をさらっと読んだ方が、いいよ
本まで買って厳密にやることはないが
>>659 それのどこがやばいのかよく分からないなぁ。
>>664 本当に必要なものならクラス数は増えても良い気がするけど。
.NETだったらコンパイルも早いし、dllに分けてスクリプト言語で書いたりもできるから 派生クラスで全部書いちゃってもいけそうだな
>>664 ふつーは、プレイヤー弾クラス、敵弾クラスとか作って、そいつがパラメタを
ファイルから読み込む or スクリプト駆動にするわな。パラメタ変更では手に
負えないような差異がある場合(バラバラの弾とレーザーとか)は、そこを
クラスに切り出す。
どこまでプログラムで書いて、どこからスクリプト or データ駆動にするかは
センスの問題。何でもかんでもスクリプトで書くと、結局 C++ で書くより手間
かかるだけだしなw
>>663 描画処理にキャラクターのデータを渡すだけでいいのですね。
図は全て継承の意で矢印を書いてしまいました。
継承と集約の相違点と関係を見直してもう一度はじめから考え直してみます。
>>665 確かに書き方が全く成っていませんね・・
ネットでUMLを説明してる所へ行ってみます!
ご指摘ありがとうございました。
大変ためになりました><
このキーワードを出すと荒れそうだけど、やっぱりデザインパターンは 一通りかじった方が良いと思うよ。そうしたら、何が悪いか見えてくる。 あと、基本的に継承しまくるのは良くない。継承よりも委譲で処理した方が スッキリする場面が多い。
>>662 まずゲーム上の意味を持たず、単純に描画関連の処理だけ行うクラスを作る。
3Dモデル、2Dスプライトとかな。
その上で、次に、3Dならモデルのモーション制御用のクラスと、2Dスプライトなら
テクスチャアニメーションや拡大縮小アニメーションなどを行うクラスを用意する。
最後に、ゲーム的に意味があるクラス(技エフェクトクラスとか)は、上記クラスの
インスタンスをメンバ変数に持たせて使う。間違っても継承するなよ。
>>670 >>671 なんでもかんでも継承すればいいというわけではないのですね・・・
is-a関係とhas-a関係をよく確かめます。
ありがとうございました。
>>672 慣れてくると悟れるようになるけど、
HogeHogeUtil
っていう名前にできるものはオブジェクトにしちゃいかんよ。
StringUtil、DBUtil、CSVUtil、DrawUtil、SpriteUtil、etcetc...
こういう「いつでもどこでも使う」ものは、本質的に
状態を持たない(=オブジェクトにはならない)もの。
これらはスタティックに関数を定義しておけばそれでOK。
初心者はここを勘違いして地獄を見ることになる。
ま、慣れてくれば分かるさ。
そういう機能メソッドのstatic化って今までとても気持ち悪く感じていた。 C#の拡張メソッドみたいなものはもっと以前からあって然るべきだった。
675 :
名前は開発中のものです。 :2007/12/24(月) 08:33:00 ID:IJjsYfw4
どうしてもクラスにしたいならシングルトンパターンだな
>>657 スクリプトでも下クラスでも同じだろ?
どっちに記述するかの問題だが
IDEサポートある環境ならクラスのほうが見通しやバグがへる
>>676 > スクリプトでも下クラスでも同じだろ?
スクリプトとかデータファイルだと、
1) 必要最小限のことしかできないように制限かけておく
2) 少ない記述量で済むようにする
から、量産するときに手間が減る。あとプログラマが一人で全部作る場合は
良いんだが、企画やスクリプタに調整してもらう場合は、開発環境そのまま
渡すのはいろいろコストが高くつく。
あとしょぼいとはいえ技術情報だだもれのうえソース持ち逃げ逃亡の可能性もでる(同人の場合)
>>677 いや、データの一元管理をしたいならクラスにまとめてかいとけばいい
だからどこに書くかどうかという程度の問題だからかわらん
外部ファイルだと整合性が取れない場合とかそういうことも考慮しないと
>>678 むしろ同人以上に仕事でやってるときのほうがソースの中とか見せたら危険すぎだね…
>>657 ま、そのくらいの規模になったらデータ化したほうがいいっすな。
>>679 > 外部ファイルだと整合性が取れない場合とかそういうことも考慮しないと
外部ファイルも事前にコンバートするから、そこで整合性担保するでしょ。
テキストで書いておいて、ツール使って実行時環境の構造体に直接マッピング
できる形に変換。実行時にテキストパーするなんて、エラーチェックの意味でも
実行効率の点でもありえんので。
開発効率に関してはたとえば、
ATK=100,THROUGH=1
とか書くのと、
struct Shot1 : IShot {
virtual int getAttackPoint() const { return 100; }
virtual bool canThrough() const { return true; }
};
とするのと、どっちが楽かって話だよな。プログラマならともかく、それ以外の人間に
後者はありえんと思う。
技術者以外でコードさわらせることってある? その程度がかけない人を使う場合はツールつかうでしょ
>>682 > 技術者以外でコードさわらせることってある?
ない。
人数増えると、開発環境をセットアップ・メンテナンスしたり、ソフトウェアの
ライセンス費用だけでも馬鹿にならんし。
アクションゲームのプレイヤーキャラクター、エネミーの状態遷移はどう管理するべき? タスクシステムとか使うんでしょうか?
Cならタスクシステムで良いと思うけどOOPでタスクシステムは勝手が悪いだけだぞ。 というかタスクシステムの話は荒れるからやめれ。
>>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 とか) を入手して使う。
関連でboost FSMって言うのがあるんだけど ゲームならこちらの方がいいかも (state_chartと違ってコストがポインタ経由の関数呼び出しと同等程度)
>>686 前に作ってたプロジェクトで、
30個くらい状態ができて、exec相当の関数が長くなりすぎ、
関数内関数にしたものの、死にそうに。
こういうときは、やっぱり、データ駆動にすべきなんかね
俺だったらまず階層化を考えるかな。
>>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;
を参照するとかね。
>>689 関数の作成単位を処理毎 (exec(), draw()) から状態毎 (_stateAlive(),
_stateDead()) にして、各関数の中に exec, draw なんかの処理を
書くよう逆転させるとメンテナンスが楽になるよ。
実装はこんな感じ。
ttp://gameobj.issei.org/trac/wiki/HSM それでも複雑になってきたら、更に状態ごとにスクリプトを貼り付ける。
状態遷移の入場動作でスクリプトを読み込み VM を設定、exec 相当の
処理ではスクリプトの VM を実行するように書く。
どこまで C++ で書いて、どこからスクリプトにするかは、一律の答えが
ないので難しい。作業を一人でやるか分担するかにもよるし、仕様変更を
どこにどれだけ見込むかにもよる。ただリソース(メモリとかテクスチャとか)の
確保・解放が絡んだら、経験上、そこは C++ で処理した方がトラブル少ない。
実は、
>>689 の後のプロジェクトでは、苦肉の策で、
簡単な非階層型の状態遷移クラスを作って対処してた。
状態ごとに派生クラス作ると、しんどかったので(これもかなりやってた)
結局、できるだけ、簡易的にするために、
draw、exec はメソッドポインタにして、状態遷移クラスに持たせ、
状態遷移クラスのdraw、execでそれらを呼び出すことに。
これなら、派生クラスを大量に作る必要がなく、気が楽(笑)
呼びたい entity に、1状態につき、initialize_hoge、draw_hoge、exec_hoge メソッドを作り、
状態遷移時に(initialize_hoge内で)、状態遷移クラスにメソッドポインタを割り当て、遷移させてた。
まあ、結局、entityのメソッドが増えるのと、階層化ができないのがキズ。
階層化は、状態遷移クラスをさらに持たせて、実現してたけど
>>691 ありがとう。
あー、逆の発想か・・・
ナルホ・・・
HSMは、(・∀・)イイ! って聞いてたけど、実際の実装を見たことがなかったので、
参考になります。
じっくり見てみる。
しかし、勉強セナあかんな・・・
>>692 > これなら、派生クラスを大量に作る必要がなく、気が楽(笑)
GoF のステートパターンよろしく、状態ごとにクラスを作るか
それともクラス一つで済ませるかも場合によるよね。
AIとかシーンのように、各状態がそれなりに複雑で個別のメンバ
変数を大量に持つような場合は、状態ごとにクラス分けた方がいい。
アクションゲームのキャラクタ程度だと、クラス分けるとクラス間の
データ受け渡しの手間がかかりすぎ。
(゚Д゚)
(・∀・)
697 :
名前は開発中のものです。 :2008/01/11(金) 13:18:44 ID:0lOBaoZM
age
698 :
名前は開発中のものです。 :2008/01/25(金) 11:38:57 ID:J9K9o4zc
保守
^^
随分漏れのIDにCが多いな。
VIAのCPUがいる
ム板のクラス名・変数名に迷ったら書き込むスレ。Part11でメソッド名を質問している内に 設計を見直したくなったので誘導に従い引越して来ました。 C++で練習用にドラクエモドキ作っているんですが class PlayChara{ int hp; int mp; … public: void receiveAttack(ATTACK_TYPE atk_type, ATTACK_POINT atk_point); } プレイキャラクラス自身に敵からのダメージを与える為のメソッドで (攻撃のタイプと攻撃力の引数を受け取る)receiveAttackってのを検討したんですけど 設計そのものを見直したほうがいいでしょうか? ・攻撃者が.attackメソッドを持って引数に被攻撃者のパラメータを渡す ・攻撃用のクラスそのものを作る
戦闘管理クラスみたいなので上からまとめてやっちゃう
なんでそんな小難しく考えるのかわからん。
hp/mpをprivateにしてメソッドで操作するメリットは、 それらを操作するコードを制限できる点で、メンテナンス性向上を期待できる。 でも、ちゃんと管理できればpublicでも全く問題ないので、 このやり方で良いとも言えるし、このやり方でなくても良いと言えるけどねw
>>702 ドラクエならダメージの計算はキャラによらず一律だし、ダメージが
発生するタイミングや順序も明確だから、他の人が言ってる様に
計算式を実装するのはプレイヤークラスではなく、戦闘の進行
管理やってるクラス。
キャラクターごとに持っているパラメタが全然違って計算式が
異なるとか、キャラクタの内部状態によってダメージあり/なしが
変わる、またリアルタム進行でダメージ判定などタイミングが
シビアな場合には、プレイヤークラス内部で計算した方が
やりやすい。対戦格闘とか一部のアクション RPG とか。
ただ、その場合は receiveAttack() というように攻撃専用の
メッセージにせず、回復やらダメージやら全部含めた汎用の
メッセージクラスを一つ用意して、
void sendMessage(Msg const* pMsg);
で送りつけてやったほうが良い。あと、メッセージは即処理せず
キューにためておいて、あとでプレイヤークラスのほうで都合が
良いようにソートしたりしてから処理するとか、インスタンスの
ポインタ直接使わずにハンドル管理にするとかした方が良い。
receiveAttack(ATTACK_TYPE atk_type, ATTACK_POINT atk_point) を damage(DAMAGE_TYPE dmg_type, DAMAGE_POINT dmg_point) に改名すれば謎は全て解ける
俺なら戦闘進行クラスに行動のプライオリティキュー持たせてコマンドパターン突っ込んでキャラクラスにキュー見せるかな。 でキャラクラスはストラテジーパターンで行動処理を分けると・・・。 キャラクラスはキャラごとにインスタンス化して行動処理はストラテジーに分離。 ぱっと思いついたがこんなもんか。
忘れてた。 ↑のコードをスクリプト言語内蔵してハードコーディングしないようにする。
>>709 ドラクエだと、コアロジックのスクリプト化は要らん気がするなぁ。
俺ならスクリプト指定にするのは、エフェクトとか SE 再生とかの種類・
タイミング制御と、あとはパラメタの定数設定ぐらいか。
スクリプト化するかどうかとかは開発において本質的な部分じゃないし 今回の実装方法の話は好きにしろとしかいえんね
712 :
702 :2008/02/02(土) 21:06:24 ID:mI6LOL9z
>>706 有難うございます。
なるべく他のアクションゲームとかにも流用できる汎用性の高い作りにしようと
思っていたのでリアルタイムに仕様変更があっても対応できるように後者のような感じ
でやってみようと思います。
取り合えずクラス候補としてこんな感じでいこうかと。
・プレイキャラ(敵キャラ含む)
・成長管理
・戦闘管理
・シナリオ進行管理
・コマンドメニュー
・アイテム(装備品含む)
・ステージ(街、ダンジョン、フィールド含む)
・ショップ
・酒場(キャラ登録、出し入れ管理)
>>712 ふつーのRPGにするなら、まずシステム全体を
・戦闘
・フィールド
・デモ(イベント)
に分割して、それぞれの間のツナギを緩やかにしておく(直接インスタンス
参照せずに、パラメタ渡して立ち上げるようにする)、さらにサブシステムを
切り替えるときには画面ブラックアウトさせるようにしておくのが敷居低いよ。
装備品や戦闘中に利用できるアイテムに関しては戦闘システムに密に
絡むので、装備品のパラメタとして何をどう持たせるかなどは戦闘システム
中心で考える。
プレイヤーに関しても、戦闘で利用するプレイヤークラスとフィールドで利用
するプレイヤークラスは別にしとく。戦闘側プレイヤークラスではアイテムの
戦闘中効果や使用可/不可の管理なども要るけど、フィールドだと個数や
値段だけ管理しとけば良いから、必要な情報が全然違う。
俺今Java MEのMIDP上に汎用のゲームミドルウェアとほかのライブラリに組み込んで使う AVGエンジン作ってるが設計は使ってる言語とプラットフォームによると思う。 たとえばCだとOOPが言語仕様にあるわけじゃないから再利用性のあるライブラリは作りにくいと思うし、 MIDPみたいなリソースが限られてる環境上だと制限多いし。
>>713 > プレイヤーに関しても、戦闘で利用するプレイヤークラスとフィールドで利用
> するプレイヤークラスは別にしとく。
あ、それでいいんだ。
現にそうやってRPGのクラス設計してたけど、もしかしたらマズイやり方なんだろうかと
不安になってたとこ。これで前進できるよ〜。
>>714 > たとえばCだとOOPが言語仕様にあるわけじゃないから再利用性のあるライブラリは作りにくいと思うし、
それはない。ただ設計が OOA/OOD じゃなくなるだけ。
むしろソース非公開でライブラリ配る場合は C++ より C の方がバイナリ
互換性を維持するの楽だし。C++ だとメンバ変数ひとつ加えただけで
バイナリ互換性崩れるから COM のようにインターフェースと実装を厳密に
分離するような細工が必要になってくる。
社内ライブラリとかでも公開 API は extern "C" してあって、中が C++
なんてのは未だに良くある。
中身も全部 C っつーのも、もちろん良くある。
見てる人自体は結構いるんだなとしみじみ感じた。
全部ベターCってのもまだいるな
さすがにそれは設計だのライブラリ配布だの以前の
C++でオブジェクト指向を生かすにはゲームはちょっときつい フラグメントの問題が面倒だしな PCのようにリソースが多い場合はJava等でOpenGLベースで作ったほうが楽かも
VGAドライバーのバグがどうしても回避できないからイマイチ安定しないよ、JOGL。 fpsはかなり出るんだが。
>>722 具体的に
JOGL単体だと不具合はまずでない
>>721 > C++でオブジェクト指向を生かすにはゲームはちょっときつい
PS2 の頃から、ゲーム部分はほとんど C++ だよ。
C++ に GC 付きの軽量スクリプト載せるのが主流じゃね? フラグメントがどうとか言ってメモリのやりくり縛ってるような人は、 GC 付き言語は絶対導入しないってことなんだろうか?
>>273 GF7600GTと特定のドライバで出る。ドライバのバグだといっただろJOGLの問題じゃない。
後はググレ
>>725 コンシューマとかサーバーとかは普通に気にするだろ
だから、素の状態だと使えん
GCつきなら問題はないが、フットプリント大きくなるからコンシューマでは採用しにくい
>>726 そんな特定のドライバで動かないといったらそんなのは大量にあるわけだが
>>727 > コンシューマとかサーバーとかは普通に気にするだろ
メモリに関しては断片化と使用量の問題がある。
断片化はモデル・テクスチャ・モーションといった数百KB単位の
リソースデータと C++ インスタンスのようなせいぜい数KB程度の
データを混在させると問題になる。最初からヒープ領域を分けて、
リソースに関しては
・事前に複数ファイルをアーカイブして1つにまとめておく
・ファイル読み込み領域を階層化して管理
・用途によっては固定長で
とすることで解決できる。
使用量は頑張れとしか…
>>725 GCつきの言語は使ってないなぁ。lua とか悪くないとは思うんだが。
メモリ使用量やCPU消費が読めないのと、そもそもスクリプタに
高度なロジック書かせない方針なので、そこまで高機能な言語は
要らなかった。
ストラテジー系のゲームで AI とかスクリプト化するとなると、Lisp
系言語を使うかもしれん。実装簡単だし。
>>728 だから、素の状態では使えないと書いた
固定長とかしばってるとC++らしいオブジェクト指向のコードが書けなくなる
結局クラスが名前空間程度のベターCでおわってしまう
D言語で良いんじゃね? バグだらけだが
>>729 > 固定長とかしばってるとC++らしいオブジェクト指向のコードが書けなくなる
断片化が問題になるのはリソースデータだから、そっちだけ固定長とか
縛り入れる。
他は気にせず new しても、ヒープ多めにとっておけば大丈夫だよ。
>>731 newとdelete繰り返しているとフラグメントがぐちゃぐちゃに
つプールかスラブ
>>732 ゲームの場合はたいていインスタンスの寿命が入れ子状になってて、
寿命がやたらに長いインスタンスが不定期のタイミングで作成される
ことは少ない。
delete されたときに、積極的に前後のアドレスの空きスペースと融合
するたいぷのメモリアロケータ使ってれば、そんなに酷いことには
ならんよ。
これがサーバ系だと、また話が変わって来るんだが。
>>706 702じゃないけど、なんか目からうろこだわ。Thanks!!
new を使わなければすべて解決
まぁゲームで new とか使わんな。ポインタも殆ど使わん。
そんなプログラムはゴミ箱へ
プログラマもゴミ箱へ。
ゴミ箱はリサクル。
なるべく一般性の高いゲームの骨作りをしたいんだけど みんなどうしているんだろう… 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(); }
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 シンボルで扱えるようにして下らないバグを 出さないようにするとか、断片化防ぐためにメモリのセグメント分割するとか、いろいろ あるけど。
>>742 過疎っている思ったのに光速レス有難う。
なんかタスク管理とか高度でかっこいいですね。
デザパタとboostをもうちょい勉強してみます。
自分のはなんかCでやってたことをクラスに詰め込んだだけっぽい。
タスクというと、タスク原理主義者の襲撃受けるのでアレだがw 直接 m_task_list に突っ込むのは、いわゆるシーンオブジェクトぐらいに しておいたほうが良い。個々のキャラクターとかエフェクトの類は、派生 クラス (TastTask1 とか) のメンバ変数で持たせる。 m_task_list は見て分かるように exec, draw 両方とも引数ないので、 これだと相互作用するようなインスタンスをうまく扱えないので。
>>706 とかでもありましたけど
タスクにキューをためるような処理の仕方が一般的なんですね。
自分はそういうスタイルで組もうとしたことがないので色々と勉強しないと…
に× を○
>>741-742 いきなり、スレタイ否定だが、
本気で一般性の高いのを目指すなら、
ここで聞くより、ソースが見られるゲームエンジン見た方が100倍いい。
力がつくよ。
俺もいろんなソースみて力つけてきた
>>747 どのエンジンが勉強に良かったか教えてくれ。
言語の講座は大量にあるけど 設計の講座はさっぱり見当たらないな。 実装部分の詳細はよくみつかるけど
>>747 俺も聞きたい。どんなエンジンを見てきたの?
>>747 >>741 のようなCの延長的な書き方でクラスで関数を纏めただけじゃん
みたいにしか組めない俺もききたい。
yaneSDKとかw
. ィ .._ .......、._ _ /:/l! :~""''.>゙' "~ ,、、''‐'、| _ ゙、'、::::::ノ:::::::_,.-=. _〜:、 /_.}'':, ``、/:::::::::__....,._ `゙'Y' _.ェ-、....._ /_゙''i゙ノ、ノ ,.--l‐''"~..-_'.x-='"゙ー 、`'-、 ,:' ノ゙ノブ " .!-'",/ `'-‐'') /\ `/ でノ-〈 .-''~ >'゙:: ‐'"゙./ ヽ.,' ~ / //::::: ', / ,:'゙
マジレスすると「ゲームデザイン」の中の人最強だろ
ゲームデザインでググって一番上に来る人のことですよね? そうじゃなければ自演乙
間違えた。 ゲームデザインの方じゃなくてABA Games最強だろ。 なんか俺の脳内で一緒になっていた
757 :
名前は開発中のものです。 :2008/02/26(火) 15:08:24 ID:xLe52R9Z
ご冗談をw
首があるから「ネコ〜」じゃないよ。
カリンさまだろ?
ゲームの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 );
プロパティが使えない言語なのか
>>761 それで数値がMAXまで行ってクリッピングされた時に
音を鳴らしたい場合どうする?
ポインタ渡しの引数増やすのも気持ち悪いし
GetLastError() みたいな別関数で状態を取得するのも気持ち悪い
見るからにC++だからなぁ。 俺なら数字っぽく扱えるクラスを書いて、 operator+()の中で範囲チェックするかなー。
765 :
764 :2008/02/27(水) 00:09:34 ID:oXng1J4U
追記
>>763 みたいな要求にこたえるときは、
作ったクラスにコールバックの仕組みを追加する、とかの方法で実現できる。
クラスのクライアントに対しては修正いらないはずだし。
プロパティが何だか分からなくて心が折れた。
要はgetHPとsetHPのこと
…VBとかの機能か。
>>761 言語がHSPなので参考になるかわからんが、
isover(val, min, max) //溢れ判定
irange(val, min, max) //上限下限
itorus(val, min, max) //ループ
ibound(val, min, max) //跳ね返り
の4つでだいたい足りている。
>>761 にプロパティを使うのは不適切だね
プロパティは外から見てフィールドのように振舞うべき
101をセットして1が返ってくるのは直感的じゃない
java使いの俺も泣けてきた。プロパティの仕様でカオスってる。 アクセッサメソッドでいいじゃん。getter/setter。
プロパティを使うときの一番ありふれた事例が 上限下限のコントロールかと思ってた…… まあ1人で開発するから問題にはなんないけど
max(0, min(val_max, val));
その程度の計算にしては高価じゃない
デバッグで失われる時間のほうが高価なので どんどん怠けましょう。
776 :
761 :2008/02/27(水) 02:08:49 ID:g7Py3Pl9
getter/setterとかのメソッド≒プロパティというんでしょうか? プレイキャラクターのクラスにダメージやら回復やらを処理させるメソッド内で 件の自作関数を呼び出しています。同じような処理ばかりあちこちにガリガリ書いていたもんで… ↓みたいにクラス化してしまう方が一般的ですかね class LimitFloat{ //.なんか勝手に良い感じにしてくれる処理 … }; class PlayChara{ LimitFloat hp; LimitFloat mp; … };
いやプロパティはアクセス時にgetter/setterが呼ばれる変数みたいなもんだろ。 プロパティが言語仕様にある言語て何があったっけ? esのプロパティはスロットだし
触ったことある言語の中だとC#にはあったな。
>>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 みたく上限加減とか
ループとか扱う関数をいくつか用意。
C#には、getter/setter関数を、通常とは異なる文法の関数1つにまとめて記述できる文法があってそれがプロパティ。
代入演算の左に来ればsetterが、それ以外ならgetterが呼ばれるから結果的にグローバル変数のように使用できる。
個人的にはプロパティの用途は以下のようだと思ってるのでプロパティで処理するのはありだとおも。
>>772 、インターフェイスのメンバにして多態性、getterのみ。
それにしてもRPGっぽいステータス管理って結構複雑だな。
今ぱっと考えただけじゃクラスが作れん。
値を上限・下限内に丸めるのとアサートによる契約プログラミングは別問題じゃないか? 単にセッタ内で丸めるという処理が目的だろこの場合。 アサートは条件に違反があった場合に吠えることが目的だろ? 違反があるかないか以外に影響しちゃだめだろアサートは。
783 :
761 :2008/02/27(水) 19:30:12 ID: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 ( ) ;
}
満タンになった瞬間だけ音が鳴るようにしてみたんですがえらく冗長に…
>>783 C++ なら、せっかくだから関数テンプレートにしとこうか。
785 :
761 :2008/02/28(木) 00:50:13 ID:fsbSiynp
関数テンプレート化頑張ってみます。
CからC++に移行したばかりで手間取りそうですが…
>>783 の条件分岐の記述はもうちょっとスマートに処理できそうな気がするんですが
良い方法が思いつかず…
アサートが何なのかわからなくて検索してしまったぜ。 要するに本来はデバッグ検出用の関数なのね
まあHPならfloatで決め打ちでもそんなに困らない気がしないでもない 将来のための勉強にはなるかな
HPとかステータス値は普通整数じゃね?
表示するときは整数でも実数で保持しておいたほうが便利なことがあるかもしれない MOTHER2みたいにダメージ受けても減少するまで時間がかかるとか……
時間とともにちょっとずつ回復みたいなことをやるなら実数の方がいいかなと。 ドラクエとかって最初から整数なのかな… 1ポイント前後のダメージって強制的に1ポイントダメージに補正されている感じだし 内部的に実数で0.1fずつ喰らったダメージが蓄積して1ポイントダメージになったりはしてなさそう
>>786 俺は assert() が入っていおらず、かつ UnitTest も書かれていない関数は
信用しない。
どうせリリース時には消えるしな
アサートっていうかイベントだな
floatと書いておけば何も考えなくてもいいのに比べて 今どき固定少数で処理するのってメリット少なくない? 処理速度の面でも遜色ないし使用するメモリも そこまでケチる時代じゃないしコードも固定少数の ほうがいくらか読みづらくなるでしょ
固定小数点数のメリットは論じても仕方ないので置いておくとして、 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すぎてすまん
言ってることは別に間違ってないけど、float値の比較に「==」とか使うような奴は ゲーム以前に計算機リテラシー欠乏者なのでこのスレでは無視していい存在では?
このスレではThe art of computer programmingは既読が前提ということか 質問しようと思ったけど出直すわ
ヘソ曲げ乙 別にそんな鈍器を買わんでも、その辺の理工学書コーナーに売ってる 薄っぺらい数値計算法の初歩本(教科書)を一冊借りて読んどけばいいよ 情報工学系大学1年次の基礎教養レベルの話なんだからさ
まあHPとかのステータス値を%で剰余出す計算することは少ないだろうし
>>796 の問題でバグ出すケースも少ないだろうな……
ステータスアップや次のレベルに必要な経験値テーブルなんかに
アクセスすることが多いLVは整数型にするだろうけど、
その場合は値を丸める処理がHPと同じじゃまずいし
リテラシー(笑)
>>795 すまん
単にMOTHER2だとかドラクエだとか
DC/PS2以前のゲーム機で浮動小数なんて使わないよということが
言いたかっただけなんだw
何でもかんでもfloatにしたら配列の添え字にも使えないわ、単純な比較は出来ないわ
論理演算は出来ないわ
余計に面倒な気がするけど。
>>802 HPを配列の添え字には使わんでしょう。ま、どっちでも良いんじゃない?
浮動小数はゆとりにはいいんじゃね? およそ3とか。
オッサンは(笑)の使いどころが微妙だな
そんなに気に障ったのか……
オッサンと言われるだけでカチンと来たら 気をつけないといけない年齢だぜ。。。
これは酷い
>>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 を理解しててもついうっかりってのがあるしかもしれないし
見えない小数部分を利用なんてしないで、 別にタイマーでも持った方がいいと思う
誰にタイマー持たせるの?
ついうっかりどころか、
>>789 はそのまんま
>>796 をやらかすに違いない。
合計10減らしたはずなのに9.999999しか減ってないとかな。
ま、このスレでは無視していい存在らしいしどうでもいいんじゃね?
何をそうカリカリしているんだ
>>809 有難うございます。
かなりスマートになりました。
ローカル変数に退避させておけばよかったんですね。
>>778 Delphiとか?C++Builderは言語仕様つーより、独自拡張ですね
>>802 も前のマシンはいつからDSに?
>>796-797 その後、「なんで、0.999999になるの?」って質問が出てこないから大丈夫かとw
最近RPGの設計話増えたな
そろそろ卒業なんじゃね? もう3月だし、さすがにそれはないかw
卒業製作なら去年の夏ごろから死んでると思う
さすがに一ヶ月未満で作ろうとは思わんよなあ
STGでボタン1を普通のショット、ボタン2を溜めショット用にしようとしているんですけど この溜めている量は 自機クラスのメンバ変数に持たすべきでしょうか? それともキー管理クラスを作って jiki.shot2 ( joypad1.getCharge ( BTN2 ) ) みたいな感じで処理すべきでしょうか?
俺だったら、自機の基底クラスである(例えば)機体クラスで管理する。 理由は、機体クラスの派生クラスで敵機クラスを作れば、 敵機の溜めショットの実装が楽になる。
おおむね>821に同意しつつ、自分なら、キーの押しっぱなし時間も同時に保持しておくかな。 溜めショット以外にも使うこと多そうだし。 カーソルとか、ポンと押した場合は1つ進むだけだけど、押しっぱなしにすると自動的にカーソルが動くとか、 そんな類の処理に流用できそう。
>>820 void 機体クラス::update()
{
if (joypad1.getOnf() & BTN2) // getOnf() はボタン押し下げてれば真
m_shot2.Charge();
}
俺なら、こうするかなぁ。機体クラスのメンバ変数に溜めショット用の
メンバ変数を持たせる。
キー管理クラスというのが何を意図してるのかわからんけど、汎用の
パッド入力処理関数として
enum { BTN1 = 0x1, BTN2 = 0x2, BTN3 = 0x4, BTN4 = 0x8, ... };
getOnf(); // 押し下げボタンの論理和が返る
getTrg(); // 直前まで放されてて、このフレームに初めて押し下げられたボタンの論理和
getRep(); // 一定時間以上押しっぱなしのボタンの論理和
ぐらいは用意しておいた方が便利だよ。
824 :
820 :2008/03/07(金) 23:07:06 ID:1kJAWqPN
825 :
820 :2008/03/07(金) 23:26:54 ID: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; //「押されていない
}
状態を管理する部分と、管理されてる情報を参照する部分を分ければいいんじゃね?
Win系ならWindowメッセージかDirectX使え。
>>825 >>826 も言ってるが
それぞれの状態について保存しておいて、それを参照すればいいじゃん
現在の状態をcurrentに0,1で保存するとして
押下した瞬間 on_trigger = (on_trigger ^ current) & ~current
離した瞬間 off_trigger = off_trigger ^ (^current & last)
過去の状態 last = current
829 :
820 :2008/03/07(金) 23:56:56 ID:1kJAWqPN
>>826 ちょっと考えて見ます
>>827 使っているのが「DXライブラリ」というDirectX用ライブラリなんですが押している状態しか
チェックできなくて難儀しています。
直接DirectXガリガリした経験がないのでわかりませんがWindowメッセージの
WM_KEYDOWN, WM_KEYUPに相当するものがあればその方が楽できそうですね…
DXライブラリってのは名前くらいしか知らんが、 1フレーム内にon/offがあった場合検知できないのかねぇ? (FPSを上げれば解決できそうな問題だと思うけど) DirectXは(デバッガで止めるなどして)1フレーム内に複数の入力あっても、 全部取得できると思った。でもDirectXはその性質上最低レベルAPIだから、 DXで済ませるならDXでやったほうがいいんじゃないかな…
stateパターンか
DXライブラリの中の人もチラと言ってたけど、そのまま使わずに、自分でラップして使った方がいいんじゃないかな? 低レベルな部分を隠すだけ、って割り切っちゃう。
>>828 横レスすまん。
たぶん俺が根本的に何かを勘違いしているんだろうけど、
どう考えても意図がわからない。
押下した瞬間 on_trigger = current & ~last
離した瞬間 off_trigger = ~current & last
ほんとはこう?
「C,C++じゃねーよ」ってのならごめん。他の言語はわからない。
素直にifを使うっていうのはどうだろうか。
そういうことだな
最近デザインパターンを覚え始めたんだが、 oopのコンポジション集約と、デザインパターンのコンポジットは全然別なことと、 デザインパターンのファザードがコンポジション集約と似た効果/構造してて戸惑った。 この違和感は普通にそのうち無くなるもの?
デザインパターンか… そろそろ俺も覚えないと不味いな
あんまりデザインパターンでゲーム設計しちゃうとデザインパターンにはめようとするからゲームではあまり使わないな。 ストラテジー・コマンド・ステートパターンはよく使うが。 デザインパターンって言ってもgofやgof以外やマルチスレッドなやつとかwebアプリケーション用とかいろいろあるよ。
>>838 あと、これも多少使うかなぁ。
・シングルトン ファイル I/O を一括管理するときとか
・オブザーバー 関連するゲームオブジェクト同士の管理(プレイヤーと、それに張り付くエフェクトとか)
実際のコードは、GoF のサンプルとはだいぶ違う形になってるけど、
まぁデザパタは設計のカタログなんで、実装の見た目が乖離する
ことはよくある。
オブザーバーっていうよりフックパターンがオブザーバーになってる事ない?
>>838-839 勉強になるよthx
まだGOF読んでないから今の段階ではさっぱりわからんけど
読むときに思い出すようにするよ
GOF本高けぇえええ!!
GoFを中心に解説してる本ならいくつかある。javaが多いけど。
Grove On Fight?
glove on fight でしょ
>>844 o がいっこ足らんぞ
Groove on Fightは名作
しかしPS版豪血寺は戦闘中に長いロードが入るという糞仕様
Gang of Fourも知らんのかここの連中は
ググって出てきたものを、知ったかぶりで書いたんだろうなぁ…
>848も言ってることは大して変わらんだろw
Glove on Fight・・・同人ゲー Groove on Fight・・・豪血寺3のサブタイトル Grove On Fight・・・俺のミスタイプ
デザインパターンも知らんで設計語ってんのか
めったに使えないGoFのやつか
継承イラネ と思う俺はたぶんまだまだ
そりゃあゲームでGoFなんて使わんだろ。上に出た通りだ。
>>854 基本クラス変数に派生クラス実体が入ってる時に関数を呼ぶと、
もし派生クラスがその関数をoverrideしてたら派生クラスの関数が呼ばれるんだぜ。
便利だと思わん?
仮想関数ならな。
>>855 上に出たとおりだと、
いくつかのパターンは使ってる
ただし実装は書籍と違うけど
だと思うんだが。読み間違い?
>>857 自分の中で、仮想でないメンバの上書きはシャドウで、オーバーライド=仮想メンバの上書きだと思ってた
>>856 そういうことができるのは知識としては持っているんだけど
例えば
モンスタークラスの派生でスライムクラス、ドラゴンクラスがあって…
とやらないで
モンスタークラスだけがあって
モンスタータイプっていうenumメンバ変数があってそれによって処理が変わる…
みたいに書いちゃうのね
まだまだスクリプト言語のときの癖が抜け切らないというか
たぶん継承をうまいこと使った方が生産性上がるんだろうけど
例えに突っ込むのは無粋だとは思うが、 外部ファイル読み込み(ハードコーティングでもいいけどさ)を考えると面倒じゃない?
>>861 ごめん。今の自分のレベルでは
継承だと外部ファイル読み込みが楽になる理由がよくわからない。
スクリプト言語を使ってたときの癖とか ノウハウとか捨てずに大事にするよろし C++だのJavaだのC#だの使っても 最終的にはスクリプトなりテーブルなりで キャラデータを管理することになるから そんときに経験は生きるぜ 継承大好きっ子にありがちなハマリ道は 何でもかんでもソースに(ハードコーディングで) 記述してみたりクラス分けしてみたりして 結果として異様に複雑で深い継承木を こさえて、仕様変更時の手間の多さに 戦慄して初心に返ること
継承って、外部ファイル読み込みを外部データベース読み込みに変えるとき楽になるとか
そういう使い方をするものだと思っていた。
今は
>>860 のスライムクラスみたいな継承の使い方をするの?
データに当たるような部分をコードに絡ませるのはなんか抵抗があるんだが。
865 :
861 :2008/03/24(月) 00:07:17 ID:tkEWMZpB
>863 言語仕様には開発者の哲学が詰まってるからなあ。 >864 俺の分かりづらい文章(>861)の翻訳dクス
866 :
862 :2008/03/24(月) 00:11:51 ID:KE3DiPkZ
>>864 なる。
ちょっとわかったような気がする。
867 :
862 :2008/03/24(月) 00:21:04 ID:KE3DiPkZ
いや、ごめん。
やっぱわかんね。
>>856 風の継承が
>>860 みたいな感じかと思っていたんだけど(違ってたらスマン)
そういう継承の仕方は主流じゃなくて
>>864 風の継承(どういうクラス構成なのかはイメージがわかないけど)のが主流なのかな?
>>863 実装継承を適当に使うと、そうなりがち。
インターフェース継承は、設計しっかりしてれば問題ないでしょ。
>>864 いや、リア厨のときに俺はそれ(
>>863 )やって
ゲロ吐いたの
でも継承木ビューワの眺めは壮観だったよ
オナニープログラミング
870 :
861 :2008/03/24(月) 00:35:53 ID:tkEWMZpB
>867 あくまで、RPGっぽい敵のデータを例として挙げたから、それに対してのツッコミってことね。 他のところで使う分には知らん。 で、だ。 RPGを作ったことがないアマチュアの意見なんで、聞き流すだけでいいんだが。 敵データを外部ファイル読み込みで作るとする。 敵の動きを変更したり、敵の種類を増やしたいと思った時は、当然そのデータを弄ることで対応するわけだ。 敵のデータを変えるたびに、ソースコードの中のクラスを書き換えるのか? 敵の種類を増やしたら、派生クラスを動的に生成するのか? そういうこと。
>>869 の継承図が見てみたい。自分も最初のころやって破綻したw
まあ多くても3回以上は継承したくはないよな
キャラ>モンスター>種族特性>個々のモンスター は既になんとやら
>>870 外部ファイルを作らず未だにステータスの固有値を派生クラスに直接書き込んでる俺はどうすrb・・・
>>870 RPGだと、
struct IEnemy;
class EnemyBase : public IEnemy {};
class EnemyBase : public EnemyBase {}; // 敵ザコクラス
class EnemyBoss1 : public EnemyBase {}; // 敵ボス1
class EnemyBoss2 : public EnemyBase {}; // 敵ボス2
って感じにするな。
ザコは全部一つのクラスで、データファイルとスクリプトで駆動。ボスは
プログラムでの特殊処理が必要なら、個別で作る。
>872 その辺は柔軟に、ってことね
874 :
862 :2008/03/24(月) 01:09:59 ID:KE3DiPkZ
>>870 えーと…
ごめん。なんか混乱してきた。
自分が何か読み違えているのかもしれないけど
>>864 が
>>861 の翻訳であるとあったので
>>864 に書いてあることを
「モンスター の 派生で スライム みたいな(哺乳類 の 派生で 犬 みたいな)
クラスの構成は間違っている。
外部データを読み込む際に便利なるような継承の仕方が実はあるよん。」
―と解釈したんだけど誤解している?
で、
>>870 を読むと「継承なんて使わずにデータを弄ることで挙動を変えるんだ」
と解釈したんだけど、それだと
>>864 の主張と矛盾するのでアレ??と思った。
どっちを勘違いしているんだろう俺は。
矛盾してるように思えないんだが
>>875 読み違えてはいないけど矛盾もしていない?
余計にわからなくなって混乱してきたので一晩寝て考えてみる。
色々有難う。
>876 >864氏の主張を僕なりに解釈 ●前半 敵データを記述するにしても、 テキストファイル(CSV)の場合もあれば、バイナリデータの場合もある。 ゲームによっては、ネット越しにデータベースへアクセスするかもしれない。 そういう部分を汎用的に書くのに継承は有効。 ●後半 スライムとスライムベスとホイミスライムとドラゴンとオオアリクイと彷徨う鎧とで いちいちクラス作ってたら一生終わんなくね?
864だが、なんかいろいろと混乱を招いたようですまん。そしてさらに混乱させるのだが……
自分自身の意見としては
>>877 の通りなんだが、
種類ごとにクラスを作るような継承の使い方が全く見当がつかなかったので質問させてもらった。
本気で全種類分クラスを作るのか、
それともスライムとスライムベスはスライムクラスにまとめてしまうのか、
その場合出現テーブルなど外から参照するときはどうするんだ(クラス名?)とか、興味が尽きない。
実際どうやるんだ?
>>872 のはどちらかというと戦闘時イベント(HP半減で台詞とか死亡エフェクトとか)など特殊処理を意識したものだと思うので
>>869 の話を聞いてみたい。
集約とかせずに強引に継承で表そうとするとそうなるんじゃね。 と869ではないが予想
オナニーの話 クラス分けして幾つもの「科」を作り、何十もの「目」を作った そして何百もの「種」を作ろうとしたとき、僕は秀丸のマクロで 大量のクラス(hpp、cpp)を作っていた 何かを間違えていることに気付き始めたのはその時だった あれは14歳の夏休みでした
14歳か… その時、俺は何やってたかなー。6001とか叩いてた気がする。
>本気で全種類分クラスを作るのか 本気で作ったよ。リビルドにかかる時間の長さに興奮した
C#でモンスターの基底クラス作って IronPythonでスライムクラスとか全部継承で作ったら面白いかも
strategyパターンオヌヌメ
>struct IEnemy; >class EnemyBase : public IEnemy {}; まだこんな命名規則使うやつ居たのか
>885 おまいは 変数hoge や Func()関数にまで突っ込むのか
>本気で作ったよ。リビルドにかかる時間の長さに興奮した
ひさしぶりに勇者を見た。
>>883 行動パターンとかをスクリプトにして外出しにするわけか。
でも動的に作成するのはなんだかコストが高そうな気がする。
888 :
872 :2008/03/24(月) 21:24:32 ID:KE3DiPkZ
うん。一晩寝て考えが纏まった。
昨日のあらすじ
>>864 継承使うよ(外部データ読み込むのにね)
>>870 継承使わないよ(外部データで弄えばいいじゃん)
>>874 (俺)矛盾しているやん!どっちやねん!?
>>875 矛盾してるように思えないんだが
>>876 (俺)え?!!
↑は置いといて取り敢えず1番の疑問の解消から…
>>864 >継承って、外部ファイル読み込みを外部データベース読み込みに変えるとき楽になるとか
ごめん。この継承の使い方、どんな使い方なのかまるで想像できない。
どんなの?
できれば、せっかく俺が書いた>877を読んでくれるとありがたいんだが。
890 :
872 :2008/03/24(月) 22:16:59 ID:KE3DiPkZ
ああ、もちろんちゃんと読んでいるよ。
いや、読んでたら>888の発想は出てこないだろ?
892 :
872 :2008/03/24(月) 22:48:16 ID:KE3DiPkZ
悪い。マジですまん。理解力なくて。 もうちょっと考えてみるわ。
まず
>>864 継承使うよ(外部データ読み込むのにね)
>>870 継承使わないよ(外部データで弄えばいいじゃん)
この時点で間違えてる。
894 :
872 :2008/03/24(月) 23:01:16 ID:KE3DiPkZ
お前はまず落ち着けw >894の疑問に関してだけ言うとだ。 >874と>888とでは、お前さんの言ってる内容が異なる……と、自分は感じた。 >874の文章を読んだ限りでは、ちゃんと理解しているように見える。 >888は間違って理解しているように見える。 >864は ・データの読み込み方法(外部ファイルとかデータベースとか)については、派生クラスを作るべき ・データだけが違うオブジェクトについて、いちいちクラス分割するのはどうなんよ? 正しいの?(疑問系) の2点について述べている。 具体的には>877を参照してほしい。 >870は データが違うだけのオブジェクトについて、クラスを分けるのは最適ではないのでは?と述べている。 データの読み込み方法については何も述べていない。 よって、両者は矛盾していない。
896 :
872 :2008/03/24(月) 23:54:26 ID:KE3DiPkZ
>>895 おけ。落ち着いたw
やっと謎が解けた。
俺が単純に 「継承使う」←→「継承使わない」で相反していることをいっているように
感じて何故かそこに噛み付いて「矛盾している!」叫んでいただけで
ずっと
「外部データの読み込みの為には派生クラスを作るけど、
データの違いで吸収できるようなことにまで派生クラス作ってどうすんの?」
って主張してるだけで別に矛盾なんてしてねーじゃん
―と。
うん。それなら問題ない。確かに自分は読み違えてはいなかった。
変な方向にこだわって混乱させてスマン。
元々
>>860 でいうように継承使わない派だからクラスをうじゃうじゃ派生しない方が
良いのはわかるし。
残る疑問は「外部データを読み込みを楽にするために派生クラス」ってやつ。
これ、さっぱり実現方法がわからない。
えー? インターフェースさえ揃えておけば 差し替えが楽になるってだけの話でしょ。 virtual void Img::Load(DestPtr* dst, FilePtr* src); を継承したクラス郡 void Jpg::Load(DestPtr* dst, FilePtr* src); void Png::Load(DestPtr* dst, FilePtr* src); void Gif::Load(DestPtr* dst, FilePtr* src); を作って差し替えるのが楽ってだけの。
898 :
872 :2008/03/25(火) 01:22:10 ID:kctvHJ5z
>>897 有難う。
説明するまでもないほど常識的なやり方なのね。
勉強不足ですまん。勉強になった。
ファイル形式が違うのを読み込むときに記述が楽出来るのね。
RPGなんてデータ駆動の典型だろ・・・
落ち着け。 お前は本当に872か?w
901 :
872 :2008/03/25(火) 02:11:16 ID:kctvHJ5z
>>899 ごめん
そもそも
>>860 でRPGを例に出したのが間違いだった。
敵の名前を皆が知ってるゲームでぱっと思いついたので安直に選んだ。
今思えばスーパーマリオの方が例としては良かった。
継承アレルギーの自分ならENEMYクラスひとつだけにして
全部データの違いで吸収するかなと。
ゲーム制作中にメットっていうファイヤーボールの効かない亀を思いついたとしても
ノコノコからの特化キャラとして派生させたりせずに
メンバ変数fireArmorを追加してメット以外のキャラを0に設定するかな。
902 :
872 :2008/03/25(火) 02:13:27 ID:kctvHJ5z
ゲームルールとか現実世界に複数の同種に思えるものが見出せるから という理由で継承の木にあてはめてしまうのはダメだよ ていうかそんなのならやらない方がいいswitch文でよろしい インターフェイスやスーパークラスを使う側に何が必要かということ 隠蔽のニーズのほうを第一に考えるべき
君は872ではなくて862だと思うんだ。
可愛いやつめw
お前ら、委譲を使えよ。 継承は多態が必要なときにしか使わないな。
継承より委譲を使えという文句が結構有名なためか、 委譲の形に書き直す際に、書き直す前の委譲元オブジェクトの継承関係を 委譲先オブジェクトがそのまま引き継いでしまうようなソースを書いても 何の疑問も持たない奴が意外と多いから注意な。 どの部分を委譲すればよいか、粒度は適切かどうかを見極めたうえで コーディングすべき。
当たり前のことだと思うんだが
よくよく考えれば当り前なことを
当り前だと認識する(定石・パターンを共有する)のが
設計・パターンの学習の第一歩なわけだから、
>>909 は最も必要な思考ではあるが
最もレスしてはいけない文章でもあるな。
ようは継承元の機能を手っ取り早く取り込む目的で継承をつかうな ということだよ そういうローカルな問題を解決するのに使ってしまうと もっと大局的な構造を記述するために使われている継承との一貫性がなくなる 名前のつけ方からして一貫した目線であるべきなんだよ ゲームを作ってる俺達はApplicationやSystemやEngineって呼べる一番高い位置から 見ているのだから敵キャラをEnemyと呼ぶのはおかしいよ こんなのたまたまプレイヤーに敵対的なAIが乗ってるだけのゲームオブジェクト に過ぎないんだから データの入出力の種類どうこうはそんなの多分インスタンスが生成される必要も ないんだろうからswitch文かなにかで書けば充分 「現実世界ではこれは〜の一種類とされています」なんてのを継承で 示してみせたところで後で見たとき何の役にも立たないわけだよ
>>911 Enemyクラスを作ろうが、一ゲームオブジェクトの処理内容をベタ書きしようが、
どちらもApplicationが敵を直接意識して操作しているという悪例に他ならず
そういった意味で両者の違いなんてほとんどないに等しいから
「現実世界のものどおりに継承関係構築するのは無意味だ」という主張の
引き合いとして「名前の付け方からして〜」以下の文章を出すのは
あまりにも不適当で意味不明。
ADVやRPGでシナリオの流れを状態で切り分けすることが多いと思います。 「1回目にここへ来たときはこっちのシナリオ、2回目以降はこっち」 「○○のアイテムを持ってるときに○○を調べるとこっちのシナリオ」 「○○への好感度が80以上のときに話しかけるとこっちのシナリオ」 様々な切り分け方があると思うのですが、そういう条件式とルートを 統括的に扱えるような設計というかやり方ってあるのでしょうか。 今やってるのはもうごちゃごちゃで、テストが不安で仕方ありません…
ADVなら、シナリオがツリー構造になってたりグラフ構造になってたり いろいろなタイプがあると思うけど、それぞれのシーン内の分岐は 基本的にはif分の羅列になると思うんだ あとこういう枯れたジャンルなら既にある優秀なツール、例えば RPGならRPGツクールを、ADVなら吉里吉里とかNスクを それぞれ参考にするといいんでねの サンプル見たりチュートリアルに沿って使ってみたりすれば イベントの基本構造とかが何となく見えてくるぞ
>>913 基本的には if 文の羅列だけど、たとえば RPG なら
・基本となるスクリプト
を用意しておいて、その上で条件が成立したときだけ
オーバーライドする内容を列挙した
・派生スクリプト
を上にかぶせるような作りにしておくと、多少は管理が楽になる。
>>913 ちょっと考えたけど難しいわ。降参。
とりあえず綺麗にソースを書いといて。
シナリオそれぞれに分かりやすい名前付けといたがよさそうね。
300件以上とかあるだろうから、どうやって名前付けるんだろう・・・
913のような問題は、構造化プログラミング的なコードだけで実現しようとすると if文の羅列で凄まじいネストになってしまったりして見難くなるんだろうなぁ。 まぁそういう制御の部分を、コードではなくスクリプトでなるべく見易くするってのはいいよね。 これらの方法は、全ての状態をグローバルなフラグなどで管理することになるのだろうから セーブやロードとかの処理は、結構簡単で良さそうだね。 915のいうような感じで、条件や処理を一つのオブジェクトに見立てて それらを動的に拡張していくような構造なら、いままでのフラグ的なものを 上手いこと隠蔽化してくれそうに思うので、一歩進んでいると感じるなぁ。 ただこれは、とあるポイントに複数の拡張が生じる場合を考えると、 優先順位が必要になると思うので、そこは考慮しないといけないね。 場合によっては一つの拡張の優先順位が複数存在することもありそうだし、 拡張の呼び出し元を拡張要求ってなものにして、それに優先順位と実拡張への参照を持たせるといいのかな。 あと現在の拡張状態をセーブするのがちょっと面倒なのかなって思う。
シナリオ構造をグラフにして、ステートマシンで管理すればOK
>>917 > 優先順位が必要になると思うので、そこは考慮しないといけないね。
実際には、ほとんど必要ない。そこまでやると、シナリオ担当がついてこられなく
なるから。
>>918 ステートマシンって一般的な単語なのかな
波動やってないとたぶん分からないきもするが
でもそんなににきがつくならこんなアホな質問はせんか
スクリプトだろうがコードだろうがっどっちも同じプログラムであって根本の話ではないし
>>920 > ステートマシンって一般的な単語なのかな
プログラマには常識だと思うな。
学生さんでも、大学で情報系専攻してれば必修だし。
考え始めたらこれ結構面白いなぁ。
さっき書いた動的拡張をスクリプトにするとして俺ならこんな感じ。
object 村人
abstract action 会話
object 村人A extends 村人
action 会話
message("おいらは村人A!")
action 魔王を倒した
object 喜ぶ村人
action 会話
message("あんたのお陰で村は平和だぜ!")
dynamic extend 喜ぶ村人 on derived(村人)
action なんか知らんが魔王が復活した
cancel dynamic extend 喜ぶ村人 on derived(村人)
>>920 ステートマシンて情報処理系の試験に出ないっけ?
波動(?)と何か関係あるの?
ものすごくスパゲッティになりそう
ここの住人はみんな情報系なのかな
波動ってハードのことね ハードだと普通に使う、というかこの考え方がないと組み込みのコードもかけないだろ
>>922 誰でも一度は考えるなw
とはいえ、”いかに綺麗な構造を実現するか”より、
”いかに大量のフラグを管理するか”を中心に据えてツール類を整備した方が
スクリプターも楽だし、メンテもし易く、バグも出づらく、高速なコードができあがるという罠。
class Event があって、List<Event> に全イベントをステージ最初にぶち込む。 で、各フェーズ毎に全イベントに、発動可能かを問い合わせる。 発動可能なら、キャラの位置を調べて、イベントの位置と合致する なら実際にイベントを発動。 これ、chain of responsibility
DirectXと付き合うこと数年。 描画担当をエンティティから切り離すのはいいとして その描画担当がシーンツリーの奥深くまでLPD3DDEVICEをもっていって 最底辺でd->SetRenderStateとかやってるのは 最近マルチパスレンダリングとか外部ファイルになったシェーダー等を考えるに 適当でないと感じるようになってきた 何かいいデザインがあるでしょうか
中間描画パケット使うてのはどうよ? MTFrameworkやPSSG(はちょっと違うが)も似たような方式だし。 [シーンツリー] --(生成)--> [中間パケット配列] --(最適化)--> [最終中間パケット] --> [描画] って流れで。 DirectX本体は、パケットの配列を読んで実行するのみで、シーンツリーには一切関与しない。 描画部を完全に切り離せる上、最適化部もシーンツリーのトラバースと分離できるメリットがある。 ただ、マテリアルやマルチレンダーターゲットの表現が難しい(的確なパケットを定義しないと冗長になってしまう)から、 パケットの設計が一番大変かと。
>>926 確かにその通りだよね。
今目に見えているものだけで動作を予測できるか、
ってとこがポイントなのかな。
自分でも、さっきのスクリプトみたいなのをスクリプターが頑張って書いても、
いざ実行してみて( ゚д゚)ポカーンってなってるのが目に浮かぶし。
でもそれは、専用のスクリプトエディタ的なアプリを作って
今見えているスクリプトに関連する情報を注釈としてオーバーレイ表示して
直ぐに関連を理解させることさえ出来れば結構改善できる気がするんだよね。
プログラムでクラス指向が普及しているのも、IDEによる直感的な補佐の
影響が効いているからだと個人的には思ってるし。
でもまぁ、一般的に想定出来る量の分岐のゲームで
ここまでやることはきっと割に合わないのだろうなぁと思う。
ただ、最近はオブリビオン(やったことないけど)とかいう、
莫大なスクリプトが存在するらしいゲームも出てるらしいじゃん。
そういったゲームリソースの肥大化から考えると、
こういうの考えておいて損はしないと思うんだよね。
>>927 こう書いたが良かった。List<Event*>
判定処理はConcreteEventクラス毎に違う
なんか勉強になる
>>929 MTFrameworkとかよくわからんけどデバイスコンテキストを持ちたくないとか、
ステートマシンにかかわりをもちたくないとか
単純なそういうものの隠蔽を望んでるわけじゃないのです
たとえば各個がDraw()を実装するような構造だと、シーンに一回デプスバッファだけ描かせるようにする
とかいう改変をしなくちゃならない場合に全部にDrawDepth()みたいな名前で同じようなことを
しなくちゃならん実装をしないといけないのはちょっと変だと思うわけです。
具体的な描画の手続きが末端におしつけられてる構造がなんとかならないかなと思ってるのかも。
わかりません。
>>933 自分でも分かってないのかよwww
まぁ俺は末端の描画処理に上層から介入したいのだと見たよ。
その前提で答えてみる。
現状ツリー上に階層化された描画物は、上層から
IDirect3DDevice*を引数としてリレーしたものを使って描画してるわけだよね。
んでこれらの描画物の描画処理に変化を加えたいということであれば、
上層で、IDirect3DDeviceを拡張したインスタンスを作りそれを下層へ放流すれば良い。
分かるかも知れんが詳細にやり方を書くと、IDirect3DDeviceって確かクラスだったよね?
であれば単純に継承して各メソッドで本物のインスタンスへの委譲メソッドを書く。
そしたら自分が拡張したいメソッド、この場合SetRenderStateか?を好きなように変更する。
そんな感じでどうよ。
もちっと考えると、そもそもIDirect3DDeviceなんかを末端から直接触らせずに
自作クラスでラップしたものを使わせるようにすると見易いし色々と便利かと思うな。
こういう考え方、きっとよく知られてる知識なんだと思うけど、俺はJavaやって初めて知ったよ。
そういうことするなら直接継承はしないだろ
>>929 なるほど意味分かった。
形状描画とマテリアル(描画嗜好)分離されてるから それでいいねえ
>>935 インタフェースなんだから直接継承しても問題ないんじゃないの?
あれ、ごめん、C++だとIDirect3DDeviceのメソッド郡はvirtualじゃないのか?
となると単純に継承しても元の型でアクセスされると拡張されたメソッドが呼ばれないのか。
じゃああれだ、自前クラスにするだな。
カプコンのなんとかフレームワークをパクればいいじゃない
言うは易し、行うは難し
中間なんたらを使うにしても結局ひとつのフレームを描画するための手続きが シーングラフの各最小単位に分散してしまうのを僕は懸念してるのだと思うのです。 優先度みたいな古臭いタスクの仕組みが採用さられてるようだけれど結局 「あれ?この直前の優先度は何番だtったっけ」とかいって探し回るマヌケな姿が目に浮かぶ です。 MTFrameworkでぐぐってもimpressのアレしかでてこないのでこんな批判ですが 何か他に資料が公開されてるのでしょうか?
会社の機密情報をホイホイと公開すると思うの? jk。
MTFrameworkについては公に出回ってる話しか知らんが >優先度みたいな古臭いタスクの仕組み 意味わからん ハードウェアに渡す描画コマンドに優先順位があるのは今も昔も同じだし よって投げるパケットに優先順位があるのも別に古臭くもなんとも無い つか必須 「タスクの仕組み」がナニを指すのか知らんが、タスクシステムスレで言うところの タスクシステム(=ギャラクシアンの実装)の話をしてるのなら、あれは エンティティ処理も描画処理も何もかも内包してる概念だから、ここでその話題を 持ってくるのは何か違う気がする エンティティを線形リストに入れるだけなんて古臭い、シーングラフを使うのが現代的 などという話をしたいなら、それはここでは無関係の話題と思われ
>描画するための手続きがシーングラフの各最小単位に分散してしまう ないない。MTFrameworkだろうがその他のミドルウェアだろうがそれはない 各エンティティがグラフに入ってようが何であろうが自由だし そのグラフ走査の順序でエンティティ更新処理が決定していようが GPUに投げる情報の順序とは独立した、全く別の話
>れはここでは無関係の話題と思われ >GPUに投げる情報の順序とは独立した、全く別の話 はい。MTFrameworkがいい、だめ、といったことを話したいんじゃなくて MTFrameworkみたいなのの上の層の、中間描画パケットや描画の手続きを投げつける 構造のほう のアイデアを伺いたいんです。 でもシーングラフ的構造を改めて設計でやりくりしようとせず そこはそのままの形を留めたまま横断的事象を管理するために 一旦描画手続きをバッファにまとめる、というのもひとつの現実解なのかもしれないですね。
945 :
944 :2008/04/15(火) 05:27:06 ID:TYyaNvw/
>>943 >ないない。MTFrameworkだろうがその他のミドルウェアだろうがそれはない
「手続き」というのは適当ではない表現だったとおもいます。
中間描画パケットはシーングラフの構成とは無関係に共通するシェーダをまとめあげる
役には立つと思うんだけど(そのためにつくられた仕組みなんでしょうし)
描画の主体は依然としてシーンのノードにあるのが普通だと思います。
全体としてみればシーングラフのツリーが描画をしていると言うことができるはず。
具体的にはシーンの最小単位がdrawとかいう名前のインターフェイスを持っていて
ここがパケットを発行するようになっているはず。
しかし一回のフレームを描画するのに全く異なる性質のものを複数回描画させられる
時代になった昨今、drawがここにあるのに違和感を感じる場面に遭遇することが多くなりました。
たとえばあるポストエフェクトのためにバックバッファとは別のバッファへデプスを描きだしていたとします
ユーザーの設定や場面によってそのエフェクトをばっさり無効にしたい場合
このバッファを描画する必要もなくなるわけです。ここでもしもシーンの各最小単位が
各々判断してバッファへの描き出しをやっていると大変なことに。シーンの最小単位が
描画の主体であるがゆえにこういった非効率が生じるわけです。
シーングラフとは別に描画の主体が存在するべきなのかもしれません。わかりませんが。
ガンダムに例えるとどういうこと?
>>945 >描画の主体は依然としてシーンのノードにあるのが普通だと思います。
>全体としてみればシーングラフのツリーが描画をしていると言うことができるはず。
>具体的にはシーンの最小単位がdrawとかいう名前のインターフェイスを持っていて
>ここがパケットを発行するようになっているはず。
シーングラフのノードにdraw()があるのが「普通」だと言いたいのか?
普通というからには有名どころの3Dゲームエンジンの少なくとも過半が
そういう設計になってることを実際に確認したんだろうな?
脳内妄想で普通とか言ってるとか言うなよ?
>>947 >しかし一回のフレームを描画するのに全く異なる性質のものを複数回描画させられる
>時代になった昨今
昨今?
見た目(形状、材質)が異なる複数種のインスタンスを効率よく描画するとか
そういう要請は10年以上前からほとんど変わってないよ
ところで俺の作文を見てくれ
GPUのモンスターパワーに物を言わせ、パフォーマンスアナライザの類を一切用いずに
呑気なコードを組んでもグリグリ動くちょい派手エフェクトの3Dアクションゲーがリリースできる
時代になった昨今
どう思う?
すごく…いい時代です… って俺なのか?w
わりぃwwww
>>948 でレスアンカー間違えたスマンコ
×
>>947 ○
>>945 >ここでもしもシーンの各最小単位が各々判断してバッファへの描き出しをやっていると
あれ、中間描画ナンチャラの話はどこへ行ったんだ
「各最小単位」がシーングラフの階層構造内の各ノードのことで
そのノードのdrawメソッドが「バッファへの描き出し」をやるのか?
それ中間描画ナンチャラも何もなく、drawメソッド内で
直接DrawPrimitiveとか呼び出してね?
>>945 シーングラフを使ったことの無い俺が頓珍漢なことを言うけど、
一概にシーングラフって言っても、グラフ構造以外の
動作の実装って、各エンジンによってバラバラなんじゃないの?
その辺をどういう風に実装してるのかを
>>944 が情報開示しなきゃ、
具体的なアドバイスって出来ないんじゃないの?
ググってみたけどこれに近いの?各個が描画処理を持ってる。
http://www.quatouch.com/products/hisui/doc/scenegraph.html こんな風に直に描画メソッドを呼び出しているから、
描画の主体がシーンの最小単位って言ってるの?
であれば「各ノードの描画要求」を仲介する管理者を立てればいいよね。
これは末端まで伝播されるコンテキストをその管理者とすると都合が良さそう。
管理者にエフェクト描画フラグとノード描画(node)メソッドを作って、その内部実装は、
if (
(!nodeはエフェクト) ||
(nodeはエフェクト && エフェクト描画フラグ)
){
node.draw(this);
}
これで良いんじゃないのかな。
ただ、各ノードが描画メソッドを持ってしまっているとすると、
ゲームの実行状態と関係してくる複数の描画処理を、
一つのノードに内包させてしまっているのかなという気がするので、
その場合は、描画処理を一つずつノードへ分解しなければいけないと思うよ。
ごめん読み直したら解釈間違ってた。 「エフェクトをばっさり無効にしたい」ってとこだけ意識してしまって、 それが要求だと勘違いしてしまった。 半透明系のエフェクトの描画処理を無効化したいものだと思って 書いてしまったので、変なところは読み飛ばして欲しい。 ほんとの要求は、「描画先バッファを上層で制御したい」ってことだよね。 まあこれも多分、先に書いた管理者のノード描画部分で制御出来るんじゃないのかな。
953 :
名前は開発中のものです。 :2008/04/16(水) 21:55:02 ID:oFemimm/
>>951 >ググってみたけどこれに近いの?各個が描画処理を持ってる。
そんなかんじです。drawをもってるcompositeパターン
>>952 >ほんとの要求は、「描画先バッファを上層で制御したい」ってことだよね
制御できるかできないかという意味では
シーングラフがdrawを実装した今のままでも十分制御できます。
リファクタリングの動機は不可能を可能にとか、そういうところにはないと思います。
>>953 Visitor風の実装に変えてみたら?
シーングラフはモデルとマテリアル情報だけ持って、
Visitorがシーングラフをトラバースして必要があれば描画する
ポストエフェクトを切りたければ、ポストエフェクトのVisitorを無視すればいい、的な。
でも、どんなに描画とデータを分離したところで、実際にゲームを作ることになれば
ノード単位でのエフェクト制御(シャドウを落とすかどうか、とか)がどうしても必要になってきて、
末端に細かいフラグが蓄積してしまってあまり意味がないんだよね。
結局、描画エンジンに限っていえば、データと処理の分離は、
最大公約数的な情報を末端のノードに持たせることになって、逆に効率を落としちゃうし、
タイムクリティカルなゲームの最適化を阻害するのが実情。
先進的なエンジンほど、制約がきつい(拡張性が無い、固定機能ばかり)のが現実だから、
何かいい構造を思いついたら発表すれば、一儲けできるかもよ?
>>953 君のシーングラフというのは
ノード(特にdrawインタフェース付きのやつ)同士の接続は何を表しているの
まぁ典型的なものなら座標系(例えば姿勢行列)の親子関係になるわけなんだけど
この場合、巡回目的は行列スタックを積み上げてながら仮想空間上の各ノードの
ワールド座標を得ることだったりするわけだが、その処理の中でdrawを呼び出すの?
>>954 大枠のコンセプトとしてはVisitorということになるのかもしれません。
ただ、VisitorそのものはC++ではその真価を発揮できない、
Compositionツリーの方に新しい要素が頻繁に追加されることが予想される
等、その弱点がちょうど今回のケースにあてはまり、そのままでは適用しずらそうです。
さらに個人的な感想をかけば、型と場合に応じて関数がいくつもできあがるのは好みません。
それこそ中間描画パケットのようなローテクなアプローチが必要なのかもしれないです。
>>956 > ただ、VisitorそのものはC++ではその真価を発揮できない、
コードを書いてみてくれ。なんか勘違いしてるような気がするんで。
>>956 ゲームに使う分には、ノードに種類フラグを持たせて、適切にアップキャストするのが常套手段だね。
Visitorは対応している種類のノードだけ処理する。
Visitorの関数の数の爆発にも、ノードの種類の増加にも簡単に対応できる。
ダブルディスパッチが目的ではないから、Visitorとはコンセプトが少し違うな。
イテレータに近いかも。
>>956 つNVSG
Traverserあたりを調べればそういう基本的な悩みは解決すると思う。
>>959 とても参考になりました。
シーングラフはあくまでデータの一群であって
それぞれの目的をその名に冠したtraversalがそれを利用してそれぞれの目的を果たすと。
レンダリングもtraversalの一種に過ぎないと。そんな解釈みたいですね。
ただコレ、NodeHintsなるものとか、ShadowMappingがなぜか埋め込まれてるとか
ちょっと気味が悪い部分もありますね。
>ちょっと気味が悪い部分もありますね。 具体的に言ってごらん
>>960 >>954 に
> ノード単位でのエフェクト制御(シャドウを落とすかどうか、とか)がどうしても必要になってきて、
> 末端に細かいフラグが蓄積してしまってあまり意味がないんだよね。
ってちゃんと書いてあるじゃねえか
NVSGはその典型例だよ
ノード毎の付加情報はあってもいいでしょ。各々のトラバーサーが自分に必要な 属性を処理すればいいだけ。C#のAttributeなんかが同じ要求から出てきたものじゃないかと思う。 プロパティグリッドの情報はオブジェクトにとって本質的じゃないけど、オブジェクト側に埋め込んでおきたい みたいな。
C#のAttributeは型とメンバにメタデータを付ける機能だよ オブジェクトには付けられない
インスタンスって意味でオブジェクトって使ったわけじゃないんだけど・・・。 じゃまぁ、s/オブジェクト/クラス・メンバ/ということで。
ほしゅ
プログラム板のデザインパターンスレから誘導されてきました。 ゲームを作ろうと思い、デザインパターンの勉強をしてるんですが Singletonをどんな風に使うのか今一ピントきません。 Singletonじゃないと困る場合。 Singletonだと助かる場合。 出来たら例を示して貰えないでしょうか。
シングルトン滅びろ
バカほど背伸びしてアレコレ使いたがるよな。
やる気になってる馬鹿が一番伸びるだろ。 いい気になってる自称天才が一番伸びねえよ。
背伸びしてアレコレ使わないとバカとやらを脱出できないだろう。 少なくとも「糞だって他の人が言っていたから」 という理由だけで、一度も使ったことのないモノを非難する人よりはマシ。
デザパタの中でシングルトンが一番わかりやすいと思うんだけどなあ
>968-971を俺なりに要約すると、 ・基本的な仕組みが判ってれば問題無い。 ・ゲームを作っていけば、自ずと使う場面がわかるはず。 ・判らないようじゃ、ゲーム制作に向いてない。 ・むしろ技法を知らなくても何時の間にかそれっぽく書けるのが理想。 ・使う言語が決まってるなら、そのスレを当たるのお勧め。
>>967 「クラスのインスタンスがひとつだけであることを保障する」というシングルトンの目的が
必要になる場面なんてほとんどないから、ピンとくるわけがない。
グローバル変数大好きなやつが免罪符みたいに使ってることのほうが多いから、
強いて言えば「グローバル変数が使いたいとき助かる」と言えるかもしれない。
>>974 画像を先読みしておいて使いまわしたい時には、
シングルトンで先読みして、
必要な時にクラス作って呼び出すってやってるんだけど、
これってもしかして、間違えてる?
>>975 それのどこでシングルトンが必要なのかわからない。
>判らないようじゃ、ゲーム制作に向いてない。 はじめから知ってろってことか
(明示的な)グローバル変数が無い言語(java?)なら必要かもしれないけど、 ハナからある言語ならシングルトンなんてスパゲティ抑止策としか思えない。 そういう言語だとシングルトンは必要と言えば必要だし、いらなきゃいらない。 と言うわけでお前等落ち着け。
979 :
名前は開発中のものです。 :2008/05/11(日) 18:41:31 ID:PCcZcAXj
>>976 つーことは。間違えてるのか。
描画クラスをダレに持たせるかが分からなくて、
ダレにも持たせないのを選択したのが、悪いのかな?
書き忘れ。C++でウインドウズ用のプログラムを作ってました。
コンストラクタやデストラクタが、近いように見受けられますが それで済むなら、シングルトンは必要ないですよね。 一つしか存在しないのを分からせる為の目印と言うには分かりにくいですし… となると、シングルトンが作られた目的というか、用途があるはずですが 例えば、データを受け取って、それをファイルへセーブするクラスはどうでしょうか。 キャラ毎に進行状況やフラグをセーブするような場合や キャラリストファイルから特定のキャラを選び、探索チームを作成し そのチームのキャラデータのみをキャラリストファイルへ反映させる場合です。 wile(チームの終わりまで) { Team[ chara_pos ].save() } (そんなごちゃごちゃしたセーブのやり方をするなと言うツッコミはなしで)
>>979 描画クラスは一つ一つのキャラクターが持つはず。
画像は同じでもアニメのパターンが違ってたりするので。
>>976 STGのザコ敵で、同じ画像を使っていて、何百匹も出る場合です。
gdgdだなぁ… クラスに画像が固定ならシングルトンでも良いけど、 可変なら微妙じゃね? (シングルトンで可変な数の画像読むなら別だろうけど、 それはそれでアクセス方法がシングルトン的じゃなくなりそうw) つか、必要か不要か二元論な奴は、 議論する暇あったらミニゲームでも作って、 いろいろ試したらどうよ…
質問する方も答える方もバカでワロタw 背伸びしすぎw
> 一つしか存在しないのを分からせる為の目印と言うには分かりにくいですし… ・シングルトンを知っていれば分かる ・知らずに2個インスタンスを作ろうとしても作れない これ以上に分かりやすい目印はないと思うが。
今、自分は、地図を開いて「このマークはわかりにくい」と言ってるような 現状だというのは分かっています。 マーク単体の意味は分かっても、それを利用する為の判断基準のようなものが 自分の中にまだ備わっていないので、先達の方に例を示して貰えないかと来てみたわけです。
いい加減くどいな。ゲーム作り始めれば判るよ。お前だって 「自転車のハンドルを右にきる理由は理解してるのですが、タイミングは何時ですか?」 と聞かれたら「転んで憶えろ」と言うしかないだろ?
シングルトンて言葉にするの、何か恥ずかしくね? 「このクラスはシングルトンです。」 とか真顔で言える気がしない。 唯一のインスタンスを保障するだけの癖に 大層な名前がついてるなって思う。
とりあえず言わせてくれ。 みんな話題待ちすぎwww突然レスがつきすぎだぜ
>>967 ハンドルとか設定とかを持たせるときとか
シングルトンは人に説明するのに便利すぎる 他のパターンと違って誤解される可能性が低いのと他よりは知名度高いからよく使ってる でも、デザパタって意外と知ってる人少ないよね 普通に会話に使うもんだと思ってGoF勉強したけどほとんど通じない
ところで、シングルトンは インスタンスがなければ生成してから返し、ある場合は既にあるインスタンスを返す関数が在るってことであってる? 個人製作なら自分ルールで最初にその手のインスタンスは初期化する、って決めておけばいらなそう。 複数人で開発する場合で、その手のインスタンスを前もって初期化したくない場合は効果がでるかもわからん
>>987 不幸なことに、シングルトンが必要と思われるケースのプログラムを
今までに組んだことがありません。
極端な言い方をすれば、この先シングルトンを使う場面に遭遇しなければ
シングルトンが何なのかさえ分かりません。
知っていて使わないのと、知らないで使えないのでは大きく意味が違うと思います。
ム板のデザインパターンスレに戻った方が良いと思うよ。 ここはGoFすらろくに知らないで設計語ってるスレだから
業務系とゲーム系だとまた求められてるものが違うから スコープはコンテナが管理するというのが今の流れだよね シングルトンであるとかプロトタイプであるとかで構成は変えないしね ゲームなら面とかでスコープかえると初期化が楽になるかもしれないけど メリットはあまりないかと オンラインゲームなら必須の知識ではあるけど
>>993 だったら使うなよ。くだらん豆知識さっさと忘れてゲーム作れ。
気がつけば「あ、これシングルトンだったね」と気がつく日もあるだろう。
>>996 失礼ですが、他の人が言ったことを繰り返して言っているだけの言動からは
貴方がデザインパターンを理解しているとは到底思えません。
挙句の果てに、妄想で批判とか、折角ゲーム作るように促してやってるのに困った奴だな…
>>998 スレタイを確認した方が良いんじゃないですか?
他の方々のレスは大変参考になりました。 ありがとうございました。
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。