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

322: 名前は開発中のものです。 [sage] 2011/09/15(木) 07:32:47.70 ID:I5TXtYrP(3/6) AAS
>>320
320(2): SGGK ◆6pZCoAtaxk [sage] 2011/09/15(木) 06:34:11.75 ID:DAY99jiD(1) AAS
>>316,317,318
ありがとうございます。
これから始めようとしているボール関係処理作り直しの参考にさせてもらいます。

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

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

一応、ZEROCUPにこだわらない案も考えてみたので戻ってきたら続きを書いてみたいと思います。
ボールをトラップするも、ドリブルも、パスもシュートも、本質的には
「選手がボールをコントロールできる相対位置・速度条件にいるとき、どのようなコントロールの意思を示すか」
によって、ボールに新しい運動速度を与えるという処理に統一できる。
つまり、選手はボールに対しては速度にしか干渉できないように制限している。

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

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

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

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

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

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

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

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

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

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

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

もしくは、ジョイパッド操作は、チーム内で一人だけ動きが違う「キーパー」操作に割り当てても良いかも。
325
(1): 名前は開発中のものです。 [sage] 2011/09/15(木) 22:21:08.89 ID:I5TXtYrP(6/6) AAS
このあと>>252
252(7): 名前は開発中のものです。 [sage] 2011/06/07(火) 00:00:23.92 ID:OJpa3qNa(1) AAS
一気にゲームを完成させるのが難しいなら、要素ごとにマイルストーンを設定するのがいいですよ。

3D見下ろし型サッカーゲームだったら、
1.グラウンドとゴールを描画する。カメラを動かしたいのならその動かし方も決めて調整しておく。
2.ボールを配置し、試験的にマウスでクリックすると蹴ったように動くようにする(物理運動シミュレーション)。
3.ラインを割った状態(スローイン、コーナーキック、ゴールキック、得点)を判定し、復帰処理をつくる。
4.選手をまず1人表示し、動かせるようにする。
5.選手とボールの接触判定をし、マウスクリックの代わりに選手が蹴るようにする。
6.CPU選手をまずは1人登場させ、動くようにする。
7.ポジション別にCPU選手のAIを調整する。
8.タイム、スコア、勝敗、タイトル画面などの装飾要素を実装する。
の順番がおすすめです。
では仕上げに入っているけれど、補足すべき要素としては、
A.選手同士の接触判定と解決処理
B.最後にボールに触れた選手によるスローイン、ゴール・コーナーキックの判別
C.オフサイドの判定
D.AI実装のための評価関数の充実
などが必要じゃないかと思う。

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

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

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

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

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

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

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

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

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

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

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

次の予定はドリブル実装に挑戦!
333: SGGK ◆6pZCoAtaxk [sage] 2011/12/31(土) 22:10:55.60 ID:OIfdTnQa(1) AAS
気付けば今年ももう終わり…。
実はまた転勤の話が出て、その準備の所為で>>332から進んでないけど、それは言い訳だと思い反省…。
本当に無理だと思う状況にならない限りは諦めないでゆっくり細々でも続けるつもり!
334: 名前は開発中のものです。 [sage] 2012/01/18(水) 00:32:02.30 ID:JkO8yqpq(1) AAS
見てるぞ、がんばれ〜。
335: SGGK ◆6pZCoAtaxk [sage] 2012/01/21(土) 00:43:07.08 ID:GhL59l/a(1/2) AAS
ありがとうございます!
まだドリブル実装で止まってますが諦めずに頑張ります。
336
(1): SGGK ◆6pZCoAtaxk [sage] 2012/01/21(土) 01:10:41.85 ID:GhL59l/a(2/2) AAS
>>65
65(4): SGGK ◆6pZCoAtaxk [sage] 2010/08/03(火) 22:32:31 ID:nPEW7e3n(1) AAS
>>51の課題が終了。
ライフ値は、各選手が移動関数を実行した直後に少しずつ減らすようにしておき、
「 現時点のライフ値/最大ライフ値xライフゲージ最大長さ 」を計算して長方形をその長さで描画する。
減り具合は完全ではないけど、今は調整する予定なし。

次の目標

●共通(ゴールキーパー以外)
(実装済)歩く Z+マウス操作
   1 走る X+マウス操作
   2 進行方向固定 Shiftキー
   3 特殊技術(ボールが頭上ならヘディング、足元ならダイビングヘッド) Spaceバー
●ボールキープ時
   4 ジャンプ(タックル避けにもなる) C
   5 ロングパス 左クリック
   6 ショートパス 右クリック
   7 シュート 左右同時クリック
   8 パス/シュートは,押す長さで強さを調整
●非ボールキープ時
   9 タックル 左クリック
  10 カット 右クリック

これらの内6個でも実装できれば上出来と考えて挑戦する予定。
期限を決めてやるのは無理そうな感じ…orz
のキー割り当てと異なってくるかもしれないけど、

マウスカーソルに向かって歩く Zキー押し続ける
マウスカーソルに向かって走る Xキー押し続ける
選手の進行方向固定      Shiftキー押し続ける
ドリブル(選手はボールに向かって移動し、ボールに近づくと
     ボールをマウスカーソルに向かって蹴る。
     これを繰り返す)  Dキーを押し続ける
ロングパス    ドリブル中にマウス左クリック

これだと、選手の進行方向を固定して進行方向以外に向けて
ノールックっぽくロングパスを出そうとすると、
Z、Dを押しながらマウスを操作しなければならず、操作性が良くないような気がしてきた…。
深夜になってしまった。(汗;
337: SGGK ◆6pZCoAtaxk [sage] 2012/01/29(日) 23:10:06.09 ID:IMaOAms7(1) AAS
しばらくプログラムから離れててソースの中身を忘れてるかもしれないのでリハビリ的に短時間作業。
選手の移動関数内には選手がボールを蹴れる当たり判定範囲を円で示す処理があるんだけど、
その処理部分を別の関数を作ってそちらに移して、選手の移動関数内には
その別に作った関数を書けばいいようにした。
これから先、選手の移動関数内にはいろいろな状態を表すフラグが増えてきて
ソースが見づらくなる事が予想されるので、ちょっと整理してみようと思った。
338
(1): SGGK ◆6pZCoAtaxk [sage] 2012/01/30(月) 23:23:48.35 ID:9k8tvKVu(1/2) AAS
次は>>116
116(8): 名前は開発中のものです。 [sage] 2010/10/10(日) 07:27:55 ID:iMXoTcjW(1) AAS
一般的な方法としては、
・E=視点座標、つまりカメラの位置をあらわす位置ベクトル
・L=投影面における視点からマウスカーソルまでの半直線ベクトル
から、仮想空間内の任意の物体との交差判定、交差位置特定がきる。

Eは、普通、プログラム上で管理されている。

Lは、FOV(視野錘台)を自分で管理されているなら容易に計算できるが、
投影変換行列の逆行列を使っても計算できると思う(そういう便利な関数があるかもしれない)。
L = Mproj.inv x (mouseX,mouseY,1)T
  Mprij.inv = 投影変換行列の逆行列
 (mouseX,mouseY,1) = マウスの座標(正規化装置座標系、同次座標表現)

特に、フィールドのような単一平面との交点計算は、
・O=原点(フィールド面上にあること)
・N=フィールドの法線ベクトル(正規化ベクトル)
に対して、Eがフィールドの表面にあると限定した場合、
LとNの内積が0以上の場合、交差しない(マウスカーソルは天空を指している)

さもなければ、
・h= フィールド面からEまでの高さ((E-O)とNの内積)
から、
・t= -h/(LとNの内積)
を求めれば、目的とするフィールド上の点Fは、
・F= E+L*t
のような手順で計算できるはず。

あとは、(F-O)をフィールドの座標軸(X-O)(Y-O)で分解すれば、2次元座標に戻せる。

うろ覚えで書いているので細かい間違いがあるかも知れないが(違ってたら乞指摘)、
ゆっくりでいいんで、参考にしてもらえれば嬉しい。
頑張れ! 
を参考にした処理がプログラム内に散らばっているので、これも整理しようと思う。
昨日と違い面倒なところがあるので時間かかるかもしれない。
昨日のはひとつのクラス内での話なので、一部分の処理を関数として書き直したい場合、
そのクラス内のメンバ関数として定義して使えば動くけど、
今回やろうとしているのは、処理がいろいろなクラスで使われているので、
今考えられるやり方としては、その処理を行う関数をメンバ関数にもつ新しいクラスを作って、
その新しいクラスのオブジェクトを>>116の処理を使っているいろいろなクラス内で定義する。
あとはその新しいクラスのオブジェクト経由?で>>116の処理を行うメンバ関数を呼び出せばなんとかできるのではと期待。
339: SGGK ◆6pZCoAtaxk [sage] 2012/01/30(月) 23:29:08.24 ID:9k8tvKVu(2/2) AAS
下から2行目は、「定義する」ではなくて「実体化する」と書いた方が良かったかもしれない。
自信ないけど、なんとなく気になったので訂正。(汗;)
340: SGGK ◆6pZCoAtaxk [sage] 2012/02/01(水) 22:32:47.56 ID:3gp/rYmv(1) AAS
>>338で言った関数を作成。
プログラムの一か所を試しにこの関数で置き換えたところ動いた。
他のところの置き換えはその都度やることにして、>>336に戻る。
341
(2): SGGK ◆6pZCoAtaxk [sage] 2012/02/02(木) 22:41:13.33 ID:Y5t1e3wS(1) AAS
あれこれ考えたけど良いのが思い浮かばない。
ドリブルの移動関数を別に用意して、選手がボールに当たったらその選手がドリブル権を持っていることにして、
その間はドリブル関数で動くようにして、他の選手がボールに触れたらドリブル権がその選手に移り、
以下同様に繰り返す…というのを考えたが、なんだか以前に失敗したときと同じことになりそうな感じがした。
そこで別の案を偶然思いついた。
22人の選手が一つの変数を共有して、ボールに当たった選手はその変数を自分のIDに書き換えて
移動処理にきたときにその共有変数を見て、自分のIDと一致した場合、移動関数をドリブル関数にする。
そんな変数できるかと思ったがこれも偶然思い出した。
自信は無いけど、静的メンバ変数を宣言して、この変数を外部定義すればよいというところまで調べて思い出した。
なので、今日は
選手クラスにID(←いままで無かった)と静的メンバ変数とそのメンバ変数に読み書きできるように
get、set関数を用意した(メンバ変数がstaticだからこれらの関数が必要だった。)。
上手くいくかどうかは全く未知な状態。
342
(1): SGGK ◆6pZCoAtaxk [sage] 2012/02/06(月) 23:22:29.56 ID:fDWM60Br(1) AAS
上の文の下から2行目のは「staticでprivateだから」の間違いのような気がしてきたけど自信なし。
今は作業を続ける前にボール関係のクラスをプリントアウトして
寝る時にこれを見ながらプログラムの中身を思い出そうとしている最中。

何故、そんな事してるかというと単純に中身を忘れたので思い出す必要があるというのと、
現在マウス左クリックでボールを蹴りだせるようにしている箇所を関数として
ボールのクラスに移して残しておきたいと思ったから。
343: SGGK ◆6pZCoAtaxk [sage] 2012/02/13(月) 23:48:23.39 ID:Z7ePs7lw(1) AAS
ボールクラスの宣言内にボールを蹴ったときの処理をするメンバ関数の名前だけ書き、
その定義をcppファイルに書いた。でも、中身はまだ空の状態。
>>342の「現在マウス左クリックでボールを蹴りだせるようにしている箇所を関数」にしようとすると、
ボールを蹴る関数が、マウスと選手の位置情報を持つ必要があり、ボールを蹴る関数が複雑になるので、
現在マウス左クリックでボールを蹴りだせるようにしている箇所でボールを蹴ろうとする方向とその大きさを計算して、
それをボールを蹴る関数に引数として渡すようにしようと思ったところで終了。
いろいろあってなかなか進まない…orz
344: SGGK ◆6pZCoAtaxk [sage] 2012/02/27(月) 23:06:42.46 ID:7NsJmhpt(1) AAS
>>341
>22人の選手が一つの変数を共有して、ボールに当たった選手はその変数を自分のIDに書き換えて

のプログラムを書き、コンパイラが通るところまで出来た。
ドリブルの関数をどうするかについてまだちょっとはっきりしてない感じ。
345: SGGK ◆6pZCoAtaxk [sage] 2012/02/28(火) 23:55:54.65 ID:3O5AYFZZ(1) AAS
>>341
>移動処理にきたときにその共有変数を見て、自分のIDと一致した場合、移動関数をドリブル関数にする。

のプログラムを書いた。
選手の移動関数の目標座標がいままではマウスカーソルだったのを選手がボールにタッチした時に目標をボール座標に切り替わるようにしただけ。
ある程度の距離分ボールを蹴りだす処理を書いていないので、ボールにタッチすると同時に選手の動きがその位置で止まってしまう。
346: SGGK ◆6pZCoAtaxk [sage] 2012/03/03(土) 22:58:58.76 ID:7buMobyS(1) AAS
しかし、良く見ると自分の選手がボールにタッチする前から選手全員がボールに向かおうとしてることに気付く。
移動出来る選手は自分が動かす1人だけだけで他選手は足元から移動方向に短い線を引くようにしていたので気付いた。
原因はボールにタッチした場合にボールに向かい、タッチしてない場にマウスカーソルに向かうのを
反対にプログラムしていたから。

次は、それでもボールが蹴れない問題。

it=(*listfp).begin();
while(it!=(*listfp).end()){
      押してるキーで移動関数(歩く・走る)を切り替える
}
++it;
}
この1行を忘れてた → it=(*listfp).begin();
while(it!=(*listfp).end()){
      ボールにタッチすると判定用変数を選手IDに上書きして、選手の移動目標をボールにして、ボールを蹴る。
}
++it;
}

しかし、ボールの動きが良くない。
最初は選手がボールを押してるような感じでずるずる動いたかと思うと
次の瞬間、勢いよく蹴ってしまう。
1-
あと 141 レスあります
スレ情報 赤レス抽出 画像レス抽出 歴の未読スレ AAサムネイル

ぬこの手 ぬこTOP 0.021s