トップページgamedev
332コメント288KB

1人でゲームが作れるように修行します。2

■ このスレッドは過去ログ倉庫に格納されています
0001名前は開発中のものです。2010/05/04(火) 00:44:29ID:HN0quC1A
がんばりましょう。

前スレ
1人でゲームが作れるように修行します。
http://pc11.2ch.net/test/read.cgi/gamedev/1006284805/
0291SGGK ◆6pZCoAtaxk 2011/06/29(水) 23:51:37.47ID:pI8KOKmf
今思えば自分の場合、全体を先に作りたいと言っていたのは、自分自身未知の作業なので作れる自信が無かった為、
作れそうか見極めたいといった目的もあったと思っています。ちなみに全体と言ってるのは、最低限の処理の流れの実装みたいなものです。
全体とか関係なく作れる場合は、好み優先で進んだ方がモチベーションが続くかも。

ホイールドラッグで画面を上下左右に動かせるようになったけど、
メタセコイアみたいにマウスで画面をつかんで動くような感じになってないので、原因調査中。
0292SGGK ◆6pZCoAtaxk 2011/07/02(土) 01:37:53.85ID:Yr95b2iZ
なんとか上下左右に動かせるようになった。(今日はたまたまこんな時間)
>291では、画面のフィールドが突然ロケットのような勢いで画面外に出て行ってしまったりして、
もうこれが自分の限界かと思った。

ディスプレイ画面上でマウスの示す位置がaからbまで移動すれば、3D座標系内のフィールド上の投影位置も
AからBに動くとして、そのベクトルABを算出して、カメラの位置ベクトルと注視点ベクトルに−ABしてやればうまくいくのではと思ってた。
これらの計算を始めた時の最初のカメラの位置をずっと初期値としてベクトルABを計算してループすればOKと思っていたのが間違いだったようだ。
毎ループ毎に計算した新しいカメラの位置および注視点ベクトルを次のループでの初期値にするよう書き直したら、
フィールドが飛んでいく不具合が解決!
0293179 ◆SLG//siTD6 2011/07/05(火) 05:05:11.63ID:oJBQ1HG/
>>290
単純だと・・・よろしいならば実装だ
ttp://gmdev.xrea.jp/st/up/380.png
って、勢いでプールだけ作ったけど、
グループクラス(&編成画面)実装にはやっぱ色々変更しないとだめぽ。。
あ、VECTORとかよくわからんので適当に配列(POOL[X][Y][PAGE])で実装してます(x`;
強引にやりすぎて中身がかなり汚い・・・w
どういうゲームか?自分でも良く分かってない/(^

>>292
ま、まぁカメラ周りは一回作ればそんなに弄ることないから
出来てしまえばこっちのモノサ
行列計算とかもうやりたくないです。ハイ
0294SGGK ◆6pZCoAtaxk 2011/07/05(火) 23:43:42.69ID:Bc+Kj7b6
>>293
カメラ周りはまだ時間かかりそうな感じだけど頑張ります。
実はまだメタセコイアを眺めてて回転の法則が見いだせない状態(汗
横の回転はたぶんこうプログラムすればいいだろうというイメージ出来たけど、
縦の回転はあともう少しで思いつきそうな感じ。
0295名前は開発中のものです。2011/07/07(木) 04:17:05.86ID:ATCSo0JT
メタセコイアの視点操作って、注視点関係なしにワーク原点を基準に
ヨー角ピッチ角の回転と距離だけじゃないかな?

CADには適しているけれど、ゲーム用のカメラとしては参考にならないよ。
0296SGGK ◆6pZCoAtaxk 2011/07/07(木) 23:37:42.40ID:RwXcD4/0
>>295
ゲームに不向とは気付かずに作業してました。ありがとうございます。
早目にこの段階を終わらせて次いきたいと思ってます。

今日は何も出来なかったけど、いちおう回転だけは土日になんとかしたい気持ち。
縦の回転方法も考えてみたので、今度こそプログラムを書いてみます。
0297179 ◆SLG//siTD6 2011/07/08(金) 00:03:46.32ID:eIT69sd4
1、原点(0,0,0)でカメラの向き(角度X,角度Y,0)の回転行列を作る
2、1のマトリックスから カメラから原点までの距離(0,0, - 距離)をトランスフォーム
3、マウスでのミドルボタン平行移動は(移動量X ,移動量 Y , 移動量Z(0))で1のマトリックスからトランスフォーム
4、2と3を足す
5、カメラに各要素をセット(4のposition、角度X,角度Y,0)

3、の 移動量Zの部分はメタセコアではズーム代わりになってると思う。
多分メタセコアのはこんな感じだと思(・x・`)
色々違ってたらゴメンナサイ、と・・・。
0298SGGK ◆6pZCoAtaxk 2011/07/09(土) 00:04:38.56ID:HknH7n3m
>>297
ありがとうございます。昨年末頃3Dの本を途中まで読んでて、
それに載っていた座標変換のことを忘れてました。
なのですぐにこれをコードに落とすのはまだ難しいけど、
プログラムのどこかでまた座標変換が必要になる頃には出来るように本を読み直してみます。
座標変換でやる場合、移動量Zを変えた時に注視点をどう変えるとズームになるかがまだ自信ないけど、
本読み直す時に解決出来ればと思ってます。

今日は、マウスの右ボタンドラッグ移動量から画面で回転させたい角度を計算するとこまで出来た。

あとは横回転はY軸に対して行い、縦回転は、注視点位置ベクトル(x、y、0)から
カメラ位置ベクトルのZ成分を0にしたベクトルをマイナスして出来たベクトルを90度回転してできたベクトルに対して
回転すればいけるかもしれないというあやしい方法を考えてました。(汗
0299SGGK ◆6pZCoAtaxk 2011/07/10(日) 22:33:55.13ID:fCX0gGeR
昨日の書き込みで間違いがあった。

縦回転は、注視点位置ベクトル(x、0、z)から
カメラ位置ベクトルのY成分を0にした (略)

が正解。自分のプログラムは垂直方向がY方向になってるのが理由。

メタセコイア風に画面内のフィールドを動かせるようになったような感じがする。
直接これをゲームに使う事はないかもしれないけど、いろいろ動かして、カメラの位置を検討するのに使えそう。
>>279でやった拡大方法だと、カメラの座標が変わらずに拡大縮小してしまうので、>>276氏の方法に変更。

次からはボールの動きに挑戦。179氏の>>297も意識して作業の予定。
0300SGGK ◆6pZCoAtaxk 2011/07/17(日) 22:29:42.21ID:3PbrHQAt
あまりの暑さなので今日はもう休もうみたいな感じ。
ボールの動きは、ゲーム開始直後に斜め45°で動きだすようにしてみたら動いた。
次は数値は適当だが重力方向の加速度を考慮した式にしてみたところボールは45°の角度で天井に向かってくだけで放物線にならず。
合計数時間は悩んだと思うけど、ループ毎にボール位置しか更新してなかったのが原因とわかる。
速度も加速度の影響で毎ループ変化してるので、速度も毎ループ毎に更新するようにしたら放物線のように動いた。
次は地面やフィールドの端でボールが跳ね返るようにすることに挑戦。
0301SGGK ◆6pZCoAtaxk 2011/08/01(月) 00:12:25.80ID:MQtVPARw
時間かかってしまったけど、ボールの跳ね返り実装完了。
ボールの動きは月面歩行みたいなゆったりな動きだけど、これで良しとする。(数値の調整でなんとかできるかも)
179氏>>297のマトリックスを掛けていく方式を意識しつつも、今回も長文プログラムで対応。
(マトリックス作成がまだ自分には理解できてない様なので、勉強しないと無理そうだと今回実感した感じ。)
指定範囲外にボールが出そうになった時に跳ね返らずに壁に沿ってボールが動いたけど、
速度だけ反転して、位置を反転して範囲内に戻してなかったのが原因。
ボールが跳ね返り、跳ね返りの高さが少しずつ小さくなり、最後は転がって止まるようにするのに苦労。
はねてる時の加速度は下向きで、転がってる時の加速(摩擦による逆向きを表現したかった)は速度と逆向きにするというような
加速度の切り替えをどうするかに時間がかかった。
ボールの位置が低い時で判定しようとするとプログラム開始時点で条件を満たして止まってしまう。
放物線の最高点での速度は水平だと思うので、水平になった時のボールの高さがある低い数値より下の場合に、
ボール位置のy成分を0にして加速度を切り替えてみた。
水平になった時を知る方法は、速度ベクトル1と速度のy成分を0にしたベクトル2の角度がプラスマイナス1度以内ならほぼ水平と判断。
角度はベクトル1と2の内積というものからcosを計算して判定。
加速度が切り替わって速度が少しずつ小さくなるので、一定値より小さくなったら停止。
…という流れで実装出来て動いてるけど、今後も問題なく動作するかは未知な感じ。
次は>>252
>3.ラインを割った状態(スローイン、コーナーキック、ゴールキック、得点)を判定し、復帰処理をつくる。
に挑戦の予定
0302SGGK ◆6pZCoAtaxk 2011/08/06(土) 23:29:11.60ID:p7p2W50E
やっぱり、簡単にはいかない予感。問題は時間の管理。
ボールがサイドラインを割ったらスローインする場合、
割った瞬間にスローイン位置にボールを復帰させるのは超反応すぎる感じがするので、
スローイン判定が出て、ちょっとボールが転がって、その後スローイン位置にボールが出現するようにしてみたいと思った。
すると、ボールがラインを割ってから、復帰までのわずかな時間をカウントして、その中断時間中はプレイ時間をカウントしないようにするにはどうすればいいんだという悩みが残る。
対象別に専用の時間を用意しなければならないのかと考えてみたが、それは時間測定対象が増えると大変な作業になる。
結構悩んだけど、時間の処理関数をメンバ関数に持つクラスを作って、必要な関数の数だけそのクラスのオブジェクトを作ればいいかもしれないと思った。
実は3D座標系でやってる今のプログラムは上記とは異なる理由から運よく時間関係をクラス化してたのでなんとかなるかもしれない。
2Dの時はこのクラスが無かった…というか思いつかなくて、3Dにするときに色々考えて、ソースを短くしたいという理由から時間関係をクラスにしていた。
時間のクラスには、
void countGameTime();//時間をカウントする。
void resetGameTime();//カウントを0にリセットする
void displayGameTime();//時間を画面表示
のメンバ関数があるけど、新たに
void tempStopGameTime();//カウントを一時停止する
void restartGameTime();//一時停止からカウント再開
を書き加える予定。

上手くいくか確認してから書いた方がいいかもしれないけど、書いてみた。(後で作業を振り返れるし。)
0303SGGK ◆6pZCoAtaxk 2011/08/17(水) 00:37:25.52ID:gcbpVhmx
>>252
>3.ラインを割った状態(スローイン、コーナーキック、ゴールキック、得点)を判定し、復帰処理をつくる。

1週間位で出来ないかなと思ったけど無理だった。
テクニックを持っていないので、if文と状態を表す変数で対応しようとしたらソースがぐちゃぐちゃになってしまった。
ノートに手書きで処理の流れを書いてからプログラムを書いてみたけど、多数の問題が発生。
一つずつ直していき、直してしまったらどんな問題だったのか思い出せないのもあったりする。
覚えている問題は、
(1)テキスト文字が表示されない。
(2)スローイン位置に復帰させたボールをけっても動かない。
(3)ボールを蹴れるようになったけど、その後再度ボールがラインを割っても何故か今度はスローインの処理に移らない。

原因と解決法
(1)原因:「ThrowIn!」のテキストがグラフィックの裏に表示されていた。(フィールドを回転できるようにしていなかったら気付かなかったかもしれない。)
   解決法:フィールドを書いてからテキストを表示すればいいけど、やり方を変えて、drawText()というメンバ関数を作り、これをメインループの最後の方に置く、
       元々テキスト描画命令を書いていたところではフラグをセットして、drawText()内に移したテキスト描画命令はフラグがセットなら命令実行するようにした。
(2)原因:3秒経過した?→YES→ボールをライン際にセット → ボール状態をSTOP → ボール状態がKICKKEDか? →YES → ボール移動
      という処理にしていたが、これだと、マウスクリックでボールの状態がKICKKEDになっても直前でSTOPに状態が変わるので、ボール状態がKICKKEDか? → NO となって動かない。
   解決法:かなり悩んだけど、3秒経過した?→YES→m_Set01==falseか?→YES→ボールをライン際にセット → ボール状態をSTOP →m_Set01=true;→ ボール状態がKICKKEDか? →YES → ボール移動
      にしたら動いた。

(3)←まだ原因不明。
0304SGGK ◆6pZCoAtaxk 2011/08/17(水) 23:01:09.88ID:umYfMU6K
(3)については、ボールの移動はそもそもボールクラスのメンバ関数moveの方で計算されるので、
状態がKICKKEDなら動くようになっていて、状態がKICKKEDになってその時の速度を再計算して直後にMOVINGという状態に移ってしまうように書いていた。
つまり、昨日の「ボール状態がKICKKEDか? →YES → ボール移動」とう処理にはいいつまでたっても進まない。
正解は、
ボール状態がMOVINGか? →YES → ライン判定の状態をリセットする
だった。
コーナーキック、ゴールキックもスローインを参考にして実装した。
これで、
>3.ラインを割った状態(スローイン、コーナーキック、ゴールキック、得点)を判定し、復帰処理をつくる。
得点以外は実装完了。

次は、
4.選手をまず1人表示し、動かせるようにする。
5.選手とボールの接触判定をし、マウスクリックの代わりに選手が蹴るようにする。
を一緒にやる時に得点実装する予定。
0305SGGK ◆6pZCoAtaxk 2011/08/19(金) 23:52:19.80ID:UUBFLar3
選手を1人だけ移動できるようにした。
今までプログラム内で処理を飛ばしていた部分を飛ばさないようにしただけだけど、
その頃は固定カメラだったので、カメラ座標が変わっても対応できるように修正。
ボールの移動関数のソースをほぼ流用できたので、なんとか出来た。
マウスを選手1人が追いかけ続けるだけだけど、とりあえずはこれで
4番は終了!
0306SGGK ◆6pZCoAtaxk 2011/09/03(土) 23:32:25.11ID:+c0ztxSK
たまにしか作業してなかったけど、問題があって進まずの状態。
選手とボールの当たり判定があった時にマウスクリックすればボール蹴れるはずが出来ない。
ボールは選手にくっついた状態で選手と一緒に動く。
しかし、なんどもクリックすればボールも少しずつ動く(これも原因不明)。
選手の移動を止めてクリックし続け、当たり判定ゾーンからボールが出ても
何故かボールが選手と同じ速度と方向で動き続ける。

ソースを読んでも原因全く不明。幸いこのボールを蹴る処理を書く前のところまで
戻れたので、もう一度書き直してみる予定。
0307SGGK ◆6pZCoAtaxk 2011/09/11(日) 22:22:25.77ID:T1L+oLn6
自分は作り始めて先月末で4年が経過してしまった…。
スレタイ通りの状況だけど、きっと何処かで作ってると思いながら、
自分も作業継続!

>306を何とかするために実際は8月30日頃から設計図を書くことにした。
大げさなものではなくてノートに手書きの状態遷移図もどき。
これにより、ボールの状態を
enum BALLSTATE{STOP=1,KICKKED,MOVING}; から、
enum MOVE_STATE{STOP=1,FREE,PRE_KEEP,KEEP};に変更してみた。
kickは選手のメンバ関数にした。
なんとなくだけど、当たり判定関数の引数を増やして、そこにフラグ値を入れて
当たり判定の有効無効を切り替えるようにした。

ボールの移動関数はほとんど書き直しになってしまい、試行錯誤の結果、
ボールが選手に付いていくようにはなった。

まだキック関数はうまく動作してくれない。
0308SGGK ◆6pZCoAtaxk 2011/09/11(日) 22:33:24.95ID:T1L+oLn6
実はボールの動きはかなり不自然な動きになってしまった。
選手の周りを衛星のようになって動く感じ。
Youtu●eでいろんなゲームを参考にしたけど、早すぎて動きのパターンがつかめなかったけど、
最終的にZEROC●Pというゲームを参考にしてみた。

>307で継続と言ったものの、4年でこの進み具合だとあと何年かかるのだろうか?
それ以前に完成出来るのだろうかという不安もあるので、この先どうなるかはやっぱりわかりません!(汗;
0309SGGK ◆6pZCoAtaxk 2011/09/11(日) 23:00:52.21ID:T1L+oLn6
今日はこれでラスト。
別に伏字にする事もないような気がしてきたので、Youtube、ZEROCUP が正解。

寝ようとしたけど、もう少しだけ作業したらボールをキックできた。

しかし、新しい問題が発生した。

ボールが一度しか蹴れない。
蹴ったボールを拾いにいってもボールが付いてこなくなった。
ボールがラインをはみ出したら試合経過時間が停止し、
ボールをフィールドに投げ込むまでの経過時間表示はされるが、
ボールが復帰位置に表示されない。
0310名前は開発中のものです。2011/09/12(月) 22:39:19.48ID:Im+6OdM9
失礼ながら、無駄に複雑にしすぎてるような気がするね。
基本的にボールの状態変数は、(x,y,z)、(vx,vy,vz)だけあればいい。
それと便宜的に(接地 or浮いている)フラグをつけてもいい。

初期値はそれぞれ、ボールの初期位置、速度は0、フラグは'接地'状態。

ボールのループごとの処理はこんな感じ。

  if(浮いている){
   垂直方向の重力加速度を速度に加算
   速度を位置に加算
   if(速度が下向きで垂直座標が地面より下){
     位置を地表に補正
     垂直方向の速度に -0.9とか反発係数を配慮した値を掛ける
     垂直速度が小さくなったら、'接地'状態とする
   }
  }else{
   水平方向の速度に0.99など転がり摩擦係数を意識した値を掛ける
  }
  水平方向の速度を水平位置に加算

蹴った瞬間、(vx,vy,vz)に初速度を与え、'浮いている'状態にするだけ。
0311SGGK ◆6pZCoAtaxk 2011/09/12(月) 22:48:41.39ID:I4CSS3jX
直観的に勢いでなんとか運よく直せた感じ。

1.ボールが一度しか蹴れない。
ボールと選手が当たってPRE_KEEP→KEEPの間は、その選手とボールのあたり判定をキャンセルするフラグを立てていたが、
 ボールを蹴った後、そのフラグを戻していなかったので、当たり判定が無効になり、ボールに触れても
 状態を変更する命令を実行しなかったから。
2.蹴ったボールを拾いにいってもボールが付いてこなくなった。
 1.の理由と同じ。
3.ボールがラインをはみ出したら試合経過時間が停止し、ボールをフィールドに投げ込むまでの経過時間表示はされるが、ボールが復帰位置に表示されない。
 ラインのはみ出し判定処理の内部でボールの復帰位置をセットしていたが、
 セットするだけではその位置に表示されるわけではない。
 enum MOVE_STATE{STOP=1,FREE,PRE_KEEP,KEEP};という4つの状態をボールに設定していたけど、
 これらは同時には存在しない状態なのでswitch〜case文にしておいて、
 それぞれのcaseの最後でその時点のボール位置を確定して、switch文を抜けてから
 描画関数にボール位置を渡していた。ちなみに変数はstaticにしたらswitchを抜けても保持されているみたいな感じ。(自信なし)
 ところが何故かcase STOPのところだけ、位置を確定する命令を書き忘れていたので、
 case FREEの時の確定位置が変数に残っていて、こちらの位置で表示されてしまったのが理由。
0312名前は開発中のものです。2011/09/12(月) 22:53:19.97ID:Im+6OdM9
ラインを割ったときには、その時点での(x,y,z)を控えておき、3秒間のカウンタを開始する。
その3秒間も、ボールのループごとの処理は継続する。

3秒たったら、控えておいた位置を復元するとともに、速度はゼロ、フラグは'接地'にセット
スローインしたときは、初速度は違うかもしれないが蹴ったときと同様。

(x,y,z)の控えや3秒カウンタは、ボールとは別のメインのクラスなどで管理するといいと思う。

0313SGGK ◆6pZCoAtaxk 2011/09/12(月) 23:12:56.43ID:I4CSS3jX
>>310,312
アドバイス、ありがとうございます。
書き込む前にリロードし忘れてしまい、すれ違ってしまいました。(汗;

自分のソースも似た感じの処理になってるようなのですが、
何故か原因不明でどんどん複雑化しているようです。
例えば、切り替えた状態が、知らない間に別のところで切り替えられてしまう…というような感じ。
ここから崩して作り直すのは厳しいので逆にこのまま>>252

6.CPU選手をまずは1人登場させ、動くようにする。
7.ポジション別にCPU選手のAIを調整する。
8.タイム、スコア、勝敗、タイトル画面などの装飾要素を実装する。

を目指してソースをupできるようにして、そこからソースの見直しをしてみたいと思います。
0314名前は開発中のものです。2011/09/13(火) 19:12:35.87ID:nrv6ZrDs
その残り3つ、急に段差がきつくなってると思う。
無理に進めずに、今までのところをきっちり固めてから進むべきじゃないかな。
0315SGGK ◆6pZCoAtaxk 2011/09/13(火) 22:23:15.13ID:UyS152Ji
>>314
書き込みありがとうございます。
AIについては何も勉強してない状態なので、ボール持ってる選手に他の選手が
近づいていくだけで、これがAIという事にしようと考えていましたが、これだけでは物足りないかもしれません。
もう少しAIっぽくしようとすると確かにきついです。
昨日は、崩して作り直すのは難しいと言ったけど、無理せず、部分的でもいいので
ソースを見直して、AIも少し調べてみようと思います。

現時点では、直したばかりのボール移動部分をさらに見直すつもり。
今の段階でも、選手が停止した状態ではボールが蹴れないとか、
ボールがマウス方向に飛ばないとか、クリックしてもすぐに蹴れないなどの不具合が出ているので、
ここはもう一度作り直した方がよさそうな気がした。
0316名前は開発中のものです。2011/09/14(水) 20:07:55.18ID:tc3GEPcb
コーディングする気はないけれど>>252を解釈してみる。
まずは「1.グラウンドとゴールを描画する。カメラを動かしたいのならその動かし方も決めて調整しておく」から。

グラウンドは大きな板ポリゴンにテクスチャを張る方法でも、自分で芝目や白線のポリゴンを描く方法でも
どっちても良いが、ポイントは「ゴールラインの中心に適切な高さのゴールを描いているかに懸かっている。
これは、基本的な座標系の方向とスケールを正しく理解してプログラミングしているかの試金石になる。

グラウンドとゴール一式を3Dモデルとして外部からインポートするという方法も有ると思うが、
その場合でも試験的にゴール枠、ゴールライン、タッチラインにプログラムで赤線を引くなどして、
平面の座方形の向きと、プログラム内でのフィールドのスケールを視覚的に確認しておくことは必須。

また、当然その様子は透視投影画像で自由にカメラ位置を変えて確認すべきなのだが、
そんなことはライブラリに専用関数が用意されているので、むしろ0番目的な段階の話だと言える。
数字キーを押したら例えばコーナーポストの外からゴール上空を注視する景色になるとか、
いつでも任意のカメラ位置から任意の地点を注視できるように、フレームワークに組み込んでおきたい。

おそらく3Dのサッカーゲームでユーザがプレイヤーに指示を与えながら
マウスでカメラも操作しろというのは無理だと思うので、完成度が上がってきたころには
自動カメラワークのアルゴリズムを検討することいなる。
ただし、現時点では切り替え式で十分。
0317名前は開発中のものです。2011/09/14(水) 20:42:28.24ID:tc3GEPcb
引き続き「2.ボールを配置し、試験的にマウスでクリックすると蹴ったように動くようにする」について。
ボールクラスの実装は>>310のとおりで、メソッドは、
(1) ボールの現在位置をセットし、速度は0にする:セットプレイ専用
(2) ループごとに実行する運動方程式の処理
(3) ボールの現在位置を求める
(4) ボールが接触した面があった場合、法線ベクトルを引数に速度を反転させ、反発面上に位置補正する処理
(5) ボールの現在速度を求める
(6) ボールに初速度を与える:キック時専用
(7) 現在位置にボールを描画する
とする。(4)の反発は、まずは地面で、次にゴールポストとクロスバーにも反応するようにしておきたい。

とりあえずテスト用には、右クリックでセンターマークに(1)ボールをセット、
左クリックで最初は固定方向でも良いので(6)ボールに初期値を与える機能を呼び出す。

ポイントは、キックによる初速度、重力加速度定数、転がり減衰係数、反発係数などの物理パラメータを
しっかりチューニングし、気持ちよくプレイできるバランスを見つけることに尽きる。

ちなみにメンバ変数はprivateにし、不用意に外部からフラグ操作しないこと。今後もおそらくその必要はないはず。
>>311によると「当たり判定をキャンセルするフラグ」のような意味不明なフラグを導入しているようだが、
物理的にナンセンスで実際バグの元にもなっている。発想を切り替えなければならない。
0318名前は開発中のものです。2011/09/14(水) 21:02:28.23ID:tc3GEPcb
連投大丈夫かな?「3.ラインを割った状態(スローイン、コーナーキック、ゴールキック、得点)を判定し、復帰処理をつくる」

日本サッカー協会の競技規定によると、ボールがラインを完全に割ったらアウトオブプレーとのことなので、
段階1で確認したプログラム上のフィールドサイズと、段階2のメソッド(3)によるボールの(中心の)現在位置と、
おそらく定数となるボールの半径から、インプレーかアウトオブプレーか判定ができる。
アウトの場合、タッチラインを割ったのか、ゴールラインを割ったのか、
またゴールラインの場合は、かごの内か外かまで判定できる。

しかし現時点ではコーナーキック、ゴールキックの区別はできない。

アウトオブプレーを検出したらフレームワーク側でホイッスルを鳴らすなり何か表示するなどの演出を始めても良いが、
ボールの物理シミュレーションメソッド(2)は呼び続けておくのが好ましい。

演出が終わったら復帰処理となるが、タッチラインを割ったときなら飛び出た位置あたりからスローインだし、
コーナーキック、ゴールキック、あるいは得点後はセットプレー扱いなので再開位置は自動的に決まるはず。
0319名前は開発中のものです。2011/09/15(木) 06:32:14.49ID:I5TXtYrP
「4.選手をまず1人表示し、動かせるようにする」

選手の3Dモデルデータが必要となるが、とりあえず雪だるまか、こけしか、冷蔵庫で代用することにし、
ここで本質的に重要なのは操作方法の決定とパラメータ調整ではないかと思う。

しかも、単に選手の2次元移動とはいいつつも、実際にはカメラの方向によってプレイヤーが混乱しない
ような工夫が必要なため、快適なプレイ環境を実現する操作方法というのは、実に奥が深いと思われる。
ここの作りこみ次第で、ゲームの面白さが左右されるはず。

しかしとりあえず暫定的なものにしておいて先の段階へ進みたいのであれば、
カメラ位置をセンターラインの延長上空、注視点をセンターマークにし、フィールド全体が見渡せる画面とし、
選手はカーソルキーかゲームパッドで移動するようなオーソドックスな方法で構わない。

この段階において、プレイヤーはフィールドの中だけ移動できるように境界条件処理をしておくと良い。
また、ボールとの関わりについては、少なくともこの段階では相互にまったく干渉しないことも確認しておく。
0320SGGK ◆6pZCoAtaxk 2011/09/15(木) 06:34:11.75ID:DAY99jiD
>>316,317,318
ありがとうございます。
これから始めようとしているボール関係処理作り直しの参考にさせてもらいます。

「1.グラウンドとゴールを描画する。カメラを動かしたいのならその動かし方も決めて調整しておく」
いまはメタセコイアっぽい操作でカメラを動かせる段階で止まっていますが、
作業が進めば、自動も考えてみたいです。

「2.ボールを配置し、試験的にマウスでクリックすると蹴ったように動くようにする」
基本的には>>310氏の案の様にいこうと今考え始めてたところで、法線による反発は将来の課題にしようと思います。
自分はZEROCUPの操作にこだわりすぎてたようで、ZEROCUPは選手がボールにあたると
ボールが選手に対してシューティングゲームのオプションのように動くので、
このボールキープ時のボールの動きは別のアルゴリズムに切り替えないと自分には無理で、
キープ中は当たり判定をOFFにしないと毎ループキープ状態への切り替え初期化がされてしまうといった事情が重なり、
だんだん複雑になっていったのだと思います。
ただ、ボールの移動処理をシンプル化しようとした時、選手がボールに当たった時に
選手の移動方向にボールが蹴られる方式では、ドリブルしながら選手の移動方向を変えようとすると、
選手がボールに当たる瞬間に方向を変えなければ、今のマウスカーソルに選手が向かう方式では
方向変更ができないと思い、これが悩みになってました。

一応、ZEROCUPにこだわらない案も考えてみたので戻ってきたら続きを書いてみたいと思います。
0321名前は開発中のものです。2011/09/15(木) 07:07:32.22ID:I5TXtYrP
「5.選手とボールの接触判定をし、マウスクリックの代わりに選手が蹴るようにする」

先の段階で放置しておいた選手とボールの作用条件について実装する。

選手もボールもともに運動する物体であることから、まずは、
段階2の(3)および(5)で得られるボールの位置および速度を、
判定対象選手のローカル座標系における相対位置、相対速度に変換する。

その上で下記の順に判定、処理を行う
(1) ボールの相対位置が選手に十分近い(距離<ボール半径+体格半径)かつ
  相対速度ベクトルが選手側に向かってきている場合、
  ボールがコントロールできない位置で単純に当たったものとみなし、
  メソッド2の(4)による反射処理を行う。法線はワールド座標系に逆変換すること。
  その際、選手自身の移動速度の法線方向成分を加味するため、
  反発係数は1.0を超えることも有り得る。

(2) ボールの相対位置が選手正面の特定領域内にあり、
  かつ選手がコントロールする意思を持った状態の場合、
  その意思に従いトラップするなりキックするなりでボールの相対速度を決め、
  ボールメソッド2(6)を呼び出す。
  その際も、選手ローカル座標からワールド座標系に戻してから渡す。

いずれでもなければ、選手はボールに干渉しない。
0322名前は開発中のものです。2011/09/15(木) 07:32:47.70ID:I5TXtYrP
>>320
ボールをトラップするも、ドリブルも、パスもシュートも、本質的には
「選手がボールをコントロールできる相対位置・速度条件にいるとき、どのようなコントロールの意思を示すか」
によって、ボールに新しい運動速度を与えるという処理に統一できる。
つまり、選手はボールに対しては速度にしか干渉できないように制限している。

これによって、もし多数の選手が団子状になったとしても、どう転がるかわからなけれど
試合自体は進行可能になると思う。

先着選手にボールが帰属(優先キープ)してしまうようなルールだと、ゲーム性が変わってくると思うけれど、
格闘よりもフィールド戦略を主にするなら、それもありかと思う。
0323名前は開発中のものです。2011/09/15(木) 21:25:19.83ID:I5TXtYrP
「6.CPU選手をまずは1人登場させ、動くようにする」

4で書き忘れたけれど選手クラスの定義には、
・現在位置(x,yz)
・向いている方向
・移動速度
・チームの識別符号
など、描画やボールへの干渉判定に必要な状態変数を持たせる。

それを少し拡張して、
・目標位置
・目標方向
をメンバに加え、
「現在位置が目標位置から遠ければ、
 向いている方向を目標位置の方向に1フレーム期間で回れる角度だけ補正し、
 移動速度も制限速度内で目標位置の方向に加速する。
 目標位置い近くなったら、
 向いている方向を目標方向に近づけるとともに、
 目的地で静止できるように減速する」
というような処理関数を作ってみる。

すると、CPU選手には「ボールを相手ゴールに向かってコントロールできる位置と方向」を与えれば、
毎フレームごとにボールに向かって突進するはず。

ボールがコントロール可能な状態(5の(2))になったなら、敵ゴールに向かってボールを蹴り出すが、
小さくければおそらくドリブルっぽくなるだろうし、ゴールに十分近づいたら強く蹴ってシュートにすればいい。
0324名前は開発中のものです。2011/09/15(木) 22:00:59.48ID:I5TXtYrP
「7.ポジション別にCPU選手のAIを調整する」
ここまでくると脳内プログラミングでは難しくなってくるが敢えて思考実験を続けてみる。

6での拡張で、個々の選手に対して、
・ボールをコントロールできない状態なら、目的地と方向を指示する
・ボールをコントロールできる状態なら、ボールのキック方向と強さを指示する
の2パターンだけ考えればよくなった。

目的地については、チームで戦うときは必ずしもボールに向かう必要はなく、
むしろパス回しを活用していかに早く安全に敵陣深く攻め込めるかを考えた配置に
なるよう、監督になった気分でそれぞれの選手に指示するべきである。

具体的には、選手間の位置関係から、ボールをコントロールできる(可能性が最も高い)選手から、
最前線の選手までの経路探索アルゴリズムを応用しつつ、個々の選手がより有利な位置に
移動するような評価関数などを駆使して、ということになりそうだが、脳内シミュレーションでは無理っぽい。

なお、選手への指示に上の2パターンを出せば、あとは自動で動いてくれるようにしたので、
ゲームパッドで選手ひとりを直接動かす操作方法は、この段階でデバッグ機能として卒業したい。

その代わりに、プレイヤーもマウスなどを使って、「どのプレイヤーをどこへ動かす」という指示を
リアルタイムに出せるインタフェースを作っておく。
こうなると完全にサッカーチームの監督ごっこというゲームシステムが固まってくる。

もしくは、ジョイパッド操作は、チーム内で一人だけ動きが違う「キーパー」操作に割り当てても良いかも。
0325名前は開発中のものです。2011/09/15(木) 22:21:08.89ID:I5TXtYrP
このあと>>252では仕上げに入っているけれど、補足すべき要素としては、
A.選手同士の接触判定と解決処理
B.最後にボールに触れた選手によるスローイン、ゴール・コーナーキックの判別
C.オフサイドの判定
D.AI実装のための評価関数の充実
などが必要じゃないかと思う。

「8.タイム、スコア、勝敗、タイトル画面などの装飾要素を実装する」については、
まあ、そのまんま好きなように作りこめば良い。

長々書いたけれど一応これで脳内では完成したつもり。
本当に実装できるか確かめていないので何の保証もないけれど、
なにか一部でも参考になれば嬉しいので自由に使ってくださいな。
0326SGGK ◆6pZCoAtaxk 2011/09/15(木) 23:35:53.55ID:7ihcTlmB
戻ってきたので>>320の続きです。
「3.ラインを割った状態(スローイン、コーナーキック、ゴールキック、得点)を判定し、復帰処理をつくる」
「4.選手をまず1人表示し、動かせるようにする」
どちらも一応大体は組み込めたような感じです。修正は今後もあると思います。
まだポリゴンキャラはやったことなく、ここで教わったビルボードというのでやってます。
いまの自分のレベルだとポリゴンキャラ実装はかなり先になりそうです…。

「5.選手とボールの接触判定をし、マウスクリックの代わりに選手が蹴るようにする」
しばらくの間は、この段階で頑張る事になると思います。
選手自身のボール反射は全く考えてなかったので、それ以外のキック、ドリブルなどの書き直しが
上手く出来たら、挑戦してみます。

「6.CPU選手をまずは1人登場させ、動くようにする」
方向をメンバに持たすのを考えてませんでした。
ポリゴンキャラじゃないので、絵的に表現させるのはまだまだ無理なので、
足元に矢印を表す直線を書いて向きを表現しようと思います。

「7.ポジション別にCPU選手のAIを調整する」
ここは未知の領域なのでまだ先ですが、この段階までこれたら参考にしたいと思います。

>>325も含めて多くの助言、ありがとうございました。
回答できなかった部分も今後の進捗に合わせて細部に取り込んでいこうと思います!

それと、ZEROCUPにこだわらない案
ドリブルキーを押すと選手とボールの位置関係と、蹴りたい方向を考慮して
選手があるていどオートで動く。
例えば、まっすぐドリブル中に90度右に動くようにマウスカーソルを動かした時に
丁度ボールを蹴りだしてしまったら、そのボールまで選手が動き、そこでマウスカーソル方向に蹴って、
選手もマウスカーソル方向に動くようになるという感じ。
0327SGGK ◆6pZCoAtaxk 2011/10/06(木) 23:08:47.15ID:9XiSdH1l
選手がボールと当たってたらボールを蹴れるようになるなどの処理を消して、
ボールの移動処理を簡素化してバグが出なくなるまで出来た。
しかし、ボールが表示されない。
とりあえず、マウスクリックでボールを蹴れるところまで戻せるよう頑張るつもり。
0328SGGK ◆6pZCoAtaxk 2011/10/17(月) 22:36:26.10ID:PMZ6FiGu
ちょっと停滞している状況にあるけど、まだ諦めてはいない(汗;
ボールが描画されなかった理由は、ボールの座標値に異常な大きさの数値が設定されていた為と思われる。
ソースを目で追うと、座標値計算の途中で0で割ろうとしている箇所があり、そこを直したらボールが表示された。
kick関数は選手のメンバ関数だったのをボールのメンバ関数に移し、左マウスクリックでkick関数を実行するようにしたら、
ボールは動くけどまだおかしい。
ボールは浮かずに常に右側にまっすぐ移動し、ラインを出てもラインアウトの判定がされなくなっている。
直接の原因はまだ不明だけど、ボールのメンバ変数にY軸回転角度と射出角度と速度の絶対値を持たせるように変えたことで、
まだ気付いていない未修正のところがあるからだと考えてる。
0329SGGK ◆6pZCoAtaxk 2011/11/06(日) 22:32:37.41ID:+A7uxjdP
あれこれ書き直している内にラインアウトの判定がいつの間にか直っていた。
ボールの軌跡がプログラムの意図と無関係な動きをする問題でつまづく。
左マウスをクリックしたときにボールの速度初期値に変更を加える方式だけど、
変更を単純にしてみたり、ボールの状態を一定にしてみてもダメ。
ふと、マウスの状態を決める箇所のプログラムを目で追っていると、
マウスを左クリックした場合、他のマウス操作をするまでずっとその状態がクリックしたままで
プログラム内で保持されている事に気づく。
そこを直したら、ボールの軌跡が直った。
前バージョンのプログラムでは何故問題なかったのか不思議だが、時間も無いのでこのまますすめることにした。
ボールの動きをバグ探しの為にかなり単純化してしまったので、
これを戻す過程でまた別のバグが出るかもしれない。
0330SGGK ◆6pZCoAtaxk 2011/11/07(月) 23:05:47.86ID:Ci/pCY6w
次に出た問題はボールを例えば傾斜60度で動かそうとしても動かない問題。
やり方はボールからマウスに向かうベクトルをY軸中心で90度回転する行列で回転させて、
そのベクトルを軸にしてボールからマウスに向かうベクトル(大きさは速度と一致させておく)を60度回転させる。

−60度にしてみたら放物線のように動いた。

なので、上記のやり方の中で、Y軸中心で−90度回転させてから、
そのベクトルを軸にして60度回転させるようにして解決。

マウスクリックでボールを動かせるようになったので、やっと選手で蹴れるかどうかというところまで戻った。
0331名前は開発中のものです。2011/11/08(火) 02:48:47.25ID:x9yT+23z
原因がジンバルロックなら一旦クォータニオンを経由させれば回避できるよ
0332SGGK ◆6pZCoAtaxk 2011/11/08(火) 23:40:07.79ID:3rFIMhjp
見てくれてありがとうございます!
プログラムの方はたぶんその可能性は無さそうな感じです。
プログラムはワールド座標系だけで書いてあり、選手から見た座標系をフィールド基準の座標系に行列一回で変換するような書き方はまだ出来てません。
ジンバルロックとクォータニオンについては難解なので、キーワードとして覚え、プログラムのレベルが上がってきたら挑戦してみたいと思います。

昨日の動作の件は、DXライブラリでの回転の正負方向が分からず、
60度で空中に向かってると思ったら、地中に60度で向かっているようで、
何故かボールが地面で反射せず、地面上を這うような動きになっていたのが原因です。

次の予定はドリブル実装に挑戦!
■ このスレッドは過去ログ倉庫に格納されています