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

[C++, Allegro] Arkanoid- detekcja miejsca kolizji w prostokątach

Ostatnio zmodyfikowano 2014-07-17 08:51
Autor Wiadomość
rav_jarosz2
Temat założony przez niniejszego użytkownika
[C++, Allegro] Arkanoid- detekcja miejsca kolizji w prostokątach
» 2014-07-16 16:21:52
Witam, jestem w trakcie pisania prostego Arkanoida i mam problem z ustaleniem miejsca odbicia kulki od klocka. Napisałem już coś takiego:
C/C++
if( kolizja( klocek_1_1.x, klocek_1_1.y, klocek_w, klocek_h, pos_ball_x, pos_ball_y, kulka->w, kulka->h ) == true && klocek_1_1.e == 1 ) //jesli jest kolizja jakakolwiek i klocek istnieje
{
    klocek_1_1.e = 0; //klocek przestaje istniec
   
    if( pos_ball_b == 1 && klocek_1_1.y + klocek_h <= pos_ball_y ) pos_ball_b = 2; //pg na pd(prawy gorny na prawy dol)
   
    if( pos_ball_b == 1 && klocek_1_1.y + klocek_h > pos_ball_y ) pos_ball_b = 4; //pg na lg(prawy gorny na lewy gora)
    // pos_ball_b to kierunek przemieszczania pilki
   
}

Piłeczka porusza się w kierunku prawego górnego rogu, i przy zetknięciu z dolną ścianką klocka powinna się odbić w dół, a odbija się w lewy górny. Macie może jakiś pomysł na określenie ścianki odbicia?

EDIT: odbija się nieraz w lewy górny a nieraz normalnie, chociaż zawsze leci w kierunku klocka w ten sam sposób
P-113859
Dragonit
» 2014-07-16 16:38:01
Zapodam ci moją funkcję wykrywania kolizji w prostokątach, to jest to co potrzebujesz :D

C/C++
// ------------------------------------------- FUNKCJA KOLIZJI DWÓCH PROSTOKĄTÓW (@Dragonit)
short int KolizjaFunc( short int x1, short int x2,
short int y1, short int y2,
short int width1, short int width2,
short int height1, short int height2 )
{
    if( x1 >= x2 && x1 <= x2 + width2 && y1 >= y2 && y1 <= y2 + height2 ) return 1;
    else if( x1 + width1 >= x2 && x1 + width1 <= x2 + width2 && y1 >= y2 && y1 <= y2 + height2 ) return 2;
    else if( x1 + width1 >= x2 && x1 + width1 <= x2 + width2 && y1 + height1 >= y2 && y1 + height1 <= y2 + height2 ) return 3;
    else if( x1 >= x2 && x1 <= x2 + width2 && y1 + height1 >= y2 && y1 + height1 <= y2 + height2 ) return 4;
    else return 0;
   
}
P-113860
rav_jarosz2
Temat założony przez niniejszego użytkownika
» 2014-07-16 17:39:58
Szczerze mówiąc nie spodziewałem się tak szybkiego rozwiązania. Wielkie dzięki.

EDIT: Ech, jednak nie to czego potrzebowałem. Twoja funkcja zwraca dwie takie same wartości w kolizji z dwoma różnymi bokami. Potrzebuję podobnej funkcji, ale takiej, która będzie zwracała różne wartości, ale dla różnych ścianek. Próbowałem już kilka razy sam ją napisać i nic :/ .
P-113864
Dragonit
» 2014-07-16 18:29:23
Ech, jednak nie to czego potrzebowałem.
 Uwierz, że to jest to czego szukasz.

Pokaz tę część kodu gdzie określasz kierunek piłki po kolizji z klockiem.  
P-113867
rav_jarosz2
Temat założony przez niniejszego użytkownika
» 2014-07-16 19:38:58
Tak, masz racje to jest to czego szukam, ale gdyby działało tak jak chcę ;) .

Tutaj określam odbicie (to jest to co próbowałem po swojemu):
C/C++
if( kolizja( klocek_1_1.x, klocek_1_1.y, klocek_w, klocek_h, pos_ball_x, pos_ball_y, kulka->w, kulka->h ) == true && klocek_1_1.e == 1 )
{
    klocek_1_1.e = 0;
    if( pos_ball_b == 1 && klocek_1_1.y + klocek_h <= pos_ball_y ) pos_ball_b = 2; //pg na pd
   
    if( pos_ball_b == 1 && klocek_1_1.y + klocek_h > pos_ball_y ) pos_ball_b = 4; //pg na lg
   
    //if (pos_ball_b == 2 && klocek_1_1.x <  pos_ball_x) pos_ball_b = 1; //pd na pg
    //if (pos_ball_b == 2 && klocek_1_1.x >= pos_ball_x) pos_ball_b = 3; //pd na ld
}

W dwóch przypadkach Twoja funkcja zwraca wartość 1, więc nie chciałem jej używać w projekcie Arkanoida.

http://naforum.zapodaj.net/7aa25fa32d36.jpg.html  W tym programiku testowałem Twoją funkcję.

W tym programiku testującym funkcję nie zrobiłem błędu.
C/C++
if( KolizjaFunc( kulka_x, klocek_x, kulka_y, klocek_y, kulka->w, klocek->w, kulka->h, klocek->h ) == 0 )
{
    kolizja = 0;
    textprintf( buffer, font, 20, 20, makecol( 255, 255, 128 ), "Kolizja : %d", kolizja );
}
if( KolizjaFunc( kulka_x, klocek_x, kulka_y, klocek_y, kulka->w, klocek->w, kulka->h, klocek->h ) == 1 )
{
    kolizja = 1;
    textprintf( buffer, font, 20, 20, makecol( 255, 255, 128 ), "Kolizja : %d", kolizja );
}
if( KolizjaFunc( kulka_x, klocek_x, kulka_y, klocek_y, kulka->w, klocek->w, kulka->h, klocek->h ) == 2 )
{
    kolizja = 2;
    textprintf( buffer, font, 20, 20, makecol( 255, 255, 128 ), "Kolizja : %d", kolizja );
}
if( KolizjaFunc( kulka_x, klocek_x, kulka_y, klocek_y, kulka->w, klocek->w, kulka->h, klocek->h ) == 3 )
{
    kolizja = 3;
    textprintf( buffer, font, 20, 20, makecol( 255, 255, 128 ), "Kolizja : %d", kolizja );
}
if( KolizjaFunc( kulka_x, klocek_x, kulka_y, klocek_y, kulka->w, klocek->w, kulka->h, klocek->h ) == 4 )
{
    kolizja = 4;
    textprintf( buffer, font, 20, 20, makecol( 255, 255, 128 ), "Kolizja : %d", kolizja );
}
P-113870
Dragonit
» 2014-07-16 20:56:42
Dam ci przykład użycia mojej funkcji dla rozpoznania boku kolizji. 

C/C++
if( Kolizja( kulkaPozX[ i ], kulkaPozX[ j ], kulkaPozY[ i ], kulkaPozY[ j ], 20, 20, 20, 20 ) == 3 ||
Kolizja( klocekPozX[ i ], klocekPozX[ j ], klocekPozY[ i ], klocekPozY[ j ], 20, 20, 20, 20 ) == 4 ) // od gory
{
    // zmień kierunek lotu piłki
    itemDeltaY[ i ] = - itemDeltaValue[ i ];
    itemDeltaY[ j ] = itemDeltaValue[ j ];
   
    if( Kolizja( kulkaPozX[ i ], kulkaPozX[ j ], kulkaPozY[ i ], kulkaPozY[ j ], 20, 20, 20, 20 ) == 2 ||
    Kolizja( klocekPozX[ i ], klocekPozX[ j ], klocekPozY[ i ], klocekPozY[ j ], 20, 20, 20, 20 ) == 3 ) // od lewej
    {
        // zmień kierunek lotu piłki
        itemDeltaX[ i ] = - itemDeltaValue[ i ];
        itemDeltaX[ j ] = itemDeltaValue[ j ];
    }

I to w zasadzie wystarczy do określenia odbicia piłki góra-dół. Lewo-prawo na tej samej zasadzie.
P-113873
rav_jarosz2
Temat założony przez niniejszego użytkownika
» 2014-07-17 08:51:09
Próbowałem użyć tej funkcji, i już wiem, co jest nie tak. Ty używałeś jej dla obiektów o tej samej wielkości, więc jeden prostokąt wchodząc na drugi, zawsze znajdował się w którymś narożniku. A moja kulka wchodząc na klocek nie zawsze dotyka jego rogu.

http://naforum.zapodaj.net/311c732be96b.jpg.html

Teraz mam 2 wyjścia, albo zmniejszyć klocek, tak by kulka zawsze dotykała któregoś rogu, albo kombinować inaczej. Ma ktoś jakieś pomysły?

EDIT: Problem rozwiązany! =D

C/C++
if( kolizja( klocek_1_1.x, klocek_1_1.y, klocek_w, klocek_h, pos_ball_x, pos_ball_y, kulka->w, kulka->h ) == true && klocek_1_1.e == 1 )
{
    klocek_1_1.e = 0;
   
    if( pos_ball_b == 1 && klocek_1_1.y + klocek_h <= pos_ball_y + 5 ) pos_ball_b = 2;
    else if( pos_ball_b == 1 && klocek_1_1.y + klocek_h > pos_ball_y + 5 ) pos_ball_b = 4;
   
    else if( pos_ball_b == 2 && klocek_1_1.y >= pos_ball_y ) pos_ball_b = 1;
    else if( pos_ball_b == 2 && klocek_1_1.y < pos_ball_y ) pos_ball_b = 3;
   
    else if( pos_ball_b == 3 && klocek_1_1.y >= pos_ball_y ) pos_ball_b = 4;
    else if( pos_ball_b == 3 && klocek_1_1.y < pos_ball_y ) pos_ball_b = 2;
   
    else if( pos_ball_b == 4 && klocek_1_1.y + klocek_h <= pos_ball_y + 5 ) pos_ball_b = 3;
    else if( pos_ball_b == 4 && klocek_1_1.y + klocek_h > pos_ball_y + 5 ) pos_ball_b = 1;
   
}

Skopiowałem taki warunek dla 8 klocków pojawiających się na ekranie. Wiem że nieprofesjonalne podejście, bo lepiej byłoby to wsadzić w funkcję, ale tak najlepiej rozumiem. Dzięki za zainteresowanie tematem. Może komuś się przyda.
P-113912
« 1 »
  Strona 1 z 1