当たり判定

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
C.C
記事: 64
登録日時: 13年前

当たり判定

#1

投稿記事 by C.C » 13年前

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にしているのにその後の

コード:

//重力
if(stage.isontheground == false)	playerY += 3;
が処理されません。
やはりWinMain関数のwhileのなかでやらないとだめなのでしょうか。

史上最悪のデスペナ
記事: 521
登録日時: 14年前

Re: 当たり判定

#2

投稿記事 by 史上最悪のデスペナ » 13年前

前スレッドが「マップが表示できません」とのことだったので見るのを止めたのですが・・・・・そこに書いてあったらごめんなさい

壁の上下左右・・・・というのがよく分かりませんが、上下というのは天井と地面という解釈でいいのでしょうか?
その場合、最初の状態で地面とキャラは本当に当たっている状態なのでしょうか?

ちなみに、私は常に重力は掛けておくほうがいいのではないかと思います

C.C
記事: 64
登録日時: 13年前

Re: 当たり判定

#3

投稿記事 by C.C » 13年前

史上最悪のデスペナ さんが書きました:前スレッドが「マップが表示できません」とのことだったので見るのを止めたのですが・・・・・そこに書いてあったらごめんなさい

壁の上下左右・・・・というのがよく分かりませんが、上下というのは天井と地面という解釈でいいのでしょうか?
その場合、最初の状態で地面とキャラは本当に当たっている状態なのでしょうか?

ちなみに、私は常に重力は掛けておくほうがいいのではないかと思います
すみません。壁というのは床(画像)です。そして
上下左右は
上→キャラクターの頭が床に当たっている状態
下→床に着地している状態
左→床の左の側面に当たっている状態
右→床の右の側面に当たっている状態
これの条件式です。
キャラクターと床はマップから座標を読み込んで表示しているので当たり判定はまったくありません。
そして調べてみるとベクトルというのがいくつかあって何かはわからないですがこれも使わないといけないのでしょうか
長々とすみません
よろしくお願いします

史上最悪のデスペナ
記事: 521
登録日時: 14年前

Re: 当たり判定

#4

投稿記事 by 史上最悪のデスペナ » 13年前

う。。。。ごめんなさい
全く状況の絵が思い浮かびません・・・・・・申し訳ありませんが絵で書いてもらってもいいですか?

最初は壁との当たり判定ということで3Dだと思っていたのですが・・・・・・もしかして床(画像)ってことは2D?

って前とぴを読めばいいんですよね。ということでちょっくら読んできます


要するにマリオですね?上が例えばアイテムブロックとの当たり判定・・・・・・・かな?

C.C
記事: 64
登録日時: 13年前

Re: 当たり判定

#5

投稿記事 by C.C » 13年前

史上最悪のデスペナ さんが書きました: 要するにマリオですね?上が例えばアイテムブロックとの当たり判定・・・・・・・かな?
わかりにくい説明で申し訳ありません。アイテムブロックではなく、床でお願いします

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: 当たり判定

#6

投稿記事 by softya(ソフト屋) » 13年前

アイテムでもブロックでも床でもやることは同じですので良いのですが確かangleもありますよね。ソッチのほうが問題ですね。
ちなみにベクトルは高1で習うと思いますが、まだ習っていない状態でしょうか? 【補足】や、高2だったかな?

【さらに補足】
登場するパラメータを整理して下さい。
床(ブロック?)のパラメータ
主人公のパラメータ
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

C.C
記事: 64
登録日時: 13年前

Re: 当たり判定

#7

投稿記事 by C.C » 13年前

softya(ソフト屋) さんが書きました:アイテムでもブロックでもやることは同じですので良いのですが確かangleもありますよね。ソッチのほうが問題ですね。
ちなみにベクトルは高1で習うと思いますが、まだ習っていない状態でしょうか? 【補足】や、高2だったかな?
ベクトルに関しては少し調べてみます。angleがあるとどのような問題があるのでしょうか

史上最悪のデスペナ
記事: 521
登録日時: 14年前

Re: 当たり判定

#8

投稿記事 by 史上最悪のデスペナ » 13年前

例えばですが、こういうのはどうですか?

コード:


0000000000000000000000000000000000
0000000000000022222222220000000000
0000000000000011111111110000000000
0000000000000000000000000000000000
0000000000000000000000000222222222
2222222222000002222222222222222222

このように、テキストファイルか何かにマップ情報を書いておいて(0:何もない、1:床(乗れない)、2:床(乗れる))
キャラが0にいる、1にいる、2にいるで場合分けして処理するとか。


デバッグしたときに、
stage.isontheground
の値がどうなってますか?
softya(ソフト屋) さんが書きました:や、高2だったかな?
うちの学校はベクトルは高2でした

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: 当たり判定

#9

投稿記事 by softya(ソフト屋) » 13年前

>ベクトルに関しては少し調べてみます。angleがあるとどのような問題があるのでしょうか

回転していない四角形同士の当たり判定は容易ですが回転している四角形同士の当たり判定は数学的に面倒だからです。

参考例。
http://www.c3.club.kyutech.ac.jp/gamewi ... 8%BD%C4%EA
【さらに補足】
登場するパラメータを整理して下さい。
床(ブロック?)のパラメータ
主人公のパラメータ
こちらも回答をお願いします。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

C.C
記事: 64
登録日時: 13年前

Re: 当たり判定

#10

投稿記事 by C.C » 13年前

softya(ソフト屋) さんが書きました:>ベクトルに関しては少し調べてみます。angleがあるとどのような問題があるのでしょうか

回転していない四角形同士の当たり判定は容易ですが回転している四角形同士の当たり判定は数学的に面倒だからです。

参考例。
http://www.c3.club.kyutech.ac.jp/gamewi ... 8%BD%C4%EA
【さらに補足】
登場するパラメータを整理して下さい。
床(ブロック?)のパラメータ
主人公のパラメータ
こちらも回答をお願いします。
txtファイルでいいですか?

コード:

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

C.C
記事: 64
登録日時: 13年前

Re: 当たり判定

#11

投稿記事 by C.C » 13年前

史上最悪のデスペナ さんが書きました:例えばですが、こういうのはどうですか?

コード:


0000000000000000000000000000000000
0000000000000022222222220000000000
0000000000000011111111110000000000
0000000000000000000000000000000000
0000000000000000000000000222222222
2222222222000002222222222222222222

このように、テキストファイルか何かにマップ情報を書いておいて(0:何もない、1:床(乗れない)、2:床(乗れる))
キャラが0にいる、1にいる、2にいるで場合分けして処理するとか。


デバッグしたときに、
stage.isontheground
の値がどうなってますか?
softya(ソフト屋) さんが書きました:や、高2だったかな?
うちの学校はベクトルは高2でした
元々読み込んでいるマップのtxtがあるのでそっちを使いたいです。すみません

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: 当たり判定

#12

投稿記事 by softya(ソフト屋) » 13年前

(1)から(4)までお願いします。

(1)床は独立して回転する可能性があるんですね?
(2)床はどういう条件で回転しますか?
(3)あと主人公は回転しないのでしょうか?
(4)それともうひとつ、動的に変化するベクトルなどのパラメータも書いて下さい。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

C.C
記事: 64
登録日時: 13年前

Re: 当たり判定

#13

投稿記事 by C.C » 13年前

softya(ソフト屋) さんが書きました:(1)から(4)までお願いします。

(1)床は独立して回転する可能性があるんですね?
(2)床はどういう条件で回転しますか?
(3)あと主人公は回転しないのでしょうか?
(4)それともうひとつ、動的に変化するベクトルなどのパラメータも書いて下さい。
(1,2,3)先ほど貼り付けたtxtファイルのラジアンをangleで読み込んでいるので値は決められていて更新されることはありません。ですので回転はしません。
(4)プレイヤーの移動のためのplayerX, playerYです

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: 当たり判定

#14

投稿記事 by softya(ソフト屋) » 13年前

C.C さんが書きました:(1,2,3)先ほど貼り付けたtxtファイルのラジアンをangleで読み込んでいるので値は決められていて更新されることはありません。ですので回転はしません。
angleが0固定なら仕様上存在する意味がありません。
バグを増やす原因になるので将来的にも不要なら削除しましょう。
DrawRota系の関数を使う意味もありません。
C.C さんが書きました: (4)プレイヤーの移動のためのplayerX, playerYです
それは座標です。ベクトルは何処へ行ったのですか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

C.C
記事: 64
登録日時: 13年前

Re: 当たり判定

#15

投稿記事 by C.C » 13年前

softya(ソフト屋) さんが書きました:
C.C さんが書きました:(1,2,3)先ほど貼り付けたtxtファイルのラジアンをangleで読み込んでいるので値は決められていて更新されることはありません。ですので回転はしません。
angleが0固定なら仕様上存在する意味がありません。
バグを増やす原因になるので将来的にも不要なら削除しましょう。
DrawRota系の関数を使う意味もありません。
C.C さんが書きました: (4)プレイヤーの移動のためのplayerX, playerYです
それは座標です。ベクトルは何処へ行ったのですか?
すみません。playerX,playerYは貼り付けたtxtファイルの主人公座標x,yです。
DrawGraphに書き替えておきます

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: 当たり判定

#16

投稿記事 by softya(ソフト屋) » 13年前

で肝心の当たり判定ですが移動するときにしか上下左右に当たり判定があるかは判定できません。
主人公に重力が働いているなら下方向に重力加速度の分だけベクトルを加算します。
あとキー入力に合わせてベクトルを加算・減算します。
で主人公の座標を上下と左右別にベクトルで移動させて当たり判定をして障害物があるか判定します。
障害物に当たったらめり込んでいる座標を補正してその方向のベクトルを0にして下方向なら物体に載っているフラグを立てておきます。

当たり判定は四角形同士に当たり判定を使います(紹介済み)。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

C.C
記事: 64
登録日時: 13年前

Re: 当たり判定

#17

投稿記事 by C.C » 13年前

RECT構造体で当たり判定を行いたいのですがエラーが出てしまいます。どうしたらよいのでしょうか。

コード:

[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: 当たり判定

#18

投稿記事 by softya(ソフト屋) » 13年前

これは何処に定義されているんでしょうか? ヘッダ or cppファイル?
そして、ここに書かれているとおりにファイルに書かれているんでしょうか?

SetRect()の関数呼び出しが関数外に書かれているので絶対にエラーになります。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

C.C
記事: 64
登録日時: 13年前

Re: 当たり判定

#19

投稿記事 by C.C » 13年前

返信ありがとうございます。
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: 当たり判定

#20

投稿記事 by softya(ソフト屋) » 13年前

1.'SetRect':再定義されています。異なる型修飾子です。
2.'SetRect':識別子が見つかりませんでした。
3."CHSRRECT"から"LPRECT"への適切な変換関数が存在しません。
のそれぞれのエラーがソースファイルのどの行に対して出ているか教えてください。

ただし、3に関しては、SetRectの第一引数がLPRECT lprc, // RECT構造体へのポインタなのにもかかわらず&c_rectを渡していますがこれは型が違うのでエラーです。
BOOL SetRect(
struct CHARRECT *lpcr,//CHARRECT構造体へのポインタ
ならOKです。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

C.C
記事: 64
登録日時: 13年前

Re: 当たり判定

#21

投稿記事 by C.C » 13年前

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));
で出ています。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: 当たり判定

#22

投稿記事 by softya(ソフト屋) » 13年前

1.SetRectと言う関数の定義が他のヘッダでもありませんか?
2.mainでSetRect関数が定義されたヘッダファイルをincludeしていますか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

C.C
記事: 64
登録日時: 13年前

Re: 当たり判定

#23

投稿記事 by C.C » 13年前


c:\Program Files\Microsoft SDKs\Windows\v7.0A\Include\WinUser.hのなかにありました。

はい。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: 当たり判定

#24

投稿記事 by softya(ソフト屋) » 13年前

C.C さんが書きました:
c:\Program Files\Microsoft SDKs\Windows\v7.0A\Include\WinUser.hのなかにありました。

はい。
1.SetRect以外に名前を変えましょう。
2.引数の型が合っていないと「識別子が見つかりませんでした。」と出る場合があります。引数の数や型を再確認してみて下さい。
よく有るミスは、intとfloatで違うやポインタ型なのにポインタを渡していないなど。
※ 名前が衝突してエラーになったので、SetRectがなかったコトにされているって事かもしれません。

[補足]
どうやってもエラーが解決しなければmain.cppだけのコンパクトな再現コードを貼ってもらったほうが早く解決しますね。
あとコンパクトな再現コードを作っている間に問題点に気づく事もあります。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

C.C
記事: 64
登録日時: 13年前

Re: 当たり判定

#25

投稿記事 by C.C » 13年前

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)で参照されました。

です。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: 当たり判定

#26

投稿記事 by softya(ソフト屋) » 13年前

C.C さんが書きました:1,SetCharRectに変えました。
2,SetCharRectはBOOL型で定義しているのですが return で true か false を返す必要はないのですか?
返さないとダメです。と言うか今までのコードで関数の定義が出て来なかったので確認不能でした。
今までは関数のプロトタイプ宣言だけなので実体定義ではありません。
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)で参照されました。

です。
SetCharRectの実体定義が見つからないと言うエラーです。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

C.C
記事: 64
登録日時: 13年前

Re: 当たり判定

#27

投稿記事 by C.C » 13年前

softya(ソフト屋) さんが書きました:
C.C さんが書きました:1,SetCharRectに変えました。
2,SetCharRectはBOOL型で定義しているのですが return で true か false を返す必要はないのですか?
返さないとダメです。と言うか今までのコードで関数の定義が出て来なかったので確認不能でした。
今までは関数のプロトタイプ宣言だけなので実体定義ではありません。
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)で参照されました。

です。
SetCharRectの実体定義が見つからないと言うエラーです。
struct CHARA_RECT{
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: 当たり判定

#28

投稿記事 by softya(ソフト屋) » 13年前

関数化を止めたんですね。

四角形(正方形・長方形)は4つの頂点で形作られます。左上と右下の座標が分かれば4つの頂点の座標は自ずと分かります。
数学・幾何学を苦手に感じられているかも知れませんが、意外と簡単な話なので紙に書いてみたらどうでしょうか?
ああっと納得できると思います。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

C.C
記事: 64
登録日時: 13年前

Re: 当たり判定

#29

投稿記事 by C.C » 13年前

コード:

ヘッダファイル
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;
すみません。2つに分けさせていただきます

C.C
記事: 64
登録日時: 13年前

Re: 当たり判定

#30

投稿記事 by C.C » 13年前

続きです。
WALL_RECT構造体で床の画像を囲んで1つずつ当り判定を行っているのですが、なぜか床に乗っていない状態でも当り判定が行われています。
移動中に床の画像が無いときにプレイヤーの落下が行われてないです。
そして当り判定の条件を満たしているときにジャンプを行うときも落下しません。上がりっぱなしです。よろしくお願いします

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: 当たり判定

#31

投稿記事 by softya(ソフト屋) » 13年前

問題点を列挙します。
1.同じ構造の構造体を複数作る意味はありませんので避けて下さいね。バグや仕様混乱のもとです。
宣言と実体定義の区別が付いていないのではないでしょうか?
2.インデントが狂っていますね。正確にインデントしないとバグの原因となります。
3.WALLの情報はデータファイルから読みこむ仕様だったはずですか?
4.同じような処理を繰り返し書くのはバグの元なので、関数化して更に配列化でループ処理をして下さいね。
WALL情報は配列だったはずですが?
5.落下の当たり判定と横移動の当たり判定は別に行って下さい。
6.障害物に当たったあと座標補正がありませんよ。これだと刺さったままになります。
7.重力加速度の処理がありませんので、これだと落下も接地確認も出来ませんね。
8.w_rect_1.left + w_rect_1.rightで右と左の座標を足してはいけません。topとbottomも同様です。
デバッガで数値の確認と紙の上で実際に四角形の図と座標を書いて机上確認してみて下さい。

【補足】
全体的に細かい確認作業や詳細な理解が不足しています。
プログラミングはそこが大事ですので手を抜かないでください。
なんとなく・・・ってのが一番良くないです。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

C.C
記事: 64
登録日時: 13年前

Re: 当たり判定

#32

投稿記事 by C.C » 13年前

なんでも
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: 当たり判定

#33

投稿記事 by softya(ソフト屋) » 13年前

>1,4 WALL_RECT構造体を1つにしてfor文で値を代入し、1つ値が代入されるごとに当たり判定を行うようにします。
何か言っている事が不安ですが出来るだけ代入は減らして下さいね。
関数化をお忘れなく。

>2,ifのそれぞれの&&以降をShiftキー+Enterキーで改行するようにします。
編集→詳細→選択範囲のフォーマットでインデントが整形できます。

>3,床の座標と幅と高さはわかっていたので直接値をいれていました。
データファイルの意味が無いですし別に登録することでメンテナンス性の低下とミスの可能性が増えます。

>5,現在のifのxとyをそれぞれのifとして分ければよいのでしょうか?
違います。上下移動と左右移動をそれぞれ当たり判定してくださいと言うことです。

>6,これは後でやるつもりでした。
コメントとして書いておいて下さい。

>7,これに関しては検討もつきません。すみません。
重力加速度の方程式をご存じですか? 物理です。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

C.C
記事: 64
登録日時: 13年前

Re: 当たり判定

#34

投稿記事 by C.C » 13年前

物理は習ったことはないです。
そして当たり判定を見て指摘していただけないでしょうか
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: 当たり判定

#35

投稿記事 by softya(ソフト屋) » 13年前

>物理は習ったことはないです。

習っている必要はないですが、次のことは理解して下さい。
重力加速度は常に下方向のベクトルが発生します。
ゲーム的にはベクトルの下方向に一定値が毎フレーム加算されます。

コレが唯一の解では無いですが、次のように処理しないと問題があるので次のように処理して下さい。
(1) 下方向の重力ベクトルを加算。
(2) 上下方向のベクトルを座標に加算する。
(3) 当たり判定する(すべての床とループ)。ベクトルが下方向で当たったら着地とみなす。当たったら上下方向のベクトルをキャンセル。上下の座標を補正。
(4) 左右方向のベクトルを座標に加算する。
(5) 当たり判定をする(すべての床とループ)。当たったら左右方向のベクトルをキャンセル。左右の座標を補正。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

C.C
記事: 64
登録日時: 13年前

Re: 当たり判定

#36

投稿記事 by C.C » 13年前

softya(ソフト屋) さんが書きました:>物理は習ったことはないです。

習っている必要はないですが、次のことは理解して下さい。
重力加速度は常に下方向のベクトルが発生します。
ゲーム的にはベクトルの下方向に一定値が毎フレーム加算されます。

コレが唯一の解では無いですが、次のように処理しないと問題があるので次のように処理して下さい。
(1) 下方向の重力ベクトルを加算。
(2) 上下方向のベクトルを座標に加算する。
(3) 当たり判定する(すべての床とループ)。ベクトルが下方向で当たったら着地とみなす。当たったら上下方向のベクトルをキャンセル。上下の座標を補正。
(4) 左右方向のベクトルを座標に加算する。
(5) 当たり判定をする(すべての床とループ)。当たったら左右方向のベクトルをキャンセル。左右の座標を補正。
ありがとうございます。当たり判定には何か問題はありますか?

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: 当たり判定

#37

投稿記事 by softya(ソフト屋) » 13年前

C.C さんが書きました:ありがとうございます。当たり判定には何か問題はありますか?
最初の当たり判定は良いですが、2つ目の当たり判定の意図がわかりません。
これです。 ↓

コード:

if(プレイヤー座標x <= 床座標x && プレイヤー座標x <= (床座標x + 床の幅)
&&(プレイヤー座標x + プレイヤーの幅) <= (床座標x + 床の幅)
&& 床座標x <= (プレイヤー座標x + プレイヤーの幅)
&& プレイヤー座標y <= 床座標y
&& プレイヤー座標y <= (床座標y + 床の高さ)
&& 床座標y <= (プレイヤー座標y + プレイヤーの高さ)
&&(床座標y + 床の高さ) <= (プレイヤー座標y + プレイヤーの高さ){
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

C.C
記事: 64
登録日時: 13年前

Re: 当たり判定

#38

投稿記事 by C.C » 13年前

softya(ソフト屋) さんが書きました:
C.C さんが書きました:ありがとうございます。当たり判定には何か問題はありますか?
最初の当たり判定は良いですが、2つ目の当たり判定の意図がわかりません。
これです。 ↓

コード:

if(プレイヤー座標x <= 床座標x && プレイヤー座標x <= (床座標x + 床の幅)
&&(プレイヤー座標x + プレイヤーの幅) <= (床座標x + 床の幅)
&& 床座標x <= (プレイヤー座標x + プレイヤーの幅)
&& プレイヤー座標y <= 床座標y
&& プレイヤー座標y <= (床座標y + 床の高さ)
&& 床座標y <= (プレイヤー座標y + プレイヤーの高さ)
&&(床座標y + 床の高さ) <= (プレイヤー座標y + プレイヤーの高さ){
これは画像の側面同士の当たり判定です。

ISLe
記事: 2650
登録日時: 14年前
連絡を取る:

Re: 当たり判定

#39

投稿記事 by ISLe » 13年前

No.29のコードは一部でしかないわけですが、この部分に限って言えば
・stage.isonthegroundがfalseになる箇所がない(trueのまま変化しない)
・重力加速度のPDownがゼロになったまま戻らない
などの点で、床から離れても落下しないという条件を満たしている気がします。


#Javaで書いたコードならブログで公開しているんですけどね。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: 当たり判定

#40

投稿記事 by softya(ソフト屋) » 13年前

C.C さんが書きました:
softya(ソフト屋) さんが書きました:
C.C さんが書きました:ありがとうございます。当たり判定には何か問題はありますか?
最初の当たり判定は良いですが、2つ目の当たり判定の意図がわかりません。
これです。 ↓

コード:

if(プレイヤー座標x <= 床座標x && プレイヤー座標x <= (床座標x + 床の幅)
&&(プレイヤー座標x + プレイヤーの幅) <= (床座標x + 床の幅)
&& 床座標x <= (プレイヤー座標x + プレイヤーの幅)
&& プレイヤー座標y <= 床座標y
&& プレイヤー座標y <= (床座標y + 床の高さ)
&& 床座標y <= (プレイヤー座標y + プレイヤーの高さ)
&&(床座標y + 床の高さ) <= (プレイヤー座標y + プレイヤーの高さ){
これは画像の側面同士の当たり判定です。
これは床が必ずプレーヤーの右か下にあって衝突した場合しか成り立ちませんが良いのでしょうか?
あと完全にプレーヤーを内包した時も成立しませんし、左や上にあると成立しません。
問題のある条件式だと思います。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

C.C
記事: 64
登録日時: 13年前

Re: 当たり判定

#41

投稿記事 by C.C » 13年前

ISLeさん、softyaさん、返信が遅くなり申し訳ありません。
お陰で当り判定ができました。すみません。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;
	}
}

C.C
記事: 64
登録日時: 13年前

Re: 当たり判定

#42

投稿記事 by C.C » 13年前

コード:

//当り判定関数
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: 当たり判定

#43

投稿記事 by softya(ソフト屋) » 13年前

だんだんソースコードが大きくなってきたので、次の点に注意して下さい。
1.ちゃんとコメントを振る。
2.インデントは正確に。
3.空白文字ではなく全角文字が入っている。これはなぜ?
4.同じような処理は関数化する。すくなくとも4行ぐらい同じ物があったら関数化するべきです。
5.ソースコードがなくコメントもない変数や関数の機能は作成者以外には分かりませんので、コメントや変数名、関数名に注意をはらって下さい。
6.c_rect.widthやc_rect.height の様に変数名と実際に扱われてい値の意味が違うものは他人にとって解読が困難ですので実態と合わせて下さい。
7.関数名と実際の機能に乖離があります(例Collision内で当たった後の処理を実行)ので、関数名と実際の動作は同じにして下さい。
Collisionに関しては当たり判定を戻り値で戻すべきで当たった後の処理は戻り値で分岐処理すべきです。

上記を直した上で、動作状況を確認したいのでソースコードと出来ればデータを全てzip圧縮して添付してもらった方が良いと思います。
版権的に問題があれば、代用データがあると嬉しいです。

【補足】
今気づきましたが上下と左右の当たり判定は別々に行うべきとアドバイスしたはずですが、それがされていません。

もしかして、これが当たり判定のつもりでしょうか?

コード:

			if( c_rect.width < w_rect.x ) {
				mv = 0;
				PDown = G;
			}
こんな簡易に当たり判定はできませんし、条件が間違っています。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

C.C
記事: 64
登録日時: 13年前

Re: 当たり判定

#44

投稿記事 by C.C » 13年前

返信遅くなり申し訳ありません。
zipファイル貼っておきます。
添付ファイル
game.zip
(12.68 MiB) ダウンロード数: 105 回

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: 当たり判定

#45

投稿記事 by softya(ソフト屋) » 13年前

とりあえず整理するために最新版の問題を箇条書きでお願いします。
ジャンプで落ちてこないだけでしょうか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

C.C
記事: 64
登録日時: 13年前

Re: 当たり判定

#46

投稿記事 by C.C » 13年前

softya(ソフト屋) さんが書きました:とりあえず整理するために最新版の問題を箇条書きでお願いします。
ジャンプで落ちてこないだけでしょうか?
返信ありがとうございます。
ジャンプで落ちてこないのはCollision関数をbool型にすると解決しました。
今の問題はスクロール処理を加えるとプレイヤー移動のPLAYER_SPEEDで設定した値よりも速いということです。for文を加えるとその問題が発生しました。問題が多くてすみません。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: 当たり判定

#47

投稿記事 by softya(ソフト屋) » 13年前

ソースを見ましたが、デバッガで見れば一目瞭然の問題があります。

(1)Wallの数だけループしてますので衝突があるとWallの数の倍数で移動します。
現状の移動速度は PLAYER_SPEED x Wallの数 です。
Wallの数だけ移動処理する必要ないはず。

(2)Wallがプレーヤーと逆方向に移動しています。
動く床に載っているようなものなのですが、これが更にスピードアップして見える原因ではないでしょうか?
同様の問題でジャンプするたびにWallが上にだけ移動します。
これは、マップスクロールの管理方法としても間違っています。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

C.C
記事: 64
登録日時: 13年前

Re: 当たり判定

#48

投稿記事 by C.C » 13年前

softya(ソフト屋) さんが書きました:ソースを見ましたが、デバッガで見れば一目瞭然の問題があります。

(1)Wallの数だけループしてますので衝突があるとWallの数の倍数で移動します。
現状の移動速度は PLAYER_SPEED x Wallの数 です。
Wallの数だけ移動処理する必要ないはず。

(2)Wallがプレーヤーと逆方向に移動しています。
動く床に載っているようなものなのですが、これが更にスピードアップして見える原因ではないでしょうか?
同様の問題でジャンプするたびにWallが上にだけ移動します。
これは、マップスクロールの管理方法としても間違っています。
スクロールは調べましたがプレイヤーに合わせてマップを動かすのはわかりました。
でもマップの動かし方がわかりません。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: 当たり判定

#49

投稿記事 by softya(ソフト屋) » 13年前

マップを動かす必要はありません。
主人公を画面の中心として表示していれば良いので、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(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

C.C
記事: 64
登録日時: 13年前

Re: 当たり判定

#50

投稿記事 by C.C » 13年前

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: 当たり判定

#51

投稿記事 by softya(ソフト屋) » 13年前

解決したソースコードを投稿していただくようにお願いします。ここのルールとなっております。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

C.C
記事: 64
登録日時: 13年前

Re: 当たり判定

#52

投稿記事 by C.C » 13年前

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);
     }
}
ありがとうございました。

閉鎖

“C言語何でも質問掲示板” へ戻る