当たり判定
当たり判定
http://dixq.net/forum/viewtopic.php?f=3&t=10944
↑
上の続きなのですが、キャラクターとマップとの当たり判定でつまずいています。
壁の上下左右の座標とキャラクターが当たっているときにflag = trueとして
そしてflag == falseのときに重力を加えるとしたいのですが、
まず壁の上下左右の座標とキャラクターが当たっているときという条件式がわかりません。調べましたが理解はできませんでした。
そして
[codeccp]//ジャンプ
if((key & PAD_INPUT_UP) && stage.isontheground == true){
playerY -= JUMP_POWER;
stage.isontheground = false;
}[/code]
ジャンプでフラグをfalseにしているのにその後の が処理されません。
やはりWinMain関数のwhileのなかでやらないとだめなのでしょうか。
↑
上の続きなのですが、キャラクターとマップとの当たり判定でつまずいています。
壁の上下左右の座標とキャラクターが当たっているときにflag = trueとして
そしてflag == falseのときに重力を加えるとしたいのですが、
まず壁の上下左右の座標とキャラクターが当たっているときという条件式がわかりません。調べましたが理解はできませんでした。
そして
[codeccp]//ジャンプ
if((key & PAD_INPUT_UP) && stage.isontheground == true){
playerY -= JUMP_POWER;
stage.isontheground = false;
}[/code]
ジャンプでフラグをfalseにしているのにその後の が処理されません。
やはりWinMain関数のwhileのなかでやらないとだめなのでしょうか。
Re: 当たり判定
すみません。壁というのは床(画像)です。そして史上最悪のデスペナ さんが書きました:前スレッドが「マップが表示できません」とのことだったので見るのを止めたのですが・・・・・そこに書いてあったらごめんなさい
壁の上下左右・・・・というのがよく分かりませんが、上下というのは天井と地面という解釈でいいのでしょうか?
その場合、最初の状態で地面とキャラは本当に当たっている状態なのでしょうか?
ちなみに、私は常に重力は掛けておくほうがいいのではないかと思います
上下左右は
上→キャラクターの頭が床に当たっている状態
下→床に着地している状態
左→床の左の側面に当たっている状態
右→床の右の側面に当たっている状態
これの条件式です。
キャラクターと床はマップから座標を読み込んで表示しているので当たり判定はまったくありません。
そして調べてみるとベクトルというのがいくつかあって何かはわからないですがこれも使わないといけないのでしょうか
長々とすみません
よろしくお願いします
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: 当たり判定
アイテムでもブロックでも床でもやることは同じですので良いのですが確かangleもありますよね。ソッチのほうが問題ですね。
ちなみにベクトルは高1で習うと思いますが、まだ習っていない状態でしょうか? 【補足】や、高2だったかな?
【さらに補足】
登場するパラメータを整理して下さい。
床(ブロック?)のパラメータ
主人公のパラメータ
ちなみにベクトルは高1で習うと思いますが、まだ習っていない状態でしょうか? 【補足】や、高2だったかな?
【さらに補足】
登場するパラメータを整理して下さい。
床(ブロック?)のパラメータ
主人公のパラメータ
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: 当たり判定
例えばですが、こういうのはどうですか?
このように、テキストファイルか何かにマップ情報を書いておいて(0:何もない、1:床(乗れない)、2:床(乗れる))
キャラが0にいる、1にいる、2にいるで場合分けして処理するとか。
デバッグしたときに、
stage.isontheground
の値がどうなってますか?
0000000000000000000000000000000000
0000000000000022222222220000000000
0000000000000011111111110000000000
0000000000000000000000000000000000
0000000000000000000000000222222222
2222222222000002222222222222222222
キャラが0にいる、1にいる、2にいるで場合分けして処理するとか。
デバッグしたときに、
stage.isontheground
の値がどうなってますか?
うちの学校はベクトルは高2でしたsoftya(ソフト屋) さんが書きました:や、高2だったかな?
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: 当たり判定
>ベクトルに関しては少し調べてみます。angleがあるとどのような問題があるのでしょうか
回転していない四角形同士の当たり判定は容易ですが回転している四角形同士の当たり判定は数学的に面倒だからです。
参考例。
http://www.c3.club.kyutech.ac.jp/gamewi ... 8%BD%C4%EA
回転していない四角形同士の当たり判定は容易ですが回転している四角形同士の当たり判定は数学的に面倒だからです。
参考例。
http://www.c3.club.kyutech.ac.jp/gamewi ... 8%BD%C4%EA
こちらも回答をお願いします。【さらに補足】
登場するパラメータを整理して下さい。
床(ブロック?)のパラメータ
主人公のパラメータ
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: 当たり判定
txtファイルでいいですか?softya(ソフト屋) さんが書きました:>ベクトルに関しては少し調べてみます。angleがあるとどのような問題があるのでしょうか
回転していない四角形同士の当たり判定は容易ですが回転している四角形同士の当たり判定は数学的に面倒だからです。
参考例。
http://www.c3.club.kyutech.ac.jp/gamewi ... 8%BD%C4%EA
こちらも回答をお願いします。【さらに補足】
登場するパラメータを整理して下さい。
床(ブロック?)のパラメータ
主人公のパラメータ
640, 480, 576, 360 //左からマップサイズx, マッツサイズy, 主人公座標x, 主人公座標y
4 //データ行数
96, 432, 568, 48, 0, 0 //床座標x, 床座標y, 床の高さ, 床の幅, ラジアン, ID
552, 432, 568, 48, 0, 0 //床座標x, 床座標y, 床の高さ, 床の幅, ラジアン, ID
24, 384, 48, 48, 0, 0 //床座標x, 床座標y, 床の高さ, 床の幅, ラジアン, ID
24, 336, 48, 48, 0, 1 //床座標x, 床座標y, 床の高さ, 床の幅, ラジアン, ID
0
Re: 当たり判定
元々読み込んでいるマップのtxtがあるのでそっちを使いたいです。すみません史上最悪のデスペナ さんが書きました:例えばですが、こういうのはどうですか?
このように、テキストファイルか何かにマップ情報を書いておいて(0:何もない、1:床(乗れない)、2:床(乗れる))0000000000000000000000000000000000 0000000000000022222222220000000000 0000000000000011111111110000000000 0000000000000000000000000000000000 0000000000000000000000000222222222 2222222222000002222222222222222222
キャラが0にいる、1にいる、2にいるで場合分けして処理するとか。
デバッグしたときに、
stage.isontheground
の値がどうなってますか?
うちの学校はベクトルは高2でしたsoftya(ソフト屋) さんが書きました:や、高2だったかな?
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: 当たり判定
(1)から(4)までお願いします。
(1)床は独立して回転する可能性があるんですね?
(2)床はどういう条件で回転しますか?
(3)あと主人公は回転しないのでしょうか?
(4)それともうひとつ、動的に変化するベクトルなどのパラメータも書いて下さい。
(1)床は独立して回転する可能性があるんですね?
(2)床はどういう条件で回転しますか?
(3)あと主人公は回転しないのでしょうか?
(4)それともうひとつ、動的に変化するベクトルなどのパラメータも書いて下さい。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: 当たり判定
angleが0固定なら仕様上存在する意味がありません。C.C さんが書きました:(1,2,3)先ほど貼り付けたtxtファイルのラジアンをangleで読み込んでいるので値は決められていて更新されることはありません。ですので回転はしません。
バグを増やす原因になるので将来的にも不要なら削除しましょう。
DrawRota系の関数を使う意味もありません。
それは座標です。ベクトルは何処へ行ったのですか?C.C さんが書きました: (4)プレイヤーの移動のためのplayerX, playerYです
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: 当たり判定
すみません。playerX,playerYは貼り付けたtxtファイルの主人公座標x,yです。softya(ソフト屋) さんが書きました:angleが0固定なら仕様上存在する意味がありません。C.C さんが書きました:(1,2,3)先ほど貼り付けたtxtファイルのラジアンをangleで読み込んでいるので値は決められていて更新されることはありません。ですので回転はしません。
バグを増やす原因になるので将来的にも不要なら削除しましょう。
DrawRota系の関数を使う意味もありません。
それは座標です。ベクトルは何処へ行ったのですか?C.C さんが書きました: (4)プレイヤーの移動のためのplayerX, playerYです
DrawGraphに書き替えておきます
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: 当たり判定
で肝心の当たり判定ですが移動するときにしか上下左右に当たり判定があるかは判定できません。
主人公に重力が働いているなら下方向に重力加速度の分だけベクトルを加算します。
あとキー入力に合わせてベクトルを加算・減算します。
で主人公の座標を上下と左右別にベクトルで移動させて当たり判定をして障害物があるか判定します。
障害物に当たったらめり込んでいる座標を補正してその方向のベクトルを0にして下方向なら物体に載っているフラグを立てておきます。
当たり判定は四角形同士に当たり判定を使います(紹介済み)。
主人公に重力が働いているなら下方向に重力加速度の分だけベクトルを加算します。
あとキー入力に合わせてベクトルを加算・減算します。
で主人公の座標を上下と左右別にベクトルで移動させて当たり判定をして障害物があるか判定します。
障害物に当たったらめり込んでいる座標を補正してその方向のベクトルを0にして下方向なら物体に載っているフラグを立てておきます。
当たり判定は四角形同士に当たり判定を使います(紹介済み)。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: 当たり判定
RECT構造体で当たり判定を行いたいのですがエラーが出てしまいます。どうしたらよいのでしょうか。
エラー
'SetRect':再定義されています。異なる型修飾子です。
'SetRect':識別子が見つかりませんでした。
"CHSRRECT"から"LPRECT"への適切な変換関数が存在しません。
よろしくお願いします。
[code=cpp]
#define PLAYER_W (49)
#define PLAYER_H (96)
//キャラクターの矩形の構造体
struct CHARRECT{
int left;
int top;
int right;
int bottom;
};
BOOL SetRect(
LPRECT lprc, // RECT構造体へのポインタ
int xLeft, // 左端の座標
int yTop, // 上端の座標
int xRight, // 右端の座標
int yBottom); // 下端の座標
CHARRECT c_rect;
SetRect(&c_rect, (int)playerX, (int)playerY, (int)(playerX + PLAYER_W), (int)(playerY + PLAYER_H));
'SetRect':再定義されています。異なる型修飾子です。
'SetRect':識別子が見つかりませんでした。
"CHSRRECT"から"LPRECT"への適切な変換関数が存在しません。
よろしくお願いします。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: 当たり判定
これは何処に定義されているんでしょうか? ヘッダ or cppファイル?
そして、ここに書かれているとおりにファイルに書かれているんでしょうか?
SetRect()の関数呼び出しが関数外に書かれているので絶対にエラーになります。
そして、ここに書かれているとおりにファイルに書かれているんでしょうか?
SetRect()の関数呼び出しが関数外に書かれているので絶対にエラーになります。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: 当たり判定
返信ありがとうございます。
struct CHARRECT{
int left;
int top;
int right;
int bottom;
};
BOOL SetRect(
LPRECT lprc, // RECT構造体へのポインタ
int xLeft, // 左端の座標
int yTop, // 上端の座標
int xRight, // 右端の座標
int yBottom); // 下端の座標
はヘッダファイルです。
#define PLAYER_W (49)
#define PLAYER_H (96)
CHARRECT c_rect;
はmain.cppです。
SetRect(&c_rect, (int)playerX, (int)playerY, (int)(playerX + PLAYER_W), (int)(playerY + PLAYER_H));
はmain.cppのDrawGameMain()関数で呼び出しています
struct CHARRECT{
int left;
int top;
int right;
int bottom;
};
BOOL SetRect(
LPRECT lprc, // RECT構造体へのポインタ
int xLeft, // 左端の座標
int yTop, // 上端の座標
int xRight, // 右端の座標
int yBottom); // 下端の座標
はヘッダファイルです。
#define PLAYER_W (49)
#define PLAYER_H (96)
CHARRECT c_rect;
はmain.cppです。
SetRect(&c_rect, (int)playerX, (int)playerY, (int)(playerX + PLAYER_W), (int)(playerY + PLAYER_H));
はmain.cppのDrawGameMain()関数で呼び出しています
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: 当たり判定
1.'SetRect':再定義されています。異なる型修飾子です。
2.'SetRect':識別子が見つかりませんでした。
3."CHSRRECT"から"LPRECT"への適切な変換関数が存在しません。
のそれぞれのエラーがソースファイルのどの行に対して出ているか教えてください。
ただし、3に関しては、SetRectの第一引数がLPRECT lprc, // RECT構造体へのポインタなのにもかかわらず&c_rectを渡していますがこれは型が違うのでエラーです。
BOOL SetRect(
struct CHARRECT *lpcr,//CHARRECT構造体へのポインタ
ならOKです。
2.'SetRect':識別子が見つかりませんでした。
3."CHSRRECT"から"LPRECT"への適切な変換関数が存在しません。
のそれぞれのエラーがソースファイルのどの行に対して出ているか教えてください。
ただし、3に関しては、SetRectの第一引数がLPRECT lprc, // RECT構造体へのポインタなのにもかかわらず&c_rectを渡していますがこれは型が違うのでエラーです。
BOOL SetRect(
struct CHARRECT *lpcr,//CHARRECT構造体へのポインタ
ならOKです。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: 当たり判定
1,
BOOL SetRect(
LPRECT lprc, // RECT構造体へのポインタ
int xLeft, // 左端の座標
int yTop, // 上端の座標
int xRight, // 右端の座標
int yBottom); // 下端の座標
の
int yBottomで出ています。
2,3
SetRect(c_rect, (int)playerX, (int)playerY, (int)(playerX + PLAYER_W), (int)(playerY + PLAYER_H));
で出ています。
BOOL SetRect(
LPRECT lprc, // RECT構造体へのポインタ
int xLeft, // 左端の座標
int yTop, // 上端の座標
int xRight, // 右端の座標
int yBottom); // 下端の座標
の
int yBottomで出ています。
2,3
SetRect(c_rect, (int)playerX, (int)playerY, (int)(playerX + PLAYER_W), (int)(playerY + PLAYER_H));
で出ています。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: 当たり判定
1.SetRectと言う関数の定義が他のヘッダでもありませんか?
2.mainでSetRect関数が定義されたヘッダファイルをincludeしていますか?
2.mainでSetRect関数が定義されたヘッダファイルをincludeしていますか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: 当たり判定
1.SetRect以外に名前を変えましょう。C.C さんが書きました:1
c:\Program Files\Microsoft SDKs\Windows\v7.0A\Include\WinUser.hのなかにありました。
2
はい。
2.引数の型が合っていないと「識別子が見つかりませんでした。」と出る場合があります。引数の数や型を再確認してみて下さい。
よく有るミスは、intとfloatで違うやポインタ型なのにポインタを渡していないなど。
※ 名前が衝突してエラーになったので、SetRectがなかったコトにされているって事かもしれません。
[補足]
どうやってもエラーが解決しなければmain.cppだけのコンパクトな再現コードを貼ってもらったほうが早く解決しますね。
あとコンパクトな再現コードを作っている間に問題点に気づく事もあります。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: 当たり判定
1,SetCharRectに変えました。
2,SetCharRectはBOOL型で定義しているのですが return で true か false を返す必要はないのですか?
すみません。また新しいエラーがでました。
error LNK2019: 未解決の外部シンボル "int_cdecl SetCharRect(struct CHAR_RECT *,int,int,int,int)" (?SetCharRect@@YAHPAUCHARA_RECT@@HHHH@Z)が関数"void_cdecl DrawGameMain(void)" (? DrawGameMain@@YAXXZ)で参照されました。
です。
2,SetCharRectはBOOL型で定義しているのですが return で true か false を返す必要はないのですか?
すみません。また新しいエラーがでました。
error LNK2019: 未解決の外部シンボル "int_cdecl SetCharRect(struct CHAR_RECT *,int,int,int,int)" (?SetCharRect@@YAHPAUCHARA_RECT@@HHHH@Z)が関数"void_cdecl DrawGameMain(void)" (? DrawGameMain@@YAXXZ)で参照されました。
です。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: 当たり判定
返さないとダメです。と言うか今までのコードで関数の定義が出て来なかったので確認不能でした。C.C さんが書きました:1,SetCharRectに変えました。
2,SetCharRectはBOOL型で定義しているのですが return で true か false を返す必要はないのですか?
今までは関数のプロトタイプ宣言だけなので実体定義ではありません。
SetCharRectの実体定義が見つからないと言うエラーです。C.C さんが書きました: すみません。また新しいエラーがでました。
error LNK2019: 未解決の外部シンボル "int_cdecl SetCharRect(struct CHAR_RECT *,int,int,int,int)" (?SetCharRect@@YAHPAUCHARA_RECT@@HHHH@Z)が関数"void_cdecl DrawGameMain(void)" (? DrawGameMain@@YAXXZ)で参照されました。
です。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: 当たり判定
struct CHARA_RECT{softya(ソフト屋) さんが書きました:返さないとダメです。と言うか今までのコードで関数の定義が出て来なかったので確認不能でした。C.C さんが書きました:1,SetCharRectに変えました。
2,SetCharRectはBOOL型で定義しているのですが return で true か false を返す必要はないのですか?
今までは関数のプロトタイプ宣言だけなので実体定義ではありません。
SetCharRectの実体定義が見つからないと言うエラーです。C.C さんが書きました: すみません。また新しいエラーがでました。
error LNK2019: 未解決の外部シンボル "int_cdecl SetCharRect(struct CHAR_RECT *,int,int,int,int)" (?SetCharRect@@YAHPAUCHARA_RECT@@HHHH@Z)が関数"void_cdecl DrawGameMain(void)" (? DrawGameMain@@YAXXZ)で参照されました。
です。
int top;
int left;
int right;
int bottom;
};
CHAR_RECT c_rect;
c_rect.top = (int)playerY;
c_rect.left = (int)playerX;
c_rect.right = (int)(playerX + PLAYER_W);
c_rect.bottom = (int)(playerY + PLAYER_H);
このようにするとエラーが消えました。
ですが、これだけでは画像を四角形で囲めたようには思えません。
何か関数が必要なのですか?
もし必要であれば使い方などを教えていただけないでしょうか
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: 当たり判定
関数化を止めたんですね。
四角形(正方形・長方形)は4つの頂点で形作られます。左上と右下の座標が分かれば4つの頂点の座標は自ずと分かります。
数学・幾何学を苦手に感じられているかも知れませんが、意外と簡単な話なので紙に書いてみたらどうでしょうか?
ああっと納得できると思います。
四角形(正方形・長方形)は4つの頂点で形作られます。左上と右下の座標が分かれば4つの頂点の座標は自ずと分かります。
数学・幾何学を苦手に感じられているかも知れませんが、意外と簡単な話なので紙に書いてみたらどうでしょうか?
ああっと納得できると思います。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: 当たり判定
ヘッダファイル
struct WALL_RECT{
int left;
int top;
int right;
int bottom;
};
struct WALL_RECT_1{
int left;
int top;
int right;
int bottom;
};
struct WALL_RECT_2{
int left;
int top;
int right;
int bottom;
};
cppファイル
WALL_RECT w_rect = {96, 432, 568, 48}; //床の画像1を矩形で囲む
WALL_RECT_1 w_rect_1 = {552, 432, 568, 48}; //床の画像2を矩形で囲む
WALL_RECT_2 w_rect_2 = {24, 384, 48, 48}; //床の画像3を矩形で囲む
if(key & PAD_INPUT_RIGHT && stage.isontheground == true){
playerX += mv;
hstate = HERO_RUNNING;
stage.isheroleft = false;
//当たり判定
if( (w_rect.left < (playerX + PLAYER_W) )
&& (w_rect.top < (playerY + PLAYER_H) )
&& ( (w_rect.left + w_rect.right) > playerX)
&& ( (w_rect.bottom + w_rect.top) > playerY) ){
AccY = 0.0f;
PDown = 0.0f;
}
else if( (w_rect_1.left < (playerX + PLAYER_W) )
&& (w_rect_1.top < (playerY + PLAYER_H) )
&& ( (w_rect_1.left + w_rect_1.right) > playerX)
&& ( (w_rect_1.bottom + w_rect_1.top) > playerY) ){
AccY = 0.0f;
PDown = 0.0f;
}
else if( (w_rect_2.left < (playerX + PLAYER_W) )
&& (w_rect_2.top < (playerY + PLAYER_H) )
&& ( (w_rect_2.left + w_rect_2.right) > playerX)
&& ( (w_rect_2.bottom + w_rect_2.top) > playerY) ){
AccY = 0.0f;
PDown = 0.0f;
}
}
else if(key & PAD_INPUT_LEFT && stage.isontheground == true){
playerX -= mv;
hstate = HERO_RUNNING;
stage.isheroleft = true;
//当たり判定
if( (w_rect.left <= (playerX + PLAYER_W) )
&& (w_rect.top <= (playerY + PLAYER_H) )
&& ( (w_rect.left + w_rect.right) >= playerX)
&& ( (w_rect.bottom + w_rect.top) >= playerY) ){
AccY = 0.0f;
PDown = 0.0f;
}
if( (w_rect_1.left <= (playerX + PLAYER_W) )
&& (w_rect_1.top <= (playerY + PLAYER_H) )
&& ( (w_rect_1.left + w_rect_1.right) >= playerX)
&& ( (w_rect_1.bottom + w_rect_1.top) >= playerY) ){
AccY = 0.0f;
PDown = 0.0f;
}
if( (w_rect_2.left <= (playerX + PLAYER_W) )
&& (w_rect_2.top <= (playerY + PLAYER_H) )
&& ( (w_rect_2.left + w_rect_2.right) >= playerX)
&& ( (w_rect_2.bottom + w_rect_2.top) >= playerY) ){
AccY = 0.0f;
PDown = 0.0f;
}
}
//ジャンプ
else if(key & PAD_INPUT_UP && stage.isontheground == true){
AccY = -JUMP_POWER;
hstate = HERO_JUMP;
}
//プレイヤーの落下
AccY += PDown;
playerY += AccY;
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: 当たり判定
問題点を列挙します。
1.同じ構造の構造体を複数作る意味はありませんので避けて下さいね。バグや仕様混乱のもとです。
宣言と実体定義の区別が付いていないのではないでしょうか?
2.インデントが狂っていますね。正確にインデントしないとバグの原因となります。
3.WALLの情報はデータファイルから読みこむ仕様だったはずですか?
4.同じような処理を繰り返し書くのはバグの元なので、関数化して更に配列化でループ処理をして下さいね。
WALL情報は配列だったはずですが?
5.落下の当たり判定と横移動の当たり判定は別に行って下さい。
6.障害物に当たったあと座標補正がありませんよ。これだと刺さったままになります。
7.重力加速度の処理がありませんので、これだと落下も接地確認も出来ませんね。
8.w_rect_1.left + w_rect_1.rightで右と左の座標を足してはいけません。topとbottomも同様です。
デバッガで数値の確認と紙の上で実際に四角形の図と座標を書いて机上確認してみて下さい。
【補足】
全体的に細かい確認作業や詳細な理解が不足しています。
プログラミングはそこが大事ですので手を抜かないでください。
なんとなく・・・ってのが一番良くないです。
1.同じ構造の構造体を複数作る意味はありませんので避けて下さいね。バグや仕様混乱のもとです。
宣言と実体定義の区別が付いていないのではないでしょうか?
2.インデントが狂っていますね。正確にインデントしないとバグの原因となります。
3.WALLの情報はデータファイルから読みこむ仕様だったはずですか?
4.同じような処理を繰り返し書くのはバグの元なので、関数化して更に配列化でループ処理をして下さいね。
WALL情報は配列だったはずですが?
5.落下の当たり判定と横移動の当たり判定は別に行って下さい。
6.障害物に当たったあと座標補正がありませんよ。これだと刺さったままになります。
7.重力加速度の処理がありませんので、これだと落下も接地確認も出来ませんね。
8.w_rect_1.left + w_rect_1.rightで右と左の座標を足してはいけません。topとbottomも同様です。
デバッガで数値の確認と紙の上で実際に四角形の図と座標を書いて机上確認してみて下さい。
【補足】
全体的に細かい確認作業や詳細な理解が不足しています。
プログラミングはそこが大事ですので手を抜かないでください。
なんとなく・・・ってのが一番良くないです。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: 当たり判定
なんでも
1,4
WALL_RECT構造体を1つにしてfor文で値を代入し、1つ値が代入されるごとに当たり判定を行うようにします。
2,ifのそれぞれの&&以降をShiftキー+Enterキーで改行するようにします。
3,床の座標と幅と高さはわかっていたので直接値をいれていました。
5,現在のifのxとyをそれぞれのifとして分ければよいのでしょうか?
6,これは後でやるつもりでした。
7,これに関しては検討もつきません。すみません。
8,やってみたいと思います。
返信ありがとうございます。softya(ソフト屋) さんが書きました:問題点を列挙します。
1.同じ構造の構造体を複数作る意味はありませんので避けて下さいね。バグや仕様混乱のもとです。
宣言と実体定義の区別が付いていないのではないでしょうか?
2.インデントが狂っていますね。正確にインデントしないとバグの原因となります。
3.WALLの情報はデータファイルから読みこむ仕様だったはずですか?
4.同じような処理を繰り返し書くのはバグの元なので、関数化して更に配列化でループ処理をして下さいね。
WALL情報は配列だったはずですが?
5.落下の当たり判定と横移動の当たり判定は別に行って下さい。
6.障害物に当たったあと座標補正がありませんよ。これだと刺さったままになります。
7.重力加速度の処理がありませんので、これだと落下も接地確認も出来ませんね。
8.w_rect_1.left + w_rect_1.rightで右と左の座標を足してはいけません。topとbottomも同様です。
デバッガで数値の確認と紙の上で実際に四角形の図と座標を書いて机上確認してみて下さい。
【補足】
全体的に細かい確認作業や詳細な理解が不足しています。
プログラミングはそこが大事ですので手を抜かないでください。
なんとなく・・・ってのが一番良くないです。
1,4
WALL_RECT構造体を1つにしてfor文で値を代入し、1つ値が代入されるごとに当たり判定を行うようにします。
2,ifのそれぞれの&&以降をShiftキー+Enterキーで改行するようにします。
3,床の座標と幅と高さはわかっていたので直接値をいれていました。
5,現在のifのxとyをそれぞれのifとして分ければよいのでしょうか?
6,これは後でやるつもりでした。
7,これに関しては検討もつきません。すみません。
8,やってみたいと思います。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: 当たり判定
>1,4 WALL_RECT構造体を1つにしてfor文で値を代入し、1つ値が代入されるごとに当たり判定を行うようにします。
何か言っている事が不安ですが出来るだけ代入は減らして下さいね。
関数化をお忘れなく。
>2,ifのそれぞれの&&以降をShiftキー+Enterキーで改行するようにします。
編集→詳細→選択範囲のフォーマットでインデントが整形できます。
>3,床の座標と幅と高さはわかっていたので直接値をいれていました。
データファイルの意味が無いですし別に登録することでメンテナンス性の低下とミスの可能性が増えます。
>5,現在のifのxとyをそれぞれのifとして分ければよいのでしょうか?
違います。上下移動と左右移動をそれぞれ当たり判定してくださいと言うことです。
>6,これは後でやるつもりでした。
コメントとして書いておいて下さい。
>7,これに関しては検討もつきません。すみません。
重力加速度の方程式をご存じですか? 物理です。
何か言っている事が不安ですが出来るだけ代入は減らして下さいね。
関数化をお忘れなく。
>2,ifのそれぞれの&&以降をShiftキー+Enterキーで改行するようにします。
編集→詳細→選択範囲のフォーマットでインデントが整形できます。
>3,床の座標と幅と高さはわかっていたので直接値をいれていました。
データファイルの意味が無いですし別に登録することでメンテナンス性の低下とミスの可能性が増えます。
>5,現在のifのxとyをそれぞれのifとして分ければよいのでしょうか?
違います。上下移動と左右移動をそれぞれ当たり判定してくださいと言うことです。
>6,これは後でやるつもりでした。
コメントとして書いておいて下さい。
>7,これに関しては検討もつきません。すみません。
重力加速度の方程式をご存じですか? 物理です。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: 当たり判定
物理は習ったことはないです。
そして当たり判定を見て指摘していただけないでしょうか
if(床座標x <= (プレイヤー座標x + プレイヤーの幅)&&プレイヤー座標x <= (床座標x + 床の幅)
&&床座標y <= (プレイヤー座標y + プレイヤーの高さ)&&プレイヤー座標y <= (床座標y + 床の高さ)){
重力を0にする
床に乗っているフラグをtrueにする
}
if(プレイヤーの移動キーが押されている&&床に乗っているフラグがtrue){
if(プレイヤー座標x <= 床座標x && プレイヤー座標x <= (床座標x + 床の幅)
&&(プレイヤー座標x + プレイヤーの幅) <= (床座標x + 床の幅)
&& 床座標x <= (プレイヤー座標x + プレイヤーの幅)
&& プレイヤー座標y <= 床座標y
&& プレイヤー座標y <= (床座標y + 床の高さ)
&& 床座標y <= (プレイヤー座標y + プレイヤーの高さ)
&&(床座標y + 床の高さ) <= (プレイヤー座標y + プレイヤーの高さ){
プレイヤーの座標補正
プレイヤーの移動量を0にする
}
プレイヤー座標y += 重力加速度
実行結果:床の画像にプレイヤーが乗っていないのに重力が働かない
よろしくお願いします
そして当たり判定を見て指摘していただけないでしょうか
if(床座標x <= (プレイヤー座標x + プレイヤーの幅)&&プレイヤー座標x <= (床座標x + 床の幅)
&&床座標y <= (プレイヤー座標y + プレイヤーの高さ)&&プレイヤー座標y <= (床座標y + 床の高さ)){
重力を0にする
床に乗っているフラグをtrueにする
}
if(プレイヤーの移動キーが押されている&&床に乗っているフラグがtrue){
if(プレイヤー座標x <= 床座標x && プレイヤー座標x <= (床座標x + 床の幅)
&&(プレイヤー座標x + プレイヤーの幅) <= (床座標x + 床の幅)
&& 床座標x <= (プレイヤー座標x + プレイヤーの幅)
&& プレイヤー座標y <= 床座標y
&& プレイヤー座標y <= (床座標y + 床の高さ)
&& 床座標y <= (プレイヤー座標y + プレイヤーの高さ)
&&(床座標y + 床の高さ) <= (プレイヤー座標y + プレイヤーの高さ){
プレイヤーの座標補正
プレイヤーの移動量を0にする
}
プレイヤー座標y += 重力加速度
実行結果:床の画像にプレイヤーが乗っていないのに重力が働かない
よろしくお願いします
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: 当たり判定
>物理は習ったことはないです。
習っている必要はないですが、次のことは理解して下さい。
重力加速度は常に下方向のベクトルが発生します。
ゲーム的にはベクトルの下方向に一定値が毎フレーム加算されます。
コレが唯一の解では無いですが、次のように処理しないと問題があるので次のように処理して下さい。
(1) 下方向の重力ベクトルを加算。
(2) 上下方向のベクトルを座標に加算する。
(3) 当たり判定する(すべての床とループ)。ベクトルが下方向で当たったら着地とみなす。当たったら上下方向のベクトルをキャンセル。上下の座標を補正。
(4) 左右方向のベクトルを座標に加算する。
(5) 当たり判定をする(すべての床とループ)。当たったら左右方向のベクトルをキャンセル。左右の座標を補正。
習っている必要はないですが、次のことは理解して下さい。
重力加速度は常に下方向のベクトルが発生します。
ゲーム的にはベクトルの下方向に一定値が毎フレーム加算されます。
コレが唯一の解では無いですが、次のように処理しないと問題があるので次のように処理して下さい。
(1) 下方向の重力ベクトルを加算。
(2) 上下方向のベクトルを座標に加算する。
(3) 当たり判定する(すべての床とループ)。ベクトルが下方向で当たったら着地とみなす。当たったら上下方向のベクトルをキャンセル。上下の座標を補正。
(4) 左右方向のベクトルを座標に加算する。
(5) 当たり判定をする(すべての床とループ)。当たったら左右方向のベクトルをキャンセル。左右の座標を補正。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: 当たり判定
ありがとうございます。当たり判定には何か問題はありますか?softya(ソフト屋) さんが書きました:>物理は習ったことはないです。
習っている必要はないですが、次のことは理解して下さい。
重力加速度は常に下方向のベクトルが発生します。
ゲーム的にはベクトルの下方向に一定値が毎フレーム加算されます。
コレが唯一の解では無いですが、次のように処理しないと問題があるので次のように処理して下さい。
(1) 下方向の重力ベクトルを加算。
(2) 上下方向のベクトルを座標に加算する。
(3) 当たり判定する(すべての床とループ)。ベクトルが下方向で当たったら着地とみなす。当たったら上下方向のベクトルをキャンセル。上下の座標を補正。
(4) 左右方向のベクトルを座標に加算する。
(5) 当たり判定をする(すべての床とループ)。当たったら左右方向のベクトルをキャンセル。左右の座標を補正。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: 当たり判定
最初の当たり判定は良いですが、2つ目の当たり判定の意図がわかりません。C.C さんが書きました:ありがとうございます。当たり判定には何か問題はありますか?
これです。 ↓
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: 当たり判定
これは画像の側面同士の当たり判定です。softya(ソフト屋) さんが書きました:最初の当たり判定は良いですが、2つ目の当たり判定の意図がわかりません。C.C さんが書きました:ありがとうございます。当たり判定には何か問題はありますか?
これです。 ↓
Re: 当たり判定
No.29のコードは一部でしかないわけですが、この部分に限って言えば
・stage.isonthegroundがfalseになる箇所がない(trueのまま変化しない)
・重力加速度のPDownがゼロになったまま戻らない
などの点で、床から離れても落下しないという条件を満たしている気がします。
#Javaで書いたコードならブログで公開しているんですけどね。
・stage.isonthegroundがfalseになる箇所がない(trueのまま変化しない)
・重力加速度のPDownがゼロになったまま戻らない
などの点で、床から離れても落下しないという条件を満たしている気がします。
#Javaで書いたコードならブログで公開しているんですけどね。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: 当たり判定
これは床が必ずプレーヤーの右か下にあって衝突した場合しか成り立ちませんが良いのでしょうか?C.C さんが書きました:これは画像の側面同士の当たり判定です。softya(ソフト屋) さんが書きました:最初の当たり判定は良いですが、2つ目の当たり判定の意図がわかりません。C.C さんが書きました:ありがとうございます。当たり判定には何か問題はありますか?
これです。 ↓
あと完全にプレーヤーを内包した時も成立しませんし、左や上にあると成立しません。
問題のある条件式だと思います。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: 当たり判定
ISLeさん、softyaさん、返信が遅くなり申し訳ありません。
お陰で当り判定ができました。すみません。2つに分けます。
お陰で当り判定ができました。すみません。2つに分けます。
#define G (0.3F) // キャラに掛かる重力加速度
#define JUMP_POWER (9.0F) // キャラのジャンプ力
#define PLAYER_W (46) //プレイヤーの幅
#define PLAYER_H (96) //プレイヤーの高さ
float PDown = G; //下方向のベクトル
float AccY = 0.0f; //上下のベクトル
void DrawGameMain(){
stage.isontheground = false; //プレイヤーが床に乗っているときのフラグ
//プレイヤーの落下
AccY += PDown;
playerY += AccY;
Collision();
HeroState hstate = HERO_STANDING;
int key = GetJoypadInputState( DX_INPUT_KEY_PAD1 );
float mv = 80.0f * g_frametime; //横方向のベクトル
if(key & PAD_INPUT_RIGHT && stage.isontheground == true){
playerX += mv;
for(int i = 0; i < stage.num_mapchara; i++){
c_rect.x = (int)( playerX - PLAYER_W / 2 );
c_rect.y = (int)( playerY - PLAYER_H / 2 );
c_rect.width = (int)( c_rect.x + PLAYER_W );
c_rect.height = (int)( c_rect.y + PLAYER_H );
w_rect.x = (int)( stage.Wall[i].ID_X - stage.Wall[i].ID_W / 2 );
w_rect.y = (int)( stage.Wall[i].ID_Y - stage.Wall[i].ID_H / 2 );
w_rect.width = (int)( w_rect.x + stage.Wall[i].ID_W);
w_rect.height = (int)( w_rect.y + stage.Wall[i].ID_H );
if( c_rect.x >= w_rect.width ){
mv = 0.0f;
PDown = G;
}
}
hstate = HERO_RUNNING;
stage.isheroleft = false;
}
else if(key & PAD_INPUT_LEFT && stage.isontheground == true){
playerX -= mv;
for(int i = 0; i < stage.num_mapchara; i++){
c_rect.x = (int)( playerX - PLAYER_W / 2 );
c_rect.y = (int)( playerY - PLAYER_H / 2 );
c_rect.width = (int)( c_rect.x + PLAYER_W );
c_rect.height = (int)( c_rect.y + PLAYER_H );
w_rect.x = (int)(stage.Wall[i].ID_X - stage.Wall[i].ID_W / 2 );
w_rect.y = (int)(stage.Wall[i].ID_Y - stage.Wall[i].ID_H / 2 );
w_rect.width = (int)( w_rect.x + stage.Wall[i].ID_W );
w_rect.height = (int)( w_rect.y + stage.Wall[i].ID_H );
if(c_rect.width < w_rect.x){
mv = 0;
PDown = G;
}
}
hstate = HERO_RUNNING;
stage.isheroleft = true;
}
//ジャンプ
if(IsBKeyTrigger(key) == true && stage.isontheground == true){
AccY = -JUMP_POWER;
hstate = HERO_JUMP;
stage.isontheground = false;
}
if(stage.isontheground == false) hstate = HERO_JUMP;
//キャラクター描画
int animpat = (g_lasttime / (1000 / 12)) % 4;
switch(hstate){
case HERO_STANDING:
DrawRotaGraph((int)playerX, (int)playerY, 1, 0, img.player[0], TRUE, stage.isheroleft);
break;
case HERO_RUNNING:
DrawRotaGraph((int)playerX, (int)playerY, 1, 0, img.player[1 + animpat], TRUE, stage.isheroleft);
break;
case HERO_JUMP:
DrawRotaGraph((int)playerX, (int)playerY, 1, 0, img.player[5], TRUE, stage.isheroleft);
break;
}
}
Re: 当たり判定
//当り判定関数
void Collision(){
for(int i = 0; i < stage.num_mapchara; i++){
c_rect.x = (int)( playerX - PLAYER_W / 2 );
c_rect.y = (int)( playerY - PLAYER_H / 2 );
c_rect.width = (int)( c_rect.x + PLAYER_W );
c_rect.height = (int)( c_rect.y + PLAYER_H );
w_rect.x = (int)( stage.Wall[i].ID_X - stage.Wall[i].ID_W / 2 );
w_rect.y = (int)( stage.Wall[i].ID_Y - stage.Wall[i].ID_H / 2 );
w_rect.width = (int)( w_rect.x + stage.Wall[i].ID_W );
w_rect.height = (int)( w_rect.y + stage.Wall[i].ID_H );
if( w_rect.x <= c_rect.width && c_rect.x <= w_rect.width && w_rect.y <= c_rect.height && c_rect.y <= w_rect.height ){
PDown = 0.0f;
playerY = (float)( stage.Wall[i].ID_Y - stage.Wall[i].ID_H - stage.Wall[i].ID_H / 2);
stage.isontheground = true;
}
}
}
ソースをみてご指摘をお願いします
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: 当たり判定
だんだんソースコードが大きくなってきたので、次の点に注意して下さい。
1.ちゃんとコメントを振る。
2.インデントは正確に。
3.空白文字ではなく全角文字が入っている。これはなぜ?
4.同じような処理は関数化する。すくなくとも4行ぐらい同じ物があったら関数化するべきです。
5.ソースコードがなくコメントもない変数や関数の機能は作成者以外には分かりませんので、コメントや変数名、関数名に注意をはらって下さい。
6.c_rect.widthやc_rect.height の様に変数名と実際に扱われてい値の意味が違うものは他人にとって解読が困難ですので実態と合わせて下さい。
7.関数名と実際の機能に乖離があります(例Collision内で当たった後の処理を実行)ので、関数名と実際の動作は同じにして下さい。
Collisionに関しては当たり判定を戻り値で戻すべきで当たった後の処理は戻り値で分岐処理すべきです。
上記を直した上で、動作状況を確認したいのでソースコードと出来ればデータを全てzip圧縮して添付してもらった方が良いと思います。
版権的に問題があれば、代用データがあると嬉しいです。
【補足】
今気づきましたが上下と左右の当たり判定は別々に行うべきとアドバイスしたはずですが、それがされていません。
もしかして、これが当たり判定のつもりでしょうか? こんな簡易に当たり判定はできませんし、条件が間違っています。
1.ちゃんとコメントを振る。
2.インデントは正確に。
3.空白文字ではなく全角文字が入っている。これはなぜ?
4.同じような処理は関数化する。すくなくとも4行ぐらい同じ物があったら関数化するべきです。
5.ソースコードがなくコメントもない変数や関数の機能は作成者以外には分かりませんので、コメントや変数名、関数名に注意をはらって下さい。
6.c_rect.widthやc_rect.height の様に変数名と実際に扱われてい値の意味が違うものは他人にとって解読が困難ですので実態と合わせて下さい。
7.関数名と実際の機能に乖離があります(例Collision内で当たった後の処理を実行)ので、関数名と実際の動作は同じにして下さい。
Collisionに関しては当たり判定を戻り値で戻すべきで当たった後の処理は戻り値で分岐処理すべきです。
上記を直した上で、動作状況を確認したいのでソースコードと出来ればデータを全てzip圧縮して添付してもらった方が良いと思います。
版権的に問題があれば、代用データがあると嬉しいです。
【補足】
今気づきましたが上下と左右の当たり判定は別々に行うべきとアドバイスしたはずですが、それがされていません。
もしかして、これが当たり判定のつもりでしょうか? こんな簡易に当たり判定はできませんし、条件が間違っています。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: 当たり判定
とりあえず整理するために最新版の問題を箇条書きでお願いします。
ジャンプで落ちてこないだけでしょうか?
ジャンプで落ちてこないだけでしょうか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: 当たり判定
ソースを見ましたが、デバッガで見れば一目瞭然の問題があります。
(1)Wallの数だけループしてますので衝突があるとWallの数の倍数で移動します。
現状の移動速度は PLAYER_SPEED x Wallの数 です。
Wallの数だけ移動処理する必要ないはず。
(2)Wallがプレーヤーと逆方向に移動しています。
動く床に載っているようなものなのですが、これが更にスピードアップして見える原因ではないでしょうか?
同様の問題でジャンプするたびにWallが上にだけ移動します。
これは、マップスクロールの管理方法としても間違っています。
(1)Wallの数だけループしてますので衝突があるとWallの数の倍数で移動します。
現状の移動速度は PLAYER_SPEED x Wallの数 です。
Wallの数だけ移動処理する必要ないはず。
(2)Wallがプレーヤーと逆方向に移動しています。
動く床に載っているようなものなのですが、これが更にスピードアップして見える原因ではないでしょうか?
同様の問題でジャンプするたびにWallが上にだけ移動します。
これは、マップスクロールの管理方法としても間違っています。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: 当たり判定
スクロールは調べましたがプレイヤーに合わせてマップを動かすのはわかりました。softya(ソフト屋) さんが書きました:ソースを見ましたが、デバッガで見れば一目瞭然の問題があります。
(1)Wallの数だけループしてますので衝突があるとWallの数の倍数で移動します。
現状の移動速度は PLAYER_SPEED x Wallの数 です。
Wallの数だけ移動処理する必要ないはず。
(2)Wallがプレーヤーと逆方向に移動しています。
動く床に載っているようなものなのですが、これが更にスピードアップして見える原因ではないでしょうか?
同様の問題でジャンプするたびにWallが上にだけ移動します。
これは、マップスクロールの管理方法としても間違っています。
でもマップの動かし方がわかりません。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: 当たり判定
マップを動かす必要はありません。
主人公を画面の中心として表示していれば良いので、DrawRotaGraph時だけ主人公やWallなどの表示位置座標をローカル変数上で補正してやれば良いのです。
(0) 変数を用意する。
float screen_x,screen_y;
(1) 主人公が画面中心になるように画面端の座標を計算する。
screen_x = playerX - (DEFAULT_SCREEN_SIZE_X/2);
screen_y = playerY - (DEFAULT_SCREEN_SIZE_Y/2);
(2) 主人公やWallなどを画面端からの相対座標で表示する。
DrawRotaGraph((int)playerX-screen_x, (int)playerY-screen_y , 1, 0, img.player[0], TRUE, stage.isheroleft);
DrawRotaGraph(wall_x-screen_x, wall_y-screen_y, 1, wall_angle, img.wall[id], TRUE);
主人公を画面の中心として表示していれば良いので、DrawRotaGraph時だけ主人公やWallなどの表示位置座標をローカル変数上で補正してやれば良いのです。
(0) 変数を用意する。
float screen_x,screen_y;
(1) 主人公が画面中心になるように画面端の座標を計算する。
screen_x = playerX - (DEFAULT_SCREEN_SIZE_X/2);
screen_y = playerY - (DEFAULT_SCREEN_SIZE_Y/2);
(2) 主人公やWallなどを画面端からの相対座標で表示する。
DrawRotaGraph((int)playerX-screen_x, (int)playerY-screen_y , 1, 0, img.player[0], TRUE, stage.isheroleft);
DrawRotaGraph(wall_x-screen_x, wall_y-screen_y, 1, wall_angle, img.wall[id], TRUE);
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: 当たり判定
ありがとうございます。無事に解決しました。softya(ソフト屋) さんが書きました:マップを動かす必要はありません。
主人公を画面の中心として表示していれば良いので、DrawRotaGraph時だけ主人公やWallなどの表示位置座標をローカル変数上で補正してやれば良いのです。
(0) 変数を用意する。
float screen_x,screen_y;
(1) 主人公が画面中心になるように画面端の座標を計算する。
screen_x = playerX - (DEFAULT_SCREEN_SIZE_X/2);
screen_y = playerY - (DEFAULT_SCREEN_SIZE_Y/2);
(2) 主人公やWallなどを画面端からの相対座標で表示する。
DrawRotaGraph((int)playerX-screen_x, (int)playerY-screen_y , 1, 0, img.player[0], TRUE, stage.isheroleft);
DrawRotaGraph(wall_x-screen_x, wall_y-screen_y, 1, wall_angle, img.wall[id], TRUE);
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: 当たり判定
解決したソースコードを投稿していただくようにお願いします。ここのルールとなっております。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: 当たり判定
すみません。softya(ソフト屋) さんが書きました:解決したソースコードを投稿していただくようにお願いします。ここのルールとなっております。
//スクロール用の変数
float screenX = playerX - ( stage.mapsize_w / 2 );
float screenY = playerY - ( stage.mapsize_h / 2 );
void DrawGameMain(){
//プレイヤーの落下
AccY += PDown;
playerY += AccY;
HeroState hstate = HERO_STANDING;
int key = GetJoypadInputState( DX_INPUT_KEY_PAD1 );
if(Collision() == true){
if( key & PAD_INPUT_RIGHT ){
playerX += PLAYER_SPEED;
hstate = HERO_RUNNING;
stage.isheroleft = false;
}
if( key & PAD_INPUT_LEFT ){
playerX -= PLAYER_SPEED;
hstate = HERO_RUNNING;
stage.isheroleft = true;
}
//ジャンプ
if( key & PAD_INPUT_UP ){
AccY = -JUMP_POWER;
hstate = HERO_JUMP;
}
}
else{
hstate = HERO_JUMP;
PDown = G;
if(key & PAD_INPUT_RIGHT) playerX += PLAYER_SPEED;
if(key & PAD_INPUT_LEFT) playerX -= PLAYER_SPEED;
}
//キャラクター描画
int animpat = (g_lasttime / (1000 / 12)) % 4;
switch(hstate){
case HERO_STANDING:
DrawRotaGraph((int)(playerX - screenX), (int)(playerY - screenY), 1, 0, img.player[0], TRUE, stage.isheroleft);
break;
case HERO_RUNNING:
DrawRotaGraph((int)(playerX - screenX), (int)(playerY - screenY), 1, 0, img.player[1 + animpat], TRUE, stage.isheroleft);
break;
case HERO_JUMP:
DrawRotaGraph((int)(playerX - screenX), (int)(playerY - screenY), 1, 0, img.player[5], TRUE, stage.isheroleft);
break;
}
}
//床の描画
void GameMapDraw(){
//床の描画
for(int i = 0; i < stage.num_mapchara; i++){
if(stage.Wall[i].used == false) continue;
int id = stage.Wall[i].ID;
int wall_x = stage.Wall[i].ID_X;
int wall_y = stage.Wall[i].ID_Y;
float wall_angle = stage.Wall[i].ID_Angle;
DrawRotaGraph((int)(wall_x - screenX), (int)(wall_y - screenY), 1, wall_angle, img.wall[id], TRUE);
}
}