初心者のためのゲームプログラミング

このエントリーをはてなブックマークに追加
929929:04/04/01 02:33 ID:KHDslUNr
ゲームを作る事を始めて1年が経ちます。
使っている言語はC++です。
ゲームと言っても15パズルやクイズなど簡単な物しか作れていませんが・・・。

色々作っていくうちに自分にも欲がでるようになり、メインの部分だけでなくタイトル画面やエンディングなど作りたいという気持ちが芽生えました。
しかし、ここで困った事が。
部分部分は作れたのですが、それのつなげ方がわからないのです。

一番シンプルに、タイトル画面でボタンを押すとメインが始まりクリアするとフェードアウトしてエンディング、そしてタイトルに戻るという流れにしたいのです。
全体をループさせてるのですが、そのループ内でまた部分部分でループを作るなど考えているのですが・・・。
一般的な方法を是非御指導お願いします。
930名前は開発中のものです。:04/04/01 02:43 ID:9wC3azde
ループをひとつ作って、その中でタイトル画面やらメインやらエンディングやらを呼び出せばいい。
と、メイン部分しか作ったことのない俺が言ってみるw
931名前は開発中のものです。:04/04/01 03:07 ID:hm1FO9Sr
>>929
俺はJava使いだけど、処理ごとにクラスを分けて、
while(true)ループ内でタイムライン管理してるな。
例を流れにすると
タイトル→メイン.Start関数呼び出し→メインループ→クリア後処理呼び出し(フェード関連関数)
→エンディング関数呼び出し→初期処理→タイトルへ

といった具合に。スタートを押したらゲームスタートさせる関数を呼び出して、
その関数の中にはゲームの開始処理が時系列で書いてあるって感じ。
932名前は開発中のものです。:04/04/01 03:07 ID:ree+3Ujs
>>929
class Scene { public: virtual void step () {} };
// 継承クラスのstep()では各場面の独自の処理を定義する
class TitleScene : public Scene { public: void step (); };
class MainScene : public Scene { public: void step (); };
class EndingScene : public Scene { public: void step (); };
Scene *currentScene; // グローバル変数
色々方法はあるけど、とりあえずC++を使ってるんだったらこんな感じでクラスを作って、
メインループの中でcurrentScene->step()を呼び出すようにすれば、currentSceneの
中身を入れ替えるだけで各場面を行ったり来たり出来るようになると思います。
933932:04/04/01 03:09 ID:ree+3Ujs
あっ、かぶった
934929:04/04/01 03:44 ID:KHDslUNr
皆さん親切に御指導ありがとうございます。
とりあえず、皆さんに教えてもらった方法を実践したいと思います。

本当にありがとうございました。
935名前は開発中のものです。:04/04/03 11:35 ID:CEwxIkew
>>932
そのポインタのあぶねー使い方をやめろ。
936名前は開発中のものです。:04/04/03 13:07 ID:RGZrBuJ3
>>935
とりあえず対案を提示してみてくれ。面白そうなので。
937名前は開発中のものです。:04/04/03 20:39 ID:CEwxIkew
>>932
>Scene *currentScene; // グローバル変数
こんな怪しいものじゃなくて、管理クラス用意しろ。
938名前は開発中のものです。:04/04/03 21:11 ID:BY5/8S1M
>>937
で、その管理クラスを用意する利点はどこら辺にあるの?
939名前は開発中のものです。:04/04/03 23:12 ID:Z6SyAO1f
後々の拡張に強いしバグの元にもなりにくいからだろ
てか、いちいち食ってかかるような手間じゃないと思うんだが
940名前は開発中のものです。:04/04/04 01:27 ID:2FxHnCxP
>>938
まあ、>>939の言うとおりだ。
もちろん、管理クラスを作っても、
インスタンスをグローバルにおいちゃったら駄目だぞ。
941名前は開発中のものです。:04/04/04 07:03 ID:RKul7yqW
>>932
まぁ、最低限インスタンスがないときは、NULLポインタで明示する
ような簡単な仕組みは必要かも。管理クラスのメンバーか
グローバルかってのは、あまり危険度と関係はないとおもわれる。
ようはちゃんと使用前にインスタンシエートされ、使用後にかたずけられる
ことさえ保証されていればいい。管理クラスのコンストラクタ・デストラクタ
でちゃんとやってなかったら結局危険なのには変わりはない。

Scene *currentScene = NULL; // グローバル変数

init(){ currentScene = new Scene; }
purge() { if( currentScene ) delete currentScene; currentScene = NULL; }

942名前は開発中のものです。:04/04/04 07:17 ID:K1YqnP+3
> インスタンスをグローバルにおいちゃったら駄目だぞ。
え、じゃどうすんの??

・pImplで?
・シングルトンで?
・メソッドの引数渡しのみ

上二つはほとんど同じだしな
下みたいな徹底は果たして可能なのか?
943940:04/04/04 14:54 ID:2FxHnCxP
>>942
もちろん「メソッドの引数渡しのみ」。
キチンと設計ができていれば、問題ないはずだよ。

また、「メソッドの引数渡し+受け取ったポインタのメンバ保存」もホントはしちゃ駄目。
必要ならその都度引数で渡してもらう。

徹底は可能かどうかってのは、その人次第だから勝手にしてくれ。
ちなみに俺はできてるよ。
944931:04/04/04 15:12 ID:F19YKyuz
簡単なのが良いと思ってStateパターンを使った方法を紹介したんだが
色々言われてるな(^_^;)
キチンと拡張性を考えるんだったら、遷移テーブルを作ってシーンオブジェクトが
終了するときに返すリターンコードで次のシーンを決められるようにしたほうが
いいと思います。各シーン間をつなぐインターフェース役の関数なりクラスを
ひとつひとつ書く必要があるんでちょっと面倒ですけどね
945940:04/04/04 15:15 ID:2FxHnCxP
ところでさっきの話題だけど、
管理クラスを作ってもScene *currentScene = NULL;←こういうの作って
使いまわすってことは関数内でのみで完結するならやるけど
普通はやらないよ。(※)
処理的にも ポインタに突っ込む=カレントのチェンジ とするよりも
カレントのチェンジ処理をする場所を固定しておいて、
次のカレントチェンジのリクエストを出して、
カレントのチェンジ処理のところに来て、はじめてカレントのチェンジ処理を
実行するってしたほうがバグが出にくいんじゃないかな。

※糞設計にぶちあたって使わなきゃならないときもあるけど。
 そのときはリスト・ツリー構造のくせに個々を識別するIDが無い。
 配列で管理してるくせに時と場合によって順不同になる場合。とかだけかな。
 ちなみにこーゆー場合は使うしかない。と思うw。
946名前は開発中のものです。:04/04/04 21:08 ID:v1VWQRb5
おまいらスレタイ読め
「初心者のためのゲームプログラミング」だぞ
俺は質問した香具師じゃないが、初心者の俺には全く意味分からん

シングルトンって何?遷移テーブルって何?
(…いや別に知りたくなったら自分で調べるから教えてくれなくていいけどさ)

とにかく説明してくれるんなら、
もっと分かりやすく簡潔に教えてあげてくださいよ、先輩方。
947名前は開発中のものです。:04/04/04 23:05 ID:ENOyCk/Q
遷移テーブルってのは、
1: タイトル画面 時間経ったら2へ スタートは5 オプションは3
2: デモ画面 終わったら1へ
3: オプション画面 EXITは1へ 操作コンフィグは4へ…
みたいの。

シングルトンてのわぁー、なんだ、
二ついらない一つでじゅうぶんなオブジェクト(うまい例が思いつかん)を、
一つだけ作るっていちいち覚えとくのがマンドクセので、オブジェクトに自分で何とかさせるd。
948名前は開発中のものです。:04/04/04 23:56 ID:8gl5+fjo
遷移テーブルってこういうののことか?
ttp://www.interq.or.jp/moonstone/person/del/seki_00.GIF
949名前は開発中のものです。:04/04/05 00:33 ID:CGA6pWZs
>>946,947
二つ要らないというか、あったら困るオブジェクトといえば入出力。
950名前は開発中のものです。:04/04/05 01:16 ID:2yX+Kvf5
>>944
キチンと拡張を考えるなら
シーンを複数同時に再生できるようにするね。俺なら。
ゲームでは別々の世界(シーン)を同時に動かさなきゃならないなんてのがよくある。
画面に映すものはアクティブなカメラによって決定する。
こうすれば、クロスフェードや2画面以上のプレイなんかの設計も楽だ。

さらに次のシーンのロードを別スレッドで処理できるようにして
先読み処理なんかも入れられるようにするとこの辺は煮詰まってくるかな。

まだまだ修行がたりねーよ、にーちゃん。
シーンをネストのあるタイムラインとして考えればどう設計すればいいかはわかってくるはず。
Flashとかモデリングソフトのアニメーションツールさわってみなはれ。
951942:04/04/05 10:25 ID:LanhLWmn
>>943
サンクソ

引数のみならず、ポインタ(オブジェクト)の保存もなしか?
# ハンドルオブジェクト(ユニークなIDを保持したもの)での保存もなしなのか?

しかし、徹底できたときのことを考えると、挑戦しがいははありそうだ
952名前は開発中のものです。:04/04/05 17:22 ID:svTBfR1P
VCでプログラム組み始めてから1週間ほどになります
>>30への猛批判を見てたら、DirectXでゲーム作るのって難しいんだなって思ってたけど、
自分にあったライブラリを使ったら結構イケるものなんですね
簡単なゲーム(?)だけどできました。この調子でブロック崩しに挑戦してみます
953名前は開発中のものです。:04/04/06 04:46 ID:SYKT3ZhJ
>>950
任意の時点で画面に表示されている全体の事象を「シーン」として
考えたほうがいいんじゃなかろうか?つまり絶対唯一のものとして定義するの。

ていうかそうしないで、シーンがネストするーとか言った途端にいったい何が「シーン」で
何が「シーン」でないのかわからなくはならないかな?
954名前は開発中のものです。:04/04/06 06:01 ID:SYKT3ZhJ
>>929
何が一般的かといえば、ループはひとつだけ、
抽象化階層のできるだけ上に置いて、そのループの中で
UpdateFrameとかRenderとかいった名前がついたメンバの画面更新メソッドを
呼び出していくのが一般的だよ。某有名FPSもそうなってました。
955名前は開発中のものです。:04/04/06 06:09 ID:RiJS7OfK
バウンディングボックスの含有関係からなるN分木で構成するのが素直かも。
ルートノードを、グローバルか別クラス内のメンバーのどっちに置くかは
実装次第で素直なやりかたでいいと思う。

class CSceneGraph
{
 vector< CSceneGraph > childs; // N個の子ノード
 CMesh*    pMesh;
 ...
};
956名前は開発中のものです。:04/04/06 06:54 ID:mn+0E41T
>>953
色々考えたことがあるけど
1つの世界を構成するのに必要なセットをシーンと
考えた方がわかりやすいので絶対唯一のものとすると
どうしても手詰まりになる。
ちなみに俺の考えるシーンはカメラがあってそこに映る世界があってこれで1つのシーン。

RPGなんかの動作だとワールドマップからステータス画面へなんてので
ワールドマップで1つ、ステータス画面で1つって感じで2つのシーンを用意しておく。
ワールドマップのシーンの動作を停止したまま、ステータス画面のシーンを動作させる。
ステータス画面のシーンを止めた後、ワールドマップのシーンの動作を開始する。
と、こんな感じで使う。

絶対唯一のものとした場合だとこの動作が1つのシーンの管轄内になるということなので
結局、俺の考えるシーンと似た概念が他に必要になるだけだと思う。
957名前は開発中のものです。:04/04/06 08:46 ID:SYKT3ZhJ
>>956
>シーンと似た概念が他に必要になるだけだと思う。
カメラと一対一の関係が必要なものなのであれば、それはビューと呼ぶことを提案しますよ。
シーンという名前はもっと全体的な概念のためにとっとこう。
そうしないとDirect3Dのマニュアルが読みにくくなるよ?
958名前は開発中のものです。:04/04/06 09:47 ID:hOijVEpi
キミたちは学生ですか?
959名前は開発中のものです。:04/04/06 11:18 ID:xIK77TWb
ビューは別物だろう。シーンはシーンでそ。シーングラフって言葉もあるし。
960名前は開発中のものです。:04/04/06 16:10 ID:mn+0E41T
>>957
いや、カメラと1対1というわけではない。

>>958
学生の作るものではこんなことは必要にならないだろ。
961名前は開発中のものです。:04/04/06 16:52 ID:ngSbzNus
おまいらスレタイをもう一度よく見たほうが良いぞ
962名前は開発中のものです。:04/04/06 17:15 ID:mn+0E41T
      「初心者のための」
           ´´
    ○/   //
   /|/  Σ
    |
963名前は開発中のものです。:04/04/06 17:39 ID:DsC04TsX
そーいや、Hotate's Coreが閉鎖(?)したな。
何でだろ?
964名前は開発中のものです。:04/04/07 03:56 ID:Ui7ZoJNN

   ∧_∧
  ( ;´Д`)               三三三三三三三 「初心者のための」
  (   つつ 
 r´ヽ ヽ
 し´ (_)
965名前は開発中のものです。:04/04/07 10:11 ID:OLcSXc4Q
Scene *currentSceneに代入しようとすると警告でませか?
そして、この警告は実に正しい。
966名前は開発中のものです。:04/04/07 11:01 ID:vzicT/hF
10 rem
20 print "OK"
30 end
967名前は開発中のものです。:04/04/07 11:54 ID:nJz78kEH
remってなんの命令文なんですか?
見たことないな・・・
968名前は開発中のものです。:04/04/07 12:49 ID:6DasGiQp
>>967
たしかコメントのためのだった希ガス
969名前は開発中のものです。:04/04/07 14:26 ID:t0mds04p
BASICのコメト???

and or の&& ||みたいなもんで
「rem」の省略形が「'」なのか。
970名前は開発中のものです。:04/04/07 20:41 ID:zIqvWm7A
/*
昔のBASICで「REM」でコメントを書くと「'」より実行速度が速くなるとか書いてあったよね。
*/
971名前は開発中のものです。:04/04/07 22:50 ID:6DasGiQp
そのコメントをC風の/**/で書いてる貴方がステキですw
972名前は開発中のものです。:04/04/08 13:59 ID:r6Mgi8cJ
以後、ここは「老人のためのゲームプログラミング」スレになります。
973名前は開発中のものです。:04/04/08 21:46 ID:/mitHwmx
ばぁさんや、バージョンアップはまだかね?
974名前は開発中のものです。:04/04/08 21:56 ID:J2Kq5kWi
おじぃさん、さっきアップされたばっかりやね
975名前は開発中のものです。:04/04/10 06:37 ID:N0rIs2WL
ばぁさんや、キーボードはどこかね?
976名前は開発中のものです。:04/04/10 12:11 ID:pNKABB3n
あらやだわおじぃさんたら。キーボードなら今自分で打ってるじゃないですか。
977名前は開発中のものです。:04/04/10 17:16 ID:9BVc8On1
おじいさんや、次スレはまだかね
978名前は開発中のものです。
c fragment of Fortran program
integer i,x
do i=1,10
x=1.0/real(i)
if(x.lt.0.5) then
goto 100
endif
enddo
100 continue