親父PGがゲームを作り始めるスレッド
■ このスレッドは過去ログ倉庫に格納されています
0001親父PG
04/03/30 02:40ID:phIrC7nNC++やC、アセンブラは昔こなしたし、プログラムの事なら自信はあるけど
ゲームは作った事が無い方。現場からも引退したし(w。
ここは一つ趣味でDirectXでも勉強して、ゲームでも作ってみようかなぁと思った、
オジサンPGのスレッドです。
一緒にマターリライブラリから作りませんか?
0002親父PG
04/03/30 02:48ID:phIrC7nNhttp://www.microsoft.com/japan/msdn/directx/downloads.asp
C++
http://www.microsoft.com/japan/msdn/visualc/
0003名前は開発中のものです。
04/03/30 02:54ID:aArzpmzM0004親父PG
04/03/30 03:15ID:phIrC7nNVisual C++ .NET Standard 2003 通常パッケージ 19,800円
アカデミック パッケージ 7,800円
最初の半年の目標
SDKをざっと読む
開発環境を整える
デモをコンパイラする
スケルトンの作成
ここからは目的に応じて多少変化すると思いますが....
タイマー、スケジュール、ポーリング部分をどのように設計するか検討する
上を設計した上で、最小単位のオブジェクトクラス(最初のメンバはLife)を設計
オブジェクトの番号を管理するクラス設計
グラフィック関連
文字関連
テクスチャ関連
マウス・キーボード関連
ビューポート関連
メッシュ関連
ライト関連
STL(動的配列関連)※クラス設計に大きく関係する DirectXとは直接関係ないけどね。
とりあえずこの辺までは共通事項かなぁ。追加があればご指摘ください
0005名前は開発中のものです。
04/03/30 03:43ID:Pg71ArARC++とかでブイブイやってたんなら、オープンソースのDirectXライブラリ持ってきて
まず何かゲームを作りつつライブラリを解析したほうが良いと思う。
パソコンを勉強するおじ様方に多いけど、本だけ読んでもあんまり身につかないからねぇ。
実際に動かして、動きを見ながらソースをトレースして理解したほうが本読むより早い。
ていうかC++なら0円でIDEも揃うけど。DEV-C++とかEclipseとか。
VC系が必要になるのはポトペタでデザイン作るときだしね。
0006親父PG
04/03/30 04:08ID:phIrC7nN早速レスありがとう
>パソコンを勉強するおじ様方に多いけど、本だけ読んでもあんまり身につかないからねぇ。
既にそのレベルは超えてもらわないと話が進まない^^;
スケルトンぐらい(質問はしてもいいけど)自作作成できないとおそらく
オープンソースライブラリなんて使いこなすのは無理でしょう。
>オープンソースのDirectXライブラリ持ってきて
>まず何かゲームを作りつつライブラリを解析したほうが良いと思う。
これは一旦自分で(調べて作って)解析した後でないと、かえって理解が遅くなると思います。
まぁあくまで持論ではあるのですけどね。
DirectXの動きを理解してからライブラリからコツコツと、それも楽しみの一つですから...
[最低でも問題のSDKのHELPは調べる]
親父PGに限った事ではないと思いますが^^;
0007名前は開発中のものです。
04/03/30 08:25ID:nseNUF3n大分前、SDKのみの自前描画で簡単な3Dモデルを表示してみた。
ちょい前、DirectXを覚えようと、とりあえず突貫工事で
Xファイルを表示してキーボードで移動させてみた。
いろんな所からサンプル拾ってほとんどコピペしただけ。
次はスキンメッシュのサンプルをどっかからパクって組み込もうと考えたが
わけ分かんなくて挫折。
最近、TCPとWinsockでS/C型の簡単な一対一チャットを作ったが、
一対多のやり方がワカンネェので挫折。
先週、暇だったからテトリス作ってみた。初めてのゲーム。
ライブラリ?クラス?なにそれ。
分割コンパイルすらままならない、道しるべが欲しいそんなダメオジサン。
0008名前は開発中のものです。
04/03/30 09:44ID:B2V5bL2qそれより親父さんよ
この板にはたくさんの厨がいる
そいつらは開発ってのを分かっていない
ここは一つ、お前さんが連中を管理してゲームを完成させるスレとかにしてみたらどう?
0009名前は開発中のものです。
04/03/30 09:46ID:1T5XDq7M0010親父PG
04/03/30 11:25ID:nbxm21Tx歓迎いたしますよ! 何か出来たことを報告してくれると、盛り上がって良いと思います
>>8
>この板にはたくさんの厨がいる そいつらは開発ってのを分かっていない
私の個人的な意見を言わせていただければ、もしPGの事が解って無くても
また、開発の事がわかってなくても、なんというか、「組立てるセンス」あれば
ある程度の事はできると思う。それは他の事でも物事を組み立てて考える力さえあれば、PG習得もその応用にすぎないからなのです。
PGには3つの壁があり、
プログラム理論ロジック習得の壁 if for
言語そのものに対する知識の壁 C++ int
環境に関する知識の壁 Windows DirectX
があると私は思っています。これらを分けてひとつひとつ知識のリンクを、つないで行けば自ずと光が見えてきます。
>ここは一つ、お前さんが連中を管理して...
そんな大それた事はできませぬ^^
参加したいのであれば年齢は問いませんが、姿勢は問いますよ。
>>9
>みんなリストラされたのか?
あはは、冗談きついなぁ。
取り合えずSDKのサンプル「三角形を回す奴」をコンパイルして実行する事
これが出来ないと先へ進めません。
回る三角形ができたら、これを四角形にする(頂点数の変更)
FVFフォーマットを変えて実験してみる。
テクスチャを張り込むにしても4画ポリゴンは基本となるので、
まずはここまでを目標にしましょう!!
0011名前は開発中のものです。
04/03/30 12:12ID:EfGGMHLP>言語そのものに対する知識の壁 C++ int
>環境に関する知識の壁 Windows DirectX
計算機の動作原理の理解に対する壁が抜けてるな。
0012名前は開発中のものです。
04/03/30 12:26ID:QXrCIhNoCPUアーキテクチャなんかは知らなくても
とりあえず何かは作れるんじゃないか?
もちろん、知っておいたほうが質の良いコードが書けるだろうけどね。
0013親父PG
04/03/30 12:47ID:nbxm21Tx偉そうな事を言える立場ではないですが、書き込みの内容を拝見するに 基本的なプログラムの技術をお持ちだと思いますので、ますはSDKサンプルの
ライブラリを見てDIRECTXの初期化とWINSOWSループあたりを見てみると良いのではないでしょうか?
WINDOWSのサンプルは描画速度はマシン速度(環境)に依存しています。
このままでは定期的な処理ができないので、PeekMessage周りを調べて定期的タイマーで特定の処理を呼び出すようなものを作ってみてはどうでしょうか?
while( WM_QUIT != msg.message )
{
if( m_bActive && m_pd3dDevice != NULL ){
if ( tTake==FALSE ){
QueryPerformanceCounter( ( LARGE_INTEGER * )&sTIME );//時間計測開始
FSP60call();//同期して動かすものはここで
}
FSP60nonSYNCcall();//何か出来ることあればやってしまおう
}
th_GetandPeekMessage( NULL );//Peek Message func
if( bGotMsg!=TRUE ){
if( m_bDeviceLost ){
// Yield some CPU time to other processes
Sleep( 100 ); // 100 milliseconds
}
if( m_bActive && m_pd3dDevice != NULL ){
if( FAILED( Render3DEnvironment() ) )SendMessage( m_hWnd, WM_CLOSE, 0, 0 );
QueryPerformanceCounter( ( LARGE_INTEGER * )&eTIME );// 計測終了
DWORD wTIME;
wTIME=( DWORD )16666;
if ( ( eTIME.LowPart - sTIME.LowPart )>wTIME ){
tTake=FALSE;
}else {tTake=TRUE;}//endof if
}
}
私が自作した部分ですが、サンプルのソースに試行錯誤を繰り返しこのような形になりました。
0014親父PG
04/03/30 13:12ID:nbxm21Tx>計算機の動作原理の理解に対する壁が抜けてるな。
理解に必用なヒントがあれば是非紹介してください。^^
これはネタとして昔やったアセンブラの事を紹介します。
PUSH AX
PUSH BX
PUSH CX
CALL fanction
function:
MOV BP,SP
MOV SS,AX
MOV AX,ES
;スタックポイントへのアクセス
MOV DX,ES:[BP+0]
MOV AX,ES:[BP+2]
このような形でスタック上の価(引数)にアクセス....
80186(V30)のころのスタックフレームへのアクセス方法です。
いまやアドレス空間幅は32ビットに広がり、
このようなことは必要ありませんが(W
かつてはCPUの動作を知らないとPGが書けなかった時代がありました。
現代の目で見ると、私の書いたような事はもはや御伽噺になっておりますなぁ...
0015名前は開発中のものです。
04/03/30 13:22ID:kPTgeVBo懐かしいな、もうそこらへんのことはすっかり忘れたよ
今やれといわれても資料読みつつじゃなきゃ絶対無理だ。
>>11は親父PG氏に計算機の動作原理の理解がない、と言ってるんじゃなくて
3つの壁じゃなくて4つの壁ではないか?と提案してるんじゃないか?
少なくとも俺はそう読んだ
まぁ計算機に関する理解は環境に関する理解に含まれると思うけどね
0016名前は開発中のものです。
04/03/30 13:26ID:KRMwobBh0017名前は開発中のものです。
04/03/30 13:41ID:kPTgeVBoQueryPerformanceCounterで取ってきた値を1/1000msecとして扱ってるが
その値は思いっきり環境依存です
環境によってはバグります
あと、LARGE_INTEGERのLowPartのみ比較はやめたほうがいいです
QueryPerformanceCounterから取得した値がなぜ64bit値なのか考えましょ
あえて荒らしにも反応しとくけど
>>16
この程度読みづらいならおまえの能力が低すぎ
0018親父PG
04/03/30 13:47ID:nbxm21Tx>11は親父PG氏に計算機の動作原理の理解がない、と言ってるんじゃなくて
私もそうとってますよ^^;
11氏が提案する部分で、具体的な話があれば是非紹介して欲しいなぁと思って...
>>16
すんませんorz 自分でも汚いと思っております(反省
訂正
違
MOV SS,AX
MOV AX,ES
正
MOV AX,SS
MOV ES,AX
ネタとは言え恥ずかしい....orz
価の移動は右から左だった。
というかセグメントレジスタに、直接価が入れられない制約があったんだよね。
(なんかまだ間違ってるような気がするけど、深く考えないようにしよう)
まだ取り組んでいませんが、シェイダーの扱いで一部アセンブラライクなものが
あるみたいなので、アセンブラの知識が(一部)役に立つかもしれません(笑
0019親父PG
04/03/30 13:52ID:nbxm21Txおお! 御指摘ありがとうございます早速、修正させてもらいます。
とはいえ
>QueryPerformanceCounterで取ってきた値を1/1000msecとして扱ってるが
>その値は思いっきり環境依存です
このあたりを解決するには調べることがありそうですね。
頑張ってみます^^
0020名前は開発中のものです。
04/03/30 14:23ID:kPTgeVBoQueryPerformanceFrequency使うと調べられます。
なお、高分解能パフォーマンスカウンタは今までサポートしていない環境を見たことがありません
(CEも業務で数種扱ってますが全て使えました)
あと、使う値はLONGLONGで定義してキャストするほうが楽です
こんな感じ
LARGE_INTEGER llStartTime, llEndTime;
LARGE_INTEGER llCounter;
DWORD dwTime;
DWORD dwKeta = 1000; //ここを好きな桁に変更してください。1000だと1msec単位、1000000で0.001msec単位
bRet = QueryPerformanceFrequency((LARGE_INTEGER*)&llCounter);
〜略〜
QueryPerformanceCounter(LARGE_INTEGER*)&llStartTime);
〜略〜
QueryPerformanceCounter(LARGE_INTEGER*)&llEndTime);
dwTime = (DWORD)((llEndTime - llStartTime) * dwKeta / llCounter);
0021名前は開発中のものです。
04/03/30 14:33ID:kPTgeVBoLARGE_INTEGER llStartTime(略)→LONGLONG llStartTime(略)
に直してください
0022親父PG
04/03/30 15:29ID:nbxm21Txなんだかありがたいなぁ。
悪いねぇ。。。。orz いろいろ教えてもらって^^;
他の方にも参考になると思います。
こういうレスがついてくることを、内心期待してはいましたがほんとにくると嬉しいです。
これからもいろいろと私にできる情報を提供使用と思います。
高精度タイマーが使えない環境はない! と私も決め打ちしています。
このへんは「ゲーム」という事で許される範囲ですかね。
高精度タイマーが動かなければ、おそらく他のゲームも動かないでしょうから^^
wTIME=( double )16666;
//駄目コード if ( ( eTIME.LowPart - sTIME.LowPart )>wTIME ){
if ( double( eTIME.QuadPart - sTIME.QuadPart )>wTIME )
安易にこんなことしてましたが、>>20の書き込みも参考にさせていただきます。
0023名前は開発中のものです。
04/03/30 21:24ID:OjGk+Cgxあとこっちは余計なお世話かもしれんが、高精度タイマなんて使わなくても
timeGetTimeあたりで十分な気もする。
(タイムスライスの精度的に、どうせどこかでぶれるんだから。)
0024親父PG
04/03/30 22:38ID:phIrC7nNご指摘ありがとうございます。
確かにtimeGetTimeの精度を一番上げた状態でも十分ではあると思います。
先にあげたソースでは実装していませんが、計測した値の差と基準となる
値を割り算して(wTIME)基準値に対して、もし遅れが出ているようなら
その値を移動係数に掛けるといった処理も、視野にいれてQueryPerformanceCounter
を選択しました。(正しいかどうかは別にして)
ところでtimeGetTimeの正体は何なのでしょう。
いわゆる昔からあるあの「ハードウェアタイマー割り込み」なのでしょうか?
OSの内部的なタイマーという解説がありますが、その内部的なタイマーとはなんぞや?
IRQ (Interrupt Request)使うアレなのだろうか...
少なくともQueryPerformanceCounterは昔からあるHWタイマーではなさそうですね。
(分解能からして、昔は無かったし<-コレ重要)
さて
QueryPerformanceCounterとtimeGetTimeはどっちが処理が重いのだろうか?
timeGettimeの精度を上げた状態とはどういうことが起きているのだろうか?
単純に精度高い=処理が重い と決め付けるわけにもいかないと思います。
いろいろと疑問が湧いてきますねぇ。
(タイマーだけで1スレ潰してしまうな、こんな話始めたら(笑 )
0025名前は開発中のものです。
04/03/30 23:07ID:bI3miJwX単語の頭と、単語と単語の切れ目は大文字っていうルールでコーディングしてるんだったら、一貫してくれないと読みづらいね。
FSP60nonSYNCcall は FSP60NonSyncCallみたいに・・・・。
0026名前は開発中のものです。
04/03/30 23:25ID:OjGk+CgxQueryPerformanceCounterを含む時間管理についてはこの辺が参考になる。
ttp://www.dwahan.net/nyaruru/programming/programming.html
ttp://www.gamedev.net/community/forums/topic.asp?topic_id=195892
あと、環境によってはQueryPerformanceCounterが300ms以上帰ってこないという現象もあるらしい。
ttp://home.att.ne.jp/yellow/hide_n/old.html
の2001/11/12。
上のURLにある問題点と関係してるのかも。
>>25
全角スペースインデントするなら、ちゃんとやれってことじゃない?
0027名前は開発中のものです。
04/03/30 23:32ID:fcRSAwJmを、実数で持ってたほうが何かと便利かも。おじさんの頃はFPUが遅かったので
固定小数点命だったろうけど、今じゃ、バリバリ浮動小数点使います。
Real fInversedFrequency;
LARGE_INTEGER liPrevCount;
void init( void )
{
LARGE_INTEGER liFrequency;
bResult = QueryPerformanceFrequency( &liFrequency );
errorCheck( !bResult ); //カウンターサポートなし。
fInversedFrequency= 1.0f / Real ( liFrequency );
liPrevCount = 0;
}
void gameLoop( void )
{
LARGE_INTEGER liCount;
Real dt; //凾 (sec)
QueryPerformanceCounter( &liCount );
if( liPrevCount != 0 ) {
dt = Real( liCount - liPrevCount ) * fInversedFrequency;
} else {
dt = 0;
}
処理:UpdateAI(), Render(), etc.....
}
■ このスレッドは過去ログ倉庫に格納されています