1 :
名前は開発中のものです。 :
2013/08/12(月) 08:07:30.67 ID:RPqvnGkC
>>1 乙
ゲームの解像度を640×480から1280×720に変更したら、画面が広い広い。
そして縦長画面のゲームを作るんですね
つ [ピボット機能付きLCD]
std::vectorのポインタってどうやってかっこよくランダムアクセスできますか? (*vectorArrayp).Size() //ださい (*vectorArrayp)[i]->GetHoge //ださい ↑こんなんでなく↓こんな感じで2行目の方法がよくわから vectorArrayp->Size() //かっこいい vectorArrayp->[i]//???
stl とかあまり使ったことないけど、こんな感じで行けるんじゃなかったか vectorArrayp->at(i)->GetHoge あまりかっこよくはないが
GetHogeに括弧がないのが気になる
コンテナをあまりポインタで扱ったことないけど、 defineかtypedefで何とかならんか?
templateでいいじゃんよ
11 :
名前は開発中のものです。 :2013/08/14(水) 12:35:23.18 ID:UHvAELVl
pv[0][i]->m() ちょっときもちわるいな
クラスのポインタに入れて渡すか参照渡しを使うことが多いので配列をポインタにして使うってあんまり無い
>>5 標準ライブラリを使うのは標準化を指向してるからだろ?
なら美醜の感覚(主観)を抑えた方がいいんじゃないかな
初心者の内から美意識に拘るのはハマり道の入り口だし
>>12 接触した相手を、接触判定クラスから通知する感じでvectorに突っ込んでるんですけどダメですかね・・・
俺も複数のオブジェクトを保持するクラス作っちゃうね。 インスタンスの管理もしたいし。 だから、vectorを直接渡すってのは殆ど無い。
>>14 クエリー結果のリスト(←線形リストではなく広義のリストね)を返す的な感じ?
非公開の(内部的な)やり取りならクエリー結果のリストを生のコンテナ(vector)で
ポンと渡すってのはアリじゃね?お互い身内同士だから結合度高くてオーケー。
お互いよく知らんもの同士、実装(リストがどんなコンテナに入れられてるか)を
知らない相手なら結合度を低めだから、vectorを仲介クラスにコンポジションするかな。
多分それが
>>15 の話かな
17 :
>>14 :2013/08/15(木) 23:35:39.49 ID:rZIVXUnn
難しくてよくわかんないです 具体的に言うと キャラクタクラスが個々で持ってる、接触した相手のvector配列があってそれに通知と称して相手を渡してます。 で、キャラクターは更新時に通知を見て自分が何にあたったかをその場で判断してリアクションを取ります。 class CCharacter{ vector<CCharacter*> PendingCollisionList; } class CollisionObjectList{ vector<CCharacter*> List; void Judge(){ for(size_t i=0;i<List.size();i++){ for(size_t t=i;t<List.size();t++){ if(接触判定){ List[i]->PendingCollisionList.push_back(List[t]); List[t]->PendingCollisionList.push_back(List[i]); } } } } } }
18 :
>>14 :2013/08/15(木) 23:37:47.67 ID:rZIVXUnn
インデントがああ
19 :
名前は開発中のものです。 :2013/08/16(金) 07:43:46.26 ID:5WkUq5kH
vectorをポインタで使うって話はどこいったの
20 :
>>14 :2013/08/16(金) 10:00:36.13 ID:XoAPOpvM
あ、こうでした void Judge(vector<CCharacter*>* PendingCollisionList){ for(size_t i=0;i<List.size();i++){ if(接触判定){ (*PendingCollisionList).push_back(List[t]); } } }
>>20 なぜ参照渡ししないのか??
変数・巻数の命名もなんかちょっとねえ・・・Judge?
それに、クラスのメンバ変数だけかと思ったらローカル変数まで先頭大文字だな
命名規則は人それぞれ そこにケチつけるのは間違ってる
リアルタイム処理でpush_backするのは頂けないなぁ。
push_back呼び出し毎でないにしろ、結構な頻度でメモリ確保する事になるし。
自分なら、最初からキャラクタ最大数分確保しておく。
で、本題だけど、vector<CCharacter*>を直接渡すんじゃなくて
vectorの入ったCCharacterListみたいなクラスを作ってそれをポインタなり参照なりで渡す。
それが
>>12-15 あたりで出てる話でないの?
毎度毎度出てくる話だけど、数百程度をpush_backしようが、 システム全体のベンチマークを取ると誤差程度も違いが出ない。 何となく時間がかかりそうだと、測定もせずに言い出す馬鹿が毎度涌くのは勘弁して欲しい。
何をもってリアルタイム処理と言っているんだろう
26 :
23 :2013/08/16(金) 22:13:24.73 ID:kN35STo7
マジか?と思ってテストコード書いた。デバッグモードでの結果だけど vector<int>でpush_back()100回後、clear()。このセットを10,000回 -> 432ms malloc()で4byte確保、直後free()。このセットを1,000,000回 -> 1785ms 開発中はデバッグモードでもコード走らせるし、 mallocの1/4程度じゃちょっと無視する気持ちになれないなぁ。 全てのキャラクター同士の衝突判定をすれば、階乗的に処理数が増えるし。 もちろんキャラクター数にもよるけどね。 やっぱり安全策をとって予め確保しておくことにするよ。
ほら、局地的にしか測定しない馬鹿だろう。 システム全体では測定不能な誤差に埋もれるレベルにしかならないという話をしているのに、 全然違うことをしている上にDebugで測定。 Releaseではご満足な結果が出なかったから仕方なかったんだろうけどさ。 メモリ確保が遅いとか吹聴するのは、毎度毎度こういうどうしようも無いクズばっかりだよ。
傍から見てる分には27の方がバカに見えるけどな。 1)自分では実際に計測せずに人のやり方にケチつけるだけ。 2)誤差の範疇かどうかは当人が決める事。
キャシャーンがやらねば、誰がやる!
他の人から突っ込みがあるかと思って待ってたんだけど、 出ないみたいだからもう一つ突っ込んでおくよ。 std::vectorでclear呼んでもメモリは解放されない。 つまり別のところで時間を食ってるだけ。 あまりにお粗末すぎないか?
あっ・・・
32 :
23 :2013/08/16(金) 23:37:24.36 ID:kN35STo7
>std::vectorでclear呼んでもメモリは解放されない。
らしいので計測。懐疑主義者がいるようなのでリリースモードでも計測。
新しく生成されたvector<int>でpush_back()100回。
このセットを10,000回 -> 1209ms(デバッグ) , 462ms(リリース)
因みに予め確保したvectorに0を1,000,000回代入 -> 94ms(デバッグ), 2ms(リリース)
うーん、都度のメモリ確保はやっぱり重いよ。
ID:NCVPitu3はこの質問スレで
>>14 をスルーして私のコーディングにしか興味が無いようだけど。
2chらしい煽り文句を着飾って私に何を言いたいの?
33 :
23 :2013/08/16(金) 23:42:05.26 ID:kN35STo7
質問スレじゃないな。失礼。
#include <Windows.h> #include <stdio.h> #include <vector> #pragma comment (lib, "winmm.lib") int main() { timeBeginPeriod(1); DWORD t = timeGetTime(); int i,j; for(j=0;j<10000;j++) { for(i=0;i<100;i++) { std::vector<INT> v; //v.reserve(100); v.push_back(0); } } printf("%d\n",timeGetTime()-t); return 0; } 試せば分かるが、そんな差は出ない。 clearの動作すら分かっていなかったし、書いているソースがおかしいだろう。
>>34 それ再確保動作行われないがただの typoか?
std::vector<INT> v; はループの外に置かないと、ただ毎回初期エクステントサイズで生成されてスコープアウトで解放するだけだよな。意味違う
もしも本当に勘違いしてるとして、一応補足しておくと、 vectorの確保領域は連続したメモリ空間に配置される事が保証されているので、 それを守るためには初期エクステントで生成(mallocのような動作)とfreeの動作だけでなく、増加させたサイズ分の確保とコピー(reallocのような動作)を再現しないと 多分話ズレるよ
#include <Windows.h> #include <stdio.h> #include <vector> #pragma comment (lib, "winmm.lib") int main() { timeBeginPeriod(1); DWORD t = timeGetTime(); int i,j; for(j=0;j<100000;j++) { std::vector<INT> v; //v.reserve(100); for(i=0;i<100;i++) { v.push_back(0); } } printf("%d\n",timeGetTime()-t); return 0; } たしかに間違い。 こっちで試してくれ。
何をどうやっても
>>32 のような462/2*1000000/10000=23100倍なんて差は出ない。
そうやってシステムに組み込まれたら、ほとんど分からなくなるような部分を、 ループで過剰に回して、さも全体にかかる負荷が大きいように吹聴するのが糞なんだよ。
そんなに気にするのなら毎回clear()したvectorを使うと良い 数が足りていりゃ何もしないし足りなければ追加で確保してくれる 最大オブジェクト数を設定してそのサイズに合わせるとかするよりはマシ そんなに使うかわからないのに初めからそんなに確保する事はない そのコード何を比べているんだ?push_backした時と一気に確保した時の違い? 最初に確保しておけば、毎回確保する必要がないって話ではなかったのか?話変わってね? stlのvectorってpush_back毎ではなくてある程度まとめて確保しているらしいが 1回数百バイト程度では毎回確保してもまあ誤差程度な気はする
ループ内で何もしないコードの実行時間とメモリ確保を繰り返すコードの実行時間を比べるのは意味不明
最初から確保しようが、std::vectorで動的に確保しようが、 数百程度のキャラクターのデータなら、 システム全体では誤差で測定不能になる程度の影響しか与えない。 首尾一貫して何度も言っているんだが。 大量にループを回してもせいぜい数倍程度しか差が出ない内容で、 ソースも出さずに23100倍の結果だけ書いていく頭の悪さは何なんだ?
結論的に、intのpush_backでは代入とほぼ同じくらいの軽い処理ってこったろ。
いつから、push_backとメモリ確保の話がごっちゃになってんだ?
ついでに、
>>37 のようなソースでは毎回同じアドレスからstd::vector<INT> vを割り当ててると思うので、
mallocのキャッシュが利いてるはず。これはあまりよろしくないメモリ確保の時間測定に見える。
ちなみにvectorって毎回のpush_backで毎回再確保&コピーはされないけど一定量越える度にコストがO(n^2)くらいの指数増加してくので、 予め上限がわかってたらreserve()するのが常套手段だよな
45 :
名前は開発中のものです。 :2013/08/17(土) 01:04:09.07 ID:gvLEj0CQ
mallocって同じアドレスだと速いの?
>>43 #include <Windows.h>
#include <stdio.h>
#include <vector>
#pragma comment (lib, "winmm.lib")
int main()
{
timeBeginPeriod(1);
DWORD t = timeGetTime();
int i,j;
for(j=0;j<100000;j++)
{
std::vector<void*> v;
//v.reserve(100);
for(i=0;i<100;i++)
{
v.push_back(malloc(rand()%100));
}
for(i=0;i<100;i++)
{
free(v[i]);
}
}
printf("%d\n",timeGetTime()-t);
return 0;
}
>mallocのキャッシュが利いてるはず。これはあまりよろしくないメモリ確保の時間測定に見える。
文句があるなら、自分でソースを出せよ。
で、具体的にmallocのキャッシュとやらを測定するソースを出してみろ。
当然、測定した上での発言なんだろ?
>>44 256で上限に達したら65536のコスト?
そんな馬鹿な実装のstlがどこにあるのか、後学のために教えてくれ。
ゲーム1フレーム内での数百程度のpush_backなんか気にすんなってのはID:zpg6JFDeと同意見だな ただ、プロのゲームプログラマになるのなら必ずしもSDKに付いてくるstd::vectorの拡張処理が効率的になってるとは限らないということを覚えておいてほしい reserveなんかいらねぇぜって思ってたらpush_backが毎度1個分ずつ確保する実装だったでござるっていうのもあったから
あほばっかw
for(j=0;j<100000;j++) { std::vector<int> v; //v.reserve(100); for(i=0;i<100;i++) { v.push_back(0); } } printf("%d\n",timeGetTime()-t); t = timeGetTime(); for(j=0;j<100000;j++) { std::vector<void*> v; //v.reserve(100); for(i=0;i<100;i++) { v.push_back(malloc(100)); free(v[i]); } } printf("%d\n",timeGetTime()-t); t = timeGetTime(); for(j=0;j<100000;j++) { std::vector<void*> v; //v.reserve(100); for(i=0;i<100;i++){ v.push_back(malloc(100)); } for(i=0;i<100;i++){ free(v[i]); } } printf("%d\n",timeGetTime()-t);
reserve無し 171 882 1123 reserve有り 36 746 984 約1.3倍速い
いったいmallocのキャッシュって何のことだ vector::reserveのことなのかmallocに魔法があるとでも
53 :
名前は開発中のものです。 :2013/08/17(土) 08:49:58.66 ID:gvLEj0CQ
>>51 その結果見ると140ms程度がreserveで改善されてるって感じじゃないの
1回あたり140nsのオーバーヘッド
1フレームで1000回以上呼び出されるようなら無視できないレベルだと思うけど
push_backの使いどころってそんなにあるかね?
>>48 >reserveなんかいらねぇぜって思ってたらpush_backが毎度1個分ずつ確保する実装だったでござるっていうのもあったから
具体的にどのstl?
あるかもしれないではなく、「あった」と言っている以上、当然知ってるよね。
>>50 全然mallocキャッシュとやらの検証は出来ていないが、頭は大丈夫か?
そもそも人のソースじゃ無くて自分のソースを出せよ。
当然、以前に自分が検証したソースがあるんだろう?
>>53 140ms/(100000*100)=14ns
55 :
名前は開発中のものです。 :2013/08/17(土) 10:12:36.51 ID:gvLEj0CQ
夏ダナー
>>56 >mallocもreallocも、実装や実行時の状況次第で所要時間が変わるからコストを評価しづらい
だからシステム全体では誤差に埋もれる程度の差しかないと何度も言っているだろう。
実際にはやらないようなあり得ない数を回して、ようやく測定できるレベルなんだから。
そうね。
>>60 ps3といってもcellのコンパイラや流出したSDKなど色々あるんだが、
具体的にどのSDKのどのバージョン?
科学的な話のはずなのに何か宗教論争じみて感じるこの感覚・・・不思議!
push_back分のメモリが確保できない場合、新たな領域確保後、要素数N-1分コピーされるわけで、 このコストを無視出来るかどうかは、要素数にもよる push_backで確保できない場合、結局内部的には一定量(実装依存)reserve&コピーされていく。 (例えばVC2012でreserve数の変化は1 2 3 4 6 9 13 19 28 42 63 94 141という感じ) したがって要素数があらかじめ予想できるならば、最初からreserveしておけば無駄がない。 あらかじめ要素数が予想できない上に、リソースが潤沢なハードなら、reserveせずにvectorの実装に任せてもいいかもね。
おひおひwwwwww
またゎいトンのχ
>>42 >>数百程度のキャラクターのデータなら、
>>数百程度のキャラクターのデータなら、
>>数百程度のキャラクターのデータなら、
そんなに威張れる「システム全体」なんか?wwww
もどきの体裁を取り繕う程度の仕様なんじゃね。
短小首尾一貫カッコイイッスネwwwww
>>63 >このコストを無視出来るかどうかは、要素数にもよる
こういう発言の何が問題なのかというと、無視できなくなる具体的な数や状況を全く明示せずにソースの提示もしないこと。
そういった前提条件が無くなると議論のしようも無く、正しく宗教論争を起こすきっかけにしかならない。
ボードゲームのAIのアルゴリズムのminmax法って、 奇数手先(相手の手)を評価するの? それとも偶数手先(自分の手)を評価するの?
勝ちから逆算する学習アルゴリズムでない限り そのへん全ては自分で決めるもんだと思うよ
>>65 それを言うなら貴方の言う「システム全体」も漠然としすぎてるんじゃない?
「フルマラソンするには数リットルの給水が必要だ」と言ってる相手に
「通常生活おくるだけならそんなに給水は必要ない」って言ってるように聞こえるんだけど。
>>54 どこが検証できていないか具体例でよろしく。
第一自分のソースとか関係ない。
単純な繰り返しの場合、速く確保できてるのを示すだけだから。
reserveは行きがけの駄賃。俺なら最初に確保しとくね。
>>68 道路に微妙に落ちている砂を事前に払っておかないと、
マラソンのタイムに影響するという方が正しい。
そもそも毎フレーム再確保するという前提自体、
そうしないと完全に測定不能なほど小さい値だからやっているだけで、
普通のシステムなら初期化やシーン切り替え時に確保作業は終わっている。
シーンの切り替えに発生する数マイクロセカンドをどうやって測定するんだ?
そうなると何をどうやっても差が生まれないんだが、
無いものを無いと証明するのは悪魔の証明で不可能だ。
だったら差が生まれる前提条件を明示しないと議論しようが無い。
なぜあると言っている奴が、条件すら書けないんだ?
>>69 mallocキャッシュとやらが効いている場合と効いていない場合で、
結局どれだけ差があるのか数値化できていない。
結果から引き算で求めるというのなら簡単に論破する準備があるから、
具体的な数字をだしてみな。
なーにいきり立ってんだ? 実装によって異なるみたいだけどSTL自体のソース読めば済む話じゃないのん せめてやるならMSVCだとかWindowsだとか限定しないとねぇ…
>>71 限定するとあるある派の逃げ道がなくなるからあえて塞がなかったんだけど。
旧世代のPDAとかリソースが貧弱で、これだけ影響するぞっていうのを期待していたんで。
毎フレームメモリを確保し直すとかいうプログラムの目的は想像がつかないから実例を挙げる難易度は高いけど。
Windowsに限定したらそういうのが無理になるだろう。
>>72 やっぱり答えないと思ったよ。
mallocキャッシュとやらの有無による違いは具体的に何ms?
ノイズが多すぎて検証しようが無いよね。
そもそもmallocキャッシュって何?
ハード側のキャッシュメモリが働くのを期待しているということ?
それともmalloc自体に何らかのキャッシュ機構があるってこと?
>>73 単位はmsなんだから3番目から2番目引いたら出るだろ。
1000万回で(この場合はreserve関係ないけど)有り241msと無し238ms
そう。malloc自体になにかある。同じアドレスは速い。
>>74 やっちゃったね、引き算。
ループの数が違うから、最適化やジャンプに引っ張られて検証なんて出来ないよ。
ちなみにこれがmallocキャッシュという謎の機構では無く、 空いている領域をきっちり調べていることを示すサンプル。 事前にデータが確保されている数が多いほど、探索に時間がかかる。 これも数を極端にしないと、検証できないレベルだけどね。 int main() { timeBeginPeriod(1); int i,j; DWORD t = timeGetTime(); while(timeGetTime()-t > 2000);//CPU省電対策 /* std::vector<void*> v2; for(i=0;i<10000;i++) v2.push_back(malloc(100)); */ t = timeGetTime(); for(j=0;j<10000;j++) { std::vector<void*> v; for(i=0;i<10000;i++) {v.push_back(malloc(100));free(v[i]);} } printf("%d\n",timeGetTime()-t); return 0; } >そう。malloc自体になにかある。同じアドレスは速い。 心霊現象かよ。
>>75 t = timeGetTime();
for(j=0;j<100000;j++)
{
std::vector<void*> v;
for(i=0;i<100;i++){ v.push_back(malloc(100)); free(v[i]); }
//for(i=0;i<100;i++){ free(0); }
}
printf("%d\n",timeGetTime()-t);
t = timeGetTime();
for(j=0;j<100000;j++)
{
std::vector<void*> v;
for(i=0;i<100;i++){ v.push_back(malloc(100)); }
for(i=0;i<100;i++){ free(v[i]); }
}
printf("%d\n",timeGetTime()-t);
コメントあり
1082
1327
コメントなし
1120
1334
リリースモード、最適化・全体の最適化なしで。
コメントを外した場合、上のほうがfree(0);のコスト分だけ上乗せされるが、
実際はそれでも勝ってる。この結果はどうする?
>>76 んな妙なCPU対策しないで、倍率可変切れよ。ブレまくるだろ。
>>76 >>77 のソースのコメントを外し、1番目と二番目を入れ替え、間にさらに10倍した
std::vector<void*> v2;
for(i=0;i<100000;i++) v2.push_back(malloc(100));
を挿入しても
1344
1133
という結果で、多くても誤差範囲だったぞ。
>事前にデータが確保されている数が多いほど、探索に時間がかかる。
いや、stlの2倍ずつ増やすという例はあるが、いくらなんでもそういうアホな実装はしてないだろ・・・
>>65 たった100程度の配列でも、1ループに付き13回の全要素コピーと、40もの余分な領域が生じるというのに、
実測現れないという曖昧な理由でこれを無視出来るあなたは、ゲームプログラムから手を引くべきだと本気で思います。
まだやってるのか・・好きに組めばいいでしょ 第一スレチなんで他でやってよ
>>77 ループの中のコードを変えたらまともに測定出来ないから、
ループの中身をいじらない
>>76 の検証用のソースを用意したんだが。
まずはその結果に対する反証や、やり方がおかしいという意見は無いのか?
モチツケ(・∀・)
>>82 ソースはそのまま、リリース、最適化・全体の最適化ON
事前確保なし 7466
事前確保あり 7187
下二桁はぶれるが数十回測ってもだいたいこんなもん。
事前確保ありのほうが何故か速いが、逆に俺の援護になっちまったんじゃないのか?
すごいスレがのびてるとおもってたどって見たら俺のレスが起因だった
>>70 私はこの議論を楽しく読ませてもらってる。
以前にもnew/deleteのコストの議論があったと思うが、あれも面白かった。同じ人かどうかは知らないが。
しかし
>無いものを無いと証明するのは悪魔の証明で不可能だ。
これは間違ってるのでつっこんでおく。ネット上ではこの勘違いがとても多いんだ。
たとえば、「最大の素数」が存在しないことは証明されている。あるいはアリバイというのは「犯行可能な時刻に、犯行可能な場所に存在しなかった証明」に他ならない。
その他諸々、非存在の証明なんて普通にある。
「悪魔の証明」というのは「非存在証明の方が手続きがめんどくさいんだから、存在を確信できる人がいるなら、その確信できる理由を挙げてもらった方が話が早い」という程度の意味だ。
87 :
名前は開発中のものです。 :2013/08/18(日) 07:26:24.56 ID:RA3uDiJA
>>76 探索ってのはアロケートの空き領域探しの事?
そうなら断片化させまくったらメモリ確保の速度が低下する可能性が微レ存?
>>84 ではこれでどう?
プロセスの優先順位の調整と、回数ごとの揺らぎが分かるように変更。
#include <Windows.h>
#include <stdio.h>
#include <vector>
#pragma comment (lib, "winmm.lib")
int main()
{
SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS);
timeBeginPeriod(1);
int i,j,k;
for(i=0;i<10000;i++) malloc(1000);
for(k=0;k<10;k++)
{
DWORD t = timeGetTime();
for(j=0;j<10000;j++)
{
std::vector<void*> v;
for(i=0;i<10000;i++){ v.push_back(malloc(100));free(v[i]); }
}
printf("%d:%d\n",k,timeGetTime()-t);
}
return 0;
}
ちなみに私の環境の結果。 これで環境ごとに結果が逆転するようなら、私の力量では測定用のコードは書けない。 mallocに無駄がなさ過ぎる。 ・ダミーメモリ無し 0:5882 1:5639 2:5639 3:5643 4:5621 5:5619 6:5637 7:5628 8:5641 9:5637 ・ダミーメモリ有り 0:5770 1:5746 2:5745 3:5736 4:5746 5:5738 6:5749 7:5749 8:5727 9:5731
>>88 ソースはそのまま、リリース、最適化・全体の最適化ON
・ダミーメモリ無し
0:7833
1:7758
2:7827
3:7884
4:7803
5:7847
6:7854
7:7888
8:7839
9:7809
・ダミーメモリ有り
0:7503
1:7503
2:7500
3:7501
4:7501
5:7501
6:7501
7:7500
8:7502
9:7507
逆転する。が、メモリ確保したほうがえらい安定してる。
そうなると単純にキャッシュの問題ではないような気もする。
キャッシュから引いてるなら差は出ないはずだから。
おい Windowsには解放されたメモリ領域をキャッシュする機能はあるって 新しくメモリを確保する時も、以前に同じサイズの領域を確保していたら、そいつとアドレスが入れ替わるとかよくある reallocでサイズを変更した時は、メモリブロックを移動する必要がある時のみコピーが行われるんだって!常にコピーされるとみなしてコストを計算するのは誤り お前のプログラムはメモリ確保だけで出来てるのかよw 上限の確実に分かるような配列のみreserve 上限が分からなくとも、頻繁に使う配列はメモリを解放せずサイズを0にして再利用 これで十分だろ気にしすぎ
初心者だからわからないんだけど vectorに一度1000回push_backしたあとclearして もう一度1000回push_backした時ってすでにメモリが確保されてるから速くなるんだよね? じゃあゲームで 毎フレームclearしてからオブジェクトをpush_backしまくる設計でも じきに負荷が軽くなってくんじゃないの?
>>92 うん
何処かに取っておけば解放されず消えない
>>91 ごもっとも。俺としてはなんらかのキャッシュがあるというのが真実ならそれでOK。
>>92 なるよ。1000回push_backするとき実装によるが、たしか倍々でreallocするので
拡張できるときは
>>91 の言うようにコピーのコストはかからない。
最後に無駄なメモリを確保してしまうが、それ以外はreserveを最初にしたのと変わらないよ.。
ただし、push_backするのがintなどならいいが、内部でnewを伴うものを入れるときのコストは結構でかいので
ポインタで持つとか工夫が必要。
補足で。 >内部でnewを伴うものを入れるときのコストは結構でかい ID:+ZBVAlmgに言わせると、誤差範囲なので気にするなと言うだろうw 多少の速度を犠牲にしてもコードの読みやすさを重視するなら選択の一つとしても別に悪くない。 俺の場合はオブジェクトプールを作って、newのオーバーロードで毎フレーム生成してる事が多い。 これなら可読性を損なわず高速化できるし、生newとの比較も簡単にできるしリーク検出にも使えるし
オブジェクトをそのままいれるようなことはしないよ たぶん あと、クラスのコンストラクタで、シングルトンデザインの管理クラスに自身を登録するって設計は、他人からみてわかりやすい? はたからみると new CKurasu(); とだけ一行で収められててわかりにくかったりする?
コメントがしっかりしてればわかるだろうけど、 コンストラクタまで見ないと何をやってるかわからないというのは、こう、ねぇ?
98 :
名前は開発中のものです。 :2013/08/18(日) 21:31:50.22 ID:RUTCCsLR
外部仕様と例外処理がしっかりしてれば中身なんてどうでもいい 使うのに中身見ないといけなくてしかもクラス間の依存性高かったら舌打ちするかもしれん
>>98 それもそうか
でもクラス間依存が少ないクラス設計ってどういうの?
テンプレート使うとか?
100 :
名前は開発中のものです。 :2013/08/19(月) 12:35:04.86 ID:O9c9TTgh
クラスひとつが1機能で完結してるってのが理想だけどそれは無理だと思うから とりあえず相互参照とかfriendなければいいんでない ひとつのクラス読み解くのに芋づる式に謎のクラスが出てくるとうんざりする
ソース管理システム使ってると 小機能の修正なのに多数のソースにまたがる変更を見せられたりして 気分が悪い
現場ではよくあること
便利なはずの手段が逆に不便の原因になってるってヤツですか。
ロールとピッチで操作する戦闘機のゲームを作ってるんですが、AIの部分で 「あの座標に向かいたい!」ってなった時、どうしたらいいでしょうか? うまくいかなくて困っています。 1.ワールド座標で、目的地 - 現在地でベクトルを取得する 2.現在の戦闘機の回転をそのベクトルに適用し、戦闘機から見た座標にする 3.座標を見てyが+だったらピッチアップして、yが-だったらピッチダウンするとかで、目標の方向に向く 4.後は適当に前進してれば目標に近づく って感じなのですが、理屈が間違ってるのか、うまくいきません。 特に2番あたりで、思った通りのベクトルが出なくて・・・
1〜2だけだけど、 戦闘機の位置と回転を適用した「戦闘機ローカル座標系をワールド座標系に変換する行列」を用意して、 その逆行列で「ワールド座標系での目的地座標」をトランスフォームしてやれば、 「戦闘機ローカル座標系で見た目的地の座標」が得られる。
それって ワールド座標系の座標を戦闘機ローカル座標系に変換する行列とは違うものなのですか? 座標系っていうほど大層なものは用意してなくて、戦闘機の正面と右と上の軸しかもってないんですが・・・
あれ、なんかたしかにAIがしっかり期待通り動くんですけど 方向を画面に描画してみたら適当な所を指してるような・・・
くっだらない話で悪いんだけどさ。 atan2()で返ってくるラジアンを見て、いくつかのラジアンだけ特別な処理に回したい。 で、今のところあるラジアンと==チェックをしてるんだけど、やっぱりときどき誤差が出て==チェックがfalseになってしまうらしい。 すこし幅を持たせればいいと思うんだけど、こういう時の誤差ってどのくらい取ってる?
>>108 どのくらいってのはその時によるからあれだけど、そもそも1ラジアンって 180.0/PI だから少なくとも == で結ぶような判定はしないなww
なので幅持たせたかったら… 例えば 4倍くらいして切り捨てた値と比較とか?
この場合、円が90ステップで等分割されてる荒さでの比較になるけど。
今回は const double angle1 = atan2(35.0,69.0); みたいにいくつかのラジアンを定数で持たせてるんだ。 たぶんいくら小数型に誤差が出ると言っても、atan2(35.0,69.0)自体はいつも同じ答えを出してくれるんだと思ってる。 でも、atan2(35.0*n,69.0*n)の場合はそうとも言いきれないらしい。 こういう場合、どのくらい幅を持って判定したら安心できるかなって。
ソフトウェアの仕様による
113 :
名前は開発中のものです。 :2013/08/25(日) 17:46:26.97 ID:WJdUU9CG
角度を点で判定することが稀な気がする まあ小数点以下四桁くらいで切っとけば問題なく動くんじゃない? 根拠はないけど
一旦スパッと決め打ちして後で調節するのがいいと思う たとえば、その角度が 2Dのシューティングゲームで敵が弾を撃つ方向を表している と仮定する 角度が1度(π/180ラジアン)ずれた2発の弾の方向の差は 100ドット弾が進んだあたりで1〜2ドット変わるぐらい ( sin(π/180) * 100 ≒ 1.745) この精度が「荒すぎ」か「細かすぎ」かは、ゲームの仕様とか 作りたいものによって変わると思う
>>112 詳しい解説のサイトをありがとう。
ただ、私では理解できなかった・・・。
もうちょっとゆっくり調べてみる。
もっとこう、だいたいこのくらい幅取ればおk、みたいなのがあるかと思ってたら、そうでもないのね。
とりあえず、0.0000000001の幅を持たせて判定させてみた。今のところはうまく動いてる。
男だったらdoubleの精度限界まで突き詰めるだろ誤差はしらん
>>115 > もっとこう、だいたいこのくらい幅取ればおk、みたいなのがあるかと思ってたら、そうでもないのね。
あぁ?んなもんねぇよ
> とりあえず、0.0000000001の幅を持たせて判定させてみた。今のところはうまく動いてる。
じゃそれで良いだろ
FLT_EPSILONは?
規制が解けたの遅レス
>>106 > 座標系っていうほど大層なものは用意してなくて、
> 戦闘機の正面と右と上の軸しかもってないんですが・・・
この3軸を表すベクトルが90度ずつの角度になっていて、
更に正規化されていれば
ローカル座標系としてそのまま変換行列にぶち込めるはず。
(2軸を正規化してから外積出せば良いと思うけど)
ここのfor( int i=0; i<256; i++ )の256の意味がよくわからないので説明していただけないでしょうか int gpUpdateKey(){ char tmpKey[256]; // 現在のキーの入力状態を格納する GetHitKeyStateAll( tmpKey ); // 全てのキーの入力状態を得る for( int i=0; i<256; i++ ){ if( tmpKey[i] ==1 ){ // i番のキーコードに対応するキーが押されていたら Key[i]++; // 加算 } else { // 押されていなければ Key[i] = 0; // 0にする } } return 0; }
SetUseDirectInputFlag を true にしたら GetHitKeyStateAll の挙動って変わる? false と true で変わったように見えんのだけども
>>121 ありがとうございます
もうちょっと聞きたいんですがDXライブラリスレに行くべき内容なので
そこで聞いてきます
124 :
名前は開発中のものです。 :2013/08/29(木) 00:07:53.36 ID:hPTXRtdt
DirectInputはキーボード・マウス入力には使うなとMSが
ソース
126 :
名前は開発中のものです。 :2013/08/31(土) 23:27:46.86 ID:JzQWrW3K
ウィキペディ
OpenGL使ってるライブラリって2Dばっかりで、3D使うときはOpenGLの関数を 使ってねテヘみたいなやつが多いから、テクスチャ1枚用意するのも大変なんだけど DXライブラリみたいな3D関数が用意されたOpenGLのライブラリってないのかな
>>129 昔からあるSDLでもダメって話か?
てかテクスチャのローダなんてそんな大変だと思えないが
ライブラリというかフレームワークならいくつかあるでしょ。
>>130 SDLは、2Dですら画像を回転させようと思ったら
OpenGLの関数使って初期設定して、SDLのフォーマットで読み込んだ画像を
GLのテクスチャにフォーマットして、そのテクスチャを板ポリにUV座標指定して貼り付ける
ってところまでやらないとダメじゃない?
SDLってハードウェア支援使ってないんじゃないの windows版だったらただのwin32apiのラッパーなんじゃないの
具体的な実装や割合までは知らんが、 使えるところは使うって設計思想と聞いたような。
>>133 ライブラリのソースコードはマルチプラットフォーム対応するように書かれてるぜ
windows版ってやつはソースをwin用コンパイラでコンパイルして.dllのバイナリとして配布してるって意味だと思われ
>>134 ソース見てみると、一番最初に呼び出されるヘッダ部分で環境変数取得して、それからOSなどを判断して
defineマクロ駆使してそれぞれのmain()を書いてるっぽい(windowsならWinMain()が書かれてる)
ちなみにこの時点でDirectXが使えるならOpenGL使わずにそっちを使うようになるらしい、すごいぜ
回転させるライブラリあったと思うけど結局面倒になってOpenGLで回す
SDLはただのプラットホーム あの上にライブラリ構築したら移植しやすいよっていう土台 だから色々なライブラリがあって、回転のやつとか定番のがあった ハードウェア支援はあるぞ
フレームワークとかわからないところがあると調べても欲しい情報が見つからなくてどうしても質問厨になってしまうんだけど みんなはどうしてんの?
そんなもんじゃね?
フレームワークの公式フォーラムやStackOverflowで聞いたり フレームワークのソースを見たり
英語力が足りてないんだろう
142 :
名前は開発中のものです。 :2013/09/10(火) 21:27:09.56 ID:V2/hDCSO
英語のドキュメント数日かけて読み解くくらいなら俺は質問厨になる
せっかく掲示板があるんだから、情報共有しようぜ
ギブアンドテイクが成り立つならな 「ファイル共有ソフト」みたいなノリで 共有って単語を使うの止めて欲しい
2chの掲示板はまともな情報共有には向かない どちらかというと誰かの親切なメモなり落書きなりを見に来るものだろう
Twitterなんかよりはマシかなー?くらいだよね
>>142 数分とか1時間じゃなくて、数日かかるのか。
それであっても質問"厨"にはならないわ
148 :
名前は開発中のものです。 :2013/09/10(火) 23:15:47.37 ID:V2/hDCSO
>>147 A4のドキュメント一枚読み解くのに余裕で1〜2時間かかりますがなにか
辞書見てる時間の方が長くなる
頻出単語は自然と覚えていくから、次第に短くなるだろ。 これからの人生のためにがんばれよ。
それを意識しすぎるといつまで経ってもゲームが完成しない罠。
Google、Exciteなどの翻訳を使えば?
プログラミング系は、簡単だと言われている技術系英語の中でも、さらに易しいからなあ。 それでも苦手だけどさ!
中高生の時英語ちゃんと勉強しなかったのか?
ソースコードという共通言語があるし、よく使われる英単語は日本語ではカタカナ化してるだけだったり するから比較的楽だよね。
話変わるけど OpenNIは、1から2になってI/Fがガラッと変わりやがりました。 1のサンプルを俺抽象化した時間は何だったんだー イスラム圏ちょっとあんたらねえ 他人の俺仕様に無駄に振り回される自分の無能さが悔しい。 それはともかく情報共有の話が出たけど、 他人に振り回される側同士、手をクロスさせてお互い慰め合う・・・ ・・・わけねーーーだろーー氏ねやー
そこは抽象化してて良かった、じゃ無いのか?
SDLってやつ触ってきたけど、あれ基本イベントドリブンでやらんといかんの? DXライブラリみたいにやりたかったら、ウインドウ閉じたかどうかのイベント以外はポイポイ捨てて キー入力は必要なときだけ呼び出せばいいんだよな
JavaやC#やJavaScriptなんかで普通に目にするonKeyDownのようなイベントハンドラ、 OpenGLのGlutでもそう、win32の基本的なメッセージポンプ自体がそう。 そんな各種フレームワークやAPIで目にする極普通のイベントドリブン構造
描画のループと処理のメインループを別のスレッドに分けるんだけど 描画と処理をわけるのなら描画のループだけ一秒間に60回回せばいいと思うんだけど 処理は何回回せば良いんだ? 100とかが無難なのかな、100カウントで一秒間ってすっきりするから
>100カウントで一秒間ってすっきりするから プログラマーの発想じゃねぇw
普通は同期タイミングの設計によって結果的に決まるもんだよな 「何秒に一回にしたらいいんだ?」って発想じゃなくて
>>159 それ一行目から既に「何のためにそれをやるのか」自分でよくわかってないだろ。
何だかよく分からないけど処理を分けるみたいだから真似すればきっとうまくいく
ということなら、まぁ、カーゴカルトかもな
負荷軽量化のためじゃないの? スレッド一つだとCPUのコア1つしか使わないから処理系ごとに分けて活用しようと思ったんだけど 他のスレッドで弄ってるリソースを参照しても大丈夫かなー?ぐらいの認識です
基本的に大丈夫じゃないんだけど、そもそもマルチスレッド処理書いた事あるか? 同期とread/writeの保証についてちゃんと認識あるか? その後、全体としてどういう処理の切り分けをして、どのタイミングで片方の結果をもう一方が拾うのか、とか
ちなみに、JavaやC#だとsynchronizedやlock使ったマルチスレッド時の同期化タイミングを作れたり色々と簡素化する手段はあるけど、 基本的にC/C++はそれらをわかった上で自分で実装するので(と言っても意味わかってれば仕掛けだけなら屁でもないが)、 その辺の認識ちゃんと染み込んでるのかなと思った。 C/C++だとboost::thread使うとずいぶん簡素になるが、コードが簡素になっても動きわかってないとおかしな事になる
iphoneやandroidでは描画スレッドを分けるのが標準になってるんで
マルチスレッドの知識がなくても使わざるを得ないという事情もある
なので
>>159 は別に背伸びしてスレッド分けしようとしているというわけでもないと思うよ
167 :
名前は開発中のものです。 :2013/09/13(金) 21:01:10.73 ID:NXjdNH8/
AndroidでUI用のスレッドで重い処理やってフリーズするような糞アプリは見た事ある
>>159 の話に合わせると、描画のループというのが、Androidゲーでは
所謂GLスレッドに相当。で、これの中でゲームのシミュレーション部の
計算もやるのって別に珍しくはないかと
使える計算資源を徹底的に使い倒す必要があるヘビー級のタイトルなら
(計算資源への)処理の充填率を高めるために比較的細かい粒度で処理の
スケジューリングをするような仕組みをわざわざ用意することもあるけど
(結果的にGLスレッドとシミュレーション部は別スレッドってことになるけど)
必要がなければやらない(複雑化を避ける)と言うのは普通にアリというか
むしろ推奨
Androidってメインループ中の処理に相当するupdateメソッドあったっけ? つかGUIってメインループなくね?あったとしても同期取るハメになるはず
170 :
名前は開発中のものです。 :2013/09/14(土) 13:44:25.30 ID:8QT9t2lk
AndroidでもNative Activityを使えばメインループは書けるみたい 普通のアプリではメインループ相当の事はOSがやるが イベントハンドラで時間のかかる処理をすればフリーズする
C++11のusingエイリアス使ってる人いない? template <class T> using Value2 = std::array<T, 2>; ってやりたいのにIDE(eclipse CDT + gcc4.8)が構文エラー扱いにしてきて困る そのくせコンパイルは通るし実行もできるからややこしい usingエイリアスならtypedefにテンプレート引数使えるって聞いたから 必死にgcc環境作ったのに悲しい悔しいtasukete
172 :
名前は開発中のものです。 :2013/09/19(木) 08:43:08.81 ID:UurgX65x
コマンドのオプションもきちんと書こう
方向ベクトルの指す方向にモデルを向けたいんですけど、どうしたらいいですか? 条件があって、正面を+z方向とした時にx軸回転した後にz軸回転だけで表現したいです。
174 :
名前は開発中のものです。 :2013/09/24(火) 20:17:12.39 ID:kERDBedE
z軸で回転させても向きは変わらんのでは?
175 :
名前は開発中のものです。 :2013/09/24(火) 20:42:59.75 ID:kERDBedE
そんなことないか 方向{x,y,z} x軸atan(y,z) z軸atan(y,x) で回転させれば向くのかな 頭が地面に向いたりしそうな気がするけど
今ネットワークゲームを独学で作ってるんだけど 一応ゲーム中に複数のクライアントをサーバーとのやり取りさせることはできたんだけど ルームの入退室は良いとして、ゲーム開始させる場合にサーバーとクライアントでどうやってゲーム開始を同期させればいいのかわかんないんだけど アドバイスしてくれ
ぱっと思い付くので言うと、例えばクライアントはサーバをポーリングしてるとして、 クライアント側全員から開始の合図が来た段階でサーバがタイムスタンプ発行し、 各クライアントはそのタイムスタンプから5秒経過したら開始とかすれば、 ポーリングがまちまちなクライアント同士で同期出来ると思う。
もうちょっと言っておくと、ポーリングの段階でサーバからはタイムスタンプをもらっておき、 それで各々クライアントは、まちまちな自分の時計とサーバタイムのオフセットを得て保持しておいて、 参加者全員がスタート伝達したタイミングで、ポーリング結果には開始時刻が返送(例えば5秒後)され、 あとは各クライアントが自分のタイムとオフセットから計算して、そのサーバタイムになったら実行、ってするだけって話。 簡単な仕掛けだが、一応それっぽい動作にはなると思う。
ポーリングってなに
googleからアク禁食らってる人 久しぶりに見た
俺ボーリング下手なんだよな 重さ12でやってるけどよく爪が割れるわ
ほらな、やっぱ基本情報ぐらい取っておいたほうが 基礎的な単語の意味がわかっていいんだよ
ポーリング while(1) { if(...) { break; } }
基本情報にポーリングなんてでないだろ
お前ら本当に普段ソフト作ってるの?
基本情報()
情報処理技術者ってイマイチバランス良くないよな 無駄にハードの知識が必要だったりプログラムの知識は 関数ポインタやオブジェクト指向すら不要だったり
そんな資格を取る暇があったら実際にゲームを作ったりネットで調べ物をした方がよほど有意義ではないか
どうせならWindowsのドライバーを作れるような知識を出してくれないかと もしくはusb3.0とか扱えるような知識を
まあ基本/応用情報etcは(一般的な会社を対象とした)就職活動用とか 入社後のポイント稼ぎ用、という印象はある 職人様方には無用なものだろうね
(´・ω・`)イヤダ!
(´・ω・`)イヤダ!
>>185 最近、ゲハ住人っぽいのがいるね。評論家気取りうぜぇ。
>>176-178 うおお、面白い。そういうやり方があるんだね
横からだけど、最近同期の方法とかに悩んでたから参考になります
2人対戦のゲームをUDPで完全に同期させる方法はネットにいろいろ参考になる資料があるんだけど
クライアントサーバで一定時間毎に同期させるような方法はあまり資料がない・・・
ゲームのジャンルやルールによってやり方が違いすぎるからかな
>>184 でるよ
>>188 総合的な知識が幅広く得られるのがメリット
プログラマは狭く深くになりがちだからそれを補える意味は大きい
関数ポインタもオブジェクト指向もでるよ
C言語の知識を補うならC言語検定もある
>>190 ベンダーべったりの知識はベンダー試験
マイクロソフトは充実してるよ
資格試験って就職時の自分に対する泊付だろ 知識を得るならその手の本を読めばいいだけ
200 :
名前は開発中のものです。 :2013/09/28(土) 13:32:24.05 ID:ihDNaDhE
まあ独占資格以外の資格なんて基本は箔付けるためのもんでしょ
一昔前の一般的なクリックゲーMMOってどういう風に同期取ってんのかな? キャラクターの位置とかはけっこうズレるし、敵にダメージ入るタイミングはズレたりはするけど、 死んでるはずの敵からの攻撃からダメージ受けることってなかったよね?(PSO2は除く) 特に派手なアクション要素がなければ、各クライアント側で起きたイベントをサーバで集めて タイムスタンプとかとあわせて整合性を取って、発生し得るイベントを全クライアントに送るって感じ?
「MMORPG」は非同期/サーバー集中型だよ ファンタシースターオンライン2は「MORPG」で非同期型/クライアント分散処理型ね
イベントはサーバー側で一括でまとめなきゃダメっしょ クライアントは移動とか攻撃とかリクエスト投げるだけじゃないと 俺のカスタムクライアントが9999ダメージを連発させるぜ
>>198 へー、C言語検定なんてものがあったのか
それは知らなかった
腕試しに受けてみようかな
はじめてのC検定
>>204 専門学校1年の秋位に受けさせるレベルで超簡単だぞ
クライアントが発生させた全てのイベントと、キャラクターの座標と角度だけ送信すればなんとかなりそう 全てのイベントの定義には移動や方向転換も含んでて情報が若干重複するから 座標と角度は一秒に一回とかでもいいかも 攻撃判定とかはサーバーで処理するのかな? それともクライアントで判定して結果だけおくるのか チートされると弱いけど。
ドラクエみたいなRPGのランダムエンカウントだけど、それをC++で実現するにはどうしたらいいのかな? 戦闘に関する処理は全てBattleっていう関数が処理してるという前提。 モンスターのLv・HP・攻撃力とかの初期値は、全てデータベースとして別のbinファイルに存在する。 今考えてるのは、 戦闘開始→乱数で「敵の数」「出現する敵のID」取得 Monsterっていうクラスを用意する。 コンストラクタで「出現する敵のID」を入力引数にする。 IDでデータベースから敵情報をリードしてくる。 リードしてきた敵のパラメータをprivateの変数に格納する。 みたいな感じになるのだろうか
モンスターのテンプレートなデータのクラスと実体のクラスは分けてるよね? それでいいんじゃね?
ランダムエンカウントって遭遇した敵の数や種類がランダムなんじゃなくて フィールド内でキャラクターが何歩あるいたら敵に遭遇するかがランダムなことなんじゃないの?
俺もそっちかと思ってたw
>>209 うーん
戦闘が始まったら関数Battleを呼ぶ
Battle内でMonsterクラスの実体monster_nowを用意する
monster_nowは配列で数個(モンスターの数分)用意
monster_nowはモンスター種別IDを基にモンスターデータベースから敵データをリードする
HPを0にすると戦闘終了処理をした後にBattle関数がリターンする
・・・という作りを考えてるんだけど、それが
>>209 が言ってることに当たるのかな?
>>210-211 完全にそうですねwすいません
補足すると class Monster { private: int HP; int MP; public: Monster(int ID); // 種別IDを基にデータをリードするコンストラクタ void Action(未定); // 敵と味方とのデータのやりとりの予定 ~Monster(); // 経験値などの戦闘終了後の処理 }; こんな感じ Battle関数が呼ばれるために int Battle() { 乱数で敵ID・数取得 Monster mob[敵の数]; 〜〜 } みたいな感じ
「出現する敵のID」は乱数で直接呼び出すんじゃなくて 出現する敵の種類と確率を定めたテーブル作ってそっちから取得した方がいいとオモ あとこれ出てくる敵は必ず1種類のみなのか?
まず乱数で数を決めて、その後種類を割り振っていくって事か
パズドラなんかだと乱数で選ばれた敵モンスターと、あらかじめ決められたモンスター場合の2パターンあるよね
ダイレクトエックスで3dゲーム作るのって、1から学び始めたらどれぐらいかかる? dxライブラリとかのフレームワークで3dゲームは一度だけ作った
人生におけるいろんな可能性をゲームプログラミングのために捨てる覚悟が必要になるね
本人の能力と過去の蓄積と応用力次第だからそんな大変でも無いかもしれないし、完全に無理かもしれない
220 :
209 :2013/09/29(日) 20:36:17.46 ID:Vo2lxUIs
あー、違う違う。 class CMonsterData { int hpmax; //最大体力 } class CMonster { CMonsterData *monsterdata; int hp; //残り体力 } こんな感じで作成する。 各個体で別々にインスタンスを作らないといけないのは分かると思う。 アクションするモンスターはデータと別に作る。 データクラスはアプリケーション実行中には絶対にデータを弄らない。 弄るとややこしくなるから。 戦闘が終わればCMonsterを綺麗さっぱりdeleteすれば分かりやすい。 自分はこんな感じで作ってる。 因みに戦闘クラスは class CBattle { CMonster *monsters[敵の数]; }; という感じでポインタを持たせる。
>>214-215 数に関してはそんな感じです
なるほど、テーブル使ったほうが確かにイイですね
そしてそのテーブルを扱うためだけの関数を作ろうと思います。
>>220 ふむ・・・少し難しいですね
その方法だとどこでモンスターを指定できるのかが良く分かりません
CBattleにコンストラクタでモンスター種別(ID)を引数にして、
IDによって持たせるポインタを変える…というのは出来ないですよね?
>>220 モンスタークラスのコンストラクタにモンスターデータクラスのインスタンス渡して、
モンスターデータクラスのコンストラクタにはプライマリキー渡して外部ファイルの読み込みとか
223 :
209 :2013/09/29(日) 22:34:23.36 ID:Vo2lxUIs
>>221 モンスターの指定はCMonsterのコンストラクタか初期化関数で
CMonsterDataのポインタを渡せばよい。
イメージとしてはCMonsterDataの統轄クラスがCMonsterを吐き出す工場メソッドを作る感じ。
敵の種類のランダム指定もそのメソッドでやらせればよい。
CBattleについては設計思想にもよると思うが、個人的にはstateパターンを薦めたい。
例えばこんな感じ。
class CState
{
protected:
CMonsterData統轄クラス *monsterdatamanager; //参照するのみ
public:
virtual int OnClick(int x,int y){return 0;} //マウス操作はあまりしないと思うが
};
class CBattle : public CState
{
CMonster *monsters[敵の数];
};
class CFieldMap : public CState
{
};
>>205 実家で技術評論社の「はじめてのC」読んでたらオカンと姉ちゃんがすげー剣幕で本をぶんどって行ったことがあったなー。
中身を確認した後顔真っ赤にして戻っていったが。
セックスの教本を居間で読むような度胸が俺にあるわけないでしょう?
ワラタ
>>203 ゲームによる。アーケードなんかはチート不能だから瞬着の当たり判定とか普通にあるよ
参考になるかどうか分からないけど、ボーダーブレイクの主武器は発砲時にレティクルが
敵に重なってれば「当たり」。クライアント側(プレイヤーの筐体側)で判定してる
わかりやすい例かと
アクションのネトゲってのも1つの夢ではあるけど 逆に非同期で実現できる面白い仕掛けのゲームも考えてみたいもんだね
報告乙です 素直に巣に帰ったようで。ありがたい
テンプレートメタプログラミングとかいう言葉を最近知ったんだけどさ コンパイル時に外部リソースを実行ファイルに取り込むのって外部リソースのメリットを潰しちゃうかな? 具体的には、箱庭ゲーとかでのイベント発生時刻(タイムラインっていうの?)とか。 逆に、ユーザーにいじって欲しくないデータは隠せそうだけど、それはそれでプログラムに直書きした定数とどう違うのという疑問もある。 みんなconstexprとか使ってんの?
我ながら意味深な文章になってしまった
真ん中らへんがメタプロの要素なくて文章が繋がってなくて意味がわからんのだが、 それはコピペミスか何かで本当は >テンプレートメタプログラミングとかいう言葉を最近知ったんだけどさ >みんなconstexprとか使ってんの? っていうレスだったのかな? それなら別に、C++11になるって制約以外には付け得なキーワードだから 付けられるとこには付けとくといいんでないかな
もっぱら面倒臭いかどうかだけで判断してる。 バランス調整でコンパイルがメンドかったら外部ファイル化。 バイナリファイル解析する奴なんてそうザラにいないし、 いざとなれば暗号化すればいいし。
C++はネイティブコードを生成するからか コンパイルが長杉
ビルドじゃなくてコンパイルが? includeが深いとか翻訳単位が多くてコンパイルとリンクが多いと長い事はあるけど
TMPをゲーム製作で使うことってほとんどなくね
STLならよく使うが?
ビルドとコンパイルってどう違うんだ ビルド∋コンパイルってことか?
コンパイル=.objファイルの生成 リンク=出来た.objから実行ファイルの生成 ビルド=それらの総称 って事だろ? 今日日、一々使い分ける事もないだろ。メンドくせぇな(^p^)
>>234 個人レベルの開発規模なら、昨今ではわりと珍しい言い分だと思うかな
普及価格帯のPCの性能、SSDの普及率、こうした背景の中でPCHを使ってれば
設計が多少ゴチャってても、コードを一部修正した後のビルドは大抵一瞬で終わる
それでも遅いなら、ファイル(ソースやヘッダ)間の依存関係がスパゲッティ状態で
一部の修正が「不必要に」多数のファイルに影響を及ぼしてるとか、ビルド設定が
腐ってるとか、その辺に原因がありそう
241 :
名前は開発中のものです。 :2013/10/03(木) 08:36:21.26 ID:1JpHSTD+
複数プロセッサのコンパイルが有効になってないとか。
ビルドが速い言語の場合、ビルドから実行まで1秒もかからん C++はまだ数秒かかるでしょ(Hello, Worldであっても) 多少は高性能な環境だと仮定しても一瞬は盛りすぎ (そもそも開発環境は一般的な最新PCより劣る場合が多い)
バランス調整関係の定数を一つのヘッダファイルに纏めると 加速度的にコンパイル時間は長くなる。 逆に、そうならないように各ヘッダで宣言すると 今度は一目で見通せなくなるから面倒臭い。 定数名で検索かければいいじゃねーかと思っても、 定数名なんて覚えてない。 そもそも、バランス調整ごときでIDE立ち上げるのも面倒臭い。 何十回もリトライするケースもあるしね。
定数ならextern使えばいいんじゃね?
変数考えるのも面倒だしコンパイル時間かかるしで よく使う変数をまとめた初期化込みGet関数込みのクラスを継承させて よほど特殊,重要な値じゃないかぎりそこでやりくりしてる 余分な変数大量に宣言&どこのクラスかで同じ変数でも意味が変わって 他人が見てもよくわからんから設計上よろしくないと思うが 普通はいちいちヘッダわけていろんな変数つけんの? 変数格納クラスに変数追加しないかぎりコンパイル時間は気にならない 副作用で変数の節約と機能ごとのカプセル化がうまくなった気がする
>>239 "総称"じゃないよ。コンパイルとリンクのステップを順に実行して、最終アウトプットに組み上げるのが、言葉通りビルド。
総称って言っちゃうと語弊がある。
あと今日日分けないって意味だと、コンパイルじゃなくてビルドって言う。
当たり前の事なのでめんどくさい話じゃない。ちゃんと正確に理解しなさい。
>>242 ・ビルドが速い言語
・ハロワのビルドに数秒かかるC++
これらについての具体的な言語処理系(の製品名)を挙げてくれるとありがたいです。
ハロワ数秒を叩き出すPC環境についても差し支えない範囲でお願いします
あとmakefileかプロジェクトファイル、コンパイルオプションもあると助かります
一応、一般的な最新PCより劣る環境として
CPU:Core i7-860(Lynnfield世代)
MEM:PC3-12800 2GBx2
HDD:1TB 7200rpm
VGA:GTX260(216SP) GDDR3 896MB 2-way
SND:SB X-Fi XtremeGamer
OS:Win7 Pro 64bit (現在はSP1)
4年前にバイトして買ったパーツがこんな感じで、今は押入れの中で
眠ってるんですが、寄せ集めて検証用に一台組んで試してみようかと
SSDNow V100 SV100S2/64Gという3000円程度のローエンドなSSDも
たまたまあるので、これも使ってみようかなと
>>247 安価見逃した上にハロワのビルドが速い言語と空目してしまったのでHQ9+と上げておくw
大体それ前後のPCで書いてるが、数秒かかるぞ?VC++2008。
ハロワ?無職なの?
数秒でハローワークを建設するスレですが何か?
どうせモジュールの概念もオブジェクト指向も理解せず、一つのファイルに 延々と全プログラムを書き出しているとかいうオチじゃね〜の? そりゃ重いよ。
ここゲームプログラミングスレじゃなくなってるよな DXスレのがよっぽどゲーム的
オレオレライブラリのファイルサイズが200kbyteを超えてるとか、 そーゆーよっぽどな理由がない限りは、DXライブラリ使った方が 良いとは俺も思う
あとグローバル変数もローカル変数も一緒くたにしてねーか? これやられっと処理速度がやたらと遅くなるんだが・・・・・・
そういや、メンバー変数とローカル変数でも処理速度は変わるよな?
雑談? チャット?
変わるだろうけど今日び気にするだけ無駄じゃね
速度を求めないなら何のためにC/C++を選んでいるんだ?C#の方がよっぽど楽だろうに・・・・・・
>>247 i5に16GB積んでVC2012でハロワをビルドしても数秒かかるよ
I/Oの強化が効果的だけど、例えばFC接続したRAID5構成(HDD24台)でRHELのGCCでビルドしたって一瞬じゃ終わらん
やっぱ、Delphiが最強だな
メンバ変数とローカル変数の差も気になるくらい速度を求めてるならアセンブリでも書けば
下手糞なアセンブラよりもCのが速いんだが
じゃあCで速度を追求したらいいんじゃね
C++使うとメモリー管理が楽なんだ。 あと、オブジェクト指向にも向いてるし、モジュール設計も楽。
お休みして
しかもC++使うと変数間の速度差とか気にかけられるぞ 良かったな
コンパイル速度の話がズレてきたぞ C++が圧倒的に遅いのは最強! 無敵!
メモリー管理できますって言った時に 別にスマートポインタ使える必要ないよな アロケータも別に
>>268 スマポ普通に使うが、なんで名前を出した?
boost::shared_ptr も、都合によって自前も。「ひらがな書けます」くらいのレベルの話だ。
>>254 自前ライブラリとかlibにしとかないか普通。
それでも遅いって話ならいいけど
自分で解放しないとなんか不安だから、スマートポインタって使う気にならないんだけど、 構造が複雑になった場合、どのタイミングで解放されているのかよくわからなくなる みたいなことってないの?
解放忘れがないならいつ解放されてもどうでもよくね?
解放忘れよりつかんでいるつもりがいなくなってる方が怖い オーナー管理で罠にハマるとつらい
>>272 なんらかのインスタンスを参照している場合、
先にインスタンスを解放してしまったら、
参照している方で不具合が起こるじゃないか。
>>271 考え方的に逆。って言うかちょっと違う。
「いつ解放されるかわからない」って状況はスマポ使う使わない以前の自分が動作を認識してるかって話であって、
ライフサイクルは自分がわかった上で利用するんだよ。
つまりそのデストラクタはいつ呼ばれるかってのを自分がわかってて書いてるのが前提。
スマポはその上の保険と省力。
>>274 それはスマポに限らず設計の問題。
JavaやC#にあるGCと混同してないか?
全く別物で、スマポは単純だぞ
C++でもインクルードするファイルの数を少なくしたりすると早くはなるけど限界あるだろ だからコンパイルの高速なスクリプト言語を組み合わせるんだ
そういうからboostのPythonいれたら、コンパイルがかなり長くなったんだが
スマポってdeleteみたいなことは原則行うの? たまたま解放忘れてても拾ってくれる保険なら労力増やしてまでやる必要が感じられない 原則delete行わずデストラクタで自動解放が主流なら今すぐ書き換えてくる
>>279 原則っていうかザックリ言うと、スコープから外れたときにdeleteを自動でやってくれる。
func(){
}
>>280 ごめん途中で送信してしまった
func(){
smart_ptr<foo> bar(new foo);
なんかごにょごにょ
} <- barだけしか使ってないならここで解放
これが基本だが、スマポ同士で代入ができるやつは関数の戻り値に渡したりするとスコープを超えられるのもある。
なので、いろいろな場所で使っていても、結果的にすべて共有しなくなった時にdeleteしてくれたりする。
なるほど、スコープはずれたら&他に参照とかなかったらデストラクタが起動してデリートするのか ちょっと勉強と動作チェックしてくる
>>281 マジかよ
スマポってそんな凄いやつだったのか!
でもそもそもnewとかdeleteしないプログラムしか書いたこと無いから意味無いような気がする・・・
>>280 >>282 なんか気になったので補足しておくと、
> デストラクタが起動してデリートするのか
delete された時、解放時の処理の為にデストラクタが呼ばれるんだぞ?
意味わかってるのか不安になった。
ああちゃんとレス読んでなかった。
スマポクラス側のデストラクタが呼ばれたら、スマポクラスが保持しているポインタをdeleteするって意味ならその通り。
ただそれだけの仕掛け。
>>284-285 はスルーで。てかクラスの入れ子関係で、デストラクタの中で、
子要素のデストラクタ呼ぶような処理普段書いてたら簡単にわかる話だ。
boost::shared_ptr はそれプラス、コピコンやコピーオペレータを持ってるだけ。だから単純な仕掛け。
>>280 それは単純な例だけど、
構造が複雑になった場合、例えば複数のヒープ変数が必要で、一方が他方を参照している場合とか、
>どのタイミングで解放されているのかよくわからなくなる
ってならない?
>>281 これまさに
>どのタイミングで解放されているのかよくわからなくなる
ってならない?
単純な仕掛けだけど、これ考えたやつ頭いいよな。 解放忘れがないか、二重デリートがないか、インスタンスが生きているか、適切なライフサイクルか、、、、 などと複雑になりやすいコードに神経を使うよりも、 スマポを持ってたら生きているのが保障されるからコードが見やすくバグも少なくなるし。 たとえば、STGなんかで親子関係を持った敵がいたとして 親が破壊されたとき、子は生きていて親を参照している場合、 スマポなら親を生存リストから外すだけでおkで、子が全滅した時点で勝手にdeleteされるなーんて。 生ポならずっと子が生きているか監視しなければならないし。 この部分のコードが減るだけでバグが少なくなるよね。 ほんとスマートだわ。
>>287 基本的にどのタイミングで解放されてもいいんだよ。むしろ気にするような組み方はよろしくない。
アクセスしたときに必ず生存していることが重要。
循環参照には気を付けないといけないけど。
>基本的にどのタイミングで解放されてもいいんだよ。むしろ気にするような組み方はよろしくない。 メモリをケチろうとして重複を無くそうとすると、 参照関係が複雑にならないか?
>>290 そんなギチギチの環境で組んでるの?
たぶん、そんな複雑な参照してる場合は設計を一度見直したほうがいい場合があるよ。
循環参照になるような時は弱参照
>>277 実行中に書き換えられるようにすると凄く便利らしいね、ああいうの
コンストラクタでエラーを出す方法は例外だけ。 例外使う場合、正しく確実にファイナライズ処理を実行する方法は事実上スマポだけ。 なので細かい事を言えば、スマポを一切使わない場合、例外禁止&2段階初期化必須&コンストラクタ内では代入くらいしかしてはいけない、みたいな設計上の制約も出てくる。 スマポは超便利ってのもあるけど、こういうC++の暗黒面を補う事情もあったりする。
今ネット通信ゲーム作ってるんだけど SOCKETの変数をいろんなところでメッチャ使うんだけど これを引数で持ってきてたんだけど、グローバル変数にしてやった方が圧倒的に楽だよな でもグローバル変数って使わないべきだし、シングルトンも同じだから使わないべきなんだけど こういうときってどうすりゃいいの
グローバル変数を使うなというのは全体構造を分かり難くするから 使わない方が無難というだけ 必要があるなら遠慮なく使えばいい
そもそもnamespaceとかexternってグローバル変数を活用するための機能だからな
>>296 グローバル変数を使うなと言われる理由はいくつかあるけど、その一つに変数は関数より柔軟性が低いってのがある。
メンバ変数をプライベートにしてsetter/getterを作れっていうのと事情は大体同じ。
例えば、4人対戦ゲーの場合、プレイヤーIDを表す変数は0〜3までの値しかとって欲しくないとする。
変数に直接代入する場合、いざ使う時になってIDが正しいかチェックする必要があって、プレイヤーIDが0〜3になっているかチェックするコードが全体にばらまかれる。
関数経由で代入する場合、引数の値をチェックしてエラーを投げることができるので、値の範囲をチェックするコードは最初のsetterだけで済む。
変数は代入しか出来ないけど、関数は付随する処理(引数チェック、ログの記録)が出来るし、仕様の変更にもある程度柔軟に対応できる。
(プレイヤー人数を6人に増やしたいと思ったときに修正しなければならい箇所の違いを考えると…)
理想的には、Socket自体は通信関係のコード以外に触れられないようにして、
SendAttack(OBJECT_ID target);
SendMove(OBJECT_ID id, Position pos);
SendChat(PLAYER_GROUP_ID groupId, const char* msg);
みたなゲームの仕様に合わせたパケット送受信関数を作って、それをゲームロジック全体で使う。
この手の送受信関数を纏めたクラスのオブジェクトが、シングルトンやグローバル変数になるのは仕方ないんだけど、
Socketが丸出しのグローバル変数ってのはあんまりよくはないな。
まぁ小規模なゲームを一人で書いてる内は、そこまで致命的でもなかったりするが。
まだ仕様がハッキリと見えてない段階でプロトタイプを書いてるときは、何も考えずグローバル変数の方が手早い事も多いし。
長文でスマン。
どっちかって言うと実際に使った時直面する問題って、グローバルに複数置いてる物があって、それらが相互に関わってるような時、 開放順が保証されないからデストラクタで何か処理するような場合困るかもしれないって事と、 namespaceも分けて無いグローバル変数でかつexternだらけとかになると迷子になる上、別の翻訳単位にもしも同名があった時面倒な事になる、ってのが 大昔に経験したリアルな問題
ちなみに、「翻訳単位内でのローカルな範囲で良いグローバル変数」には、 普通 static キーワード付けて、externさせないってのが常套手段だよな。
static = private extern = public
>>300 そうは限らないよ。
親から一定間隔離れて行動したり、親の状況で振る舞いを変えることがあるから。
どちらの場合もある。
extern Kelsi Olesya_Rulin; そう、グローバルを遠慮する必要なんてない、ってのは合意事項だよな
>>305 親から全ての子に指示するべきじゃない?
子供が親の参照はよくないと思う
>>308 Ogre3Dは親子それぞれ参照をもってるんだがな
>>308 それも場合によると思うなぁ。親を辿りたい時があるし、
親が子に干渉しすぎるのはちょっと、という考え方もあるだろうし。
親子の捉え方が違うとなんともいえんような 例えばシューティングでの位置関係なら 親の移動が子全体に影響するなら、親が子の参照を持っているのが便利だよな これはシーングラフみたいなやつか、スプライトとかはコッチだろうな 逆に子が親の行動をトレースするタイプだと参照の持ち方は逆になる こっちはカメラのスナップかな、親が持つんじゃなくて、子が勝手にぶらさがる
親ノードは子ノードの配列を持ち 子ノードは親ノードの弱参照を持つという形にしている
親子関係といっても様々な層にあるからねぇ 例えばゲーム設定上の関係性(物理、組織、通信回線、人間模様、etc)は色々だし これらの関係性も、実装上は、制御(操作)の流れ、データの流れ、色々だし 話の前提条件が何かを伏せてる限り、問題の所在も実装の最適解も本人にしかわからん 説明が面倒なら、頑張れとしか言えん
アクションなんかで敵キャラクターの種類によって戦闘ロジックを変える場合って、種類ごとに継承するのが普通? それとも、戦闘ロジックの部分だけ無名関数で差し替えるとか?
戦闘ロジックには関数ポインタを使った事と、スクリプト言語を使った事がある 処理速度では前者、汎用性では後者だな
>>314 前者が、敵1体を1単位とするような粗い粒度の処理の差し替えの話で
後者が、無名関数でもおkな程度に細かな粒度の処理の差し替えの話なら
場合に応じてそうした実装の使い分けをするというのは普通にアリなのでは
分解能について教えて欲しいんだけど timeBeginPeriodとtimeEndPeriodはプログラム全体で同じ分解能なら開始時と終了時に1回呼ぶだけで合ってる? それともタイムを使うごとに毎回呼ばないといけない?
毎回呼ぶのは無駄ぽいんだが 1回だけだと他のプロセスで精度を悪いほうに変えられたら駄目だろうな
>>318 ありがとうございます
そうか他のプロセスで弄られる可能性が有るから毎回呼ぶほうがいいのか・・・
1回呼べば固定されるはずなのにサンプルコードで何で毎回呼ぶのかわからなかったけどようやくわかった
>>317 一回でいい。
ただtimeBeginPeriodとかはOS共有だから
他のアプリで操作されたらどうしようもない。
なんでCとC++をごっちゃにしてんだよこのスレ C++アンチはどこに行けばいいんだよ
C++アンチなんて意味のない行為はやめてしまえ
C++11は許せるがそれ以前はコードに吐き気を覚えるわ
324 :
名前は開発中のものです。 :2013/10/07(月) 17:34:45.52 ID:HiWWBNmC
オタク系の板みたいにプログラム板にC++アンチスレって立ててみたら?
この板でもよくね?人が集まるかどうかは板の需要と1のカリスマ次第
それって「C++でゲームを『作らない』スレ」ってこと? だとしたらゲ製でやることじゃないな
タダでさえ住人の少ないゲ製板の、タダでさえ住人の少ないC/C++スレを さらに分割してどうするんだよ。
今時純粋にCのみてのは居ないだろ。Cのみと言ってて知らずにC++の機能つかってるやつおるし。
コードに吐き気覚えるとか言っちゃう人って、要は書けないし理解も出来ない人が自分を正当化するために言う台詞だから無視でおk
そうかな。重苦しいコードってあると思うよ
ほほほ。そんなのほっとけ 個人の趣味の時は人目を気にすることなくベターC留まりの 作り捨て上等のコードでいいのよ 家ではみんなパンツ一枚でしょ
△作り捨て上等のコードでいいのよ ○作り捨て上等のコードで“も”いいのよ
今はもうC++(とスクリプト言語)でしか書かない もちろんオブジェクト指向
class myclass{ private: int* p; public: void hoge(); } void myclass::hoge() { p = new int[ sizeof( int) ]; } void main() { myclass obj; obj.hoge(); obj.hoge(); } この場合初めにNewした領域はプログラムが完全に終了するまで消すことは出来ませんよね?
うん
一個目どころか二個目も駄目じゃね
>>335 >>336 ありがとうございます!!
2個目を消す場合、
クラスにDelete()関数を追加して、
void myclass::Delete()
{
delete[] p;
p = NULL;
}
void main()
{
myclass obj;
obj.hoge();
obj.hoge();
obj.Delete();
}
でも、ダメですか?
いいけど、そこはかとなくダメコードのにおいがする
>>338 実際にこれを使うわけではないので安心してください!
プログラムの勉強を始めたばかりで内部的にどうなってるか知りたかったんです。
答えてくださった方たちありがとうございました!
>>337 一回目のnewで確保した領域をメモリリークさせるコードを書きたいの?
よくわからんテストコードだな。
>>337 myclassのデストラクタで配列解放しない理由は?
>>339 普通と言うかよくやる考え方の順序で言うと、まず真っ先に一旦myclass側のデストラクタで、そのクラスの管理責任として、
自身がメンバとして持っている要素の解放処理書いとくってのをワンセットにしてそれを土台の考え方として、
その後、それじゃ困るようななんらか事情や実装都合、あるいは設計上の理由があった時、
実行時の動作パス踏まえて考えた上で、そこでやってるような開放専用関数追加するとかって順番で考えて。
まぁ奇怪なコードを書きたくなるという性癖は割とありがちなので (じゃなきゃIOCCCなんて生まれない) 気持ちはわからないでも
たしか前スレだったか シングルトン使いまくりという自由人がいたような記憶があるが あーいうのもオブジェクト指向的には奇怪な部類に入るだろうか
ゲームなんざ細かいこと気にする必要なんかねえよ どうせたかだが数万行の糞コードだろ 多少設計が糞でも力技でねじ伏せられるレベルだろ 少なくとも設計が悪いせいで開発が頓挫するほどのことじゃない 細かいこと気にしてる前にどんどん手を動かせ ゲームなんかmain関数一本のグローバル変数使いまくりでも何の問題もない
>>345 個人レベルなら本当にこれだけど、チームでやってるときにそれやられると死ぬ
あと、キャラクタークラスとかは流石に分けないときつくないか
あまりクソ設計にするとバグだらけになったりコードに触る気が無くなって頓挫するぞ!!
>>346 >個人レベルなら本当にこれだけど、チームでやってるときにそれやられると死ぬ
全くその通りだよな。
俺はグローバル変数使いまくりのベターCプログラミングでゲーム数本作ってるけど、”プログラミングできる”という箔が全く付かない。
だって一人で、しかも小規模なゲームしか作れないから、他に応用ができん。
クラス化すると変数管理楽だよ Cチックだとしても機能ごとに構造体くらい使おう
自分一人で作るにしても、次回作の時に使い回しが面倒だろ。
本当に入門者初心者レベルが多いってよくわかる流れだった
お題がクソコードですし
>>348 グローバル変数の使用はあまりおすすめしませんね
(おすすめしないだけで使ってはいけないルールはないが)
C言語ゲーム開発の章
http://c-games.main.jp/ ここでC言語及びC++のゲームプログラミング解説サイトを運営している者です
よかったら参考にしてみてください
3Dゲームで、距離が離れるとSE音量が変わるのってどつやってるんだろう SE再生する関数に、自キャラからSE発生した場所の距離を取得して音量変えればいいのかな
>>345 N88-BASIC(+ハンドアセンブル)あがりとしては、その心意気は買うけどさ
心情的には理解できなくもないけどさ
>ゲームなんかmain関数一本のグローバル変数使いまくりでも何の問題もない
ネタにマジレスすまんが、それは可能だけど、何の問題もないというのは
痩せ我慢しすぎだよな。構造化の恩恵くらいは素直に享受していいのよ・・・
かつてのN88-BASIC使いにとっては、構造体、関数、ローカル変数、とかは
垂涎ものの新要素で、TrueBasicの構造化プログラミングの世界は極楽だった
構造化プログラミング機能が齎す恩恵は、OOP機能のそれに比べれば癖がなく
万人に手放しでオススメできるかと
>>354 X3DAudioは相対位置情報による簡易な3D音響やってくれるよ。
Windows以外ならOpenAL-Soft+ALUREあたりかな。同じような機能
そこらの有名どころの3Dゲームエンジンの類もみんなこういう機能を
サポートしてるから、昨今ではそっちの使い方の情報のほうが多いん
じゃないかな
>>354 http://ja.wikipedia.org/wiki/DirectSound より引用
>誤解されやすいが、DirectSound 3Dの3D音源は、エコー、リバーブ等の環境音を模倣するエフェクトと、
>リスナーの位置と音源(モノラル)の位置関係を簡易に計算するライブラリが主体である。
>やっていることは、旧来、ステレオPCM音源のパンとボリュームを自前で調整することで、
>擬似的に音源の位置(音像)を表現していたが、これをライブラリとして吸収しただけである。
>したがって、実際の空気中を伝播する音の物理そのものを、シミュレートして計算しているわけではなく、
>遮蔽や反射などは考慮されていない。
らしいから、基本的な考え方はそれでOKっぽい
オブジェクト指向って自分でやろうとすると設計ムズいんだよなー C++は多重継承できるから多少は誤魔化しは効くけど IDEによるバックアップ(委譲のメソッドを自動でコーディングしてくれるとか)か、 Rubyのmixin的な言語仕様がないとコード書くのもめんどいめんどい。 ただ既存のライブラリ使う分には、CのままよりもC++のオブジェクト指向で ラップしてくれてる方が使いやすいよね、SDLは疲れた
>>360 多重継承云々でちょっと引っ掛かった。
もしもそれが純粋仮想(ようするにインタフェース)を念頭に置いた話なら良いんだが、
そうでない場合、個人的には密結より粗結を中心に考えたいよなと思った。コンポジッションが設計の主体って言うか。
当たり前な話なので、もしも前者の意図だったらスルーよろしく、
>>361 んにゃ、ご指摘の通り。差分プログラミング目的だから後者のつもりだったよ
全てのクラスにおいて、インターフェースとその実現クラスに分けてるなら、
多重継承よりも、インターフェースの多重実装と包含→委譲の方がスマートだと思うけど
IDEでサポートされてないとその委譲のコーディングすらめんどいって言いたかった
>>362 あぁごめんそういう事か。設計観点じゃなくて、コーディング時の作業か。
インテリセンス(コードアシスト)で候補出てくれない件。そういう事なら確かに。
コードアシストじゃなくて定義へのジャンプ。言葉ミス。 風邪引いて熱でふらふらしてるわ俺いま
>>363 いや、俺の方が未熟でごめんなさい
実装のコーディングがめんどくさくなるようであれば
設計の失敗みたいに思ってました
UDP通信について訊きたいんですが sendtoって何バイトまで送信できるんですか サーバー側で送信するときに114バイトは送信できて、115バイト以上は送信しないんです でもクライアント側だと255バイトを送信できてるんです ただ、送信してるかどうかの確認を受信できてるかどうかで見てるだけなんでもしかしたら受信側がおかしい可能性も否定できません どうなんでしょうか?
65535からヘッダを引いたサイズ
サイズをchar やunsigned charで指定してるのか?
>>368 サイズはstring型変数.size()で指定してます
すいませんが解決しました
送信の回数を減らすと普通にサイズがでかくてもできていたので大量に送信すると送信量を受信しきる前に内部的にバッファオーバーフローか何かで受信ができなかったのだと思います。
フレームレートを算出しようと思っているのですが main() { DWORD time; for(int i=0; i<10000000; i++) { timeBeginPeriod(1); time = timeGetTime(); timeEndPeriod(1); printf("%d\n" time); } } このコードでは15ms位の精度になってしまいます、ただ、timeEndPriod(1)を使わない場合は1ms精度で取れます この2つ(時間の取得を合わせたら3つ)はセットで使うべきだと思っていたのですが、そうではないのでしょうか
ちょっとソースを変えて int main() { DWORD start, end; timeBeginPeriod(1); start = timeGetTime(); for(int i=0; i<1000000000; i++) { end = timeGetTime(); if(start < end) { printf("%d回目 %d\n", i, start); start = end; } } timeEndPeriod(1) } こうした場合最初に2回(397575回目 2800264、865774回目 2800279、877500回目 2800295)が15msの精度で変わるのですが、何故かわかりますか
お前は標準出力が消費する時間を考えたことはあるか?
>>374 そのままのソースで試しにやってみたけど、ちゃんと1ms精度でカウントしてるみたいよ
53877回目 73604548
99144回目 73604549
139853回目 73604550
環境は、Windows7x64、VS10、release build、最適化無効(/Od)
「ゲーム内状態の更新(時間の経過)」と「描画」のFPSの話なんですが 現在は講座サイトに従って、 ・更新の後に描画を行う ・更新が16ミリ秒内に終わらなかったら、そのフレームの描画をスキップして、即座に次フレームへ ・描画が16ミリ秒内に終わったら、16ミリ秒経過するまでsleepした後に次フレームへ というメインループを組んでます で、自分はこのやり方のことをてっきり「固定フレームレート」だとばかり思ってたんだけど 垂直同期に合わせるのではなく、sleepを入れて時間で調整するなら、言葉で説明するとしたら 「可変フレームレート」と説明したほうが正しいのでしょうか? 更に言えば描画をスキップするんで「フレームスキップ方式の可変フレームレート」でしょうか
>>378 なるほど・・・拝見したところ、どうも考え方の前提の次元からしてズレてるようでした
俺の前提は、描画はオマケであって、例えフレームスキップされまくって10FPSしか出てないような状況でも、
キー入力は60FPSで受け付けてゲーム内を正しく更新することを目的としています。
つまり、フレームスキップが連続で起きているときは、それが解消されて次に画面が描画されるまでは
現在見えている画面とゲーム内のデータが食い違っているということが平然と起こります
参考サイトですと、いかに画面上の見た目とゲーム内の情報を同期するか、という話のようですね
それをA宗というのだが・・・
フレームスキップは、どっちかっていうと固定フレームレート側のテクニックじゃないか?
>>377 常に60FPSを目指すのが固定フレームレート(上限が定められている)
(コンピュータの能力が足りない場合、20FPSや30FPSなどFPSが小さくなる場合がある。60FPSより大きくはならない)
常に全力でFPSを増やそうとするのが可変フレームレート(上限が定められていない)
(コンピュータの能力が高ければ高いほどFPSは大きくなる。高性能だと150FPS、低性能だと7FPSなど)
ここでいう固定や可変は描画フレームレートの事。内部フレームレートは関係ない。
固定や可変っていうのは上限が定められているかどうかの意味。
>>380-382 みんなありがとうございます
根本的な潜入観があったみたいです
マルチスレッドというものを全く意識していませんでした
モニタのリフレッシュレート以上に描画処理を回しても意味ないんだが
VSYNCに同期してなくても意味ない リフレッシュレートが60だとして描画処理が1秒に180回回ってるとしたら 画面に表示されないグラフィックの描画処理が無駄に走ってることになる 描画は別スレッドにしてVSYNC同期で問題ない
それ同期してるじゃん
お前ら話噛み合ってないな
ワロタ
非同期なんだよ
大体お前らモニタのハードがどういう仕組みで画面に映像表示してるのかちゃんと理解してるのか? そこの前提ぼやっとしたまま聞きかじりの単語だけで話して無いか?
描画処理をリフレッシュレート以上走らすことに意味あるのか
ティアリングが発生するかわりに反応速度が速くなる。
>>386 の条件だと、非同期だと画面VSYNC中だろうと反映されるので、1/3ずつ重なって描画しているが、
同期の場合はVSYNCを待つので最大1/60秒遅れる。
ちらつき怖い
2dアクションで人の前でボタン押したらセリフ出そうとしてるんだけど、テキストの内容でどうやって読み込んでます?ソースにべた書き?csvファイルとかを読む?
テキストべた読みでもいいしスクリプト言語に頼ってもいい csvでスクリプト言語っぽい事をしてもいい
>>395 テキストのリソースは基本的に外出しでないかい?
まぁ作りやすい方でどうぞ
文字コードでつまづいてるのかな?
自作すると非常に省力化&使い勝手がいい 機能が少ないのが難点だけど
モノによるけどなぁ。 ピーチ姫を救出して"Thank you,Mario!"って言うくらいなら ソースにべた書きでもいいし。 アクションRPGとかになると外部ファイルが普通になるかな?
外部ファイルってか ソースに組み込むとしてもテキストが主のファイルに分離するだろ 他人が作業に介入するなら完全にソースと切り離した方が良い
一人ならベタでもいいんじゃないの。 シナリオ担当から「ここ変更してー」っての毎回聞いてるとめんどくさくてかなわん。 そいつらが変更できる形式だと、そんなん自分でやっといてやーって言える。
世界に売るなら言語は差し替えられるようにしとけ
ちょっとした説明文じゃなくて、RPGとかでガチでメッセージ内容推敲するなら、 スクリプトチックな仕様は必須だと思うわ 制御文字は固定の仕様として決めておいて 置換文字はcsvで自由に登録できるようにしておくといいかもね
>>393 1/60秒じゃないぞ、スレッド分けてるならトリプルバッファのはず
最大3フレーム+vista以降なら遅延バッファの影響で、さらに8フレーム
基本的なアクション部分は実装したからとりあえず次はメッセージ表示っていう 所でどうやって実装すればいいか悩んでたんです。 スクリプトでやってみようと思ってluaを入れたけど、ビルドエラーがなかなか解決 できなかったから、別の方法でしてみようと思って。まだ文字コードでつまづいたからとか そこまで行き着けていませんでした。一人で全部担当です。
別にスクリプト言語はLuaだけじゃない
>>405 8なんて中途半端な数どっからでてきたの
vista以降の遅延は3で設定で0にできるんじゃ?
わからなかったらluaは後回しにして、単純に文字列を加工する関数作るのが良いよね てかlua使いこなそうと思ったらエンジン以外は全部luaで作った方がいいってレベルになるだろうし
Aeroで遅延3フレームもどこから来た話なのか分からない ソースも無いし誰も説明してくれない それはディスプレイドライバの設定の問題ではないのか? トリプルバッファリングでも表示されるまでの時間は最大16msだろ それは間違いない
>>406 文字コード 読み込み テキスト C++でぐぐっとけば良いかと
こんな感じかな?コンソールで読み込んだテキストファイルを一行だけ表示するプログラム。 #include <windows.h> #include <stdio.h> #include <stdlib.h> #include <string.h> int _tmain(int argc, _TCHAR* argv[]) { if(argc != 2)return 0; FILE * fp; if( _tfopen_s( &fp, argv[1], _T("r") ) != 0 ) return 0; char buf[32767]; _TCHAR buf2[32767]; if( fgets(buf,32767,fp) == NULL ) return false; size_t size = strlen(buf); if( size > 1 ){ if( buf[ size - 1 ] == '\n') buf[ size - 1 ] = 0; } int len = MultiByteToWideChar( CP_THREAD_ACP,0,buf,32767,buf2,32767 ); MessageBox(NULL,buf2,_T(""),MB_OK); fclose( fp ); return 0; }
>>413 実行ファイルにテキストファイルをドラッグ&ドロップすれば動く
>>414 そのページに書いてあることって根拠のない迷信だよね
>>414 いや…
3フレームまで遅延おkってMSが言ったのならソースが何処か知りたいが見つからないんだもの
AeroじゃなかったDWMだ でもこれMSに責任ないでしょ 先読みレンダリングはサードパーティのツールで無効に出来るって書いてある所もある
VSYNCでリフレッシュレートと同じ回数描画するのが無駄が無くて一番いいんじゃないの リフレッシュレート以上の回数描画処理を走らせるメリットなんかあるのか むしろティアリング発生するデメリットしかないじゃん 描画処理でなく内部の計算処理をリフレッシュレートを超えて走らすのはメリットあるかもしれんが
>>416 迷信じゃないはず。
だいぶ昔なので詳細は忘れたが、同期フリップしても一瞬でもどってくるのでおかしいと思って調べたことがある。
そしたらバッファがいっぱいになるまで待ってくれないことが判明。
DRM切ったら正常になったけど、クレームが来たwww
ドライバで3を0にできるとか当時わからんかったので、その辺は詳しくない。
俺も混乱してきたのでまとめてみる ●垂直同期を使った時 画面の書き換えが終わるまで待つので処理は最小でも16ms間隔になり遅延は最大16msになる →待っている時間が無駄に思えるが遅延は少なくティアリングは発生しない ●垂直同期を使わなかった時 ドライバの設定した値を上限に先読みレンダーが行われるが 0にすれば遅延無し →CPU、GPUをフルに使えるし、DWMなしかつ先読み0なら遅延無し(DWM有効時はそれでも最大16ms遅延?)無論DWMなしではティアリングする
いや、別にする事が無いのならCPUの無駄ではないか 画面が書き換わるまで処理をブロックする通常の垂直同期はそんなに問題ないと思う 画面を書き換えている間に処理を行う方法もあるようだな 次のフレームの処理まで行ったら遅延するかもしれないが、これはプログラマーが決められるから問題ないだろう
あ、オクルージョンクエリーを発行して1フレーム後に結果を参照して先読みを防ぐような手法は聞いたことあるな ソフトウェア側で垂直同期を実装した時もドライバ側がもう画面書き換え終わったって嘘付いたら処理が16ms間隔じゃなくなるけどそんな事する?
ドライバが嘘つきか確かめる 垂直同期のサンプルコードちょうだいよ
426 :
名前は開発中のものです。 :2013/10/15(火) 12:06:29.46 ID:eNYxuu1N
krkr
可変フレームレートって、描画の更新頻度あげるのはいいいけど、モデルやゲーム自体の処理が固定だったら意味なくね? 例えば1秒間に60回処理を更新するゲームで120fps出しても、(処理によるけど)同じ画面が2回描画されるわけだろ?
相変わらず遅延の奴ってソース求めるといなくなるよね 実験したって奴ですらどうやったの?って聞くといなくなる 自分でやらなくてもどっかの有名なサイトとかで実証してそうなもんだが まあいいけど DirectxX11.2のLow-latency APIも画面の更新の話じゃなくインプットの話だよね
どうしても気になるんならユーザーに「フルスクリーンでやってね!」 でいいと思うけどなw
>>428 そんなずっと張り付いてられるかよw
昔のことなのでソース出せと言われてももうないし、やるなら新規に作らんといかんわ。
当時パフォーマンスカウンタとDwmGetCompositionTimingInfoなぞを使って組んだのしか覚えてない。
だいたい、こりゃだめだと思ってもうプログラム側でどうにかするのあきらめたし。
>>427 やるなら内部処理は当然60以上じゃないと。
あと、最近は120Hzのリフレッシュレートを持ったディスプレイがあるからね。
欲しいがいかんせん金がないw
描画処理は別スレッドにしてVSYNC同期で何の問題があるのか というかこれがベストな解でこれ以外ありえないと思うんだけど
434 :
名前は開発中のものです。 :2013/10/15(火) 17:01:51.50 ID:9FpDK6sK
無いっていうのが難しいとか悪魔の証明みたいな話だ
上のとこだと最少で45ms遅れていると書かれてるで
>>431 のMSのサンプルが今までの状態だと46ms遅れてるらしいから
IDXGIDevice1::SetMaximumFrameLatencyの設定は同じ?って事かな
でそのLow-latency presentation APIなるものを使う事によってこれを16msまで
縮めることができますよって事かな???
遅延が妄想とか言ってた
>>428 は
みんなにごめんなさいしてね!
あーよく読み直したらちょっと違うわもういいや(;´Д`)
結局、
>>395 はどうなった?unicodeとShift-JISコードの違いは理解出来たのか?
もしまだならば、unicode Shift-JIS _TCHARで検索する事をオススメする。
このスレの住人は、自分らが初心者だった頃を忘れてないかい?
文字集合と符号化方式を同列に比較しようとする
>>439 みたいな馬鹿は早く死滅すればいいのに。
441 :
名前は開発中のものです。 :2013/10/15(火) 20:51:31.75 ID:qytxVZMa
>>436 >>435 は*描画の*遅延の話
描画が遅れたら結果的に入力遅延になるのだが
結局垂直同期オンではそんな問題にならないって事で良いだろ
使わない場合でも、Direct3D9ExのSetMaximumFrameLatencyでレイテンシを1フレームに設定できるとある
MSが新設するのは必ず毎フレーム入力処理が出来るようにするAPIっぽい
>>440 理解しているなら自分で教えたら?そうすりゃ間違えて教える人も減るから
443 :
名前は開発中のものです。 :2013/10/15(火) 21:04:14.65 ID:RUDXx8qG
「UTF-8とWindows-31J」と言えと?
UTF-8で全て開発したいぜ・・・・
正直ブイシンクとか気にしたことないんだけど 垂直同期っていったって電子銃ってやつは一個しかなくて左上から順番に打ってくわけだろ 何が同期されんの
垂直同期の説明 int i=0; void update() { i++; } void draw() { printf("%d\n", i); } 画面のフレームレートが60fpsで、実行時のフレームレートが180fpsとする 垂直同期が有効なら 1秒で1〜60の数字が描画される 1/60秒毎に1増えた数字が表示される 垂直同期が無効なら 1秒で1〜180の数字が描画される だが、1/60秒後とに3つの数字が同時に表示される これでわかんなかったらどう説明したら良いかわからん
>>445 その電子銃が下から上に移動する一瞬の時間の事だ
ちなみに今はCRTなんてほとんど売ってないぞ
>>444 俺はUTF-8に対応済み
しかし海外に対応する気は全く無い
Windows-31Jで発生するバグがUTF-8だと直ってるんだよな Windows-31Jの頃は運用で回避してきたが
APIとやりとりするならUTF-16じゃないのか? なんでUTF-8でバグが直るんだ?
451 :
名前は開発中のものです。 :2013/10/16(水) 10:14:36.63 ID:OgPi9Jui
細けえ事はいいんだよ!
文字コードなんてゲームと関係ないじゃねーか
ゲーム以前の基礎レベルの話だもんな
デフォルトで使ってて変だと思ったら変えればいいんや
20時までに書き込みがあったらゲーム作る
456 :
名前は開発中のものです。 :2013/10/17(木) 18:40:34.59 ID:GUz904Uc
はよ
期待
何作るの?
459 :
名前は開発中のものです。 :2013/10/17(木) 22:56:47.94 ID:vaYuLY10
FPSで決まりだろJK
この板のどこかでゲーム作ってたけどff14やりすぎて手に付かない
461 :
名前は開発中のものです。 :2013/10/18(金) 00:34:01.43 ID:GBldfOBg
>>460 俺も昔、灰プレイしてたけど
友人の一言でゲームしなく成った
友人「無限ループって怖くねぇ」
俺「………」
殆ど同じ毎日を過ごしてる俺にとって
一番、効いた一言だったかもな…
年を取ると分かるが
狭く見えてた地域が大きく感じる
若い内から此処は狭いと決め付けてたから
気付くのに時間がかかった
色んな事に目を向けると見たものだけ世界が広がるぞ
>>460 俺は日替わりanvaderだ。
日替わりモードでは、ランダムにレベルデザインされてるんだが、これが熱い!
くそっ、アイツに負けたくない!
スレチだが、ランダム要素が増えると、スコアアタックに対する情熱が冷めやすくなるな。
>>463 なんか色々怪しい解説だな…。
Windowsは1/60秒ごとにメッセージを送ってくるとか、パソコンのFPSの設定とか…。(リフレッシュレートの事?)
フレームレートに依存しないことと、タイミングが正確なことは別もんなんだけど、あまり区別がついていないようにも感じる…。
描画処理はVSYNC同期にしてリフレッシュレートと同じ回数実行するべき 計算処理は経過時間を考慮してモニタのリフレッシュレート以上の速度で実行すれば問題ない 描画処理と計算処理を分けて考えるべき 描画処理はリフレッシュレートを超えて実行するのは無駄だし VSYNC固定してないとティアリングが発生するから固定するべき
液晶モニタってvsyncどう扱ってんの? 走査線も無いのに
液晶の表示の変化に時間がかかるんだ 昔は液晶だと動画がブレまくってねぇ・・・・・・
モニタが画面を更新するタイミングと同期を取る事を伝統的に垂直帰線同期と呼んでるだけで、モニタの仕組みがどうのっていうのは今や関係ない。 2D画像の合成の事を、本来のモノと仕組みも出来ることの幅もまるで違うのに、未だにスプライトって呼んでるのと似たようなもんじゃない?
>463を見て、kとかJで始まる何かを思い出してしまったのだが…
>>463 1/60でなんで固定してんだよ
120Hzのモニターだったらタイミングが変わるだろ・・・
あ、kazukiだわ お察し・・・・
なぜ、この板の住人はあいつの誘導にすぐ引っかかるかね
引っ掛かっているのは奴の追っかけだけだろ 勝手に住人全員とばかりに決めつけるんじゃねえよ
全員と決め付けてるのはあんた 全員なんて書いてないっしょ
>>463 こいつ何年もタイトル画面ばっか作ってんな
なのに、いつもサイトの名前が「ゲーム開発〜」っていう。
タイトル画面しかないゲームとか斬新すぎるわ
>>315 ,316
ありがとう。
共通するメンバをできるだけ基底クラスに集めて、
ロジックだけ差し替える感じでやってみる。
いつまでもタイトル画面とか 基礎の部分は既存のフレームワークを参考に作ればすぐ終わるのに・・・
>>463 他の解説記事も見てきたけどあっちこっち怪しいところ間違ってるところ多いな
解説を書くならもうちょっと勉強してからの方がよくね?
>>478 すでに何人も改めるように提言したが無理
風物詩と思ってアキラメロン
>>470 60Hzのモニターでも120Hzのモニターでも
その速度で描画可能にするためには
パソコンがその速度に対応している必要があります
そのパソコンが管理している時間(カウント)を扱って処理制御しているので
問題ないと思われますが
>>464 「Windowsは1/60秒ごとにメッセージを送ってくる」ではなく
「Windowsに1/60秒ごとにメッセージを送る必要がある」です
そうやってメッセージを送ってる時に
例外ハンドラーが働き
Windowsがエラーであることを理解するのです
自分で自分のHNをNGワードとかwww さすがは現実逃避を繰り返し続ける コミュ不全なナマポニートのやる事は一味違うなw
悪口以外書かれることが無いって自覚してんだなw
C++ってfor文ないの? C++は初心者なもんで
タイトル画面開発: タイトル画面開発: タイトル画面開発: タイトル画面開発: 逃亡
>>488 その解説は間違っています
> //Windowsからのメッセージを処理
> if( ProcessMessage() == -1 ) {
> break;
> }
この部分のProcessMessage関数のコメントが間違っています
正しくは「Windowsからのメッセージを処理」ではなく
ProcessMessage関数でWindowsにメッセージを送り
その返り値で処理するです
この場合、Windowsにメッセージを送る処理をProcessMessage関数で行い
その処理に失敗した場合にbreakです
ProcessMessage(); C言語およびC++でこのようにコードを書いた場合、 関数を呼び出す命令になります これは基本中の基本です この場合、ProcessMessage関数を評価し その結果がProcessMessage関数のreturnに代入され 成功したら「0」を、失敗したら「-1」を返します int a = ProcessMessage(); つまり、このようなコードを書いて処理に成功した場合は a変数に「0」が代入されます
> if( DxLib_Init() == -1 ) {
> return -1;
> }
あと、DXライブラリの初期化処理に、
こんなコードを書いていますが
例外処理にはtryブロックとcatchブロックを使うようにしましょう
// 例外処理
try {
// DXライブラリの初期化処理
if( DxLib_Init() ) throw 0;
}
//失敗時の処理
catch(int){
return -1;
}
http://c-games.main.jp/ckiso/ckiso17.html C言語の書籍を出してる割には大したことないですね
ひょっとしてProcessMessage関数知らない? 必須機能っしょ
さわらないでスルーかスルー推奨って書くかにしろ
素朴な疑問を投げかけてみる if( a > 0 ){ a=1; b=2; } if文を使う時、こんな風に よく中カッコを使うコードを見かけることがあるのですが、 私はこれは演算子が増えた分、処理が遅くなるように思える if( a > 0 ) a=1 , b=2 ; 私はこのように組んだ方が、{ } (中カッコ2つ)と ;(セミコロン1つ)の計3つの演算子を使わない分 こっちの方が処理速度が僅かに早くなるように思える どちらもエラーコードではないので 素朴な疑問を呟いてみただけです
処理が速くなっても誤差レベル。 それよりもコードが見づらくなって不具合を起こしやすくなるだけでしょ。
アホなことを言う前に、 出力されたアセンブラのコードを見てみろ いかに間抜けなことを言っていたか分かるから
まずそのif文が大量に並んだクソみたいなコードをなんとかすることを考えろ
ところでどんなミニゲームを作ろうかと ずっと悩んでいたのですが ようやく決まった ミニゲーム第一弾はスロットゲームにしよう パチスロ仕様なスロットにしてボタンを押して絵柄を揃えたら 絵柄の種類によってお金をゲットするというものです で、400G以上ゲット出来たらミニゲーム2が出現する そしてミニゲーム2の内容はUFOキャッチャーにしてみよう プレイヤーがゲットした人形がプレイヤーの分身になってゲームをプレイしていく さらに、ミニゲーム3の出現条件は、ミニゲーム2で1つ以上人形をゲットにします つまり、ミニゲーム2で人形をゲットできなければ またミニゲーム1に戻ってお金を貯めないといけない で、ミニゲーム3はマウスを使ったハエ叩きゲームでもしようかな
また一人で語り始めたよ。 そろそろブログ消去かな。
>>482 >>488 >>493 >>496 >>498 >>500 わざわざ相手するからだよ
どんなに紳士的に且つ真剣に間違いを指摘したところでそれを間違いと認めず
自身の学んだものが何より一番正しいと思い込んで一方的に語りたいだけだから
何言っても無駄。
わざわざレスしたものなら自分語りするための餌を与えるだけだから無視するに限る。
kazukiって書いとけばレス来ないんだろ 天安門みたいだな
>>503 C/C++でのゲーム製作のスレなのに
誰一人、ゲーム製作の話題を出さない方が異常かと思う
というか、ゲーム製作の話題がないと面白くない
このスレに訪れる人はゲーム製作の話題を期待して来ている
そして私は現在進行形でC/C++によるゲーム開発中
きっと、そんな彼のサイトに行けば
色んなゲームの作り方を盗めると思う
http://c-games.main.jp/ もう今は、ここでは多くは語らない
気が向いた時に一言二言発言するだけに留めている
実はデブだったストーカー君には目もくれない
ポーカーでメダルを稼ぐ ↓ 高レート勝負が解禁されるのでもっと稼ぐ ↓ 伝説のディーラーが現れる 去年ツクールでやってたのとたいして発想が変わってないな kazuki
上のほうでゲーム製作の話もいろいろ出てるのに一体どのスレのことを言ってるんだろうな kazuki
スレを一番に荒らそうとしている奴が 正常なスレ進行を望むとかwww kazuki
>色んなゲームの作り方を盗める ゲーム制作じゃなくてc++によるアニメーション作成しかしてないじゃん… kazuki
まったく成長してないな いったい何を職業訓練で学んできたのか kazuki
講座の前にゲームの一つでも公開したほうがいいんじゃね つくったことない人間がつくりかた語るのって滑稽だろ kazuki
私が作るスロットゲームはただのスロットではないよ リーチアクションでプレイヤーを興奮させたい(台を派手に光らせる)し、 最後の絵柄は1コマずつ回転して 惜しいところになるとゆっくり回転し 絵柄が過ぎたと思ったら、最後に逆戻りして絵柄が揃って パンパカパーン!と(笑) UFOキャッチャーでは、 本物のUFOキャッチャーみたいに クレーンで人形を釣り上げているのに 僅かな振動で落ちてしまったりと、面白要素満載にしてみたい ちなみに各ミニゲームは4ステージまであり UFOキャッチャーは1ゲーム100G必要 なので、400G以上持ってないと遊べない
ちなみにUFOキャッチャーで釣り上げた人形がプレイヤーの分身になるのだが、 複数の人形をゲットすれば、 プレイヤーキャラをいつでも変更が可能になる で、別のミニゲームでスーパーマリオのようなゲームを用意する 選択した人形によって、走るスピードやジャンプ力が異なったりして ゲームを有利に展開することも出来る さらに、別のミニゲームでもっとお金を稼がせるゲームを用意し そのお金を使って車を購入して、3Dレースゲームにもなる 車種は複数あり値段によって能力も違う 部品を購入して車のカスタマイズも可能 さらに宇宙船を購入してシューティングゲームにも発展させて どこかの星に到着すると、ミニRPGに発展(笑) まあ、ゲームを面白くする要素を色々考えています。 お楽しみに
>>500 なんか俺もこんな感じになってるわ
もうちょっと単純な分岐だけど
移動操作に、入力されたキーに応じて特定の法則で値を入れると、8方向の分岐判定ができるって
過去にこの手のスレで騒いだんだけど見づらくなるからif文にしろと一喝されてな・・・
◯値を入れると ×値を加算していくと
みんな暇そうなので質問 効果音,画像,モデルのロードや管理はどうやってる? モデル、画像は単体で存在できないから物クラス板クラスをnewするときに持たせたりロードさせてるんだけど、 効果音の管理がうまくできない 今システム音は一括起動ロード、ゲーム内の音は音を出す物体に持たせてる でもバラバラになりやすくて困る
>>515 8方向移動のコードですか
ちょっと考えてみました
//移動
void Idou(){
if( 上ボタン ) y--;
if( 下ボタン ) y++;
if( 左ボタン ) x--;
if( 右ボタン ) x++;
if( 上ボタン && 右上ボタン ) y-- , x++;
if( 上ボタン && 左上ボタン ) y-- , x--;
if( 下ボタン && 右下ボタン ) y++ , x++;
if( 下ボタン && 左下ボタン ) y++ , x--;
}
//エラー
void Idou_E(){
if( 上ボタン && 下ボタン );
if( 右ボタン && 左ボタン );
}
こんな感じの2つの関数を作って2つとも呼び出せばいいのかな?
間違った(笑) こうかな? //移動 void Idou(){ if( 上ボタン ) y--; if( 下ボタン ) y++; if( 左ボタン ) x--; if( 右ボタン ) x++; if( 上ボタン && 右ボタン ) y-- , x++; if( 上ボタン && 左ボタン ) y-- , x--; if( 下ボタン && 右ボタン ) y++ , x++; if( 下ボタン && 左ボタン ) y++ , x--; } まあキャラクターを移動するところになったら もっとじっくり考えてみよう
このスレで聞くよりなんでも掲示板行った方がいいぞw
>>515 さすがに移動処理をまとめるのはないわ
それを言われてifだらけにするのもないわ
例えばAジャンプB加速C攻撃Dガードだとまとめることは不可能
同じキー処理なのにあっちではfor、こっちではifとか見にくいからifで統一すべきってこと
移動量なんかよりキー処理の方が大きい存在だから移動量側の都合に合わせたらあかん
効果音って結構使い回すからグローバルクラス作って全部押し込んでるな よくないんだろうけど
>>520 Windowsから送られるメッセージを処理するで絶対間違いないって
なんならDXライブラリ作った人に掲示板で聞いてきてあげようか?
>>517 俺も
>>523 みたいな感じだな。マネージャクラスを作ってデータの実体はそこで一元管理してる。
ロードは各シーンに移ったタイミングで使うファイルを指定して全て一括ロード。
動的なロード/アンロードみたいなことはしてない。
古典的で単純な設計だけど、変に工夫しても複雑化するばっかで使いづらいだけだったので結局コレに落ち着いた。
今やメモリ2Gがゴミスペックって時代だし、個人レベルで作れる規模のゲームならリソースの容量的にもロード時間やメモリ残量がネックになることはないと思うし。
高度なリソース管理システムがないと管理不能な程リソース数があるわけでもなし。
なので、重複ロードだけ防げればいいかなって考え。
よく使う(かもしれない)リソースはキャッシュしている 使っている間はリソースが解放されないようにさえしておけば キャッシュの最大容量を減らすだけで低メモリ環境に対応できる メモリが十分あるなら最大容量を多めにしてロード時間を削減できる バッググラウンドで次使うデータをロードし続けると、更にロード時間削減するのに良いが流石にこれは難しい
解説サイト作るならdoom3やquake3のソースを丁寧に解説してくれれば すんげー便利なんだが…、まぁ読むのがめんどくさいだけなんだがな(´д`;)
グローバル管理はきついからなぁ… キャッシュ機能追加してみよう
ボクは移動とかのキー入力に関しては携帯ゲーム機のキーコードを参考にビットで演算してる ぶっちゃけそんなに使うキーも無いし特定のボタンを特定のビットに対応させてtrueとfalseで、判定させたい時に&で比較して押されてるか確認する 改行多いって言われたから連投する 画像のロードはたぶん誰かがすでに手法の公開とかしてると思うけど res.h #pragma once #include <string> namespace res { namespace ID { enum { NONE = 0, TEST_1, TEST_2, MAX }; } const std::string FILE_NAME[ID::MAX] { //NONE用 "", "res/test_1", "res/test_2" } static int FileReadCount[ID::MAX] = {0}; std::string LoadFile(const int ID); bool UnLoadFile(const int ID); }
res.cpp #include "res.h" std::string res::LoadFile(const int ID) { res::FileReadCount++; return res::FILE_NAME[ID] } bool res::UnLoadFile(const int ID) { res::FileReadCount--; if(res::FileReadCount <= 0) { return true; } return false; } すまんかなり見辛いな ヘッダーとcppソースファイルの両方使ってる それと外部テキストファイルに書き出してそのシーンで使うと思われるのを全てコンストラクタでそのシーン用のリソースが書いてある外部テキストファイルからロードして、デストラクタ時にそのファイルを全て破棄するってのもやってた けど、前述のソース載せてる方の方が使いやすくて結局そっちだけしか使ってない 今は、今のシーンと次のシーンで同じファイルを使うなら使うファイルだけ破棄しないで使わないファイルは破棄して移行するってのを作ってる
これ見てちょっとオサレな多機能マネージャー思い付いたかもしれん 既存のと組み合わせて頑張ってみる
クラスでprivate宣言するものは全てcppファイルに書くのってどうなんだろう?
hに書いた方がいいんじゃね cppをいじる時にパッとタブ切り替えた時にメンバ一覧として分かり易いしその程度だけど
メンバ定義をヘッダに書くとヘッダの依存関係がな… 実装の隠蔽とか以前に結局pimplとか使わんと作業上の支障が出てしまう。
そういえば、ヘッダでメンバ定義する時の話だけど メンバに、あるインターフェースクラスのポインタを持たせるときって @インターフェースのヘッダをインクルードする? Aそれともインターフェースの型を前方宣言する? もちろん、相互に参照しなきゃいけないときは、片方はAを強制される場合もあるけど
テンプレートにする
>>536 ハーブサッターはAって言ってたな(gotwの7番、理由はコンパイル時間)
俺はよくヘッダ間のinclude関係忘れるからcpp側でも全部includeするけど
STLとかベンダでまちまちらしいし
>>520 それだと複数のボタンが同時に押されている場合、効果が相殺されてしまう
例えば上ボタンと下ボタンの両方が押されていると
y--した後に、y++するのでy座標はじっとしたままになる
2行目以降はifではなく、else ifにした方がいいよ
>>539 上下同時押しの時に相殺された方がいいかどちらかが優先された方がいいかは好みの問題じゃない?
それより斜め移動の速度が2の平方根の二倍になってるほうが問題あるだろ
ネタにマジレスしてしまったのだろうか
まっすぐよりジグザグ移動の方が速いゲームが確かあったな
0.9899って地味にいい数値だよな
飛行機にしろ自動車にしろ全方位に等速で動けると考える方がおかしい。 結局作りたいものによる。
縦横と斜めで三倍の差というのは流石に開きすぎとも思ったけど、クォータービューだと良いのかもな
マリオ系のアクションは左右と上下分割した方が扱いやすいし、シレン系とかのマス移動なんかは斜めの速度なんて考慮する必要ないし、 まぁケースバイケースか
>>520 これ、例えば環境具体的にして、winならば GetAsyncKeyState 使う等して、要は「その時のキーの状態を見る」って前提があれば
8方向移動でも2行で終わるし、
そうでない場合でも必要なキーがわかってるなら、前提としてこの関数呼び出す時点で複数のキー状態わかるようにしとけば
こうはならないかなと
4行ベタがき安定っすわ マス型じゃなければ大なり小なりキー処理とは別の移動衝突判定作るだろうし 移動量を加算しておくだけ。
16要素のベクトルの配列用意してそこから引くってのはどうだろ 斜め移動の時の正規化の手間が一度ですむ int index = 上ボタン | (下ボタン << 1) | (左ボタン << 2) | (右ボタン << 3); const VECTOR &v = ARROW_VECTORS[index];
>>548 vectorと言うかbitでそれ表して同じ流れってのは昔からある方法
あ、ごめんちゃんと見てなかった
>>548 で合ってる。それ昔からある方法の一つ。キー入力に限らず。
8方向ってテンキー対応方式で数値化してると、実方向(ベクトルとか)との 互換が案外面倒なんだよねえ 1~9という数値に、数学のベクトル的なセマンティクス持たせるのが難しいから 専用のゴリ変換マッピングをしなければならないという
3の商と余りでうんたらって奴?
>>551 どんなの想像してるかアレだけど、正規化された二軸のベクトルと思えばそんな大変でも無いと思うけど
>>553 例えば4ビットそれぞれに意味を持たせて、それで得られる16通り分の定数を配列から拾ってるだけ
byte k=0; k |= 上?8:0; k |=下?4:0; k |= 左?2:0; k |= 右?1:0; で、kには0から15の16通りの値が決まるから、 配列に方向値の構造体とか予め入れておいて取り出すのような。
一度作った後は使い回すだけだと思うけど いろいろ考えるんだなw
うーんそれを使うと if( 上ボタン ) y--; が if( 定数==上 ) y--; みたいな感じになるの?
>>558 ifすら使わない
関数ポインタの配列でおk
というか、何でもかんでもifをアホみたいに並べるのは某バカkだけでおなか一杯
普段そのやり方でやってる人って押してから20カウントごとに移動(選択肢移動みたいなの)とかどう拡張してんの
関数_上 y-- 関数_右 x++ 関数_上右 y--;x++ みたいなのを作って関数ポインタ配列に入れて 関数ポインタ配列「キー入力値」 みたいな感じでアクセスするのか。なるほど
swichで定数で飛ばせば最適化がうまく働くんじゃないかね でも使うのって秒間60回前後だろうし分かり易ければ何でもいいようなと思う反面 どうせベンチに現れない誤差でしかないのに テーブルだとキャッシュ汚染するんじゃないだろうかと心配もしてしまう貧乏性が情けないわ
>>564 そう。
俺はif(keycount[num]%20==1)
みたいな感じでやってるけど
最初からカウントするなら利点消してそうだし
>>563 のスイッチだと見にくくなりそう
vsync固定しないやり方でキーリピートってどうやんの
vsync関係ないと思うが
いや、下記のようにやって キーリピートのカウンターが60になってたら1秒経過したことにしたりするんでしょ vsync待ちしないで全速力でぶん回してたらカウンターが60になってても1秒経過したことにならないよね while(1) { checkKey(); calc(); draw(); flip(); waitVsync(); }
普通そういう処理って、システムが持ってるタイマー利用して経過時間見るよ。環境によっては無いかも知れないが。 winで言うと、QueryPerformanceほげほげ系の関数
>>565 リピートはねー、俺の場合はそこで実装してないんだよね
キーボードとジョイスティックを管理するクラスでやってるので
リピート付きの取得関数と無しの関数をもってて
受け取る側はリピートのこと考えなくていい
>>552 それなりに工夫のしようはあると思うけど
たとえば、「9の逆方向」とかがアルゴリズムで処理しにくいよねってこと
あ、いや、まぁ、逆方向なら 10 - 値 でいいんだけど、
左右反転とか斜め反転とか、ゲームだといろいろとそういう数学的な処理が
必要になってくると思うから、ベクトルと相互変換できるのセマンティクス無視の
ゴリマッピングメソッドは用意しておいた方がやりやすいよねってこと
流れで聞くけど「入力された瞬間」と「押しっぱなし」で動きを変えたいときははどう処理するんだろう 各キー毎に押しっぱなし処理があるから全部に関数_上押しっぱとか作ってられないし…
>>572 俺が昔実装した方法で言うと、入力ハンドリングの処理はキーの状態変化とその経過時間をFIFOキューに溜めていくだけにして、
入力に対して何か行動する処理はキューから結果をもらうって方法を取った。
短い時間の押し具合と、長押しや押しっぱなしの判断は、キューから取得したステートで判断てかんじ。
ポイントは経過時間(要件的には時計で言う時間でなくても良い、メインループの経過カウンタでも良い)で判定って所。
>>572 いろいろやり方あるけど俺はダブルバッファリング派
前回と今回が違う値だったら押した瞬間
あぁ押した瞬間とかの識別方法の話しじゃないんだ。処理を変える方法というか… キー入力関数ポインタ[16]={関数_上,関数_下,…} さっき上で話してたやつ。こんなのがあるとして 関数_上() { if(押しっぱ) { }else {} } みたいなことしてたら全部のキー関数でif文しないといけないじゃない? そこで「関数_上押しっぱ」みたいなのを作りたいんだけど そうするとキー入力関数ポインタじゃアクセスできなくなる… どういう感じに判別して処理を変えればスマートだろうか
ボタンの押下状態を取得する関数に、 引数で「その瞬間のみ」というフラグを立てれるようにしてる。 キーリピートや、10フレーム以上押しっぱなしで真にする、とかも同じような感じで取れる
>>575 やりたいことによって違うので、それだけの情報じゃ何とも言えんが例えば
if(押しっぱ) おしっぱ関数ポインタ[キー入力値];
else おした瞬間関数ポインタ[キー入力値];
とか?
>>577 それだと「上をおしっぱの状態で右が初めて押された時」とかができないんだよね
そんなの使う時あるの?って聞かれたらなんとも言えないけど…
押されてたらカウンタをインクリメントしていって カウンタが1だったら始めて押されてたことにすればいいんじゃ
>>580 単純ならそれでいいが、複雑な処理になると死ねる
格闘系のコマンド入力を例にすると
間に変なキーが挟まっても処理できるように、履歴を参照できないとキツイ
ああ、そういうことか。 それなら自分が前にやったのは、>573とだいたい同じっぽい。
俺は格闘コマンドは入力部分はいじらずに入力を監視するオートマトン用意してるな 受理したら発動みたいな
入力履歴はそのまま記録すればリプレイにも使えるしデバッグにも利用できる。
>>583 その監視側が履歴を必要とするはずだから、多分それは遠回りな実装。
具体的にコードパス説明してみ
テンプレートとautoってどう使い分けんの?
>>586 使い分けるも何もテンプレートとautoは全く別
std::vector< std::map<std::string, int> > map_vec;
こういうのがあったとしてイテレータを取るには
std::vector< std::map<std::string, int> >::iterator i = map_vec.begin();
と長ったらしく書かないといけないが、autoで型推論させると
auto i = map_vec.begin();
でいいわけ
>>586 勘違いしてる可能性があるから一応念のため言っておくけど
auto型っていう型がある訳ではないからね
吐きそう
エラーが?
コアかもしれん
別にイテレータじゃなく適当なクラスのバッファにならないの?型推論で void hoge(auto a,auto b); とかでもいいのかなーと
template<class T1, class T2> void hoge(T1 a, T2 b);
>>592 それに近い使い方は戻り値のautoかな
しかし確かに
>>593 みたいな糖衣構文が来ても悪くないような気もするね
ただ、C++のテンプレートだと特殊化が命みたいなとこもあるからなぁ
テンプレートメソッドをオーバーロードしたら自動的に 特殊化扱いになるようにしてくれたら良いのに 思わぬとこで「オーバーロードが曖昧です」とか言われても焦る
テンプレートってヘッダに定義書かないとダメなの? せっかく美しく宣言と定義わけて書いてるのに
ファイルを分けるなら、ヘッダ内で定義をincludeすればいいだけ。
そういえばそんな宣言無かったっけ? 正式採用されなかった気もするが
他のコンパイル単位でテンプレートの定義あることに期待して 自分のコンパイル単位ではテンプレートの定義をインクルードしないっていう キーワードは追加されたけど、ぶっちゃけどういう時に使えばいいのかわからん
まあいいさ、そのうち、私の解説サイトで RPGの作り方を解説してみるさ そしたら、それほど難しくないことが解かることでしょう
私のってポナちゃんの?
レスが飛んでると思ったら
DXライブラリ総合スレと思って誤爆しているんだろw ゲーム製作云々より自画自賛の解説サイトの宣伝に夢中で あれがやりたいだのこれをやってみせるだのと 手を動かさず口だけ妄想と自分語りしか出来ないで 複数のスレッドに目をつけては書き込みするタイミングを伺っている
複数のスレっつーか こことあそこがメインフィールドだと思う 今日(もう昨日か)は文体だけで識別することに成功したから ようやく俺もゲ製の一員になれたような、そんな気分になれたよ
なあ、今作ってるゲームの実行ファイルのサイズって何kバイトぐらい? 俺のは280kほど。ちなみに画像とか音声とかは別にしてある。
ランタイムを実行ファイルに組み込むか外に持つかで全然変わる。
RPGよりノベルゲームの方が作るのは簡単だよ! だからまずはノベルゲームの作り方から入ったら?
文章書かなきゃならないとか……高難易度すぎるだろ……
じゃあアドベンチャーゲームとかw つ〜かプログラムの作成難易度はノベルゲーム→アドベンチャーゲーム→RPGなんだがな
そういえば、文章の難易度は、RPG→アドベンチャゲームー→ノベルゲームかな?
戦闘シーンだけ、あるいは探索シーンだけなら、 他ジャンルと比べてプログラム自体が難しいわけじゃないと思うんだよね。
シーンの変更もそれほど難しいとは思わないが?
それでふと思ったが、ゲーム製作って言うより完全にプログラミングそのものの領分になるけど、 シーンの管理処理とか、表面的に目立たない屋台骨の部分について最初から自分の中で定番化するような物考えて持ってると、 正直どうとでも応用効くよな。 で初心者の人とか、初心者が開いた入門講座みたいな物コピペしてただ覚えたような人だと その部分が自分の中で定式化出来ないから「難しい、わからない、思い付かない」になるのかなと。 あくまで一般的な話だけど。
>>612 シーンの変更というよりは、ミニゲーム2つ3つ作るようなもんじゃん?
もちろん使い回すコードはあるにしてもさ。
それぞれのシーンが難しくないならば、ふたつ作るのもたいして変わらない 一桁の足し算を100回やるのは面倒ではあるけど難しくはならないだろう?
ソースに文章書き込むなら簡単だけどスクリプトとか文字列操作熟知してないと難しそう えんいー
スクリプトの作成ってインジェクション対策がめんどくさそう ある程度適当な文法でもエラー出力作ってなかったら通っちゃうだろうし 外部に置くってなると他人に触らせること前提ってイメージがある
他人の作った組み込みスクリプトを使うという方法もある けれども基本的には、自作する事で得られる様々な知識や知恵の方が大事かと まあ簡単なノベルゲームやアドベンチャーゲームの一つ二つ作るつもりで挑むべし つーか、これらのゲームも基本的にはスクリプトを使ってると思った方が良いかと
そもそもシーンの変更を扱う方法はスクリプトに限らない。 マルチスレッドを使う方法もあれば、タスクシステムを使う 方法もある。フラグや分岐や関数ポインタでえっちらおっちら やったっていいし。どの方法にも一長一短がある。どうせ内部で どんな挙動をしているかは作ったプログラマにしか分からない んだし、自分の好きなやり方でやるべし。
>>613 そういう人たちにはむしろ組み込みスクリプトを教えた方が良いのかもしれんな
組み込みスクリプトを使っている人達には迷惑かもしれんが
シーンの変更はオブジェクト指向で実現しようとすると難しいなぁ 主に共有したいデータのやり取りとか あと、コンソールゲームと違ってループを意識して状態を保存できないといけない Boostにコルーチンあるけど、自分のに組み込むほどの理解には至れないなー 描画を別スレッドにするのでも良いけど、マウスゲーのように画面と操作(MV)が密接に 関わっているような作りだと、フレムワーク自分で作るのは骨だろうね
自前主義からの脱却を
シーンごとに別のループを用意するんじゃダメなの? 俺の場合、メインスレッドを用意して、シーンごとに別のループを作ってるが。 この方法の問題点は同期処理関連をおろそかにするとフリーズする事かな? Windows7以降だとそうでも無いんだが、昔のOSだとOSごとフリーズするので、 デバッグでは苦労した覚えがある。
>>621 ごめん、なんか引っ掛かった。
> シーンの変更はオブジェクト指向で実現しようとすると難しいなぁ
> 主に共有したいデータのやり取りとか
それ、全体としての実装手法の話と、アプリケーション固有の(自分自身の)設計の話が切り別れて無い印象を受けた。
もしかして固定的な何か一つの実装をイメージしてないか?
複数スレッド使う事や全体としてOOの考え方で実装する事と、シーンの変更がしんどいか否かはレイヤの違う話かと。
ループは一つにしておけよ・・・
ソースが分かりにくくなるから却下
一つのメインループの中で、現在設定されてるシーンに対応したイベントと描画処理を呼び出すのではいかんのか
例えば、シーンが変わるごとに同じループでフラグ管理とかポインタ関数管理とかやってると、 一度に二重三重のシーン変更処理が入った場合にバグを発生させる可能性が高くなるからな。 シーンごとに別ループで管理しておけば、少なくともそういったバグが出る可能性は無い。
昔のOSでフリーズしてる時点でバグが有るんだろw
スレッドの同期関連のバグとシーン変更関連のバグを同列で扱う馬鹿よりはマシかと
昔のOSはちょっと間違えるだけでフリーズしたりブルースクリーンが出たりして大変だったよな
MS-DOS時代はフリーズしてもあんまし文句言われなかったのにな
DOS時代だって数百万円するのに使えないCADとか不満多かったけど バックアップするにもドライブ遅いから時間かかるし 一太郎だって安定してた4.3を使い続けたりだとか
うーん、そんなに複雑になるものかな? 自分の場合、ゲームのメインループ自体の仕事はFPSの計測と負荷調整だけで、いつシーンが変更されたかなんて気にしなくていいような設計にしてたもんで……
でも昔はリセットボタンを手軽に押せたけど今は手軽に押せないじゃん っていうか、最近リセットボタン使ってないなぁ・・・・・・
>>634 RPGで?それは凄いな。バグの解析で頭こんがらがらない?
メインループ設けるだけでバグの解析が難しくなる設計ってどうやるんだ
岩押したり船やドラゴンに乗ったりNPCを特定動作させたりランダム動作させたり あと何やったかな?そんな所ですが
>>636 俺の場合、最初と次に作ったゲームはシーン毎にループ処理やってたけど、
それ以降はメインループ一本にしたら、管理とか変更とかすげー楽になった。
設計の意味知らないんじゃん・・・
>>639 ID凄ぇ
なんか、自分とは逆だな。昔はメインループ一本だったのに、今はループを分けて作ってる。
バグを出さない方向に工夫した結果なんだがな。
>>640 DQ2とFFを足して割ったようなゲームを作る以上の事は特に考えずに、
その場の思いつきでRPG作ってるからなぁ・・・
久々にひどいワナビバカを見たわw アマチュア時代は自分で思いついたことを素晴らしいことだと思わず、 すでに実績のあることを自分のものにすることに力を入れたほうがいいぞ。
>>638 メインループとゲームのロジックは、明確に分けるべき。構造化プログラミングすら出来てないんじゃないか?
横レスだけど ヤバイ 何を言ってるのか理解できない ボクはプログラミング力が低いらしい メインループ内でシーンマネージャー呼ぶ シーンマネージャーの中で各シーンの処理を呼ぶ 各シーンの処理の中でそのシーンでやりたいことの処理を呼ぶ こんな感じじゃダメなの?
いいよそれで
>>645 普通に考えるとそういう設計になると思う。てか、ドシンプルに最初に書く屋台骨ってそうなると思う。
合ってる。そういう設計プロセスのイメージが出来ない人ってのが、つまり
>>613 に書かれてるような、考えと整理の経験が足らない人って事になると思う。
メインループを分けるってことはメッセージ処理をあちこちから呼び出すってことが
それのどこがわるいんだ?龍神録の講座でもメインループは一つのみ、 複数あったら設計がおかしいとか書いてあるけど、 メッセージ処理とかするのに、わざわざ深いネストから抜けないといけないじゃん。
メッセージ処理とやらをシーンがやんの?
メッセージ処理をまとめた関数をシーンが自由に呼び出す
ゲームのメインループはメインスレッド上に用意し、 メッセージループはDirect3Dのオブジェクト管理をしているが?
なんかマルチスレッドとか使ったらすごい複雑になりそう
同期処理関連を理解してれば問題無い
メッセージループでPeekMessage使うとCPU使用率が100%にならない? それが嫌だからマルチスレッド使ってる。
100%になるのはSleep入れてないからでは?
>>651 メッセージ処理とやらをシーンから呼び出す必要があんの?
メッセージ処理って何?
メッセージループにSleep入れるとOSの動作が不安定になってただろ?
>>657 普通にPeekMessageとかのウィンドウ一連の処理。
>>658 いや?不安定になるのは長く入れすぎじゃないか?
むしろSleep(0)として、ほかのスレッドに処理渡さないと逆に不安定になると思うが・・・・
>>658 普通ならない。
>>660 も言ってるけど、OSと自分の書いてるアプリケーションの関係、つまりメッセージの循環(OSのメッセージポンプ、メッセージディスパッチ)の
立場とか意味わかって書いてたらならないと思う。
>>660 昔、PeekMessageにSleep(16)とかやってたなぁ、そういや。
今はGetMessageにタイマースレッドとメインスレッドを組み合わせているから関係ないが。
663 :
名前は開発中のものです。 :2013/11/10(日) 13:46:45.40 ID:NUelFT18
↑まずこの土台の中で、抜けてる考えが無い前提の上で、話してるんだよな? > 今はGetMessageにタイマースレッドとメインスレッドを組み合わせているから ちょっと引っかかったけど、GetMessageってただ単にOSのメッセージキューからメッセージ引っこ抜いて構造体に詰めてくれるだけ、かつ 取得するまで処理が返らない訳だから、書かれてる内容から察すると、要は別スレッドから OSのメッセージキューにお構いなしにブチ込んで 自分のやりたい処理はウィンドプロシージャへのディスパッチ経由で動かしてるって言う、なんか変に遠回しな方法になってるけど そこら辺の動作はちゃんと見えてる上で、設計してるか?
そこら辺は俺もちょっと気になった。ループがタイマーに依存するから、 常にアイドルイベント発生させて、そっちでやったほうが良いような・・・
昔のコードを見るのは久しぶりだな。土台の部分は while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } ままだよ?WinProcは最近は全然いじってない。 主にいじるのはメインスレッドだけ。
いや、そういえばマルチスレッドか。 メインスレッドはどういう処理を司ってるの?
668 :
名前は開発中のものです。 :2013/11/10(日) 14:18:19.26 ID:7FOwMs/k
我はメインスレッド 世界を司るものなり
>>666 自分の設計による実装都合の範疇だから良い悪いを言う話じゃないが、そこに書かれてる動作って基本的に、
「OSと言うプログラム側が行っている、一番大きな、こちらからは見えないレイヤのループの中で、
OS管轄のメッセージキューにメッセージが放り込まれるまで 『待機する』 形式」 なので、
それで要件が間に合うならそれでいいし(例えばOSベンダ提供のAPIを単に利用したユーティリティとか)、そうでないなら違う。
そこの意味と切り分けをした上での選択であれば、普通の処理だよ。
そしてメインスレッドってのは、そのメッセージループを 「OSと言うプログラムが、自分のアプリケーションコードを、エントリ関数から実行している最初のスレッド」 の事なので
> 主にいじるのはメインスレッドだけ。
↑この言い様と書かれたコードの間に差異があるように見える。
メインスレッドでゲームの主な処理全般をやってて、WinProcがレストア対策とかを、 タイマースレッドはこんだけ。 DWORD _DrawTim(LPVOID pParam) { while(g_boolTimeLoop) { Sleep(DRAW_TIME_WAIT); SetEvent(m_hMainEvent); } PostMessage(g_hWnd,WM_SYSCOMMAND,SC_CLOSE,NULL); return 0; }
あぁ、もしかして
>>666 が言っている 「メインスレッド」 って、いわゆるメインスレッドじゃなくて、
「自分で別に起こした、ゲーム処理用のスレッドの事」 の事か。
で、OS側とのポンプを行うディスパッチは、「本当のメインスレッド側に任せている」 みたいな。
もしもそういう意図で言ってるならいいんじゃねと思うが。多分にエスパーだけど。
用語に齟齬がある感じか?
>>672 ああ、そういう事を聞きたかったのか。理解力が無くてすまん。
それで当たってる。
把握
>>671 > メインスレッドでゲームの主な処理全般をやってて、WinProcがレストア対策とかを、
入れ違ったけど、
>>672 で合ってたようだ。
そしてその様子だと、なんかOS側都合の処理と自分のアプリケーションコードと、切り分けないで行ったり来たり混ぜ込んでるみたいだけど
… いやそれで問題無いなら別にいいが、エラく遠回りな実行パスになってるなぁとは思うけど。
あと "タイマー" スレッドって言うか、それもしかしてハートビート処理してるんじゃね的な印象受けるが。
いや、いいならいいんだけど。
一応念の為、今ここで話してる内容は、単に 「その人の都合でそう実装してる」 の範疇を今の所出ていないので、 一絡げに良い悪いでぶった切れる訳じゃないって事を一応書いておく。
えっと、ハートビート処理っていうのか、これ。 始めはマイクロ秒単位に直すべきかな?とは思ってたんだけど、 なんだか最近はどうでも良くなってね。 多分、苦情も出ないだろうと。
いや、本当にハートビートなのか単なるタイマーなのかは、その処理がどういう文脈やアイデンティティを持たされて単位化されたかによるので、
違う使われ方なら違うと思うけど、
>>671 のコードだけ見ると、一定速で足並みそろえる為だけに別スレッド起こして
定期的に処理全体の速度決めてるみたいだから、それっぽく見えただけ。 ループ1回のテンポ管理って言うか。
>>675 レストア関連の処理を登録型にして、オブジェクトの生成時に自動登録してるから変に思うのかな?
>>679 ?いや全然そういう事じゃなくて、書いてる通り。
あと、「変」 と思ってる訳じゃなくて、これも書いてる通り、エラく遠回りな実行パスになってるなぁって話。
> OS側都合の処理と自分のアプリケーションコードと、切り分けないで行ったり来たり混ぜ込んでるみたいだけど
こういう事。OS側都合の処理と、自分側都合のアプリケーション設計のレイヤをキレイに整理して分けないで、あえて混ぜ込んでるのかなと思ったって事。
そう思った理由が、要は別スレッドに分けようがどうしようがいいんだけど、いちいちOS側のメッセージポンプ経由してやりとりしてるように見えたから。
あああと、こう言ったらいいか。 OSに対してメッセージを送信したり受信したりって動作は、メッセージキューに対してデータをストアしたり自分で取得したりって言葉に置き換えられて、 で、取得したメッセージデータをディスパッチするなりなんなりしてポンプとやりとりするその繰り返しを、つまりメッセージループと呼ぶ訳だけど、 その動作の正体って、要はこちらのアプリケーションコードがOSと協調して動く為に、 OS側の都合で用意された仕組みな訳で、いわば 「ここで動く物ならば、書かねばならない事」 な訳だけど、 それはそれ、これはこれって話で、逆にこちらのアプリケーションコード側には当然こちらの処理都合や設計がある訳で、 その両者、つまりOS側都合のコードと、アプリケーションの設計に基づく自分都合のコードと、それらの仲立ちをする部分ってのを 明確に分けないで、常にOS側に寄ってるような書き様に見えた、って事。 でも細かい事を言えば、例えば描画処理やキーやマウスなんかの入力状態の取得は 結局OS側API経由で行う訳だから、その意味では完全に切り分かりはしないんだけど、メッセージポンプそのものを直接操作する部分まで 自分のレイヤに置いてるから、実行パスがなんか長く無いか? と思うって事。 真面目に書くと長い。
この手の話で描画を別スレッドでやるとかの話がよく出るんだけど 具体的にどんなふんにやってるのか、それがよくわからんのよね メインスレッドはメッセージポンプだけ担当させて メッセージは別の状態更新スレッドに送って、さらに描画を別スレッドでやる? 1/60秒で処理をやるにしても、正確に処理をまわせるのか?って悩んでるんだけど。
ゲームスレッドの中に色々とループ処理を入れて それぞれのシーンを表現しているけれども、 それに違和感を感じたって事かな?
描画を別スレッドでやる意味あるのか? ゲームの処理を終わらせた後じゃないと描画する意味が無いから メインループ { 1F経過まで待つ シーンマネージャー処理(ゲーム処理) シーンマネージャー処理(描画処理) } もちろんゲームの処理は中でできるとこだけマルチスレッドにしてもいいけど こんな感じじゃダメなの?
>描画を別スレッド 自分の場合は描画もゲームスレッドでやってるからそれは何とも言えない。 ただ単純に、 for(int i = 0;i<30;i++){1F経過まで待つ;ゲーム処理;描画処理;} ってやれると楽そうだな、という発想でゲームスレッドでやってるから。
こんな感じ。 //初めのシーン for(int i = 0;i<30;i++){1F経過まで待つ;ゲーム処理;描画処理;} //ゲームシーン(breakで抜けるまで続く) for(;;){1F経過まで待つ;ゲーム処理;描画処理;} //終了シーン for(int i = 0;i<30;i++){1F経過まで待つ;ゲーム処理;描画処理;}
>>686 やっぱり言葉よりコードだな、ようやく言いたいことが分かった。
確かに分かりやすいし書きやすい。
もう少し粒度を小さくしないと、後々大変そうだけどね…
どの当たりが楽になったの?
簡易的なコルーチンのように使えるはず
じゃあコルーチン使えばいいじゃんw
だね
データの複製を2つ用意して、計3つ(A、B、C)のデータを 2つのスレッドで構造体のポインタをスワップする方式とか構想したことあるなぁ Aを描画スレッドが使って、Cをルーチンスレッドが更新、 AとCのスレッド同期待ちを防ぐためにBがあるんだけどメモリ消費3倍の割りに 得るものがほとんどないんだよねw A ←→ B ←→ C
描画コマンドをリストに貯めてそいつをダブルバッファとしておけばいいんじゃないの? DirectX11のマルチスレッド対応も実際には描画してないし
垂直同期って具体的にどうやるの? データから頂点の座標取得したりする描画スレッドとそれ以外のメッセージ処理や更新判定処理スレッドの 二つがあるとして メインループの中で 更新 判定 描画 ってやってるんだけどちょちょいのちょいで出来るようにならない? 一応オブジェクト指向に則って疎結合を意識してるつもりな設計
あ、ごめん、5行目からは現状の話ね
OpenGLやDirectX使わないと垂直同期ってとれないんじゃないかな?
ちゃんとした垂直同期はDXGIじゃなかったか? なんちゃって垂直同期は16ms待てばいい
DXGIってDirectX10以降か。 それ以前と以降では仕組みが違うんかな。
普通にD3D9以前でもできたっぺ 基本フルスクリーンモードでなきゃなんちゃってだけど
702 :
名前は開発中のものです。 :2013/11/11(月) 16:02:02.14 ID:QJvegRhH
DirectX9 シェーダプログラミングブックを手にいれたんだけど、ネット見てるとアプリケーションウィザードってのが使えないらしい これのかわりになるものってありますか? ちなみにPCはWindows7でDirectX11です。
Windows8.1でDirectXが11.2に進化 CPUやメモリへの負荷がさらに軽減され、 超高解像度の大画面などの表示もこれまで以上に快適になりました
ほんとかよ(´・ω・`)
Windowsが8にしんかした
>>702 もしかして VisualStudioのAppWizardの事言ってる?
Directx9の時だったかあったかも 最後の方のDirectX9のサンプルを持ってればその中にEmptyProjectってのが代わりにあった これをそのまま毎回コピペして読み込めばたぶん一緒 最近のVisualStudioなら最初にテンプレートのエクスポートすればコピペしなくて済みそうだ
>>707 確かにEmptyProjectってのはありました
テンプレートのエクスポートってのをちょっと詳しく教えてください
そもそも必要性がないから無くなったのに、それで何がしたいんだ?
VisualStudioのAppWizardの事なら無償のExpress版と有償版で扱い違うから、 テンプレート書き換えの際に注意な。 あと基本的に自己責任
>>709 DirectX9 シェーダープログラミングブックではその機能を使って進めてるから、ない場合はどうすればいいのかなと疑問に思っただけ
>>709 大体シェーダプログラミングってお題でなんでAppWizard必要なのかってのは
俺もずっと引っ掛かってた
>>711 そのお題で言うなら、要点はhlsl書く部分なので、
いつも通りのDirectXコード書いた上で、追加するイメージだよ
>>713 なるほどわかりました
丁寧な回答ありがとうございました!
DXlibずっと使ってたからわかんないんだけど 3dゲームでモデルファイル読み込むときって自分でバイナリ展開して頂点一個づつメモリ確保しておくの? それともdorectxにそういう型があるの?
>>708 EmptyProjectでもなんでもいいんだけど読み込んでビルドして問題ないようなら
メニューから→ファイル→テンプレートのエクスポートしておくと
新規作成で同じプロジェクトが量産できる
>>716 そうなんですか?
めちゃくちゃ便利ですねww
今度使ってみます
頂点リストをメッシュに持たせて、フレームで束ねるだけ。 シェーダでは使いやすい構造を自分で定義して使う。
>>715 一応D3DXMESH型って言ういわゆる xフォーマットって呼ばれる形式はあるよ。
あるが、都合によっては遠回りだった色々あるので、VertexBufferやIndexBufferに詰めて、カスタムFVFで頂点情報指定して、
自分でDrawしたりする、
でその際、hlslのVertexShaderでは頂点の表示用移動計算したり、PixelShaderではラスタライズする際の色の計算したりする。
そんな感じ。
俺はDirectXとOpenGLの両方でキャラクタコントロール処理書いてるけど、どっちも基本的な考え方と処理方法の方針は同じ。
ちなみに必須じゃないけど、一度上に書いたような処理について深く掘り下げて理解しておくと、 例えばAndroidアプリ作るような場合にもほぼそのまま同じ考え方を持っていけるので楽しい。
ちょい質問なんだけど、RPGとかのマップチップって例えば100×100のマップで既に 4byte(int) * 100 * 100 = 40Kbyte をメモリ上に展開しちゃうことになると思うんだけど、 そんなにメモリ使っちゃってOKなんかな? charで節約したりした方がいいのん?
40kを気にするほどかつかつな環境で作ってるなら自分で工夫しないと。 それはそれとして、普通8bitで収まる情報量なら聞くまでもなくわざわざ4byteで持たないと思うけど。
どうしても足りないときはVRAMの画面外使ったりしてたなw 将来的にも、640KBもあれば充分だw
(*゚ω゚ ) 不安ならメモリ増設すればいいじゃないか つi'"': `、:_i'
今時数十kbyteのメモリーの心配って、どんな環境よ?
よし、16KB拡張RAM挿すか!
>>722 ありがとう。レイヤに分けるとけっこう嵩みそうだったから気になったの
マップエディタによっては8bitじゃ収まらないものもあるよ
クラス使ってると構造体を使う必要性が感じられないんだがいいんだろうか
クラスだとmemcpyが使えないからなぁ……
c++でのclassとstructは実体がほぼ同じだし classばっかり使ってても別に問題ないと思うよ 使い分け指針は人によって違ってくるんじゃないかな 俺は、PODでメンバ関数をほとんど持たないものはstructにして それ以外はclassにしてる
thx アイテムとかはクラスにするか
>>731 構造体だって、メンバに仮想関数がいる時点でアウト。
クラスと構造体の違いは、デフォルトの属性だけだ。
ファイルアクセスにはよく使う。
ファイルアクセスって構造体できるの? 配列でやってるが セーブデータ類は一旦構造体にまとめてるな
それともファイル入出力時に書く魔法の呪文の一部のあれか
「グローバル変数は使わない方がいい」と言うので勉強しなおしてるんですが、ずっと頭を悩ませてます。 例えば、いままで下のようにプログラミングしてました。 int loopflg = 1 ; main() { }
あ、すみません途中送信しちゃいました。 int loopflg = 1; main (){ while( loopflg) { //色々処理 } } こうしてると、プログラムのどこでもloopflgをオフにすればプログラムを終了させたりする事ができてたのですが、 これをグローバル変数でなくするとしたら、いちいちポインタをloopflgを使うであろう全関数に渡さなくてはいけないって事になるのでしょうか?
普通はメッセージを投げる
俺は、コピーの時に内容をまるまるコピーしても大丈夫なものをstruct ダメなモノをclassで定義してるな
趣味レベルのたかだか数千行クラスの糞コードなんか グローバル変数使いまくりでもmain関数一本でも力技でねじ伏せられるから 何の問題もないよ
ポインタを渡して書き換えさせるのなら、結局グローバル変数と同じ危険性があるじゃないか…… 何でグローバル変数の濫用がいけないのか、その理由について調べた方が良いよ
>>742 それでいいって考え方のまま定着すると、当然本人が糞しか知らない人間になるけどな。
それでいいならご自由に。
グローバル変数はどこからでもアクセスできるから危険なのであってポインタは渡せなければアクセス出来ないから グローバル変数よりかは安全
どこからでも変更できる事が利点として働いているなら グローバル変数のままで良いんじゃないかな
AクラスをBクラスで使いたくて、 BクラスでAクラスのヘッダーをincludeしてから、 A* a; って宣言したんだけど、「 構文エラー : ';' が '*' の前にありません。」って怒られる。 宣言を削除したらエラーは解消されるんだけど。誰か助けてー。
循環参照になってんじゃない? もしそうならBヘッダ内でのinclude Aを消して、class A;ってだけ書けばいけると思う Bヘッダ内でAのポインタ以外も使ってるとこの方法でも駄目だから、 その場合は循環参照をなくすかヘッダ内はポインタのみの使用にしないとだめ
>>747 Aクラスの宣言の終わりの } の後ろにつけるべき
セミコロンが抜けていると思われる
class A {
...
} ; ←コレ
これがないから、次に書いた「A* a」の「A」が変数名と取られて
変数宣言文なのにセミコロンで終わってねーよ、って怒ってるんだと思う
ありがとうございます! セミコロンは入っていたので、他の変数で循環参照になってないか見てみます。 includeしないでclassを宣言するって方法も調べた時に見つけたのですが、 そうするとAのメソッドや変数を使う時に困らないですか?
それはヘッダーファイルにincludeしないだけでcppファイルでincludeする 基本的にcppファイルをincludeすることはないからな
コンパイル通った! ありがとうございます。 cppとhどっちにincludeするかでどう違うかは勉強しないと。 どっちみちincludeしたソースを展開するから一緒の意味かと思ってました。
includeは単にその場所にファイルの中に書かれてる文字列をぶちまけるだけ
未解決の外部シンボルが解決できないー。 ちゃんとincludeしてるのに。
>>754 外部シンボルの解決はリンカの範疇の話だから、includeの話じゃない
たまたま include先で pragma してたらリンクされるけど、本質的にリンカの話。
ビルド時にリンクしてないんじゃないの?
>>754 ヘッダーに宣言があってもリンク時に定義(本体)が見つからなければそらエラーになるさ
ライブラリをリンクし忘れる以外でも
関数の本体を書くのを忘れた、とか
書いていてもcppがプロジェクトに入ってなくてコンパイルされていないとかでも起こる
そのとおりでした。 Aクラスはコンストラクタ2つ宣言してて1つしか定義していませんでした。。。 Aクラスの親クラスは2つ定義していたから勘違いしててずっと気づかなかった。 ありがとうございました!
なんかちょっと前に同じ質問見た気がする
スティックでのカメラ回転作ってみたんだけど縦回転のときキモイ動きしやがる
詳しく教えろ
レスだけ見ると多分本人の計算ミス
z-up右手系やろうとして平行移動がキモくなったことならある
横回転(左)はこれで
cam.dirX += cam.speed;
cam.posX = cam.range * sinf(cam.dirX * PI / 180.0f);
cam.posZ = cam.range * cosf(cam.dirX * PI / 180.0f);
縦回転(上)はこれなんだが
cam.dirY += cam.speed;
cam.posY = cam.range * sinf(cam.dirY * PI / 180.0f);
cam.posZ = cam.range * cosf(cam.dirY * PI / 180.0f);
縦回転するときだけX軸にぐにゃっと動きながら回転するんだよなぁ、多分
>>761 の通りミスかも
出先だから詳しくなくてすまん、あとdirは角度
>>763 そういうときはsinをcos変えてみるべ
sinとcosを入れ替えて試すって意味です
軸をどうとっているかは知らないが、Yがプラスマイナス逆になってないか?
原点がどこか、座標の正方向がどっちなのかって 結構バラバラだったりするしなあ。
posZ = range * cosf(dirX * PI / 180.0f); posZ = range * cosf(dirY * PI / 180.0f); バグのもと 上の式から逆算してdirX計算してるならxが動くのもあたりまえ(dirX=dirY、斜めに回転) 初期状態で全部変わるから行列から計算しなきゃ出ないと思うよ 3Dアクションのソース見れば幸せになれる
同時に処理してるんじゃなくそれぞれのキーを押してる間だけなのよ… 視点はプレイヤー固定なのでsinとcosをちょっと弄ってみるかなぁありがとう
行列をおすすめするけどなぁ… 直接式書くなら三角関数の数はxzは2つyは1つだと思う
ここDxlibスレじゃないや アクションのソースとか言っちゃった恥ずかし 一応初期値(1,0,0)でY軸回転αZ軸回転βなら x=L*cosα*cosβ y=L*cosα*sinβ z=L*sinα 間違ってる可能性もあるし参考程度にどうぞ
原野 栗山 千葉 小村 西塚
座標関連はうまくいくと気持ち良いな 時間かかったけどカメラの角度にあわせてキャラを動かすのって結構理解してないと出来ないよな・・・
角度に合わせて移動ならスクリーン変換して終わりじゃない? カメラと一緒に移動させるのは面倒だった気がする こっち向ける+カメラ位置が動くと移動+カメラ角度が動くと移動
普通、キャラに移動に合わせてカメラを動かすものじゃないのか?
プレイヤーの移動ループにcamera.posX+=10.0f;とかでカメラの移動を仕込むの?
キャラクターの位置だけわかっていれば十分。 あとは想定している角度と距離でカメラを動かすだけ。
>>777 追従ターゲットとは別にステータスとか視界回り固定しなきゃいけないのを3D使うときにいる
そこから「こっち向ける」を消せば角度コンパスになるし
ねじりだけ追従ターゲットにすれば飛行機操縦でダメージ受けたときの揺れを表現できたり
2Dと3Dオブジェクトを同じカメラでやろうとするのが間抜けなんだよ。 一つのシーンを描画するのに、カメラを一つしか作れないという固定観念に捕らわれているやつを見ると、 なんでこんなに頭が固いんだろうとしか思えない。 スクリーンの特定の位置に固定するのなら、それがやりやすい座標が使えるカメラを用意すればいいだけ。 カメラは描画するものに応じて切り替えろ。 3D空間上のワールド座標を使用する平面オブジェクトなら、 頂点シェーダでワールド変換をかけた後に、平面を引き延ばせば余計な逆変換もいらない。 簡単にできることを、なんで遠回りで無駄な方法でやろうとするのかさっぱり理解できない。
あーあ変なやつきちゃった
>>779 例が悪くてすまんね
最初は追従する属性を持ったオブジェクトとして3D衝突判定用カメラで管理したいから実装したんだ
例はそれを2D用に移植しただけ
それともオブジェクトの下に移動用カメラがあるなら設計の違いだね
その実装にかかる労力が違う
>3D衝突判定用カメラ カメラで衝突判定?
カメラぶん投げるじゃん? 何かに当たるじゃん? そこは通行不可じゃん?
あれか、ドライブレコーダーってやつ
3dの衝突判定ってどうすんの? 岩みたいな地形をキャラクターに歩かせたり、 車で凹凸によるジャンプとかしたいんだけど
物理学もしっかり勉強せい
>>786 判定よ判定
true or falseで知りたい
yes
>>787 1.Bulletの衝突検出は物理部分抜きの単体で使えるからそれを使う
2.ODEの衝突検出が、OPCODEっつー単体のライブラリとして使えるからそれを使う。
3.DirectXMathにプリミティブの衝突判定がいくつかあるからそれを使う。
4.「ゲームプログラミングのためのリアルタイム衝突判定」って本があるからそれを読んで自分で作る。
好きな道を選ぶといい。やりたいことにもよるけど、大抵下に行くほど茨の道。
>>787 その true or false で結果を得られる判定の為に、物理と代数幾何が必要って事。
すり抜けの対処入れるとキッツイわ
すり抜けなんてねぇ 前フレームと現フレームを線でつないで適度な太さのカプセルと判定させる ゲーム判定なんてそんなもん
空気抵抗を入れてすり抜け出来ない速度までしか加速出来ないようにしても良いな
そもそも3Dの当たり判定ぶち抜くほどの速さってソニックでも作る気か
三角形ポリゴンと移動ベクトルですり抜ける事はないだろ。
精度の関係でコリジョンの角とかにキャラを ぐりぐりするとすり抜けちゃう市販ゲームがちらほらと
>>793-795 お前ら普段どんな処理書いてるの?
移動と、接触の、処理のイメージがちゃんとプログラムのレベルで見えてるか?
そこまでいうなら説明してあげたまえ。
せやな。
>処理のイメージがちゃんとプログラムのレベルで見えてる この辺が抽象的過ぎて何を言いたいのかさっぱり掴めん
知ったかぶりして優越感欲しいだけだよ言わせんな恥ずかしい
知りたいことがあったら技術板で知ったかぶりすると誰かがすごい勢いで教えてくれるって聞いたことあるけど 今じゃ放置が基本なのかな
人に教える暇があったら自分のコードがりがりします
>>800 自分で実装してたら、それが抽象的に見えたりさっぱりわからないなんて事無いと思うけど。
単純に方向決めて座標の数値加算だけして、移動前と移動後の線分と対象の面との交差判定するにしろ、
計算量との兼ね合いで荒い凸包との交差計算する事になった時に、その隙間にあたってすり抜ける事だってあるがな
>>801 違ぇよ。自分で書け。ここで説明とかいらないから。
あるいは移動前移動後の線分と面との交差って言うアプローチでなく、 2Dでよくあるような論理マップ上のマスとの移動先との接触計算を応用したような場合、 そのマスに決めた単位を越えるような加算をしたら当然突き抜けちゃう訳で、 「必ず突き抜けない」って事も無いし、「必ず突き抜ける」って事も無いだろ。 だから普段、どう実装してたら空気抵抗だの、スピードで変わるような言い様だの出てくるんだと思った訳だ。 わかれ。
>>800 俺は
>>797 ではないが
さすがに言ってることの意味は分かるよ
移動処理のコードを思い浮かべると
キー入力でキャラが移動
具体的には移動に割り当てた変数が加算したり減算したり
その変数をカメラ位置座標と中視点座標にも割り当てれば
カメラも同時に付いていく
次に接触処理のコードを思い浮かべると
接触範囲に割り当てた座標の変数も同時に加算もしくは減算
主人公と敵の周囲当たり当たり判定の座標が接触したら
戦闘画面に突入
戦闘BGMスタート!
と同時に2Dコマンド欄がピキン!と表示
>>805 どっかで手を抜かないとなかなかゲームは完成しないぞ?
で、手を抜いた結果として突き抜けバグが発生したりする
>>807 ん、安価ミス?俺自身はずいぶん前にリリースしてる。BPなんで自社製品じゃないけど、多分世にも出てる。
趣味でも書くけど。
ああ、エスパーの結果を書いてたのか。ちと誤解してた。
空気抵抗は、最高速に制限をかけることに対する比喩表現だと思ったんだが ってかすでに804と806の言っている事がすでに食い違っているように見えるが それも俺の無学のせいなのか
ピキン!
「すでに」が一文に2個出てきてる辺り俺の無学度合いはお察しだな すまんしばらくROMるわ
空気抵抗は速くうごくほど強くなるから加速度が一定なら最高速度は決まってくる というか、加速度と空気抵抗が釣り合う速度が最高速度になる
だからその空気抵抗ってのが「マスに決めた単位を越えるような加算をしたら当然突き抜けちゃう」 をなくすための方便だって話だろ? 「なんで自由落下してこれ以上加速しないの?」 A1「マスを突き抜けないための措置です」 A2「空気抵抗のためです」
リミット超えたら判定を複数回やればいいだけの話なのになあ。
何をどう複数回すればボックスを越えた判定をできるのだろうか
隙間ができない単位まで分解して判定するだけだよ。 単純な話なのに、なんでそんなに頭が固いの?
818 :
816 :2013/12/03(火) 22:50:50.54 ID:Wgs9ad3o
ごめん、
>>817 がどう判定してるのか聞きたい
俺の実装してる判定方法(
>>814 よりの方法?)だと何をいってるのかわからん
819 :
816 :2013/12/03(火) 23:05:43.07 ID:TlKrHF27
失礼、完全に
>>804 >>805 の吟味不足でした
ベクトルと面でやるときに加速度制限する人いないのか…
三角関数でのジャンプの作り方を知りたいです pow += gravity; Y = gravity * sinf(pow * PI / 180.0f); jump=初速度 gravity=重力 Y=Y座標 こんな感じですが全くうまくいきません
jump=初速度じゃないpow=初速度だった
>>821 そこに書かれてる処理って、
・角度(degree)に重力値を加算
・重力*sin(角度(ラジアン))がY位置
重力値に9.87とか放り込んで計算したら、
びよんびよんと高速で上下にワープ移動するような結果にならね?
試してないけど、書かれてる内容的に。
>>822 確かに・・・
player.Y += player.jumppow;
player.jumppow -= func.Gravity;
これでもジャンプ力50.0fの重力1.0fなら良い動きをするんですが
少し数字が変わると慣性が無くなったような動きになってしまいます
初速度と重力だけで作るのは無謀でしょうか?
むしろ初速度と重力があるならsinいらない気ガス
825 :
名前は開発中のものです。 :2013/12/05(木) 00:32:12.50 ID:Q4Rc5btO
>>823 その計算ならだいたいどんな値でも放物線えがくと思うけど
慣性の無くなったような動きってどうなんの?
3Dゲームってだいたい頂天に近づくほど加速が遅くなるから
アクション的には
>>823 だとけっこうジャンプ攻撃とかで不都合が
jumppowに最初にジャンプ力を設定するんだよな 問題なくね?
ちょっと聞きたいんだけど プレステ型のゲームパッドのボタン番号と、実際のプレステコントローラの 一番一般的な番号対応とかあるのかな? 俺の手持ちは2つでどちらもエレコムだけど、それだけで既に相違がある。 1つめはエレコムのUSBパッドで、ボタンに印字されてる番号は1から振られてるけどプログラム的には0から始まってる 0 □ 1 △ 2 × 3 ○ 4 L1 5 R1 6 L2 7 R2 8 セレクト 9 スタート 10 L3 11 R3
ないからコンフィグで対応するしかない 製品ごとの対応データベースでもどこかにあれば良いんだけどね
もう1つは本物のプレステコントローラをUSB接続可能にするコンバーターで LRの1と2が逆だったり、スタートとセレクトが逆だったりする もちろんキーコンフィグはアリにするんだけど デフォルトでさっくり操作できた方が気持ちいと思うんだよね
>>829 更新してなかった、ありがとう。
このへん標準みたいなのがあるとすごくありがたいんだけどねー
あとは、ちょっとこれとは話は違うけど、パッド操作をキーボードに割り当てる場合の
標準とかも欲しいよね。まぁそこはツクールに合わせればいいのかな?
ホリパッドでもPS2コンと微妙に違ったりするから困る・・・ ところでキャラクターのstate処理を作りたいんだけど、 キー受付やジャンプ処理みたいなループ処理の部分の最初にstate=0(棒立ち)を書いてて 当たり前だけどキー操作してないとき(ジャンプ中や攻撃中)は強制的に棒立ちになっちゃうんだけどどう書いたらいいんだろう 最初に問答無用でstate0にしてるのがダメなのかな
そもそもなんで最初に強制的に棒立ちにしてるのだ。前の状態を維持しないでいいのか。
>>833 前のstateにしておくと止まってるのに移動モーションになったり
キー押し続けて移動してる状態から元に戻ったときの判定ができてないだけなんだけどどう組んだらいいのか・・・
「移動中」に止まれば「棒立ち」にすればいいし 「棒立ち中」にキーが押されれば「移動中」にする、じゃだめなのかよ。 処理の最初に状態を棒立ちに強制リセットしたら、いま移動中なのか棒立ち中なのかジャンプ中なのかわからんじゃないか。
何も押されていなかったら棒立ちにする 初期値を棒立ちにする 同じように見えて違う
>>835 ごめんググったりしても分からなかった
>>836 その何も押されていないって判定難しいんだよね
というか他の行動中も棒立ちになっちゃダメだし
>>837 こちらこそごめん。君が何を悩んでるのか解らない。
例えば、stateが「棒立ち」「ジャンプ」「移動中」の3種類があったとして
switch ( state ) {
case 棒立ち :
ジャンプボタン押されてたらstateをジャンプへ
移動キー押されてたら stateを移動中へ
case ジャンプ
地面に着地したらstateを棒立ちへ
case 移動中
ジャンプボタン押されてたらstateをジャンプへ
キー入力がなければ棒立ちへ
}
(breakは略)
ってやりゃ済む問題じゃないの?
今日は引数つきコンストラクタを持つクラスの配列が必要になってしまって 一部根本から設計変えるはめになった new Class[n](a)とかやらせてくれよ
>>838 ごめん馬鹿過ぎました
なんでstateでswitch使うのを考えられなかったんだ・・・わざわざありがとう
あとはstateの最初にモーション変更しこんどけば完璧じゃねぇの!?
待て待て頭だと止まってるのに跳んでるモーションのフレームが1ループ分できるぞ
各stateの最初って意味よ 立ちstateの最初に立ちモーション、ジャンプstateの最初にジャンプモーション 前フレームのoldstateでも作っておけば多分大丈夫 しかしstate関連は抽象的だからググっても出でこないしゲームプログラム本買うしかないか
state内容で描画内容変えるのは簡単だけどstateの中身変えるのに状態やキー入力や優先順位とか考えて書いてたらif文が気持ち悪いことになってた アクションゲーム作るのに重要だと思うのに解説してるサイトってほんと少ない
Intelのコンパイラってどうよ?使ってる人居る?
初心者が使うべきVisual Studio Expressは2008 2010 2012 2013のどれ? 素直に2013でいいの? それとも使用されてる期間や人数が少ない最新版は避けて1つ手前の2012? あるいは入門書とかにくっついてる2008や2010を本を見ながらやるのがいい?
>>846 基本的に最新版の方が良いが、特定の関数とか定数が削除されたりすることもあるのでその場合考えると入門書とかにくっ付いてるやつが何も考えなくていいと思う
ただ、個人的お勧めは2010だけどな
2012だとDirectX使ってデバッグしててどっかで止まるとOSハングしてると思うんだけどそれがクソ長くてな・・・
まぁ2010でも有るけど本当に少しの間だけだしそんなに問題ないと思う
>>845 学校の先生の話だがコンパイル時の最適化はたぶん一番良いが、それ以外が駄目過ぎて嫌だし、業界ではあまり使われて無いから学校では教えるのはVisualStudioにしてるって言ってた
>>846 参考にしてる本が2010で解説してるなら、2010使った方がバージョン間の差で躓かないだろうからその方がいいだろうな。
別に躓いても何とかするわ、っていうなら2013。
2012と2013は全体的にマイナーバージョンアップって感じだし。(C++以外の部分でも)
2008は古すぎるので、これから初めて勉強するためのチョイスとしては微妙。
C++も言語的にだいぶ変わってるし。
自分が使いたい奴を使う 全部無料なんですから全て試してみて 一番使いやすいのを選べばいいでしょう
2010使うぐらいなら2012か2008だろ IDE含めて一番出来が悪い autoとか便利なのが使える2012以降が一番おすすめ
>>847 >2012だとDirectX使ってデバッグしててどっかで止まるとOSハングしてると思うんだけどそれがクソ長くてな・・・
同じ現象かどうかわからんのだけど、Win8+VS2012+DX11に変えてから、windowsキー無効化するのにLowLevelフックするコード入れたら、
ブレークポイントで停止がやたら重かったり、キーボードやマウスが操作困難になるくらい重くなる現象が起きるようになったな。
少なくともVista+2010+DX9で、そのWindowsキー無効化コード使ってたときは、そういうことは起きてなかったと思うんだが、
色々環境もコードも変え過ぎたせいでVS2012が原因かは不明だけど…。
ぶっちゃけ2010が最高にクールだね 大盛り牛丼的なバランス感
俺がゲーム作ったら3.500円で販売するので買いましょう
3円50銭かな?
買ってやろう、0.5円は駄賃だ
>>852 > autoとか便利なのが使える2012以降
C++0x 対応開始したんだっけか。
2010出来が悪いって言ってんのは共通プロパティページの事かな。
確かに方式急に変わったので困るは困る。2012でまた戻ったの?
あと2008はインテリセンスが効かなくなるから、その点では2010のの方が良く無いか?
2013でもまた かなり対応部分が増えたらしいねー
autoで型推論は2010から対応してるっしょ。ラムダ式も2010だし。 C++11正式対応しだしたのは2012からだけど、tr1として2010からそこそこ入ってるがな。 でも2010使ってた当時は2013あたりにはとっくにC++11対応完了してると思ってたのに…。 なんて様だ…。
15年近く前のC99にすらろくに対応してない時点で察せよ
C11「」
VC2008でやってるけど一度デバッグするとしばらくの時間、書き込めませんとか出てデバッグ出来なくなって困ってる 2013なら治ってるかな
C++14「」
キャラクターのステータスってどういう処理の時に加算すればいいかな 普通Lvで上がる基本能力に装備やスキルの+とか足してって計算すると思うんだけど 攻撃力とか防御力とか項目多いから毎フレーム計算するわけにはいかないし、 かといって装備時やスキル習得時に加算しようとすると、その装備やスキル内容作ってないとダメだし なにか良い方法はないかねぇ
めんどいけど後者でいいな
再計算する処理作っといて、いつでも「変わった時」にそれを呼び出すようにすればいいんじゃないの?
ものにもよるけど、 再計算する処理を作っておいて、いつでも「そのデータが必要になったとき」に呼び出してる。 処理の量は多くなるけど、これが原因でフレーム落ちしたという経験はまだない。 10や20のパラメータをキャラクター数百体計算させてもたぶん余裕。 ただし2D。3Dは描画で時間がかかってて、ほかの処理にあまりまわせないなんてことはあるのかもしれない。
なるほどなぁありがとう 人数分ループとかさせると行にして500行とかになるもんな・・・
500人いるゲームなら、あらかじめ基本ステータスとしてテーブルを持っておくだろ だったら個々のステータスは変数でもいいんじゃね
500人って 仮定が極端すぎじゃねw
500人程度なら、グラ処理の方がステ処理なんかより桁2つ違う次元で重たいから気にする意味なんて無いんじゃね?、とマジレス。 グラはテキストベースです!とか、ステータスの種類自体が1000項目あります!とかならアレだがw まーアクセサ経由にしてお茶を濁しておくね、俺なら。んで後で本当に「ステ処理が原因で重い」って状況になったら、差分処理なりポーリングなり仕込む。 当然関数1個挟む事になるからその分のオーバーヘッドはあるけど、そのコストはもう割り切るわ。 それを悩むべきタイミングを先延ばしにできるというメリットで十分ペイできると俺は思うで。
このやり方だとプレイヤーだけじゃなく敵も毎フレームやることになるからそれだと重いかもな 敵の最大数×ステータス数で…うほっ
2Dゲームを作る場合、DirectXのバージョンを9から上げる必要はありますか?
11との比較でXP捨てていいんなら9にこだわるメリットはないよ ハードも9以降の物なら大丈夫だし
俺3Dでも2DでもまだDirectX9ベースだ。 固定パイプライン使ってないけど。
んーと、10や11に2Dで使えそうな機能はないって事で良いのかな?
Direct2Dを使うならVista以降に限られるので、まぁDirectX9に拘る理由はないな。 API的にはDirectX11の方が整理されてて使いやすくはなってる。 デバロスもないし。 自前で2D描画処理書くんなら9の機能で十分だから、XPをサポートしたいっていうんなら9でも良いと思う。 10や11の機能を2Dに応用はもちろん出来るんだけど、2Dゲーにはオーバースペック過ぎて必要ないかな俺的にだけど。
Audio - low-level audio API using XAudio2 人に勧めといてあれだけど・・いつの間に 更にC++版XNAみたいになってきとる ついでに簡単なXNAモドキなフレームワークでも提供してくれればいいのに
クリスマスの夜にリア充カップルを射殺しまくるFPSを作って公開するか
2Dのアクションゲームを作ろうと思っているのですが、ブロックと当たり判定したあとにブロックの位置まで戻すにはどうすればいいのでしょうか?
きっと 当たり判定後に、ブロックにめり込まない位置(=ブロックに接する位置)に移動させたい と言う事だとエスパー気味に
移動するときに移動後の位置で判定して、その移動はしない、じゃダメなのか
>>884 さらに言うと、その判定の後でどのくらいめりこんだかの差分取ってキャラの位置戻すだけだよな。
Box2Dをインストールして、判定全部を任せたら 今まで俺は何をやってたんだ!と思っちゃうレベルに楽チン
わからない事から逃げて楽チンになるのと、わかってる人間が楽チンになるのとじゃ大分意味違うけどな
ブロックとの当たり判定は俺も悩むなぁ。 以前に作ったことはあるんだけど、色々と問題(課題)もあって 解決の糸口が見つからないままなんだよ。
僕は取り敢えず移動させてめり込んでたら戻すって感じでやってる
ドット単位で動かしてるときは、移動不可なら処理前の位置に戻すんじゃダメなんだよな 1フレームあたり移動距離の途中でぶつかることがあるからね 俺は悩んで結局投げた経験あるわ シューティング系のコモン探して参考にしてみたらどうかな
俺が悩んだ(悩んでる)のは二つのブロックを経由した場合だ。 例えば下図のように、斜めブロックと四角ブロックが並んでいて A ______ /| | /_|_B _| A地点からB地点まで1フレームで移動した場合に、右の四角ブロックだけ判定して移動を戻してたから 両方のブロックの間に挟まってしまってた。
止めろ! 2Dのアクションゲーでのブロック判定とか超絶黒歴史を思い出させるな! 1フレームでの移動距離を一気に移動させるんじゃなくて1フレームの中で少しずつその距離になるようにループで移動させて 表示的には1フレームで移動してるけど内部的には1フレーム内で何回も移動してるとか そんなクソ処理しか書けなかった黒歴史は忘れさせてよお! ちなみに今でもどうするのが正解かわからん
一気に移動させて引っかかったら1ドットずつ移動に切り替え、じゃだめなの? なお壁に向かって走ると重くなるもよう
地面の法線と落下ベクトルの内積やら外積やらで、着地時に少し前に滑るようにする
ブロックとの当たり判定をするオブジェクト(プレイヤーキャラや敵キャラなど)は数十個くらいなら 「ぶつかったら移動速度を-1して再判定」でも問題なく動く。 さすがに数百個でそれやったら重かったので、二分木もどきに改造したけど。
pos_x += idouryou; if( atari() ) { pos_x -= idouryou; } ってやるから駄目なんだろ for(int i=0; i<idouryou; i++) { pos_x++; if( atari() ) { pos_x--; } } ってやればいいじゃん
この程度も思いつかないとかなんなの 向いてないから死んだ方がいいよ
>>896 これって
>>892 が発狂してたやつと同じやり方じゃね?
後、せめてbreak書こうぜ(ドヤッ
>>897 この程度も思いつかないとかなんなの
向いてないから死んだ方がいいよとか書いてるくせに
この程度の処理を軽くすることすら思いつかないとかなんなの
向いてないから死んだ方がいいよ
発 者 同 . 。_ ____ 争 生 同 .じ . /´ | (ゝ___) い .し 士 .レ .__/'r-┴<ゝi,,ノ ro、 は、 .な で .ベ ∠ゝ (ゝ.//` ./`| }⌒j .い し .ル } ⌒ /`ヽ、_∠l,ノ ・ヽ´ .! ! か の / ´..:.} >、、___, .r、 ソ、`\ / ..:.:.} / |∨ ` ̄ / ..:.:./ | 丶 / _、 ..:.:.:.{ .{.:.:. \ { ..:Y .ゝ、 {.:.:.:.:. ヽ |、 ..:/ 丿 .:〉 >.- ⌒ . ヽ / {. ..:./ ソ ..:./ .( ..:.:.:` ..:} ./..:.:}.:.:./ ヘ、 ..:./ .\ ..:.:r_,ノ、.:.:} ./..:.:/|.:/ {.:./ X.:.:}.} X X /..:.:/ .}.:| }:/ .Y丶ヽ Y.:Y . __/.:/ { } 《.〈、 _,,__>.:》丶 Y.:\ /.:.:.:.:.::/ !.:.:ゝ ゝ.:. ̄ヾ ´:.:.:.:.:.:.:.:.:ヾゝ \.: ̄>
breakなんて女子供がやるもんだ 男は黙ってcontinue
なんでatan()なんか使ってるんだ?と思ったが、atari()か……疲れてるのかな。
そういえば左下から右上のブロックにジャンプしたときに、X軸とY軸のどっちを戻せばいいかってどうやればいいんだろう・・・
>>903 どっちの軸か、じゃなくて方向ベクトルに対して逆向きにするだけじゃないの?
>>903 基本は、めり込んだ距離の短い方に合わせる。
ただ個人的には、よほど差がなければy方向(上下)に優先的にずらす方が好み。
何でxとyを同時に処理するんだよ xとyは別々に処理する xを処理したときはxを戻せばいいし yを処理したときはyを戻せばいい この程度も思いつかないとかなんなの 向いてないから死んだ方がいいよ
>>906 それXとYどっちを先に処理するかって事だから903の言ってるXとYのどっちにするかという問題の解決にまったくなってないわけだが。
>>900 無駄な繰り返しをしないように
typedef struct position {
int x;
int y;
} position;
position pos;
for(int i=0; i<movement; i++) {
pos.x++;
if(hit()) {
pos.y--;
break;
}
}
このほうが無駄な繰り返しが発生しなくなるからその分軽くなると思うんだが
continueだと結局無駄に繰り返すから意味無いし
そもそもゲームって常に処理してるからね 処理分岐の中に入るかどうかで決まる
メンバ変数の配列を初期化したい時ってどうすればいいの?
コンストラクタにfor文でどうぞ。
適用にググればいろいろでてくるやろ・・・
やっぱりstaticを使うしか方法はないのかな?
え、なんで俺スルーされてんの?
>>914 ごめんorz
とりあえずソース書いてもらえると助かる
はい釣りきたー
>>915 メンバ変数とか関係なく、普通に配列へ代入するつもりでやる。ほんと普通に。
MyClass :: MyClass()
{
for(int i=0; i<MAX; ++i) array[i]=0;
}
array アライー default デファウルト
プリミティブ型なら違う楽な書き方もあるけど
引数付きコンストラクタをもったクラスの配列とかもありえるから
>>917 のやり方で統一するのは一貫性があって良いと思う
>>919 > プリミティブ型なら違う楽な書き方もあるけど
よかったらそのやり方教えて
これは
「なぜ
>>917 が推奨されてるか理解しないまま、見た目がそれっぽいからという理由だけで楽な書き方を導入してその後どつぼにはまる」
流れ
memsetとかじゃね
>>919 のこともあるしそもそもC++なんだから使うなって感じだけど
やる気を出すにはどうしたらいいですか モチベーションはどうやって保ってますか
スレチだが真面目な話ちょっと体を鍛えるといいよ 身体動かすと視床下部が刺激されてやる気出るし
やりたくないことをやるといい。 勉強とか仕事とか。 現実逃避してこっちをやりたくなる。
そんな無理してやらんでもw
セーブ&ロードのための凄く単純なシリアライズくらいはできるようになったんだけど ロード画面でセーブデータのプレイ時間とかちょっとした情報を表示するにはどうすればいいのかな? というか俺のシリアライズのやり方次第で詰んでる可能性も? シリアライズ時にゲームオブジェクトから直接ストリームに順番に書き出して、 デシリアライズ時にゲームオブジェクトに順番に直接復元する方式にしちゃったんだけど、 もしかしてここは、ゲームオブジェクトのデータから「セーブデータクラス」をいったん生成して、 そいつをシリアライズ対象にして、復元時はセーブデータクラスの値からゲームオブジェクトを復元しないといけなかった? でもそうするとポインタの復元が難しいというか、Mementoパターンとか深く考えずに、 Boostシリアライズのパワーに頼ってしまったんだが、セーブデータからは極力ポインタを 排除するようにしたほうが良かったんだろうか
ヘッダと本体をわけろ
>>928 迅速な回答ありがとうございます!
なるほど「セーブデータクラス」ではなく「セーブデータヘッダークラス」で十分なんですね、
これにBoostパワーで得たストリームをくっつけてみます、ありがとうございました
なぜ初心者は専門用語を使いたがるのか
いずれリフレクション付き言語でObjectStream使ったら boostなんて大して便利ではないことに気づくだろう
セーブデータってやっぱりキャラクタークラスのポインタからスカラにまで落としてテキストで保存した方がいいの? セーブデータ用のクラスの作ってセーブする時にデータぶっこんでバイナリしゅわーんして ロードする時にクラスのインスタンスの先頭アドレスあたりからバイナリどかーんってやってその後しこしこ値を取り出せたらかっこいいんだけど vectorとか可変長データ扱えなさそう
>>932 Boostパワーでしこしこシコりまくってドカーン、アヘーって保存したほうがいい
ポインタに関連する全てが壊れるが
意味ねぇ
ポインタ壊さないのがBoostパワーだろ
言語仕様の限界であの程度のことしかできないのは仕方ないさ
雲ってどうやって表示してる? 板ポリ一枚だとPS1みたいになっちゃうね
海の波ってどうやって自然に表示してる?
その辺はもう初心者向けの内容じゃないので、NVIDIAのGemsとか読むとヒントがあるかも。 俺も一冊持ってるけど。
ゲームとしては水や雲ってすごく基本的なことなのにやたら難しいよね 参考サイトもろくに無くて挫折ポイントですよ 水って透明なブロック状3Dモデルに青いテクスチャーはっ付けてテクスチャー滑らせてるだけかと思ってた
リアルな水や雲がゲームの基本的な事って言う発想が既にかなり間違ってる。 その辺は完全にビジュアルとしての演出処理の範疇で、さらにその辺は設計者やプログラマの創意工夫の分野なので、 特に教科書的な単一の正解も無いから、方法も様々だし書きようがない。 ただ、ジュンク堂みたいなでかい本屋行くと、NVIDIAが出してる技術書とか置いてると思うので、読んでみるといい。 考え方や部分式が書いてあるから。
ちなみにGemsのその辺の文献は、見ればわかると思うけど初心者向けの内容じゃなく、応用編の先の先の世界なので、 プログラミングに熟練してる事がまず大前提で、特にシェーダプログラミング当たり前。 その中で最低限高校数学B以上の知識も必要でそれ以上が無いと多分説明そのものが理解できない。 何も前提が無い人向けにあれの説明始めたら、何倍のテキスト量になるかわからないほどの内容。 もしもあなたが理系の大学生かまたはビジュアル処理の研究者だったら、かなり参考になると思う。 そうじゃなくても知識と想像力と実験力持ってれば行けると思うけど。 とにかく、興味あったら一度手にとって実際に自分で目を通して。俺が言ってる意味がわかるから。
そんなレベルの奴が雲だの水だの言ってんのかよwww
あかん 数学の知識は因数分解の所で止まっとる 知恵袋にプログラミングは数学や英語の知識なんて必要ないって書いてあったのに嘘つかれた 今から独学で勉強するのキツイだろうな
何でも難しい計算は全てコンピュータがやってくれるから人間が考える必要ないとか何とか言ってた
×難しい計算 ○めんどくさい計算
949 :
名前は開発中のものです。 :2014/01/07(火) 12:22:01.86 ID:n8ArE3NN
言っても初等数学だし むしろ因数分解のほうがコンピュータ的には難しいくらい
計算はコンピュータがするが、 計算手順は人様がコンピュータに教えてやらねばならん。
メンバ関数を持つクラスを、配列で宣言した場合、 そのメンバ関数内で自分が配列の何番目であるかを取得するにはどうしたらいいでしょうか?
クラスのメンバ変数として番号を保持すれば良いのでは
レスありがとうございます。 それはもちろん考えたんですけど、いちいち設定するのってスマートじゃないから他に方法があるかなと思いまして。 そもそも配列の番号を頻繁に必要とする時点で設計を間違ってるとは思うのですが、まだ力不足でして……。
配列のポインタをそのクラスに持たせて 自身のポインタかなんらかのID値を配列から検索して割り出す。
アドレス解ってんなら引き算するだけだろ
それ、番号を使用している場所を 番号の代わりにポインタを使うようにすれば すっきりしそうに思える 勘で言うけど
>>947 その辺の話は、
>>950 も言ってるけど、もともとコンピュータに何をやらせたいのかって話と、
単純にプログラミング行為そのものの話を一緒くたにしてる一般の人が陥る話。
簡単な例で言えば、会社会計の処理をするプログラムを作ろうとしたら、会計士が求めるような用件しらないと作れない。
でも単純にプログラミングする上で会社会計や決算についての知識は必須か?って言われたら明らかに不要。
それと同じ。やらせたい事自体の本質は何で、そこになんの知識が必要かってのは目的によるって事。
それが違えば高度な数学がいる事もあるし、まったくいらない事もあるってだけ。
959 :
名前は開発中のものです。 :2014/01/08(水) 07:29:15.57 ID:BLQUEdhx
一般的なプログラマが作る業務アプリなんかはゲームで使う幾何計算とか無縁だからな ワークフローにそった処理作るだけだからそりゃ数学は必要ない
でも原理は知っておかないと。 例えば三角関数の軽量版が作れないなら、ゲームプログラミングでは意味が無い。
そうなんだすごい
ごめん流れ変わるけど よく当たり判定用のフレームを用意して判定すると軽いっていうけど、 一発で判定用フレームって作れないもんかなぁ Metasequoiaでやってるけどなんかスムーズにいかない
頂点の数を減らすだけでいいんじゃないかな
>>962 convex-hull でググれ。
ちなみにbullet にその計算生成処理を実装した機能あるよ
>>963 それだと形が変わっちゃうからなぁ
>>964 物理エンジンか・・・プログラム側でやるのか
966 :
名前は開発中のものです。 :2014/01/10(金) 03:11:17.85 ID:MSpxeAqe
>>965 プログラムでやらずにどこでやるつもり
データとして最初から用意しておきたいって話なら、例えばその生成データを自分でファイルに書き出してもいいし、
あるいはBlenderのShrinkWrapでも使って作っても良い訳だし
あるクラスの集合を表すクラスってなんて命名したら良いのかな? 今個別のキー入力を確認できるクラス作ってたんだけど class KeyState { }
969 :
968 :2014/01/12(日) 18:17:38.04 ID:MPtGFllK
すまんミスった。 今のところ(かなり簡略化してる) class KeyState { bool isKeyDown(); } class KeysState { bool isKeyDown(int keyNo); } class KeysStateManager { bool isKeyDown(int joypadNo, int keyNo); } って感じなんだけど、上2つがかなり紛らわしい。
Win32APIだと GetKeyState() // 引数で与えた特定のキーの状態を取得 GetKeyStates() // 全部のキーの状態を取得 だな。 まぁ集合って意味なら安直にKeySetStateとか。 あるいはKeyboardState、GamepadState、InputDeviceState みたいな、デバイスのステートって感じにするとか。
>>969 上2つの動作の違いを書いてくれ
クラス分けする必要が無いように感じる
とりあえずエスパーで回答すると
1、1つ目の方には引数が無いから何かしら押している状態で2つ目が引数が1つあるから特定のキーを押した場合と考える
そうすると1つ目にはisAnyKeyStateクラスのisKeyDown関数で2つ目にisKeyStateクラスのisKeyDown(int keyNo)関数とする
2、何かもう色々とアレだから違うこと書く気がするから参考にしないでくれ
class Keybord {
bool isAnyKeyDown();
bool isKeyDown(int keyNo);
bool isKeysDown(const char *keyNo, ...);
}
class Joypad {
bool isButtonDown(int joypadNo, int buttonNo);
}
class Input {
Keybord keybord;
Joypad joypad;
}
>>970-971 即レスサンクス!
>>970 >KeySetState
おおなるほど、このやり方があったのね。
接尾にListとかSetとか来るとコンテナの派生と紛らわしいかなーと思ったけど
このやり方ならそれらと区別が付いて良さそうだね。
>>971 わざわざ詳しくありがとう
ごめん、AnyKeyの判定をするんではなくて「ある1つのキー」のクラスだったね
そして複数形が同じ単語にハマるところまでがワンセット(笑)
まつ毛の動かし方分からなくて詰んだ 最近のゲーム(というかPS2あたりから)で目ぱちぱちとかあるけど あれプログラムで動かしてるの?それともボーン仕込み・・・?
>>975 プログラムが楽したいならボーンでやると良い
リソースが楽したいならプログラムでやると良い
プログラムで動かすにしろ、ボーンなりモーフターゲットなりUVアニメなりは必要だろ
イニシャライザ誤解しててえらいめにあったぜ struct Rect { int x, y, w, h = 100; }; 他の言語だと4つとも100になるのだがc++だと最後のhだけなのな。
そーいや、そのへん言語によって結構バラバラだった気がするな
>>976-977 ボーン必要か・・・サンクス
ただ試してみたけど間接曲げるのとは違って歪むなぁ
>>980 1本の毛で2〜3本付ける感じでやると滑らかになるよ
といっても1本の毛じゃなくて片方の睫毛全体を横に3分割して、それを2〜3本の骨にする感じだけど
まつ毛ってアルファ付きの海苔一枚じゃないのん?
>>978 逆に、それで4つとも100になる言語って何だろうって思ってしまった。
ちなみにPythonだとタプル表現でまとめて格納は出来るけど、あれイニシャライザとしての動作じゃないしなぁと。
4つとも100になる言語がわからない
100になる言語が大半でしょ とか思ってたら=じゃなくて,なのか あるのかよ?
ちょっと違うけどアリスソフトのSystem4には const int a=1, b, c, d; ↓ a=1, b=2, c=3, d=4 なんつー奇妙な初期化があったな
列挙型と思えばまあ
a, b, c, d = 1, 2, 3, 4
というのならあるけど、
>>978 は知らんなあ
>>986 ふいた。
何その変態仕様w 嫌いじゃないぜ
もうさ 1行に制御1つって仕様にしようぜ int a = 1; int b = 2; int c = 3; int d = 4; みんなこうしよう!
int a=1,b=2,c=3,d=4; がいいな
const int a = 1; const int b = 2; ...
defineとかわんないよ
>>994 実は微妙に違う。こんな事が出来る。
const int w=getW(),h=getH();
#defineとconstってどっちのほうが速いっていうかメモリに無駄が少ないんかね 最適化で同じになるかな
#define をなんだと思ってるんだ君は
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。