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

[C++, Allegro] Scrollowanie mapy platformowej w 2D a wykrywanie kolizji

Ostatnio zmodyfikowano 2015-01-21 18:30
Autor Wiadomość
rav_jarosz2
Temat założony przez niniejszego użytkownika
[C++, Allegro] Scrollowanie mapy platformowej w 2D a wykrywanie kolizji
» 2015-01-21 18:30:19
Hej. Mam problem. Wiem, że może porywam się z motyką na słońce, ale zacząłem robić w 2D grę sandbox platformową
(coś a`la Terraria). Wszystko szło ładnie aż do momentu gdy musiałem zaprogramować przesuwanie mapy gdy zbliżamy się do krawędzi. Nie mam jak wytłumaczyć o co mi za bardzo chodzi. Najlepiej zobaczcie kod i screenshooty.
C/C++
#include <allegro.h>


volatile long speed_program = 0;
void increment_program()
{
    speed_program++;
}
END_OF_FUNCTION( increment_program );
LOCK_VARIABLE( speed_program );
LOCK_FUNCTION( increment_program );

int main()
{
   
    allegro_init();
   
    set_color_depth( 24 );
    set_gfx_mode( GFX_AUTODETECT_WINDOWED, 800, 600, 0, 0 );
    clear_to_color( screen, makecol( 0, 0, 0 ) );
   
    install_keyboard();
   
    install_mouse();
   
    install_timer();
    install_int_ex( increment_program, BPS_TO_TIMER( 250 ) );
   
    BITMAP * buffer = create_bitmap( 800, 600 );
    clear_to_color( buffer, makecol( 0, 0, 0 ) );
   
    BITMAP * map = create_bitmap( 1920, 1080 );
    map = load_bmp( "Data/Graphics/map.bmp", default_palette );
   
    BITMAP * kursor = create_bitmap( 0, 0 );
    kursor = load_bitmap( "Data/Graphics/kursor.bmp", default_palette );
   
    BITMAP * character_animation_right = create_bitmap( 0, 0 );
    character_animation_right = load_bmp( "Data/Graphics/character_animation_right.bmp", default_palette );
   
    BITMAP * character_animation_left = create_bitmap( 0, 0 );
    character_animation_left = load_bmp( "Data/Graphics/character_animation_left.bmp", default_palette );
   
    BITMAP * kartka_background = create_bitmap( 0, 0 );
    kartka_background = load_bmp( "Data/Graphics/kratka_background.bmp", default_palette );
   
    BITMAP * forest_background = create_bitmap( 0, 0 );
    forest_background = load_bmp( "Data/Graphics/forest_background.bmp", default_palette );
   
    BITMAP * lake_background = create_bitmap( 0, 0 );
    lake_background = load_bmp( "Data/Graphics/lake_background.bmp", default_palette );
   
    int map_x = 0;
    int map_y = 0;
   
    struct character
    {
        int x;
        int y;
       
        int move;
        int kierunek;
        int frame;
    };
   
    character player1;
    player1.x = 0;
    player1.y = 0;
    player1.move = 0;
    player1.kierunek = 1;
    player1.frame = 0;
   
    while( !key[ KEY_ESC ] )
    {
        //*********************************************************************
        //Sterowanie i obsługa zdarzeń
        //*********************************************************************
        // if (getpixel(ziemia, ludek_x, ludek_y) != makecol(255,0,255) polecenia;
        while( speed_program > 0 )
        {
            speed_program--;
           
            player1.move = 0;
           
            if( key[ KEY_A ] && getpixel( map, player1.x + 10 - 1, player1.y ) == makecol( 255, 0, 255 )
            && getpixel( map, player1.x + 10 - 1, player1.y +( 70 - 1 ) / 2 ) == makecol( 255, 0, 255 )
            && getpixel( map, player1.x + 10 - 1, player1.y + 70 - 1 ) == makecol( 255, 0, 255 ) )
            {
                player1.x--;
                if( player1.x < 100 ) player1.x++;
               
                player1.move = 1;
            }
           
            if( key[ KEY_D ] && getpixel( map, player1.x + 40 + 1, player1.y ) == makecol( 255, 0, 255 )
            && getpixel( map, player1.x + 40 + 1, player1.y +( 70 - 1 ) / 2 ) == makecol( 255, 0, 255 )
            && getpixel( map, player1.x + 40 + 1, player1.y + 70 - 1 ) == makecol( 255, 0, 255 ) )
            {
                player1.x++;
                if( player1.x > buffer->w - 100 ) player1.x--;
               
                player1.move = 1;
            }
           
            if(( key[ KEY_A ] ) &&( key[ KEY_D ] ) )
            {
                player1.move = 0;
            }
           
            if( key[ KEY_SPACE ] && getpixel( map, player1.x + 10, player1.y - 1 ) == makecol( 255, 0, 255 ) //x+10 dla dokładności
            && getpixel( map, player1.x + 40, player1.y - 1 ) == makecol( 255, 0, 255 ) )
            {
                player1.y = player1.y - 2;
            }
           
            if( key[ KEY_R ] ) //********************RESET DO POZYCJI 0 0
            {
                player1.x = 0;
                player1.y = 0;
            }
           
            if( mouse_x >= player1.x +( 50 / 2 ) ) player1.kierunek = 1;
           
            if( mouse_x <= player1.x +( 50 / 2 ) ) player1.kierunek = 0;
           
            if( player1.move == 1 )
            {
                player1.frame++;
                if( player1.frame >= 120 ) player1.frame = 0;
               
            }
            if( player1.move == 0 )
            {
                player1.frame = 20;
            }
           
            //Grawitacja (test)
            /*if( getpixel(map, map_x+player1.x+10, map_y+player1.y+70) == makecol(255,0,255)   //x+10 dla dokładności
                         && getpixel(map, map_x+player1.x+40, map_y+player1.y+70) == makecol(255,0,255) ) //x-10 dla dokładności
                        {
                        player1.y++;
                        }*/
           
            if( getpixel( map, player1.x + 10, player1.y + 70 ) == makecol( 255, 0, 255 ) //x+10 dla dokładności
            && getpixel( map, player1.x + 40, player1.y + 70 ) == makecol( 255, 0, 255 ) ) //x-10 dla dokładności
            {
                player1.y++;
            }
           
           
        } // (speed_program>0)
        //*********************************************************************
       
        //*********************************************************************
        //Wyświetlanie
        //*********************************************************************
       
        //blit(kartka_background, buffer, 0, 0, 0, 0, kartka_background->w, kartka_background->h);
        blit( forest_background, buffer, 0, 0, - 1000, - 440, forest_background->w, forest_background->h );
        //blit(lake_background, buffer, 0, 0, 0, 0, lake_background->w, lake_background->h);
       
        masked_blit( map, buffer, 0, 0, map_x, map_y, map->w, map->h );
       
        if( player1.x <= 100 &&( key[ KEY_A ] ) ) map_x = map_x + 3;
       
        if( player1.x >= 700 &&( key[ KEY_D ] ) ) map_x = map_x - 3;
       
        textprintf_ex( buffer, font, 20, 20, makecol( 200, 200, 200 ), - 1, "Myszka x = %d, y = %d, klawisz = %d !", mouse_x, mouse_y, mouse_b );
       
        if( player1.kierunek == 1 )
        {
            if( player1.frame >= 0 && player1.frame < 20 ) masked_blit( character_animation_right, buffer, 1, 1, player1.x, player1.y, 50, 70 );
           
            if( player1.frame >= 20 && player1.frame < 40 ) masked_blit( character_animation_right, buffer, 52, 1, player1.x, player1.y, 50, 70 );
           
            if( player1.frame >= 40 && player1.frame < 60 ) masked_blit( character_animation_right, buffer, 103, 1, player1.x, player1.y, 50, 70 );
           
            if( player1.frame >= 60 && player1.frame < 80 ) masked_blit( character_animation_right, buffer, 154, 1, player1.x, player1.y, 50, 70 );
           
            if( player1.frame >= 80 && player1.frame < 100 ) masked_blit( character_animation_right, buffer, 103, 1, player1.x, player1.y, 50, 70 );
           
            if( player1.frame >= 100 && player1.frame < 120 ) masked_blit( character_animation_right, buffer, 52, 1, player1.x, player1.y, 50, 70 );
           
        }
        if( player1.kierunek == 0 )
        {
            if( player1.frame >= 0 && player1.frame < 20 ) masked_blit( character_animation_left, buffer, 1, 1, player1.x, player1.y, 50, 70 );
           
            if( player1.frame >= 20 && player1.frame < 40 ) masked_blit( character_animation_left, buffer, 52, 1, player1.x, player1.y, 50, 70 );
           
            if( player1.frame >= 40 && player1.frame < 60 ) masked_blit( character_animation_left, buffer, 103, 1, player1.x, player1.y, 50, 70 );
           
            if( player1.frame >= 60 && player1.frame < 80 ) masked_blit( character_animation_left, buffer, 154, 1, player1.x, player1.y, 50, 70 );
           
            if( player1.frame >= 80 && player1.frame < 100 ) masked_blit( character_animation_left, buffer, 103, 1, player1.x, player1.y, 50, 70 );
           
            if( player1.frame >= 100 && player1.frame < 120 ) masked_blit( character_animation_left, buffer, 52, 1, player1.x, player1.y, 50, 70 );
           
        }
        //                            *****
        if( mouse_b == 1 ) rectfill( map, mouse_x -( mouse_x % 25 ), mouse_y -( mouse_y % 25 ),( mouse_x - mouse_x % 25 ) + 25, mouse_y -( mouse_y % 25 ) + 25, makecol( 0, 0, 0 ) );
       
        if( mouse_b == 2 ) clear_to_color( map, makecol( 255, 0, 255 ) );
       
        masked_blit( kursor, buffer, 0, 0, mouse_x, mouse_y, kursor->w, kursor->h );
        blit( buffer, screen, 0, 0, 0, 0, 800, 600 );
        clear_to_color( buffer, makecol( 0, 0, 0 ) );
       
        //*********************************************************************
    } // (!key[KEY_ESC])
   
   
    destroy_bitmap( buffer );
    destroy_bitmap( kartka_background );
    destroy_bitmap( forest_background );
    destroy_bitmap( lake_background );
    destroy_bitmap( character_animation_right );
    destroy_bitmap( character_animation_left );
    destroy_bitmap( kursor );
    destroy_bitmap( map );
    return 0;
}
END_OF_MAIN();

To jest mniej więcej testowanie grawitacji, kolizji itp.

Gdy dochodzimy do krawędzi ekranu, bitmapa map (czyli te wszystkie kwadraty) przesuwa się. Ale kolizja jest nadal w tym samym miejscu (np ściana jest po prawej stronie, ale kolizja w tym samym miejscu)

Zamieszczam screenshooty abyście mogli zobaczyć efekt.

http://screenshooter.net/101961768/SS3
http://screenshooter.net/101961768/SS4 // kolorem czerwonym oznaczyłem jak wygląda kolizja


Proszę o pomoc w rozwiązaniu tego problemu, choć nie wiem czy ktoś w jest w jakiś sposób w stanie mi pomóc.


EDIT: Już zrobione. Problem rozwiązany. Posiedziałem kilka godzin i doszedłem.
Ten fragment:
C/C++
if( mouse_b == 1 ) rectfill( map, mouse_x -( mouse_x % 25 ), mouse_y -( mouse_y % 25 ),( mouse_x - mouse_x % 25 ) + 25, mouse_y -( mouse_y % 25 ) + 25, makecol( 0, 0, 0 ) );

Zamieniłem na to:
C/C++
if( mouse_b == 1 ) rectfill( map,( mouse_x -( mouse_x % 25 ) ) - map_x,( mouse_y -( mouse_y % 25 ) ) - map_y,( mouse_x -( mouse_x % 25 ) + 25 ) - map_x,( mouse_y -( mouse_y % 25 ) + 25 ) - map_y, makecol( 0, 0, 0 ) );


Dzięki temu po scrollowaniu mapy pod uwagę brana jest aktualna pozycja kursora względem przesunięcia.

Do pozostałych rzeczy związanych z kolizjami np:
C/C++
if( key[ KEY_A ] && getpixel( map, player1.x + 10 - 1, player1.y ) == makecol( 255, 0, 255 )
&& getpixel( map, player1.x + 10 - 1, player1.y +( 70 - 1 ) / 2 ) == makecol( 255, 0, 255 )
&& getpixel( map, player1.x + 10 - 1, player1.y + 70 - 1 ) == makecol( 255, 0, 255 ) )

Musiałem odjąć map_x i map_y, aby kolizje też uwzględniały przesunięcia.
P-125322
« 1 »
  Strona 1 z 1