0

過去数日間、私はOpenGLを使用して描画されたオブジェクトの単純な衝突検出を実装しようとしてきました。私の助けを借りて、Pearson, Computer Graphics with OpenGL私は次の関数を書くことができました:

void move(){
    if(check_collision(sprite,platform1) || check_collision(sprite,platform2)){ //if colliding...
        if     (downKeyPressed ){ y_Vel += speed; downKeyPressed  = false;} //going down
        else if(upKeyPressed   ){ y_Vel -= speed; upKeyPressed    = false;} //going up
        else if(rightKeyPressed){ x_Vel -= speed; rightKeyPressed = false;} //going right
        else if(leftKeyPressed ){ x_Vel += speed; leftKeyPressed  = false;} //going left
    } // always glitches on whatever is last else if above?!?!
    else{ glTranslatef(sprite.x+x_Vel, sprite.y+y_Vel, 0.0); }
}

スプライトはキーボード入力(矢印キー)に従って移動します。静止している物体と衝突すると、移動を停止し、その位置に留まります。

これまでのところ、静止オブジェクトの上部、左側、下部と衝突するときに機能します。残念ながら(同じロジックを使用していますが)右側は機能せず、衝突するとスプライトは元のx/y座標で再描画されます。私は困惑しています。

move()結局のところ、関数の最後のチェック(最後else-if)が機能しないものです...と交換しましたleftが、最後のチェックと再生されるのはrightいつですか?left上 :(

これを改善してグリッチを防ぐ方法についてのアドバイスやアイデアはありますか?

私の素朴でアマチュアのコーディングを許してください。私は独学の始まりにすぎません。ありがとう。

4

3 に答える 3

2

の場合はelseを使用しないでください。同じフレームの側面と上面または底面に当たっている可能性があります。それぞれをチェックしたいので、それらをすべてのifに変更してみてください。または、少なくともこれに変更します。

if( /* check top */)
{

}
else if( /* check bot */)
{

}

if( /* check right */ )
{

}
else if( /* check left */)
{

}

また、混乱を招くため、Y_VELやX_VELなどのグローバル変数を宣言することは避けてください。足を濡らすためにこれをしているだけかもしれませんが、私はそれを避けます。オブジェクトごとにクラスを作成し、そのクラスのメンバーとして速度を設定します。

于 2013-03-21T18:10:09.953 に答える
1

さて、実際のオブジェクトの翻訳に関しては、問題があるように思われます。あなたの移動コードは述べています

if(there is a collision)
{ 
    //do stuff
}
else
{
    glTranslateF( );
}

したがって、衝突が発生するたびに、translate関数が呼び出されることはありません。

私の意見では、glTranslateF()呼び出しを引き出す必要がありますelse {...}。毎回呼び出されるようにしてください。ただし、プレーヤーのスプライトだけでなく、すべての長方形にまったく同じ「描画」関数を使用しているようです。おそらく、通常の長方形(プラットフォームなど)とプレーヤーの長方形を区別する方法を示す必要があります。おそらく、これを実装するための最も簡単な方法は、2つの異なるdrawSprite機能を持つことです。1つは通常のプラットフォーム用で、もう1つはプレーヤー用です。move()プレイヤーの描画関数内からのみ関数を呼び出します(おそらくdrawPlayer()?と呼ばれます)。

現時点では、すべてのコードを調べて、より知識に基づいた具体的な提案を行う時間がありません。ただし、この質問がまだ開いていてサポートが必要な場合は、今晩遅くに無料になります。

于 2013-03-21T18:17:03.150 に答える
1

すでに理解しているように、問題はglTranslate()に関連しています。スプライトの位置と速度の両方を操作するため、速度を使用して位置を繰り返し更新する必要があります。あれは:

sprite.x += x_vel;
sprite.y += y_vel;

そして、それを常に単純に行います(つまり、scneが繰り返し再描画される場合は、タイマーまたはフレームごとに)。衝突は、衝突効果をシミュレートするために何らかの方法で速度ベクトル(x_vel、y_vel)を変更することと同じです。つまり、ゼロにして移動を完全に停止するか、速度成分の符号(x_vel = -x_vel)を変更して完全に弾力性のある方法でリバウンドさせます。または適切な何かをします。

ここで何が起こるかというとglTranslate()x_vel, y_vel実際には開始位置からのオフセットを保持しますが、移動速度は保持しません。

于 2013-03-21T18:41:47.487 に答える