トップページgamedev
981コメント424KB

ゲームプログラミング相談室【Part6】

■ このスレッドは過去ログ倉庫に格納されています
0001名前は開発中のものです。04/03/06 01:25ID:d2e/eEyg
ゲームプログラミング全般の質問スレッド。
扱う話題のダイナミックレンジはやや広め。包容力高め。
他の初心者質問スレとの棲み分けを探りつつ
これからもマターリと活用しておくれ。
 
■過去スレ
【Part2】http://pc.2ch.net/tech/kako/985/985540361.html
【Part3】http://pc.2ch.net/tech/kako/1002/10028/1002894129.html
【Part4】http://game.2ch.net/gamedev/kako/1005/10050/1005040025.html
【Part5】http://pc2.2ch.net/test/read.cgi/gamedev/1036410116/
■関連スレなど
>>2-5
0783名前は開発中のものです。2006/02/11(土) 22:39:19ID:QzYc1Fwd
>>781
なるほど。
全てXファイルを使用するなら必要のない機能ということですね
0784名前は開発中のものです。2006/02/11(土) 22:45:31ID:8qUzzjc4
そりゃあんた、一周の待ち時間が*1だからじゃよ。
(余計にかかった時間が)2フレームの描画時間以上なら…
と読み替えればよろし。

つか、キモいコメントだね。
関西人ってみんなこうなの
0785名前は開発中のものです。2006/02/11(土) 22:54:06ID:5Zuq4Zo9
関東だろうが関西だろうが、キモい奴はキモいんだよ。
関西人と一括りにするのは失礼。
0786名前は開発中のものです。2006/02/12(日) 01:38:10ID:w8yo3LTb
関西人だけど確かに>>780はキモイ希ガス
0787名前は開発中のものです。2006/02/12(日) 01:39:35ID:w8yo3LTb
ちなみにコイツはチュンだな
0788名前は開発中のものです。2006/02/12(日) 01:43:36ID:BClNNt0M
初心者の俺をキモい呼ばわりですか
07897822006/02/12(日) 03:40:55ID:MOr6hByS
>>784
実をいうと2フレームというところからして理解できないので
m_bFrameSkip = dwDelay > 0;
としました。
0790名前は開発中のものです。2006/02/12(日) 11:39:09ID:n176RnBh
>>782
コメントもコードもキモすぎると思ったら
あの偏執狂やねうらおか
0791名前は開発中のものです。2006/02/14(火) 03:36:39ID:G6ky4O6B
また大阪か
0792名前は開発中のものです。2006/02/14(火) 03:47:35ID:eoybXVvM
テクスチャのお勉強にDirect3Dを使って2Dのゲームを作りたいのですが、
薄い面だけのポリゴンを複数画面に並べ、そこにマップチップ等のテクスチャを貼り付ければいいのですか?
自キャラの描画もキャラ用の薄い面にアルファ値を設定したテクスチャを貼れば大丈夫ですよね?
0793名前は開発中のものです。2006/02/14(火) 04:05:40ID:Qt9KWBeq
>792
日本語で(ry

マジで薄い面って何だよ
0794名前は開発中のものです。2006/02/14(火) 04:11:34ID:eoybXVvM
三次元のポリゴンでなくて頂点が4つしかない普通の四角形
日本語は苦手
0795名前は開発中のものです。2006/02/14(火) 08:19:24ID:DFRR3HSf
ポリゴンはそもそもただの三角形。
0796名前は開発中のものです。2006/02/14(火) 08:51:04ID:NbMr8it4
>>795
それは言い過ぎ。
「ポリゴン」とだけ言った場合は「多角形」という意味。

>>792-794
マジエスパーすると、いわゆる矩形スプライトのことだろう。
0797名前は開発中のものです。2006/02/14(火) 10:49:04ID:9HsB+cDe
もうちっと3Dグラフィックに関する勉強が必要なんじゃないか
0798名前は開発中のものです。2006/02/14(火) 14:00:53ID:eoybXVvM
>>796
それっぽいです
ポリゴンに貼り付けないと2Dは描画できないと思っていたので

>>797
参考書と睨めっことか嫌いだから
いろいろ作りながら覚えていこうと思ってる

いってくる
0799名前は開発中のものです。2006/02/14(火) 21:01:27ID:m/P5BAbG
「ビルボード」でいいんでない?
0800名前は開発中のものです。2006/02/15(水) 13:57:58ID:DANF+Uun
SDKだと「スプライト」が座標変換無しの2D画像で
「ビルボード」は爆発とかに使う座標変換ありの1枚板だな
0801名前は開発中のものです。2006/02/15(水) 18:51:04ID:CAX6fixr
>>80
ゼノギアスの戦闘シーンのキャラとか、FFTのキャラとかがビルボードですな。
爆発にも使えるけど。

どちらかといえば2Dの描画というより、3Dの背景の中に
2D絵をなじませるための技術だと思っていたが、その理解でいいのかな?
0802名前は開発中のものです。2006/02/18(土) 19:38:52ID:qqhUmVxW
3Dゲームは描画用マップとコリジョンマップに分けると聞いたのですが、
描画用マップとコリジョンマップは1ステージ全て1つのXファイルで作るんですか?
0803名前は開発中のものです。2006/02/18(土) 20:10:32ID:+8ZFcTvr
キャラクターと衝突判定する部分だけに特化したデータを作ってもらうといいじょー。
例えば天井に衝突しないゲームなら、デザイナーさんに天井無しにしてもらうとか。
描画用ではカーブでも衝突用のは多少ごつごつしてても平気っす。
描画用もヒットチェック用もXファイルじゃなくってもいいけど、基本別々です。
08048032006/02/18(土) 20:13:53ID:+8ZFcTvr
×カーブ ○滑らかなカーブ
0805名前は開発中のものです。2006/02/18(土) 21:07:24ID:qqhUmVxW
>>803
なるほど、描画用マップはテクスチャ情報の付いたXファイルなど、
コリジョンマップは壁や各オブジェクトの位置を表したデータファイル・・・であってますか?

>作ってもらうといいじょー。
業界人ではないので誰にも作ってもらえないですorz
コリジョンマップエディタとかあるらしいのですが有料でしょうか
0806名前は開発中のものです。2006/02/18(土) 21:28:28ID:5dz9KLeS
逆にコリジョンマップを含めたステージの論理的なデータから
風景を生成するっていう考え方もあるが、まぁ普通は別々に作るんだろうな
08078032006/02/18(土) 21:51:17ID:+8ZFcTvr
>>805
そそ、描画データが大体、x,y,z,nx,ny,nz,u,v,面情報,マテリアル情報などなど〜、とかだけど
コリジョン用は、x,y,z,面情報、で十分なので。

>コリジョンマップエディタ
オラにはわかりませんです。

>>806
風景データの完成後、それをコピって別レイヤーで
がすがす頂点削ってく作業なので結構すぐ作ってくれます。
2〜3週間で作るデータでも、1・2日でコリジョンデータは出来てくるっす。
0808名前は開発中のものです。2006/02/18(土) 23:15:29ID:vUI3VTnm
gtkradiantだっけ?
そういうのもあるらしい。
0809名前は開発中のものです。2006/02/19(日) 00:17:34ID:GTOCpkng
FF7〜9のように一枚の2D絵に描かれた3D世界の中を3Dのポリゴンキャラが動き回るゲームって
どうやって実現しているんでしょう?
特に、スクロールとかやった時にどうして遠近感や空間関係が破綻しないのか不思議です。
なんたって、キャラは3Dで背景は2Dですからね。作るの難しいですかね?
0810名前は開発中のものです。2006/02/19(日) 01:57:03ID:prU8DMPB
あれは一枚のように見えるけど一枚じゃないぞ
0811名前は開発中のものです。2006/02/19(日) 09:01:11ID:rJ6jDAqF
>>809
フィールドは、全部3Dでおおまかなブロックにわけてスクロール。FF7で時々読み込み失敗する;;(飛空挺?とかで)
ダンジョンは、カメラの視点・注視点が動かないシーンは背景を2Dでプレイヤーの前面にくるオブジェを
3D計算で(これは2D計算(描画順序のみ)のままでもいけるところもあるかも)。
ムービーへ切り替えするときは、背景をムービーとして、カメラワークとプレイヤーの前面にくるオブジェだけ3D計算。
0812名前は開発中のものです。2006/02/19(日) 14:15:08ID:GTOCpkng
注視点が動かないシーンなら分かるんです。コンポジションソフトと同じ要領でしょ?
問題はカメラがキャラを追って大きくパン(背景絵もスクロール)するような広いダンジョンの場合は?
空間関係を保持出来ませんよねぇ?
0813名前は開発中のものです。2006/02/19(日) 15:12:31ID:rJ6jDAqF
コツとしては絵の中の道は実際の3Dデータとして考えて、
カメラワークをキャラクターの位置から背景2D絵に対して平行にすべらせるとFF7〜9のようにできます。
(道がキャラクターより前面にくる時は当然3Dオブジェとして描画します。
というかFF7〜9の背景データは3Dデータから2Dにおとしてる?)

背景データが3Dじゃないと表現できないのはカメラ視点が平行移動せず奥へ向かって行く場合っす。
FF7〜9ではそういう時、ムービーを使用しています。
そういえばバイオハザードとかも同じっすね。
0814名前は開発中のものです。2006/02/19(日) 15:14:58ID:prU8DMPB
FFに視点・注視点が動くような場面あったかな
単純にスクロールしてるだけだと思ったが
http://gamdev.org/up/img/4707.jpg
08158132006/02/19(日) 15:41:30ID:rJ6jDAqF
×奥へ ○奥や手前へ

>>814
そう思います。プレステ1だし風景まで3Dってわけにはいかなかったのかも。
0816名前は開発中のものです。2006/02/20(月) 00:21:23ID:Ez2JkE7H
理解しました。つまりカメラがキャラの移動に対して常に平行移動する限り、カメラアングルに「角度」的変化は無いので背景絵と矛盾しなかったんですね。
しかしその場合でも、スクリーン何個分もスクロールするような長い道などの場合マップ絵の読み込みだけで相当なメモリを消費するんじゃないかと思うんですが。
それに3D処理とマップ描きは別の工程での作業になると思うんですが、
実際プログラム上で実行した時に3D処理上の当り判定とマップ絵上の壁とが
寸分違わず一致してますよね〜。一体どうやってるんでしょう?
0817名前は開発中のものです。2006/02/20(月) 00:22:51ID:IKQC9DMw
寸分違わず一致しない理由がわからん。
0818名前は開発中のものです。2006/02/20(月) 01:44:52ID:Ez2JkE7H
だってだって、普通少しくらいズレたって良さそうじゃん?
3D処理用の簡易モデル・シーン情報→マップ描く人のツールに移す→細かいパーツとか付け足し、テクスチャ貼り→プリレンダ絵完成
この工程のどこかでズレそうじゃん、どこかでマウスがブレたりして。またはカメラの設定トチったりして。
0819名前は開発中のものです。2006/02/20(月) 01:52:21ID:HTNVYcWy
製品レベルではズレることは許されない
0820名前は開発中のものです。2006/02/20(月) 02:14:38ID:Ez2JkE7H
じゃあ慎重な作業と根性でズレないようにしていると理解してよろしいですか?

ちなみにこういったシステム(FF7・8・9/初期バイオハザード)のゲームを作るにはどの程度のプログラムの技術が必要になりますか?
自分はプログラムは組めないので、出来る人を探さなければいけないんですが。
例えばこのスレにいる皆さんなら作れます?キャラモデルやマップ等は全部こっちで用意すると仮定して。
0821名前は開発中のものです。2006/02/20(月) 02:33:26ID:7NofXH/9
>>820
出来る人は結構いるけど、あんたに付き合っている暇がある人はいないと思われ。
0822名前は開発中のものです。2006/02/20(月) 04:31:14ID:kdfJprxL
割と大変な方。
0823名前は開発中のものです。NGNG
>>820
技術もさることながら、単純にマンパワーが必要になるよ
FF7〜クオリティ・量のグラフィックデータを自前で全部作れるのならそんな心配無いのかもしれんけど
0824名前は開発中のものです。2006/02/20(月) 12:13:27ID:oi3Frd4a
上司「高速化がご飯作ってくれるの!?」
オラ「でもスクエ二君の家は・・・」
上司「スクエニ君の家はスクエニ君の家!!うちはうち!!」
0825名前は開発中のものです。2006/02/20(月) 13:24:47ID:ko93Nstz
プロの作品って技術もさることながらマンパワーが凄まじいよなぁ
0826名前は開発中のものです。2006/02/20(月) 15:48:34ID:g7wRkPfK
確かに。
0827名前は開発中のものです。2006/02/20(月) 19:14:27ID:DhgD3x+I
Softimage|XSI FTKに詳しい方に質問です。
XSIのスケルトンをエクスポートしたいんですが、BASEPOSE とSRTの相関関係が良くわかりません。
BASEPOSE, SRT を4x4行列変換済みメンバーとして、スケルトンがRoot->bone->bone2 というチェーンとし、
rootのグローバル変換行列とジオメトリブレンディングは無視するとして、最終的にbone2に結び付けられたenvelopeというメッシュのローカル変換行列Lを得たいとします。
このとき、↓のようにBASEPOSEを無視してよいのか、
Matrix L = bone.SRT * bone2.SRT * envelope.SRT
それとも↓のようにBASEPOSEと相対的にSRTがあるんでしょうか?
Matrix L = (bone.SRT * bone.BASEPOSE) * (bone2.SRT * bone2.BASEPOSE) * (envelope.SRT * envelope.BASEPOSE)
それとも何か別の考え方に基づいているんでしょうか?
0828名前は開発中のものです。2006/02/20(月) 19:21:56ID:ZusWQmSS
>>827
CG技術板じゃないか?
0829名前は開発中のものです。2006/02/20(月) 19:27:55ID:XpFlk9zt
>>825
そりゃ、ゲーム作るのに50人とか使えるんだからな。
アマチュアはどう頑張っても10人程度が限度だろう。
0830名前は開発中のものです。2006/02/20(月) 19:34:52ID:jsb+bV9/
プロジェクト管理する人は、相当な交渉能力と
カリスマ性と幅広い知識が無いと、50人なんて統制できないんだろね
0831名前は開発中のものです。2006/02/20(月) 20:11:51ID:hi1jYPiS
金がありゃ何とかなるんじゃね?
0832名前は開発中のものです。2006/02/20(月) 22:32:44ID:bkUHwmA4
2Dのファミコンのドラクエの洞窟みたいなマップのシステムを作るには
どのようなやり方がよいですか?
参考になるようなサンプルとかないでしょうか。

環境:VC++
0833名前は開発中のものです。2006/02/20(月) 22:32:58ID:pF6ek0Cc
>>828
XSIの中間フォーマットdotXSIからゲーム製作などに必要なデータをコンバートするためのライブラリがFTKのようだ
0834名前は開発中のものです。2006/02/20(月) 22:58:49ID:LyW0l92U
>>827
以前自分がやった時は、良く分からないまま試行錯誤してたら上手く行った感じに
なっただけなので、もしかしたら問題あるかもしれんが書いてみる。
ソース見ても良く思い出せないけどね。バージョンによっても違うかもしれんし。

基本的に、SRTを階層で乗算していった物がそれぞれのBASEPOSEになるみたい。
なので、アニメーションさせないならBASEPSOEだけ使えば、SRTによる階層での乗算は不要かと。
SRTはFCurveで値を変更できるようなので、アニメーションするならSRTも必要。
FCurveでアニメーションさせる場合、SRTにはFCurveの1フレーム目が入っているようだ。
ジオメトリブレンディングをやるならSRTだけじゃ駄目で、BASEPOSEが必要と思われる。
自分のソース上では、BASEPOSEの逆行列保持して、SRTで動かして元に戻す感じになってる。

自分で書いてても良く分からなくなってしまった。
聞きたい事と全然違ったらごめんね。
0835名前は開発中のものです。2006/02/21(火) 01:05:32ID:2/rlrMq6
今度オリジナルのカードゲームをHSPで作ろうと思うのですが
どういう風にプログラミングすればいいのでしょうか?
0836名前は開発中のものです。2006/02/21(火) 02:30:10ID:dgLZBZXY
>>835 オリジナルでおk
08378272006/02/21(火) 13:28:47ID:Ry7crMJu
>>834
>基本的に、SRTを階層で乗算していった物がそれぞれのBASEPOSEになるみたい。

どもです。BASEPOSEはIKで使うようですね。エフェクターを動かした後、この逆行列を掛けて変換行列を得るようです。
0838前4302006/02/21(火) 22:19:53ID:NxD57HWX
>>835
割り込みがあるルールの場合は、お互いのカードをスタックに積んで上から処理する。
0839名前は開発中のものです。2006/02/24(金) 03:15:19ID:9TnWIlnr
Direct3D使ってゲームを作りたいのですが、クラス構成で悩んでます

WinMain┬Rendererクラス ・・・レンダラーの初期化と描画開始・終了・Present()
     └Sceneクラス   ・・・シーンの構築と描画 レンダラークラスからポインタで呼び出される

今のところこんな形になってるのですが、(某DX本の構成)
ここにキャラクターの移動や描画などの処理をまとめたCharクラス
マップのスクロールや描画をまとめたMapクラス
などのオブジェクトを表すクラスを組み込むとしたらどこに入れればいいのでしょうか?
上の構成はぶっ壊してもいいです
0840名前は開発中のものです。2006/02/24(金) 12:49:41ID:yHhdLc83
悩むところなんだろうか?ぶっちゃけどこに入れても
その先の部分をきちんと書けばちゃんと回ると思うんだが。
0841名前は開発中のものです。2006/02/24(金) 16:44:36ID:9TnWIlnr
オブジェクトクラスが入力と描画どちらにも対応しないといけないから
描画用クラスに組み込むとおかしくなるし
描画用クラスの外に出すとどうやって描画するかが分からなくて
0842名前は開発中のものです。2006/02/24(金) 17:07:15ID:yHhdLc83
ひょっとすると俺には想像もつかない複雑な構成になってるのか。
そもそも説明文と図が矛盾してる(レンダラーからシーンが呼び出されるのに
図ではWinMainを介してしか繋がってないように見える)しな。
0843名前は開発中のものです。2006/02/24(金) 19:48:30ID:9TnWIlnr
ttp://dream.my-sv.net/upload/src/up0140.zip
ごめん今こんなものしかない
WinMainからレンダラー呼び出してその中でDirectXの初期化
次にシーンクラスのCreateScene()呼び出してテクスチャとかメッシュとかアニメーションとか設定
WinMain最後にスレッド生成。スレッド内は無限ループ。
レンダラークラスのRenderScene関数にシーンクラスへのポインタ渡して
RenderScene関数内で画面クリア後、シーンクラスのDraw関数呼び出してモデルを描画
その後RenderSceneに戻ってpresent()したらWinMainに戻る
打っててなんかおかしいとおもた
長々とスマソ
0844名前は開発中のものです。2006/02/24(金) 20:43:19ID:yHhdLc83
CSceneクラスにオブジェクトクラスなりそのポインタなりのリストを保持させる
0845名前は開発中のものです。2006/02/24(金) 21:50:22ID:9TnWIlnr
やっぱりシーンクラス内になりますか
スレッド内で移動処理などしたいのでWinMainにクラス持たせてポインタを渡すことにします
ありがとう
0846名前は開発中のものです。2006/02/26(日) 21:47:41ID:qag5ydFj
タスクシステムとやらを組んでみた
コンパイルエラーの嵐
関数ポインタとメモリが絡んでくると毎回酷いことになる
0847名前は開発中のものです。2006/02/27(月) 08:33:07ID:wV/qPqZG
コンパイルエラー云々言ってる段階じゃ
まだ話にならんと思うんだが。
0848名前は開発中のものです。2006/02/27(月) 16:41:18ID:oEXfl838
いや関数ポインタの方はあまり使ったことないからその辺はまぁ・・

Class1::test(TASK *t)  //TASKはタスク用の構造体
{
  ・・・
}

この関数をタスクの行動関数に指定してタスクを生成したいんだけど
タスククラスのpTask->TaskCreate(test, NULL, 1, 1)でタスク生成関数に関数testのアドレスを渡しても
「void (* (_closure )(TASK *))(TASK *)' 型は 'void *' 型に変換できない」とかエラーが出る
渡す先はタスククラスメンバ関数の
TASK* TaskCreate(void* Func, void* Release, DWORD Priority, DWORD Type)

クラスのメンバ関数はvoid*型に変換できないの?
0849名前は開発中のものです。2006/02/27(月) 16:45:29ID:E/UIX170
>>848
>クラスのメンバ関数はvoid*型に変換できないの?
ムリ。
いや、無理すれば出来るけど。
bind1stで調べてみると分かる、かも?
0850名前は開発中のものです。2006/02/27(月) 16:46:40ID:oEXfl838
あとクラス内のメンバ関数ではなくクラス外の関数なら普通に渡せた
void test(TASK *t){/*・・・*/}とか
0851名前は開発中のものです。2006/02/27(月) 16:47:36ID:oEXfl838
>>849
更新してなかった
>bind1st
ありがとう、ちょっとググってくる
0852名前は開発中のものです。2006/02/27(月) 20:12:08ID:BluJBaYX
>>848
クラスの多重継承を考えると、sizeof(メソッド)は
sizeof(単純な関数ポインタ)+sizeof(オフセット)
が必要になるよ。
0853名前は開発中のものです。2006/02/27(月) 20:35:03ID:oEXfl838
しばらく検索してみたけどどうにも・・

>>852
よく分からんです・・
タスク用のデータエリアのことなら
pTask = new CTask;
TASK* Task = pTask->TaskCreate(行動関数,開放関数,優先度,タイプ); //タスク生成、リスト追加
Task->Data = new データ型;
Task->Data = (void*)データ;
で確保してるのでサイズは大丈夫だと思う

タスクってポインタをガシガシ切り替えて処理するものだと思ってたけど
CじゃなくC++のクラスを使ったタスクシステムを見てみると
どれも継承元で仮想関数使って継承先に処理を記述する処理固定のしかないんだなぁ・・・
0854名前は開発中のものです。2006/02/27(月) 20:47:17ID:IKST4ZuK
つStateパターン

あと、関数ポインタじゃなくてboost::function使うと色々できるよ。
パフォーマンスは知らんけど。
0855名前は開発中のものです。2006/02/27(月) 20:50:42ID:BluJBaYX
>>853
C++でもポインタの切り替えはできるよ。というかできたよ。
理由は>>852の通りなんだけど、
とりあえずクラスメソッドはvoid*型に変換できないんで
TASK* TaskCreate(void* Func, void* Release, DWORD Priority, DWORD Type)

typedef ...(ClassName::*FuncType1)(...);
typedef ...(ClassName::*FuncType2)(...);
TASK* TaskCreate(FuncType1 Func, FuncType2 Release, DWORD Priority, DWORD Type)
のようにする必要がある。
0856名前は開発中のものです。2006/02/27(月) 21:47:38ID:oEXfl838
>>854
>Stateパターン
Stateで検索してたつもりがいつのまにかデザインパターン全般のページ見てた
奥が深いね・・・こっち関連の書籍持ってないから今度買ってみる
boostはライブラリをあまり使いたくない派なので迷う
>>855
異なる複数のクラスに対応させる場合、
生成関数をその分用意しないといけないので大変ですね・・
なんでクラスメソッド渡せないんだか・・

デザインパターンに興味を持ったのでStateパターン覚えてからしばらくそっちに走ってみます
0857名前は開発中のものです。2006/02/27(月) 22:08:46ID:BluJBaYX
> 異なる複数のクラスに対応させる場合、
> 生成関数をその分用意しないといけないので大変ですね・・
> なんでクラスメソッド渡せないんだか・・
まさにここが工夫のしどころで、
いちいち作らないようにする方法はある。
0858名前は開発中のものです。2006/02/27(月) 22:13:28ID:oEXfl838
>>857
今思い出したからうろ覚えだけど
もしかして関数テンプレート機能?
0859名前は開発中のものです。2006/02/27(月) 22:47:19ID:BluJBaYX
ういうい。
このくらいはできて当然だから、がんばっちくり。
0860名前は開発中のものです。2006/02/27(月) 22:49:43ID:oEXfl838
ありがとう
俺物忘れ激しいな・・
C++基礎からやり直した方がいいかも
0861名前は開発中のものです。2006/02/27(月) 22:53:02ID:NtZAdaLq
タスクシステムなんて言うから C で組んでるのかと思ったら、 C++ だったのかよ。
普通に仮想関数使えば終了だな。キモイキャストの連発ともおさらばだ。

関数ポインタから void* への変換は、メンバ関数に限らず不可。
もしできたように見えたとしても、それはコンパイラの独自拡張だろう。
0862名前は開発中のものです。2006/02/27(月) 23:23:15ID:BluJBaYX
>>861
やってみれば分かるけど、仮想関数のみだとキャストしないと無理。
あと、関数ポインタからvoid*への変換は確かに環境依存なんだけど、
boost.function はそれを駆使して実装されてるんで、
boost.function が動く環境ならどこでもできるよ。
0863名前は開発中のものです。2006/02/27(月) 23:37:54ID:NtZAdaLq
>>862
単に「タスクシステム」っていうと、メインループがタスクのポインタ握って
ポインタから仮想関数を呼び出すぐらいしか無いと思うんだけど、
何にキャストが要るの?

boost::function が関数ポインタから void* への変換を駆使してる?
どこにそんな情報があるの?
とりあえず現状のソースでは union 使ってるみたいだけど。
http://cvs.sourceforge.net/viewcvs.py/boost/boost/boost/function/function_base.hpp?view=markup
0864名前は開発中のものです。2006/02/28(火) 00:21:53ID:6zNpXrV2
class ClassA {
public:
  void static funcA(void* se1f)
  {
    ClassA *self = (ClassA*)se1f;
    cout << self->num++ << endl;
  }
private:
  int num;
};

void call_func(void (*func)(void*), void *arg)
{
  func(arg);
}

int main()
{
  ClassA *class_a = new ClassA;
  call_func(class_a->funcA, class_a);
}

Perlとかに慣れているなら self の存在を許せるよね…
0865名前は開発中のものです。2006/02/28(火) 00:29:02ID:zCKm/IVQ
>>863
タスクシステムって言うのは
class Task {
public:
 void begin_task() { ... set_task(&Task::task1); }
protected:
 void task1() { ... set_task(&Task::task2); }
 void task2() {}
};
とか、こういうのを指してると思うんだ。
で、コールするべきメソッドを保存するためには、
テンプレートを使わないならキャストする必要があるよと。
もちろん1タスク1関数を遵守してもいいんだけど、これはこれでなかなか便利だよ。
あと、boostの方は間違えた。
関数オブジェクトを保存しているフィールドと関数ポインタのフィールドを見誤ったようだ。
0866名前は開発中のものです。2006/02/28(火) 00:31:23ID:zCKm/IVQ
↑set_taskとそれを呼び出すメソッドは適当に補完して。
0867名前は開発中のものです。2006/02/28(火) 00:31:28ID:aXLiBRlK
ゲームの描画と処理は別にした方がいい?
別にする場合の構成とかどんなもん?
0868名前は開発中のものです。2006/02/28(火) 03:24:56ID:nWNa1RWo
>853
C++でやるならもっと型安全に気を使おう。
そんな古典的な手法を使うならCでやれ。

C++的には
>継承元で仮想関数使って継承先に処理を記述する
その継承先の処理の記述で、
ifやswitchやメンバ関数ポインタやstaticメンバ関数へのポインタを使って分岐するのが、
型安全でカプセル化でスマート。

>861
void *に変換した物は、何も弄らず元の型に戻せば、
正しく復元される(関数ポインタだとしても)って聞いたんだが。
0869名前は開発中のものです。2006/02/28(火) 09:48:42ID:q2yPrwLQ
>>867
普通は別にするとおもわれ。
構成なんて漠然としたこと聞かれても困る。
例を示されよ。
0870名前は開発中のものです。2006/02/28(火) 12:17:07ID:kxpJE7Cj
>>868
オブジェクトポインタと関数ポインタの間での変換は規格では認められていない。
C の時からそう。
0871名前は開発中のものです。2006/02/28(火) 12:57:51ID:aEEYZl8l
タスクシステムってまさかCodezineに載ってるアレのことか?
C++でやるならStateパターン+1キャラクタ1クラスでFAだろ。
0872名前は開発中のものです。2006/02/28(火) 13:39:14ID:kxpJE7Cj
>>865
その形でどこにキャストが要るのかわからない。
0873名前は開発中のものです。2006/02/28(火) 21:40:21ID:zCKm/IVQ
>>870
確かにコンパイラの独自拡張なんだけど、もはや共通拡張と言ってもいいくらい浸透してるみたいだね。
条件付きではあるけれど。
ttp://forums.belution.com/ja/cpp/000/015/67s.shtml

>>871
状態によって処理を変える必要しかないならそれでもいいだろうね。
ただ、例えばタイトル画面なんかの場合は
1)タイトル文字をフェードイン+移動しながら表示
2)サブタイトルを移動しながら表示
3)全体にエフェクトをかける
みたいに状態によって左右されないシームレスな記述が必要になる。
これを扱う方法としてswitchやマイクロスレッドがあるんだけど、
もう一つの方法がこのオリジナルタスク。
オリジナルとはいっても
Codezineのタスクシステム + Move or Drawメソッドの呼び出し先を変えられる
ってだけなんだけど。

>>872
新規クラス Task2 や Task3 を導入したときに問題になる。
0874名前は開発中のものです。2006/02/28(火) 22:38:49ID:K7Ri/qFO
状態によって処理を変えるのが、Stateパターンじゃないのか
0875名前は開発中のものです。2006/02/28(火) 23:36:27ID:l+ExwxPF
タスクシステムのあとから生まれた、関数ポインタとか隠蔽しているC++で
タスクシステムの方を優先して設計するのはナンセンスだと思うよ。

関数ポインタを使って実現したいことは処理の共通化だろうし、それは仮想関数だけじゃなくて
普通に継承元になる側にも関数いれときゃいいし。
継承元のクラスポインタに、派生したいろんなクラスをまとめていれられる。
0876名前は開発中のものです。2006/02/28(火) 23:47:24ID:aXLiBRlK
WinMain下の構造教えてくれ
0877名前は開発中のものです。2006/03/01(水) 00:51:17ID:CUoSF3s4
>>865の言ってるタスクシステムとか百害あって一利無しじゃね?
>状態によって左右されないシームレスな記述
ってのは単に処理をどこで区切ってStateに分けるかの話だろ。
08788722006/03/01(水) 00:59:35ID:IPZ1L++y
>>873
> 確かにコンパイラの独自拡張なんだけど、もはや共通拡張と言ってもいいくらい浸透してるみたいだね。
> 条件付きではあるけれど。

そんなに必死に正当化しなくても、非標準なんだから使わないようにすれば済む話。
「共通拡張」なんて胡散臭い言葉を持ち出すのは混乱の元。

> 新規クラス Task2 や Task3 を導入したときに問題になる。

やっぱりわからない。わかんないのは俺だけ?
何から何へのキャストが要るのか、書いてもらえると分かるかも。
0879名前は開発中のものです。2006/03/01(水) 01:09:15ID:2CSbAmuS
>>878
もういいじゃん。
そっとしておいてあげようよ…。

共通拡張の時点で分かるでしょ。
もういっぱいいっぱいなんだよ。
わかってやれよ。
0880名前は開発中のものです。2006/03/01(水) 01:28:04ID:MsffCk59
これは例が悪かったのかな。もう一度プログラムを書いてみる。
これは擬似コードなので動かないし、NULLチェックとかもしてないよ。

// 描画系のメソッドは略
class TaskBase {
public:
typedef @ FuncType;
TaskBase() : m_func(&TaskBase::begin_task) {}
void set_task(FuncType func) {m_func = func; /*A*/ }
void update() { m_func(); }
protected:
virtual void begin_task() {}
private:
FuncType m_func;
};

class Task1 : TaskBase {
public:
Task1() {}
protected:
void begin_task() { set_task(&Task1::task1); }
void task1() {}
};

class Task2 : TaskBase {
public:
Task2() {}
protected:
void begin_task() { set_task(&Task2::task1); }
void task1() {}
};
0881名前は開発中のものです。2006/03/01(水) 02:16:32ID:MsffCk59
>>875
関数ポインタを使ってしたいことは、処理の共通化でもあるんだけど、
タスクの場合は主に長い処理を1フレーム分に分割することにある。
マイクロスレッドなりスレッドなりを使わないと、どうしてもぶつ切りにせざるを得ないので。
もちろん、templateメソッドみたいに呼び出すメソッドがあらかじめ分かっていれば、
継承元側に仮想関数を追加しておくことはできるよ。
ただタスクシステムの場合、それはほとんど不可能。

>>877
Stateを使うってことは、状態一つに対してクラスを一つ作るってことなのかな?
例えば、>>873にあげた1)2)3)でそれぞれに対してクラスを作るの?
これの代替機能としてはswitchやマイクロスレッドがあげられると思うんだけど、
何でステートパターンにこだわるんだか、俺には分からない。
これだと粒度大きすぎると思うんだけど。
(細切れの関数に対していちいちクラスを作らないといけないってことね)

>>878
> そんなに必死に正当化しなくても、非標準なんだから使わないようにすれば済む話。
> 「共通拡張」なんて胡散臭い言葉を持ち出すのは混乱の元。
一緒に示したソース見た?
その中に「共通の拡張」って表現があるから、それを借りただけなんだけど・・・
この辺は>>868や俺のように間違えてる人が多いから、一応確認しただけ。
これは本題ではないので、こちらからはこれ以上レスしないよ。

あと、>>880に示したプログラムではテンプレートを使ってないので、
@に何を書いてもAでキャストすることになる。
使わない方法があれば、俺も知りたい。
0882名前は開発中のものです。2006/03/01(水) 02:36:11ID:MsffCk59
>>881
× @に何を書いてもAでキャストすることになる。
○ @に何を書いてもset_taskの呼び出し時にキャストすることになる。
0883名前は開発中のものです。2006/03/01(水) 03:14:04ID:IPZ1L++y
>>880,881
キャストが要るようになったらプログラムが間違ってるのを疑えよ。
なんで仮想関数で得られる型安全を自ら壊すような「タスクシステム」に
こだわるんだ?そんなシステム要らない。

↓これでいいんじゃないの。

class State {
public:
 virtual void update() = 0;
};

class State1 : public State {
public:
 State1() : m_update_task(&State1::begin_task) {}
 void update() { (this->*m_update_task)(); }
private:
 void (State1::*m_update_task)();
 void begin_task() { m_update_task = &State1::task1; }
 void task1() {}
};
■ このスレッドは過去ログ倉庫に格納されています