Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[SDL2.0] Kolizja obiektów - kulka-kulka oraz kulka-ściana

Ostatnio zmodyfikowano 2014-09-24 18:13
Autor Wiadomość
Mattowy
Temat założony przez niniejszego użytkownika
[SDL2.0] Kolizja obiektów - kulka-kulka oraz kulka-ściana
» 2014-09-23 23:05:32
Witam!
Mam problem z algorytmem kolizyjnym. Na ekranie tworzą mi się 3. obiekty. Dwie kulki i prostokąt. Poruszam się kulką, a moimi przeszkodami są pozostałe elementy. Problem polega na tym, ze moja kulka maksymalnie może dojechać do pozycji x-owej pierwszej napotkanej przeszkody. Nie przekroczy jej przy żadnej współrzędnej y.

Circle - struktura o obiektach x,y oraz r.

Oto moje algorytmy kolizji
C/C++
//Funkcja do obliczania kwadratu odleglosci miedzy punktami
double distanceSquared( int x1, int y1, int x2, int y2 )
{
    int deltaX = x2 - x1;
    int deltaY = y2 - y1;
    return deltaX * deltaX + deltaY * deltaY;
}

bool checkCollision( Circle & a, Circle & b )
{
    //Calculate total radius squared
    int totalRadiusSquared = a.r + b.r;
    //totalRadiusSquared = totalRadiusSquared * totalRadiusSquared;
   
    //If the distance between the centers of the circles is less than the sum of their radii
    if( sqrt( distanceSquared( a.x, a.y, b.x, b.y ) ) <( totalRadiusSquared ) )
    {
        //The circles have collided
        return true;
    }
   
    //If not
    return false;
}

bool checkCollision( Circle & a, SDL_Rect & b )
{
    //rectangle's points of width
    int x1, x2;
    //rectangle's points of height
    int y1, y2;
    x1 = b.x;
    x2 = b.x + b.w;
    y1 = b.y;
    y2 = b.y + b.h;
   
    //If the objects is in a rectangle -  (x1,x2) and (y1,y2)
    if(( a.x + a.r > x1 ) &&( a.x - a.r < x2 ) &&( a.y + a.r > y1 ) &&( a.y - a.r < y2 ) )
         return true;
    else
         return false;
   
}

Wykorzystywane są do tej metody:

C/C++
void Dot::move( SDL_Rect & square, Circle & circle, bool( * checkCollisionCC )( Circle &, Circle & ), bool( * checkCollisionCR )( Circle &, SDL_Rect & ) )
{
    //Move the dot left or right
    mPosX += mVelX;
    shiftColliders();
   
    //If the dot collided or went too far to the left or right
    if(( mPosX - mCollider.r < 0 ) ||(( mPosX - mCollider.r + DOT_WIDTH ) > SCREEN_WIDTH ) || checkCollisionCR( mCollider, square ) || checkCollisionCC( mCollider, circle ) )
    {
        //Move back
        mPosX -= mVelX;
        shiftColliders();
    }
   
    //Move the dot up or down
    mPosY += mVelY;
    shiftColliders();
   
    //If the dot collided or went too far up or down
    if(( mPosY - mCollider.r < 0 ) ||(( mPosY - mCollider.r + DOT_HEIGHT ) > SCREEN_HEIGHT ) || checkCollisionCR( mCollider, square ) || checkCollisionCC( mCollider, circle ) )
    {
        mPosY -= mVelY;
        shiftColliders();
    }
}

W powyższej metodzie używam wskaźnika na funkcje. Algorytmy kolizji implementuję w mainie, metody w osobnych plikach.

W głównej pętli programu wykorzystuję to tak:
wall - obiekt prostokąta
otherDot.getCollider - tutaj zostanie zwrócony mi obiekt koło o strukturze x, y i r(promień)
C/C++
//move dot and check collision
dot.move( wall, otherDot.getCollider(), & checkCollision, & checkCollision );
P-117403
maly
» 2014-09-24 09:37:09
To bool checkCollision( Circle & a, SDL_Rect & b ) jest tylko sprawdzanie kolizji między prostokątami.

Podejrzewam że nikt tu niepomoże bez odsyłania w Googla więc wrzucę to co ja używam do sprawdzenia kolizji między okręgiem a prostokątem:
C/C++
bool intersects( float cx, float cy, float radius, float left, float top, float right, float bottom )
{
    float closestX =( cx < left ? left:( cx > right ? right: cx ) );
    float closestY =( cy < top ? top:( cy > bottom ? bottom: cy ) );
    float dx = closestX - cx;
    float dy = closestY - cy;
   
    return( dx * dx + dy * dy ) <= radius * radius;
}
P-117407
Mattowy
Temat założony przez niniejszego użytkownika
up
» 2014-09-24 16:39:41
To jest to samo, co ja napisałem, tylko innym kodem.
P-117432
maly
» 2014-09-24 16:59:43
To jest zupełnie coś innego niż Ty napisałeś, ale z tym innym kodem masz całkowitą rację, to jest napisane innym kodem:)
P-117433
pekfos
» 2014-09-24 18:13:46
C/C++
if( sqrt( distanceSquared( a.x, a.y, b.x, b.y ) ) <( totalRadiusSquared ) )
Porównujesz pierwiastek z kwadratem.
P-117437
« 1 »
  Strona 1 z 1