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

[Allegro, C++] Kolizje

Ostatnio zmodyfikowano 2011-09-21 21:41
Autor Wiadomość
Wrzochu
Temat założony przez niniejszego użytkownika
» 2011-08-30 00:40:39
Źle się zrozumieliśmy chodziło mi o używanie getpixel'a.
P-40215
lynx
» 2011-08-30 00:44:44
"A jeśli obiektów jest bardzo dużo ? To mam wypisywać wszystkie możliwe kolizje ?"
Tak, jeśli nie zastosujesz jakiejś tablicy i fora to będziesz się bawił z wpisywaniem kodu dla każdych możliwych kolizji obiektów.

Co do pozostałej części moim zdaniem powinieneś to zrobić tak jak pisze malan.
P-40216
Wrzochu
Temat założony przez niniejszego użytkownika
» 2011-08-30 00:47:12
Ok, dzięki wielkie za  pomoc. Nie pozostaje nic innego jak posiedzenie przy tym i kombinowanie :)
P-40218
Wrzochu
Temat założony przez niniejszego użytkownika
» 2011-09-14 11:29:01
Przerobiłem program żeby działał obiektowo tutaj podaje kod:

C/C++
#include <allegro.h>
#include <cstdlib>
#include <ctime>



// Inicjowanie timera
volatile long speed = 0;
enum MAPSTATE { MS_NOTSTARTED, MS_START, MS_KOL, MS_EXIT };
MAPSTATE MS_MapState = MS_NOTSTARTED;

const int ENEMY_NUMBER = 45;

void increment_speed()
{
    speed++;
}

END_OF_FUNCTION( increment_speed );
LOCK_VARIABLE( speed );
LOCK_FUNCTION( increment_speed );

// Zmienne potrzebne do mapy
// DEFINICJA MAPY

short int map[ 120 ][ 120 ] =
{
    // wypełniona tablica odpowiedzialna za mapę kaflowa
};


int x, y;
int mapa_x = 0, mapa_y = 0;
int frame, frame2;
int kolizja = 0;
BITMAP * teren = NULL;
BITMAP * bufor = NULL;
BITMAP * autoo2 = NULL;

//KLASY

class cAuto
{
public:
    int x, y, x2, y2, i;
    int kierunek;
    int a, b;
    BITMAP * autoo2;
   
    void rys_sam();
    bool ustaw_poz();
    void przemiesc_sam();
    bool kolizja();
};

//  **PROTOTYPY FUNKCJI**
void swiatla()
{
    if(( frame2 >= 0 ) &&( frame2 <= 350 ) )
    {
        map[ 640 / 20 ][ 280 / 20 ] = 54;
        map[ 740 / 20 ][ 280 / 20 ] = 48;
        map[ 640 / 20 ][ 380 / 20 ] = 50;
        map[ 740 / 20 ][ 380 / 20 ] = 52;
       
        map[ 1460 / 20 ][ 1180 / 20 ] = 54;
        map[ 1560 / 20 ][ 1180 / 20 ] = 48;
        map[ 1460 / 20 ][ 1280 / 20 ] = 50;
        map[ 1560 / 20 ][ 1280 / 20 ] = 52;
       
        map[ 1280 / 20 ][ 1620 / 20 ] = 49;
        map[ 1380 / 20 ][ 1620 / 20 ] = 53;
        map[ 1280 / 20 ][ 1720 / 20 ] = 51;
        map[ 1380 / 20 ][ 1720 / 20 ] = 47;
    }
   
    frame2++;
    if( frame2 > 800 ) frame2 = 0;
   
};


void cAuto::rys_sam()
{
    autoo2 = load_bmp( "autoo2.bmp", default_palette );
    if( !autoo2 )
    {
        set_gfx_mode( GFX_TEXT, 0, 0, 0, 0 );
        allegro_message( "Nie mogę załadować bitmapy !" );
        allegro_exit();
    }
    masked_blit( autoo2, bufor, kierunek * 20, 0, x - mapa_x * 20, y - mapa_y * 20, 20, 20 );
    textprintf_ex( bufor, font, 10, 10, makecol( 255, 255, 255 ), - 1, "X: %d", x );
    textprintf_ex( bufor, font, 10, 20, makecol( 255, 255, 255 ), - 1, "Y: %d", y );
};

bool cAuto::ustaw_poz()
{
    if( MS_MapState != MS_NOTSTARTED ) return false; // sprawdza czy stan gry faktycznie jest NONSTARTED
    // Ustawienie obiektu
    for(;; )
    {
        a =( rand() % 120 + 1 ) * 20;
        b =( rand() % 120 + 1 ) * 20;
       
        textprintf_ex( bufor, font, 10, 50, makecol( 255, 255, 255 ), - 1, "X: %d", a );
        textprintf_ex( bufor, font, 10, 60, makecol( 255, 255, 255 ), - 1, "Y: %d", b );
       
        if(( a % 20 == 0 ) &&( b % 20 == 0 ) &&((( map[ b / 20 ][ a / 20 ] ) == 16 ) ||(( map[ b / 20 ][ a / 20 ] ) == 18 ) ||(( map[ b / 20 ][ a / 20 ] ) == 7 ) ||(( map[ b / 20 ][ a / 20 ] ) == 17 ) ||(( map[ b / 20 ][ a / 20 ] ) == 8 ) ) ) break;
       
    }
    x = a;
    y = b;
    return true;
};


void cAuto::przemiesc_sam()
{
    if( !kolizja() ) {
       
        //###########PRAWY PAS##########
        // w góre
        if((( map[( y - 1 ) / 20 ][ x / 20 ] ) == 26 ) &&(( map[( y ) / 20 ][( x - 1 ) / 20 ] ) == 16 ) )
        {
            y = y - 1;
            kierunek = 0;
        }
        if((( map[( y - 1 ) / 20 ][ x / 20 ] ) == 8 ) &&(( map[( y ) / 20 ][( x - 1 ) / 20 ] ) == 16 ) &&(( map[( y - 21 ) / 20 ][( x ) / 20 ] ) != 58 ) &&(( map[( y ) / 20 ][( x ) / 20 ] ) != 56 ) )
        {
            y = y - 1;
            kierunek = 0;
        }
        // Tu znajdują sięw arunki poruszania po mapie takie jak te dwa wyżej
       
        frame++;
        frame2++;
        if( frame2 > 800 ) frame2 = 0;
       
        if( frame > 5 )
        {
            frame = 2;
            srand( time( NULL ) );
            frame = rand() % 4 + 1;
        }
    }
    rys_sam();
};

bool cAuto::kolizja()
{
   
    if( x2 <= x + 20 && x2 > x && y2 >= y && y2 <= y + 20 ) return true; else
    if( x2 <= x + 20 && x2 > x && y2 + 20 >= y && y2 + 20 <= y + 20 ) return true; else
    if( x2 + 20 <= x + 20 && x2 + 20 > x && y2 >= y && y2 <= y + 20 ) return true; else
    if( x2 + 20 <= x + 20 && x2 + 20 > x && y2 + 20 >= y && y2 + 20 <= y + 20 ) return true;
    else return false;
   
};

// Funkcja wyświetlająca mapę:

void wys_mape()
{
    int licznik_x, licznik_y;
    for( licznik_x = 0; licznik_x < 120; licznik_x++ )
    {
        for( licznik_y = 0; licznik_y < 120; licznik_y++ )
        {
            blit( teren, bufor,
            ( map[ licznik_y + mapa_y ][ licznik_x + mapa_x ] % 8 ) * 20,
            ( map[ licznik_y + mapa_y ][ licznik_x + mapa_x ] / 8 ) * 20,
            licznik_x * 20, licznik_y * 20, 20, 20 );
        }
    }
};

// FUNKCJA GŁÓWNA

int main()
{
    allegro_init();
    install_keyboard();
    set_color_depth( 16 );
    set_gfx_mode( GFX_AUTODETECT_WINDOWED, 800, 600, 0, 0 );
    install_timer();
    install_int_ex( increment_speed, BPS_TO_TIMER( 40 ) );
   
    // Tworzenie bufora
   
    bufor = create_bitmap( 800, 600 );
    if( !bufor )
    {
        set_gfx_mode( GFX_TEXT, 0, 0, 0, 0 );
        allegro_message( "Nie mogę utworzyć bufora !" );
        allegro_exit();
        return 0;
    }
   
    // Ładowanie grafiki
   
    teren = load_bmp( "teren.bmp", default_palette );
    if( !teren )
    {
        set_gfx_mode( GFX_TEXT, 0, 0, 0, 0 );
        allegro_message( "Nie mogę załadować bitmapy !" );
        allegro_exit();
        return 0;
    }
   
    // Czyszczenie bufora
   
    clear_to_color( bufor, makecol( 150, 150, 150 ) );
   
    // Wyświetlanie mapy
   
    wys_mape();
    cAuto sam[ 45 ];
    for( int i = 0; i < ENEMY_NUMBER; ++i ) /* petla ktora ustawia i rysuje przeciwnikow*/
    {
        sam[ i ].ustaw_poz();
        sam[ i ].rys_sam();
    };
   
    blit( bufor, screen, 0, 0, 0, 0, 800, 600 );
   
    MS_MapState = MS_START;
   
    for(;; ) // PETLA GLOWNA
    {
        while( speed > 0 )
        {
            // SCROLLOWANIE MAPY
            if(( key[ KEY_RIGHT ] ) &&( mapa_x < 80 ) ) { mapa_x = mapa_x + 1; } else
            if(( key[ KEY_LEFT ] ) &&( mapa_x > 0 ) ) { mapa_x = mapa_x - 1; } else
            if(( key[ KEY_DOWN ] ) &&( mapa_y < 90 ) ) { mapa_y = mapa_y + 1; } else
            if(( key[ KEY_UP ] ) &&( mapa_y > 0 ) ) { mapa_y = mapa_y - 1; }
            if( key[ KEY_Q ] ) { map[ 140 / 20 ][ 280 / 20 ] = 7; }
           
            clear_to_color( bufor, makecol( 150, 150, 150 ) );
            wys_mape();
           
            for( int i = 0; i < ENEMY_NUMBER; ++i ) /* petla ktora ustawia i rysuje przeciwnikow*/
            {
                sam[ i ].kolizja();
                sam[ i ].przemiesc_sam();
            };
           
            blit( bufor, screen, 0, 0, 0, 0, 800, 600 );
            if( key[ KEY_ESC ] ) MS_MapState = MS_EXIT;
           
            speed--;
           
        }
       
        if(( MS_MapState == MS_EXIT ) ) break;
       
    };
   
    // Usuwanie wszystkiego z pamięci.
   
    remove_int( increment_speed );
    clear_keybuf();
    destroy_bitmap( teren );
    destroy_bitmap( autoo2 );
    destroy_bitmap( bufor );
    allegro_exit();
    return 0;
}
END_OF_MAIN();

Ale niestety kolizje dalej nie są wykrywane i samochody dalej przelatują przez siebie. Dodam że auta są pewną formą botów które same poruszają się po mapie, a chce aby wykrywali że np. na światłach przed nim stoi inny samochód i nie jechał dalej. Jeśli ma ktoś pomysł co jest źle to proszę o pomoc,
z  góry dziękuje.
P-40942
Gabes
» 2011-09-14 12:45:12
Zastosuj wykrywanie kolizji wielostopniowe:
1.-Najpierw czy kolizja miała miejsce kwadrat-kwadrat.
2.-Następnie z którego kierunku z lewej, prawej, z dołu,z góry.
3.-Na koniec  getpixel .
Gdy nie ma w ogóle kolizji nie ma potrzeby sprawdzania punktu 2 i 3.
Umieść sobie na środku ekranu kwadrat , puść bota z lewej strony na kwadrat czyli w prawo napisz funkcje Stop gdy kolizja dla 1. 2. i 3. punktu w zależności od potrzeb.
Bota z góry w dół , itd. czyli z czterech kierunków.
Wiem może to pierdoły no ale jak sam to zrobisz , napiszesz zupełnie od podstaw własną uniwersalną kolizje (podobno takiej nie ma) i zrozumiesz to powiesz jakie to proste .
Z poważaniem Gabes.
P-40944
Wrzochu
Temat założony przez niniejszego użytkownika
» 2011-09-14 13:15:31
Dzięki za szybką odpowiedź.
No za kolizje kwadrat/kwadrat odpowiada:
C/C++
bool cAuto::kolizja()
{
   
    if( x2 <= x + 20 && x2 > x && y2 >= y && y2 <= y + 20 ) return true; else
    if( x2 <= x + 20 && x2 > x && y2 + 20 >= y && y2 + 20 <= y + 20 ) return true; else
    if( x2 + 20 <= x + 20 && x2 + 20 > x && y2 >= y && y2 <= y + 20 ) return true; else
    if( x2 + 20 <= x + 20 && x2 + 20 > x && y2 + 20 >= y && y2 + 20 <= y + 20 ) return true;
    else return false;
   
};
I już w tym momencie jest problem bo nie działa... I co gorsza  nie wiem co może być w tym źle...
P-40946
Gabes
» 2011-09-14 13:58:37
Pierwsza funkcja ma tylko wykryć kolizje  napisz jakieś zapytanie
Czy funkcja działa.
if( kolizja(...)==true)
{
  textout_ex(bufor,font,"Kolizja !",0,0 ,makecol(255,255,255),-1);
}
Jeśli tak to z którego kierunku ? kolizja 2.
Oczywiście znasz tę strone jest tam o kolizjach
http://www.easykoder.vot.pl/arty/kolizja
http://www.easykoder.vot.pl/download
P-40949
Wrzochu
Temat założony przez niniejszego użytkownika
» 2011-09-14 14:11:18
Tak znam tą stronę. I wiem o Ci teraz chodzi ale i tak mi kolizji nie wykrywa... No nic walczę dalej.
P-40950
1 « 2 » 3
Poprzednia strona Strona 2 z 3 Następna strona