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. #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 ] ) { 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 ) && getpixel( map, player1.x + 40, player1.y - 1 ) == makecol( 255, 0, 255 ) ) { player1.y = player1.y - 2; } if( key[ KEY_R ] ) { 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; } if( getpixel( map, player1.x + 10, player1.y + 70 ) == makecol( 255, 0, 255 ) && getpixel( map, player1.x + 40, player1.y + 70 ) == makecol( 255, 0, 255 ) ) { player1.y++; } } blit( forest_background, buffer, 0, 0, - 1000, - 440, forest_background->w, forest_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 ) ); } 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: 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: 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: 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. |