プロが教える店舗&オフィスのセキュリティ対策術

四角い2つブロックの当たり判定をとりたいです。1つのブロックは十字キーによって移動することができ、もうひとつのブロックは画面中央に固定されたまま動くことはありません。2つの四角形が当たった時に擦りぬけないようにしたいのですが、ぶつかったときに十字キーで上下左右に動かしてもすりぬけないようにしたのですが、斜めに移動させるとおかしくなってしまいます。次のプログラムをどう修正すればいいでしょうか?

変数の説明
Player.x:動く四角形のX座標
Player.y:動く四角形のY座標
Player.width:動く四角形の幅
Player.height:動く四角形の高さ
Wall.x:動く四角形のX座標
Wall.y:動く四角形のY座標
Wall.width:動く四角形の幅
Wall.height:動く四角形の高さ

//2つの四角形がぶつかっていなかったら
if(!(((Player.x > Wall.x && Player.x < Wall.x + Wall.width) || (Wall.x > Player.x && Wall.x < Player.x + Player.width)) && ((Player.y > Wall.y && Player.y < Wall.y + Wall.height) || (Wall.y > Player.y && Wall.y < Player.y + Player.height))))
{
//右キーを押していたら
if(g_keyState[DIK_RIGHT] & 0x80 )
{
Player.x += 3;

if((((Player.x > Wall.x && Player.x < Wall.x + Wall.width) || (Wall.x > Player.x && Wall.x < Player.x + Player.width)) && ((Player.y > Wall.y && Player.y < Wall.y + Wall.height) || (Wall.y > Player.y && Wall.y < Player.y + Player.height))))
Player.x = Wall.x - Player.width - 1;
}

//左キーを押していたら
if(g_keyState[DIK_LEFT] & 0x80)
{
Player.x -= 3;

if((((Player.x > Wall.x && Player.x < Wall.x + Wall.width) || (Wall.x > Player.x && Wall.x < Player.x + Player.width)) && ((Player.y > Wall.y && Player.y < Wall.y + Wall.height) || (Wall.y > Player.y && Wall.y < Player.y + Player.height))))
Player.x = Wall.x + Wall.width + 1;
}

//上キーを押していたら
if(g_keyState[DIK_UP] & 0x80)
{
Player.y -= 3;

if((((Player.x > Wall.x && Player.x < Wall.x + Wall.width) || (Wall.x > Player.x && Wall.x < Player.x + Player.width)) && ((Player.y > Wall.y && Player.y < Wall.y + Wall.height) || (Wall.y > Player.y && Wall.y < Player.y + Player.height))))
Player.y = Wall.y + Wall.height + 1;
}

//下キーを押していたら
if(g_keyState[DIK_DOWN] & 0x80)
{
Player.y += 3;

if((((Player.x > Wall.x && Player.x < Wall.x + Wall.width) || (Wall.x > Player.x && Wall.x < Player.x + Player.width)) && ((Player.y > Wall.y && Player.y < Wall.y + Wall.height) || (Wall.y > Player.y && Wall.y < Player.y + Player.height))))
Player.y = Wall.y - Player.height - 1;
}
}

A 回答 (2件)

ですから、あなたのいう「おかしい」というのがどうゆう現象かはっきりしてくれないと、どこを直していいのかわかりません。



今の状態だと、斜めにしていると、ぶつかった四角に沿って滑る感じになると思います。
その動き自体があなたの求めているものなのかどうなのか。違うのならどうなって欲しいのか。
それによって対処法も違ってきます。

あるいは、めり込んでしまう、のなら、なにか判定の見落しがあるのかもしれません。
それも「めりこむ」という現象が起るのかどうかでプログラムに検証方法も変わってきます。

この回答への補足

斜め移動させて、固定された四角形にぶつかって滑っていくと、四角形と四角形の角がぶつかったタイミングで四角形が別の個所に移動してしまいます。例えば、左から固定された四角形にぶつかり、下キーと右キーを入力したまま滑らすと、動く四角形の右上座標と固定された四角形の左上がかぶったときに動く四角形の右下座標が固定されている四角形の左上座標の所に移動してしまいます。説明わかりにくくてすいません。

補足日時:2011/11/21 18:56
    • good
    • 0

どんな風に変なのかがよくわからないけど



このプログラムだと、(入力判定→移動→衝突判定→調整)を順番にやっているので、斜めへの移動は、横の移動→縦の移動と2回に分けて入力したのと同じです。この横移動→衝突→調整の後に縦移動、というのが、あなたの予想した動きとの違いになっていないでしょうか。

判定の不等号に=が必要な箇所がないか、補正させる場所はその計算でいいのか、あたりも確認しては?

あと、こんな条件式を何度も書くのは、勧められません。
関数にすればスッキリするし、修正も楽です。

この回答への補足

ソースを次のように変更してみたのですがうまくいきません。
移動前のPlayerの座標を別の変数に保存しておき、キー入力によって移動させます。
この時点でPlayerがWallに当たっている可能性があるので当たっていた場合はPlayerの座標を修正。この時移動後のPlayerの座標だけではWallに右から当たったのか左から当たったのかわからないため保存しておいた移動前のPlayerの座標を使います。

PrevPlayer = Player;

if(g_keyState[DIK_UP] & 0x80)
Player.y -= 3;

if(g_keyState[DIK_RIGHT] & 0x80)
Player.x += 3;

if(g_keyState[DIK_DOWN] & 0x80)
Player.y += 3;

if(g_keyState[DIK_LEFT] & 0x80)
Player.x -= 3;

if(Player.y < Wall.y + Wall.height && Player.y + Player.height > Wall.y)
{
if(PrevPlayer.x < Player.x){
if((Player.x + Player.width) >Wall.x)
Player.x = Wall.x - Player.width;
}

else if(PrevPlayer.x > Player.x)
{
if(Player.x < (Wall.x + Wall.width))
Player.x = Wall.x + Wall.width;
}
}

if(Player.x < Wall.x + Wall.width && Player.x + Player.width > Wall.x)
{
if(PrevPlayer.y < Player.y)
{
if((Player.y + Player.height) >Wall.y)
Player.y = Wall.y - Player.height;
}

else if(PrevPlayer.y > Player.y)
{
if(Player.y < (Wall.y + Wall.height))
Player.y = Wall.y + Wall.height;
}
}

補足日時:2011/11/20 14:52
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!