1人でゲームが作れるように修行します。2 (487レス)
1-

70
(2): SGGK ◆6pZCoAtaxk 2010/09/02(木)23:42 ID:N3a4x6pe(1) AAS
とりあえずベクトル関係の変数と関数を宣言したヘッダーファイル、vector3.hと
それらの変数や関数を定義したファイル、vector3.cppを作成してみた。
とは言うものの、中身は変数を3つ持つ構造体とその構造体の型を持つ変数を引数にもつ関数で
関数は、

ベクトル=ベクトル+ベクトル
微小時間後の位置を示すベクトル=現在の位置を示すベクトル+微小時間xその時点での速度を表すベクトル

の2式だけ。
この微小時間がいわゆるフレームタイムであり、今までのプログラムだと
メインループ関数の中で、DXライブラリのScreenFlip()関数を30回ループしてその平均を
フレームタイムとしてる。ScreenFlip()関数は画面のリフレッシュレートとやらと同期して動くらしいので
そういうやり方でフレームタイムが計算できるらしい。
でも、これだとメインループ関数の外側で宣言・定義されてる微小時間後の位置を示すベクトルを計算するための
関数に必要な微小時間(フレームタイム)が読み取れないと予想。
とりあえず、30回ループする部分を関数にして、vector3.h、vector3.cppで宣言・定義して、
その30回ループする部分を関数にしたのをメインループで呼び出してなんとかできないかと思ったところで終了。
71
(1): 2010/09/04(土)10:45 ID:BWH+wHQ4(1) AAS
>>69
> + の意味を定義しなおす機能があるようなので、これかなと思ったけど、あまりにも内容が難しいので、諦める。

class Vector3{
public:
float x;

Vector3(){}
Vector3(float x_) : x(x_){}
Vector3 operator+(Vector3 &obj){
return Vector3(x + obj.x);
}
};

class A{
public:
A(float x) : vec(x){}
Vector3 vec;
};

void main(){
A a(1),b(2);
a.vec = a.vec + b.vec;
cout << a.vec.x << endl;
}

こういう事?
operator+はその性質上、returnで新しいクラスを作る必要があるから処理速度の面で微妙
俺だったら使わない
72: SGGK ◆6pZCoAtaxk 2010/09/05(日)00:15 ID:t7yjfHHg(1) AAS
>>71
す…凄いです。そうです!そのoperatorがなんとかというそれでした。
まだ自分は答えを見ても何がわからないかもわからない初心レベルですが感謝します。
処理速度が微妙であるとのコメントを参考にして、なんとか>70のやり方(C言語風?)でやれるよう頑張ってみます。
73
(1): SGGK ◆6pZCoAtaxk 2010/09/05(日)23:38 ID:glSoiJ6G(1) AAS
>>70の下から4行に書いたやり方は諦める事にした。
vector3.hにfloat frametime=0;と書いてコンパイルすると
frametimeは既に定義されてると言う内容のエラーが続々発生。
これは、vector3.hがいろんなcppファイルのヘッダーファイルにインクルードされてるからだろうと予想。
float frametime;と書き直しても同じ結果。初期化の有無は関係なかった様子。
vector3.hの中でfloat frametime;と書いておき、他のcppファイルでframetimeを使いたい場合には、
そのcppファイルのヘッダーファイルでなく、cppファイルの上の方の行でextern float frametime;と書いたら直った。
たぶんこれでframetimeは外部変数扱いになってどこからでも使える変数になったかなと思うけど、
ベクトル計算の関数定義の中で使おうと考えているframetimeの値が外部変数として渡すやり方だと
なんとなく後々の問題になりそうなので、ベクトル計算用関数の引数を増やして、その引数に値経由でframetimeを渡せないかと考えて終了。
そして、frametimeの外部変数化も中止。(あまり進まず。)
74
(2): 2010/09/06(月)06:18 ID:WWj0DWld(1) AAS
・Vector3.hのクラス定義内にて、 static float frametime;
・適当なcppにて、float Vector3::frametime=初期値;
ということがしたいのかな?
75: SGGK ◆6pZCoAtaxk 2010/09/06(月)23:10 ID:5jVgy4R8(1) AAS
>>74
その通りです。
ただVector3.hでは、クラスの宣言や定義はしていなくて、ベクトルを表す構造体などを引数にしてベクトルを表す構造体をreturnする関数を宣言するのみ。
そうすればベクトル関係の関数は外部関数になってどのcppファイルからでも使えるかなというのを期待して書いてます。
そしてVector3.cppでその関数の定義をしようとすると関数内のframetimeという変数がメインループで計算するframetimeと名前を同じにしても
このままでは中身が別物なはずなので、Vector3.hかframetimeを使うcppファイルのどこかで1度だけ
frametimeを定義して、他の残りについては、extern float frametime;とすれば動きそうだと思ったわけです。
externにしたのは、cppファイルが複数あるからstaticよりこちらがいいかなと思っただけであまり自信無し。
「extern static 違い C言語」で検索するとろいろ出てきて読むと自信無くなってきたけど
なんとかトライしてみます。
76: SGGK ◆6pZCoAtaxk 2010/09/07(火)23:20 ID:qyxrqbqY(1) AAS
いままでのプログラムをベクトルを表す構造体で表現する変更作業の開始。
とりえあず先にヘッダーファイルだけを変更する予定。
しかし、ヘッダーファイルを変えただけでコンパイルすればcppファイルの方でエラーが出るはずなので、
ヘッダーファイルを全部コピーしてファイル名の前の方にv_を付けてファイル名を変えた方で変更作業する。
そうすれば、cppファイルと矛盾してエラーが出るという状態を避けられるはず。
そしてヘッダーファイルの変更が終われば、古いヘッダーファイルを削除して、新しいヘッダーファイルのファイル名からv_を取り除いて、
今度はcppファイルを直す。
変なやり方かもしれないけど、やってみる。
77: SGGK ◆6pZCoAtaxk 2010/09/08(水)23:42 ID:2FQaVedh(1) AAS
ヘッダファイルを4個書き直した。
あと12個残ってる。
78: SGGK ◆6pZCoAtaxk 2010/09/09(木)23:34 ID:u4JUxGaq(1) AAS
今日も4個しか出来なかった。
cppファイルを直す時に泥沼状態になる事を予想して、
変更箇所を表計算ソフト(エクセルのこと)にメモしながら進めてるから作業が遅いのかもしれない。
79: SGGK ◆6pZCoAtaxk 2010/09/12(日)23:34 ID:zuikLtmE(1) AAS
ヘッダファイルあと残り1つ。
これは選手の移動関数を定義してるファイルだけど、気になる箇所があった。
今のプログラムは、どのような速度のパソコンでも60Hzで1フレーム時間あたりの移動量を1〜20ドットにしたい場合の移動量を
20個の配列を用意して入れてるんだけど、これが外部の移動関数から読めてる。
…というのは知ってたけどそういえばextern使ってないのに何故だろうと思い、14歳わくわくC++を調べてみると、
メンバ関数やメンバ変数にstaticを付けるとグローバルな関数、変数扱いに出来るとのこと。
そして呼び出すときには、クラス名::変数または関数とすればよいらしい。
さらに変数の場合は、外部に実体の定義が必要。
忘れてた…。
これは>>74氏のそのままでOKではないか〜!ということでextern無しで書くことにした。
よって>>73で言ってた
>ベクトル計算用関数の引数を増やして、その引数に値経由でframetimeを渡せないかと
も中止。
とりあえず、最後に残ったヘッダファイルにある移動関数の一つを書き直してコンパイルしてみたら通った。
移動関数はあと3つ残ってる。
80: SGGK ◆6pZCoAtaxk 2010/09/13(月)22:59 ID:621XmSry(1) AAS
ヘッダファイルの書き直しが完了。
何もヘッダファイルを読み込んでないヘッダファイルを先に直して、
ヘッダファイルの読み込みの少ないヘッダファイルを先に直すような順番で書き直していったからかどうかはわからないけど、
あまりバグが出なかった。次はcppファイルの書き直しに挑戦。たぶんもっと時間がかかるはず。
81: SGGK ◆6pZCoAtaxk 2010/09/14(火)22:23 ID:8SPHlgRS(1) AAS
とりあえず修正対象にするcppファイルを1つ選び、
そのcppファイルがインクルードしてるヘッダファイルのファイル名の頭に付けてたv_(←修正中のヘッダファイルに付けてたやつ)をはずして、
そのままでは古いヘッダファイルと同じ名前になってしまうので、先に古いヘッダファイルは別のフォルダに移動しておく。
そしてコンパイルしてみる。
一個ずつ直してみたがバグがなかなか減らないし、ヘッダファイルもコンパイルの画面に新旧入り混じっている状態では
かえってややこしくなってくる。
cppファイルも一個ずつ順番に直してバグが無くなったら次に…と思っていたが、
うまく説明できないが、そうはならないはずとの考えに至る。
cppファイル単位できれいに独立してるわけではなくて、あるcppファイルのオブジェクトが呼ぶオブジェクトは別のcppファイルで定義されてて
そこからまた他のところへ…、するとそのcppファイルでインクルードしてるヘッダファイルも直した方のヘッダファイルに入れ替えなければならない。
結局、全部のヘッダファイルを新しい方だけ残して全部一気にコンパイルしてしまった。
エラーの総数が今現在349個。
ヘッダファイルの修正箇所をエクセルにメモする作業が無駄になってしまったかもしれない。
82: SGGK ◆6pZCoAtaxk 2010/09/15(水)22:31 ID:/g+buLkb(1) AAS
昨日は一気に全部まとめてコンパイルしたけど、描画関係をまとめたcppファイルはその時点で修正済。
そうした上でのバグ349個。
その後の修正で何故かバグが358個まで増えたけど、なんとかして344個に減ったところで終了。(今日はちょっと疲労気味なので…)
83
(1): 2010/09/16(木)03:09 ID:OhUUY93b(1/2) AAS
コツコツ頑張ってて偉いなぁ…本気で尊敬する。
84
(2): STG 2010/09/16(木)03:35 ID:YtfF1rT+(1) AAS
俺はずっとモデリング勉強&練習…
85
(1): 2010/09/16(木)03:50 ID:OhUUY93b(2/2) AAS
>>84
ガンガレ超ガンガレ
俺もそろそろ頑張ってみるか…
86: SGGK ◆6pZCoAtaxk 2010/09/16(木)23:40 ID:62n4CZRN(1) AAS
>>83
自分はこの板のおかげでゲーム作りへの挑戦は約3年1ヶ月程続いているけど、あまり進んでいないかもしれません。が…頑張ります!。
>>84>>85
お互い頑張りましょ〜!期待してます。
87
(3): SGGK ◆6pZCoAtaxk 2010/09/17(金)00:11 ID:iwt7bbkw(1) AAS
ベクトルの構造体を宣言・定義したから、ボールや選手などのオブジェクトの
座標その他のメンバ変数を初期化するときには、例えば初期化関数の内部で
オブジェクト.x=848;
オブジェクト.y=544;
オブジェクト.z=0;
としていたのを
オブジェクト.構造体変数名 = {848、544、0};
にできるのではと期待して書いてみるとエラーになる。
略)\source\ballcontrol.cpp(45) : error C2059: 構文エラー : '{'
略)\source\ballcontrol.cpp(45) : error C2143: 構文エラー : ';' が '{' の前にありません。
略)\source\ballcontrol.cpp(45) : error C2143: 構文エラー : ';' が '}' の前にありません。

これと同じようなエラーをクラスのオブジェクトでやった経験を思い出し、
オブジェクト.構造体変数名.x=848;
オブジェクト.構造体変数名.y=544;
オブジェクト.構造体変数名.z=0;
と書いたらエラーは出なくなった。
これだけならまだしも関数の引数にも構造体を使おうとしているので、
これもエラーになったらどうしようかと思いつつ、動作している事を優先して作業を進め、 現在のバグは274個。
ネットで調べると自分では構造体を書いたつもりでいても、Cの構造体とC++の構造体には違いがあるらしくて、
自分が見たサイトの説明によれば、

実は、構造体はメンバがデフォルトで公開されているクラスである。
つまり、
"stuct X{" = "class X{ public :"
となる。クラスと構造体の差異はそれだけである。

との事。
Cで書いたベクトルの記事を本で見て、それを今まで書いてたC++のソースに
使おうとしたから、自分の気付かない理由で上手くいってない感じ。
まずは今のままで進めてみて関数にベクトル構造体を引数にしたところでも
問題が出るようなら、また考え直すつもり。
88
(1): 2010/09/17(金)02:15 ID:zNJRouQ+(1) AAS
>>87
見方を変えると「Cの構造体に関数も書けるようにしたものがC++の構造体」とも言えると思う
Cの構造体で出来ることはC++でもそっくりそのまま書けると思うんだけどね

>自分の気付かない理由で上手くいってない感じ。
バグに関して絶対こうだとは言えないが、CとC++の違いが原因ではないような気がするなー
89
(1): 2010/09/17(金)22:28 ID:pd/LBTti(1/2) AAS
>>87

x、y、zを初期化するコンストラクタを定義されていれば
オブジェクト.構造体変数名 = クラス名(848,544,0);
のような代入ができる。

もしくは、構造体変数をセットするメンバ関数を定義してもいいかも。
90
(2): 2010/09/17(金)22:40 ID:pd/LBTti(2/2) AAS
上の補足

コンストラクタを定義していなければ、
オブジェクト.構造体変数名 = {848,544,0};
のような代入もできる。
91
(1): 2010/09/17(金)23:57 ID:iQtTD6+I(1) AAS
>>90
それは初期化時のみじゃない?

struct vector{
int x,y,z;
};

void main(){
vector a = { 1,2,3 }; //ok
a = { 4,5,6 }; //エラー
}
92
(2): SGGK ◆6pZCoAtaxk 2010/09/18(土)01:00 ID:wU0YURT9(1) AAS
ありがとうございます。今日は調べるだけで終了でした…。
>>88
たしかにバグの原因がCとC++の違いだと思い込んでしまうと他の原因の可能性を見落としやすくなりそうなので気をつけます。
>>89
今のソースではベクトル関係がクラスでなく構造体で表現されていてコンストラクタについてはまだ考えてませんでした。
バグが結局取り切れなかった場合、勉強しなおしてベクトル関係もクラス化する最終手段に挑戦してみようと思います。
>>90
コンストラクタの定義はしてないのですが、何故かエラーになってしまうので、
今は以下に書くとりあえず的なやり方でエラーを回避してます。
>>91
「構造体の初期化」で検索したところ、とあるサイトにそのような感じの
「構造体変数の初期化は、変数の宣言時には常に行うことが出来る点に注意しよう。」とあり、これを参考に以下のようにしてます。

ベクトル関係のヘッダファイルで
struct Vector3{float x,y,z;};

あるオブジェクトの初期化用関数の内部では昨日のやり方から少し変更して、

Vector3 a1={848,544,0};
fp.xy(←これは昨日書いていたオブジェクト.構造体変数名の事)=a1;

と書いてもバグが出ないのでこれでやってみようと思います。
今日は調べただけなので、バグは減ってないけど、全部取れるまで頑張ってみます。
93
(1): 2010/09/18(土)01:45 ID:ZJvrb5gA(1/3) AAS
>>92
>ベクトル関係もクラス化する最終手段に挑戦してみようと思います。
>>87は自分で書いててよく分かってないみたいだけど、classとstructは根本的には同じもの

struct Vector3{
Vector3(float x_, float y_, float z_): x(x_), y(y_), z(z_){}
float x,y,z;
};

void main(){
Vector3 a(1,2,3);
cout << a.x << " : " << a.y << " : " << a.z << endl;
a = Vector3(4,5,6);
cout << a.x << " : " << a.y << " : " << a.z << endl;
}
94
(1): 2010/09/18(土)01:56 ID:ZJvrb5gA(2/3) AAS
>>92
>Vector3 a1={848,544,0};
>fp.xy(←これは昨日書いていたオブジェクト.構造体変数名の事)=a1;
ちょっとこのレスで、代入のコストが気になったんで検証してみた

struct A{
A(){}
A(int x_, int y_, int z_): x(x_), y(y_), z(z_){}
int x,y,z;
};
struct B{
B(){}
B(int x_, int y_, int z_): x(x_), y(y_), z(z_){}
int x,y,z;
void operator=(B &val){
x=val.x; y=val.y; z=val.z;
}
};

AとBの違いはoperator=を使用してるかどうかだけ
A a,b;
a = b;
こんな感じでただ代入するだけの式を、それぞれ100万回ずつ実行
結果は予想外にもBの方が7倍も遅かった(単位はミリ秒)
A 5
B 35

そこで試しに、構造体に「double a[256];」を追加して実行
今度はBは変わらず、Aが極端に遅くなった
A 255
B 36
95
(1): 2010/09/18(土)02:09 ID:ZJvrb5gA(3/3) AAS
最初Bの方が遅かったのは、operator=のオーバーロード
つまり関数オーバーヘッド分の差が出たのだろう

変数を増やすとAが遅くなるのは、ほぼ間違いなくコピーコンストラクタが発生してるからだろう
ここら辺は言語仕様のレベルでBのような代入にしてくれてもいいような気がするなー

ま、結論としてはoperator=は弄らない方が速い
96
(1): SGGK ◆6pZCoAtaxk 2010/09/20(月)00:00 ID:y8zi6Evk(1) AAS
>>93>>94>>95
詳細な解説に感謝します。
自分にはまだ難しすぎるのですが、「c++  構造体の代入 問題点」で検索してみたところ、
以下のHPがこれらを理解するのに参考になり(理解は出来ず雰囲気だけなんとなく自分に伝わったような感じ。)、
リンク先はpdfなので要注意かもしれませんが、
外部リンク[pdf]:ist.ksc.kwansei.ac.jp
の12〜13ページあたりで、C++にはいろいろな種類のコンストラクタがあり、
結果は同じようでもその書き方によっては、コンストラクタが多く呼び出されて処理に時間がかかるらしい。
あと>>94のコンストラクタの書き方が見たことない書き方だったけど、
ちょうど17ページにある説明と似てるので、これかな?と思ってみたりで勉強になりました。

バグの方は、126個まで減少。
97: SGGK ◆6pZCoAtaxk 2010/09/20(月)23:18 ID:L4tJFEVm(1) AAS
今日もあまり作業出来てないけど、バグの残り36個。
98: SGGK ◆6pZCoAtaxk 2010/09/21(火)23:17 ID:48pAG2m3(1) AAS
やっとバグが0個になった。エラーメッセージが0個になったと言う方が正しい表現に近いかもしれない。
しかし、画面でスタート直後にボールに近い選手が通常よりも早いスピードで画面外に出ていくような動きをして、
画面端に到達してそこから動かなくなる問題が出た。
やっぱり出た。エラーメッセージの出ないバグが…。
もしも、>>96のようなコンストラクタがどうのこうのが理由で動かないとなるとやっかいな予感。
自分は>>96はもちろんのこと今までに難しいといったところはなかなか理解が出来てないから…。
99: SGGK ◆6pZCoAtaxk 2010/09/22(水)23:13 ID:gcFU0B9v(1) AAS
バグはまだ取れない。
選手が画面やレーダーに表示されてるという事は、画面の表示範囲を決めてるカメラ関係のところに原因があるという可能性はなさそう。
選手の座標を計算してる箇所を調べる。今書いてる計算式は、説明を省くのでわかりにくいけど、以下のような内容。

fp->xy = AddVector(fp->xy,MulVector(sv,Application::frametime/sq));

Application::frametimeの中身が気になったので、printfDx( " frametime = %f \n" , frametime ) ;で調べると、
15.100000と表示された。もう一回やり直すと15.633333と出た。
このframetimeは、dxライブラリのGetNowCount()を毎ループに1回計算し、
ループ前後の差を30回足して、それを30で割った平均値を意味してる。
調べるまで忘れてたけど、GetNowCount()の単位はミリ秒なので、先ほどの式では、1フレームで15ドット近い移動量になっているだろうから、
1秒が約60hzのパソコンだと1秒で1000ドット近く移動するはずなので、昨日の早すぎる移動スピードの原因だけはわかった。
とりあえず、
fp->xy = AddVector(fp->xy,MulVector(sv,Application::frametime/sq/1000));
のように書き直したら、選手がほとんど動かないけど、単位の間違いが原因だとわかった。
選手がボールに向かってくれない原因は未解決。
1-
あと 388 レスあります
スレ情報 赤レス抽出 画像レス抽出 歴の未読スレ

ぬこの手 ぬこTOP 0.008s