すいません、初めて質問させていただきます。
①使用ソフト visual stusio2010 C+ スクロールアクション
②質問 画面をスクロールさせるとともに当たり判定をスクロールさせたい。
悪魔城ドラキュラのようなスクロール型アクションゲームを製作していますffといいます。
サンプルプログラムを利用させていただき、、とりあえず横スクロールを導入しようとしたのですが、
マップとキャラクターの移動は思うようにできたものの当たり判定が思うようにスクロールせずに悩んでいます。
過去の質問を見て「キャラクターの画面上の座標」と「キャラクターのマップにおける座標」を分けて管理し、
当たり判定もその相対座標で補正するとは書かれていたのですが、CharMoveの引数に「キャラクターのマップにおける座標」を
渡してもうまくいきません。
解決の糸口でもいいのでどなたかご助言のほど、よろしくおねがいします。
あと後々マップを増やしくことを考え、ヘッダーに分けて管理していくように作成しているですが、
編集効率のいい設計をするうえで注意すべきことはあるでしょうか?
ファイルダウンロードURL(pass:ff)
http://ll.la/zb.O
よろしくおねがいします。
あたり判定のスクロール
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 15年前
- 住所: 東海地方
- 連絡を取る:
Re: あたり判定のスクロール
>解決の糸口でもいいのでどなたかご助言のほど、よろしくおねがいします。
座標は「マップ全体の仮想的な座標」ですべて管理した方が良いです。
その方が考え方がシンプルになります。
移動・当たり判定・攻撃などすべて「マップ全体の仮想的な座標」で処理します。
それに対してスクロール画面は表示専用で、主人公を中心に計算して求めるようにしてします。
つまり、表示にか使用しない座標系と言うことです。
なので、CharMoveではスクロール有無にかかわらず「マップ全体の仮想的な座標」系で処理すれば良いことになります。
>あと後々マップを増やしくことを考え、ヘッダーに分けて管理していくように作成しているですが、
>編集効率のいい設計をするうえで注意すべきことはあるでしょうか?
「新・C言語 ~ゲームプログラミングの館~ [DXライブラリ]」
http://dixq.net/g/
ここの
d.1 メイン関数の作り方
d.2 複数のファイルにわけてコンパイルする
d.3 ゲームの設計と分割コンパイル(1)
d.4 ゲームの設計と分割コンパイル(2)
d.5 ゲームの設計と分割コンパイル(3)
が参考になると思います。
座標は「マップ全体の仮想的な座標」ですべて管理した方が良いです。
その方が考え方がシンプルになります。
移動・当たり判定・攻撃などすべて「マップ全体の仮想的な座標」で処理します。
それに対してスクロール画面は表示専用で、主人公を中心に計算して求めるようにしてします。
つまり、表示にか使用しない座標系と言うことです。
なので、CharMoveではスクロール有無にかかわらず「マップ全体の仮想的な座標」系で処理すれば良いことになります。
>あと後々マップを増やしくことを考え、ヘッダーに分けて管理していくように作成しているですが、
>編集効率のいい設計をするうえで注意すべきことはあるでしょうか?
「新・C言語 ~ゲームプログラミングの館~ [DXライブラリ]」
http://dixq.net/g/
ここの
d.1 メイン関数の作り方
d.2 複数のファイルにわけてコンパイルする
d.3 ゲームの設計と分割コンパイル(1)
d.4 ゲームの設計と分割コンパイル(2)
d.5 ゲームの設計と分割コンパイル(3)
が参考になると思います。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
-
ff
Re: あたり判定のスクロール
回答いただきありがとうございます。
理解を深めるためにも、回答を自分なりに要約すると
①プレイヤーの位置や敵、弾、判定などはスクロールするマップ全体の仮想座標で考える。
(640×480を縦横4画面スクロールするなら、2560×1920のマップ全体で仮想座標を考える)
例:プレイヤーの中心の仮想座標 [V_Px,V_Py]=[1860,1210]
敵Aの仮想座標 [V_E1x,V_E1y]=[1900,1210]
敵Bの仮想座標 [V_E2x,V_E2y]=[240,1300]
マップの当たり判定 の仮想座標 [Mx,My] ※リフトなど動く足場でないかぎり固定値
とする
②マップ全体のどこを実際に画面表示するか(カメラをどこにするか)を、プレイヤーの仮想座標から割り出す。
例:プレイヤーを実際の画面の【R_Px,R_Py】=【320,400】に表示する場合
→画面の左上、つまり表示座標【0,0】を仮想座標[V_Px - R_Px ,V_Py - R_Py]=[1860-320,1210-400]=[1540,810]に対応させる
→仮想座標[1540,810]が画面表示座標【0,0】に対応したときの敵、当たり判定の画面表示座標を求める
敵Aの画面表示座標 = 【V_E1x - (V_Px - R_Px) , V_E1y - (V_Py - R_Py)】 = 【1900 - 1540 , 1210 - 810 】 = 【 360 , 400 】
敵Bの画面表示座標 = 【V_E2x - (V_Px - R_Px) , V_E2y - (V_Py - R_Py)】 = 【 240 - 1540 , 1300 - 810 】 = 【 -1300 , 490】 ※X座標が0以下のため実際には表示されない(画面外)
マップの当たり判定の画面表示座標 = 【 Mx - (V_Px - R_Px) , My - (V_Py - R_Py) 】
思考の流れはこんな感じであっているでしょうか?
またこれを関数にした場合
①キーボードの判定から変化量を取得
②変化量を引数としてそれぞれの各仮想座標をもとめる関数を呼び出し、戻り値として受け取る。
③(プレイヤーの仮想座標を求める関数から受け取った戻り値)=(プレイターの仮想座標)とプレイヤーの画面表示座標から【0,0】に対応する仮想座標(カメラ仮想座標)をもとめる
④カメラ仮想座標を引数としてそれぞれの表示座標をもとめる関数を呼び出し、戻りとして受け取る
⑤受け取った戻り値=表示座標を引数としてそれぞれのDraw関数を呼び出し描写
このように関数を作成し、その関数をそれぞれヘッダーにするという形でいいのでしょうか?
ご紹介いただいたページは以前に読ませていただき、大変勉強になったのですが私のオブジェク、モジュールトというものの理解が浅く、
ヘッダーファイルをどうように分類すべきかの理解につながらなかったため重複になるとは思いますが質問させていただきました。
(プレイヤー、敵というオブジェクトでヘッダーファイルを作成した場合、仮想座標を求める関数でヘッダーファイルを作成し、また画面表示関数を求める関数でヘッダーファイルを作成すべきなのか
それとも、プレイヤーに関する関数はすべて1つにまとめるておくべきなのか。またカメラ仮想座標から画面表示座標を求める関数など、プレイヤーの処理も敵の処理も同じ場合はどのようにまとめたら効率化が図れるのかなど。)
長々と書いてしまい、何度もお手数をおかけしますが
ご指導のほどよろしくおねがいします。
理解を深めるためにも、回答を自分なりに要約すると
①プレイヤーの位置や敵、弾、判定などはスクロールするマップ全体の仮想座標で考える。
(640×480を縦横4画面スクロールするなら、2560×1920のマップ全体で仮想座標を考える)
例:プレイヤーの中心の仮想座標 [V_Px,V_Py]=[1860,1210]
敵Aの仮想座標 [V_E1x,V_E1y]=[1900,1210]
敵Bの仮想座標 [V_E2x,V_E2y]=[240,1300]
マップの当たり判定 の仮想座標 [Mx,My] ※リフトなど動く足場でないかぎり固定値
とする
②マップ全体のどこを実際に画面表示するか(カメラをどこにするか)を、プレイヤーの仮想座標から割り出す。
例:プレイヤーを実際の画面の【R_Px,R_Py】=【320,400】に表示する場合
→画面の左上、つまり表示座標【0,0】を仮想座標[V_Px - R_Px ,V_Py - R_Py]=[1860-320,1210-400]=[1540,810]に対応させる
→仮想座標[1540,810]が画面表示座標【0,0】に対応したときの敵、当たり判定の画面表示座標を求める
敵Aの画面表示座標 = 【V_E1x - (V_Px - R_Px) , V_E1y - (V_Py - R_Py)】 = 【1900 - 1540 , 1210 - 810 】 = 【 360 , 400 】
敵Bの画面表示座標 = 【V_E2x - (V_Px - R_Px) , V_E2y - (V_Py - R_Py)】 = 【 240 - 1540 , 1300 - 810 】 = 【 -1300 , 490】 ※X座標が0以下のため実際には表示されない(画面外)
マップの当たり判定の画面表示座標 = 【 Mx - (V_Px - R_Px) , My - (V_Py - R_Py) 】
思考の流れはこんな感じであっているでしょうか?
またこれを関数にした場合
①キーボードの判定から変化量を取得
②変化量を引数としてそれぞれの各仮想座標をもとめる関数を呼び出し、戻り値として受け取る。
③(プレイヤーの仮想座標を求める関数から受け取った戻り値)=(プレイターの仮想座標)とプレイヤーの画面表示座標から【0,0】に対応する仮想座標(カメラ仮想座標)をもとめる
④カメラ仮想座標を引数としてそれぞれの表示座標をもとめる関数を呼び出し、戻りとして受け取る
⑤受け取った戻り値=表示座標を引数としてそれぞれのDraw関数を呼び出し描写
このように関数を作成し、その関数をそれぞれヘッダーにするという形でいいのでしょうか?
ご紹介いただいたページは以前に読ませていただき、大変勉強になったのですが私のオブジェク、モジュールトというものの理解が浅く、
ヘッダーファイルをどうように分類すべきかの理解につながらなかったため重複になるとは思いますが質問させていただきました。
(プレイヤー、敵というオブジェクトでヘッダーファイルを作成した場合、仮想座標を求める関数でヘッダーファイルを作成し、また画面表示関数を求める関数でヘッダーファイルを作成すべきなのか
それとも、プレイヤーに関する関数はすべて1つにまとめるておくべきなのか。またカメラ仮想座標から画面表示座標を求める関数など、プレイヤーの処理も敵の処理も同じ場合はどのようにまとめたら効率化が図れるのかなど。)
長々と書いてしまい、何度もお手数をおかけしますが
ご指導のほどよろしくおねがいします。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 15年前
- 住所: 東海地方
- 連絡を取る:
Re: あたり判定のスクロール
仮想と表示座標の考え方はOKだと思います。気になる点は、
「マップの当たり判定の画面表示座標」の座標を表示座標に変換する必要はありません。
これはマップパーツの表示座標という意味でしょうか?
>思考の流れはこんな感じであっているでしょうか?
>またこれを関数にした場合
・プレイヤーの移動関数でキーボードの判定で動作を決めれば良いと思います。
・敵や弾は仮想座標で移動・攻撃を行い当たり判定をします。
・表示を開始する前に、主人公座標をもとに表示座標の元になるスクリーン左上座標=カメラ座標を求めます。
・各表示関数は、スクリーン左上座標を元に表示します。
各ソースファイルとヘッダーファイルは一対一対応で作成して、モジュール化と言う意味で機能単位にソースファイル分けたほうが良いと思います。
つまり、プレイヤー、敵、弾、マップを別々のソースファイルにすると言うことです。なのでプレイヤーの移動、表示など関連するものは同じソースファイルに入れます。
プレーヤー、敵、弾など共通となるものがあった場合は、共通処理関数を集めたソースファイルを作りそちらを呼び出してください。それほど多くはないはずです。
「マップの当たり判定の画面表示座標」の座標を表示座標に変換する必要はありません。
これはマップパーツの表示座標という意味でしょうか?
>思考の流れはこんな感じであっているでしょうか?
>またこれを関数にした場合
・プレイヤーの移動関数でキーボードの判定で動作を決めれば良いと思います。
・敵や弾は仮想座標で移動・攻撃を行い当たり判定をします。
・表示を開始する前に、主人公座標をもとに表示座標の元になるスクリーン左上座標=カメラ座標を求めます。
・各表示関数は、スクリーン左上座標を元に表示します。
関数のプロトタイプ宣言だけをヘッダーに書きます。このように関数を作成し、その関数をそれぞれヘッダーにするという形でいいのでしょうか?
ご紹介いただいたページは以前に読ませていただき、大変勉強になったのですが私のオブジェク、モジュールトというものの理解が浅く、
ヘッダーファイルをどうように分類すべきかの理解につながらなかったため重複になるとは思いますが質問させていただきました。
(プレイヤー、敵というオブジェクトでヘッダーファイルを作成した場合、仮想座標を求める関数でヘッダーファイルを作成し、また画面表示関数を求める関数でヘッダーファイルを作成すべきなのか
それとも、プレイヤーに関する関数はすべて1つにまとめるておくべきなのか。またカメラ仮想座標から画面表示座標を求める関数など、プレイヤーの処理も敵の処理も同じ場合はどのようにまとめたら効率化が図れるのかなど。)
各ソースファイルとヘッダーファイルは一対一対応で作成して、モジュール化と言う意味で機能単位にソースファイル分けたほうが良いと思います。
つまり、プレイヤー、敵、弾、マップを別々のソースファイルにすると言うことです。なのでプレイヤーの移動、表示など関連するものは同じソースファイルに入れます。
プレーヤー、敵、弾など共通となるものがあった場合は、共通処理関数を集めたソースファイルを作りそちらを呼び出してください。それほど多くはないはずです。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
-
ff
Re: あたり判定のスクロール
返信ありがとうございます。
ご指摘いただいたように、もしかしたら当たり判定について大きな思い違いをしていたかもしれません。
・今までは全体マップの配列情報とは別に、マップの当たり判定を座標として管理するのかと思っていました
↓
・マップの当たり判定は、プレイヤーの仮想座標を決定する際に、全体マップの配列情報を参照することによって管理する
(マップにぶつかる場合にはプレイヤーの仮想座標が変化しないとする。敵の当たり判定については敵の仮想座標を参照する。)
こういうことでしょうか?となると、
①プレイヤーの仮想座標は敵や弾などの動くオブジェクトの仮想座標を先に計算し、他のオブジェクトの仮想座標や全体マップの配列情報を参照して計算することでそれらの当たり判定を管理する。
↓
②そしてプレイヤーの仮想座標と表示座標の相対関係から、他のオブジェクとマップパーツのの表示座標(画面の左上[0,0]が仮想座標のどこに相当するか)を計算して表示する。
と、すればよいのでしょうか?
正直まだ思い違いをしてそうなので、ご指摘いただくと助かります。
また、機能単位でのソースファイルの分類の仕方についても教えていただきありがとうございます。
さっそく、①プレイヤー、②敵、③マップ、④弾、⑤共通処理 などにわけてみようとおもいます。
以上、よろしくお願いします。
ご指摘いただいたように、もしかしたら当たり判定について大きな思い違いをしていたかもしれません。
・今までは全体マップの配列情報とは別に、マップの当たり判定を座標として管理するのかと思っていました
↓
・マップの当たり判定は、プレイヤーの仮想座標を決定する際に、全体マップの配列情報を参照することによって管理する
(マップにぶつかる場合にはプレイヤーの仮想座標が変化しないとする。敵の当たり判定については敵の仮想座標を参照する。)
こういうことでしょうか?となると、
①プレイヤーの仮想座標は敵や弾などの動くオブジェクトの仮想座標を先に計算し、他のオブジェクトの仮想座標や全体マップの配列情報を参照して計算することでそれらの当たり判定を管理する。
↓
②そしてプレイヤーの仮想座標と表示座標の相対関係から、他のオブジェクとマップパーツのの表示座標(画面の左上[0,0]が仮想座標のどこに相当するか)を計算して表示する。
と、すればよいのでしょうか?
正直まだ思い違いをしてそうなので、ご指摘いただくと助かります。
また、機能単位でのソースファイルの分類の仕方についても教えていただきありがとうございます。
さっそく、①プレイヤー、②敵、③マップ、④弾、⑤共通処理 などにわけてみようとおもいます。
以上、よろしくお願いします。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 15年前
- 住所: 東海地方
- 連絡を取る:
Re: あたり判定のスクロール
大体、それで合っていると思います。
それだとシンプルになるますので、やりやすくなると思います。
それだとシンプルになるますので、やりやすくなると思います。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。