Allegro5 część 4 Timer i myszka Timer i myszka Autor: Kamil Krzyszczuk - C mons 1.Wstęp. Witam w juŝ czwartej części kursu tym razem będzie taki miszmasz, gdyŝ ta część jest poświęcona timerom i gryzoniowi. Zacznijmy od początku, czyli czym jest ten tajemniczy timer. 2.Timer. A więc co to takiego ten timer? OtóŜ jest to taki swoisty licznik który odlicza podany czas bezwzględnie czyli niezaleŝnie od tego jak szybko działa program. Ale po co nam to? A no po to aby móc wykonywać chociaŝby jakąś akcję w grze w równych odstępach czasu. Najlepiej podam jakiś przykład: Wyobraź sobie, Ŝe stworzyłeś program gdzie animuje się ludzik-patyczak ma on się animować równym tempem ale nie masz kontroli nad tym jak szybko program się wykonuje co za tym idzie patyczak moŝe animować się róŝnie, raz wolniej a raz szybciej. Wtedy z pomocą przychodzi timer! Dzięki niemu moŝemy wykonać jakąś akcję co określoną ilość czasu prawda? A więc moŝemy zmienić klatkę animacji przykładowo co pół sekundy. Wtedy będziemy mieli pewność, Ŝe co pół sekundy zmieni się klatka animacji czyli sama animacja będzie działać w równym tempie. Tak więc timer to licznik, który odlicza czas i kiedy skończy liczyć informuje nas o tym przez co moŝemy w tym momencie wykonać jakąś akcję. 2.Dwie drogi. OtóŜ allegro5 udostępnia system timerów aczkolwiek zmusza on do uŝywania tak zwanych zdarzeń a my ich jeszcze nie znamy ( osobiście uwaŝam Ŝe ten sposób jest równieŝ niewygodny ). Tak więc porwiemy się na inny sposób - uŝyjemy pewnej funkcji którą równieŝ oferuje nam allegro5 funkcja ta zwraca czas w sekundach, który minął od uruchomienia allegro. 3.Zegarek. Wyobraź sobie Ŝe patrzysz na zegarek i widzisz na nim godzinę zapamiętujesz ją, załóŝmy Ŝe jest to 12:00 teraz gapisz się przez jakiś czas na ten sam zegar i w końcu zauwaŝasz Ŝe jest juŝ 12:10. Wniosek z tego Ŝe minęło 10 minut. Fakt ten jest oczywisty ale pomoŝe nam zrozumieć jak będzie działał ten inny sposób na timer. OtóŜ będziemy zapamiętywać czas i sprawdzać co chwilę czy nie minęło od zapamiętanego czasu juŝ choćby te 10 minut lub 10 sekund lub jakakolwiek inna ilość czasu. :) Jeśli juŝ wszystko wiemy to moŝemy przejść do kodu i do jego analizy. 4.Kod. Skompiluj ten kod i przejdź do analizy. #include <allegro5/allegro5.h> #include <allegro5/a5_primitives.h> #include <allegro5/a5_iio.h> #include <allegro5/a5_font.h> #include <allegro5/a5_ttf.h> #include <iostream> #undef main void main() al_init(); al_install_keyboard(); al_install_mouse(); al_init_font_addon(); al_init_iio_addon(); if (!al_create_display(640,480) )
std::cout << "Nie udalo sie utworzyc okna!" << std::endl; al_set_window_title("kurs Allegro - timer i myszka"); ALLEGRO_FONT* font = al_load_ttf_font( "times.ttf", 30, 0 ); if (!font ) std::cout << "Nie udalo sie wczytac czcionki!" << std::endl; ALLEGRO_BITMAP *ludzik = al_load_bitmap("ludzik.bmp"); if (!ludzik ) std::cout << "Nie udalo sie wczytac obrazka ludzik.bmp" << std::endl; al_convert_mask_to_alpha( ludzik, al_map_rgb(255,0,255) ); ALLEGRO_BITMAP *kursor = al_load_bitmap("kursor.bmp"); if (!kursor ) std::cout << "Nie udalo sie wczytac obrazka kursor.bmp" << std::endl; al_convert_mask_to_alpha( kursor, al_map_rgb(255,0,255) ); ALLEGRO_KEYBOARD_STATE key_state; //keyboard al_get_keyboard_state(&key_state); ALLEGRO_MOUSE_STATE mouse_state; //mouse al_get_mouse_state(&mouse_state); al_hide_mouse_cursor(); double timer = al_current_time(); //timer int numerklatki = 0; while(!al_key_down(&key_state, ALLEGRO_KEY_ESCAPE) ) al_get_keyboard_state(&key_state); //keyboard al_get_mouse_state(&mouse_state); //mouse al_clear_to_color( al_map_rgb(205,146,0) ); al_draw_rectangle( 100, 100, 540, 380, al_map_rgb(255,0,0), 1 ); int x = mouse_state.x; int y = mouse_state.y; int z = mouse_state.z; int przycisk = mouse_state.buttons; al_draw_textf( font, 0, 0, NULL, "X: %d Y: %d Z: %d", x, y, z ); al_draw_textf( font, 0, 30, NULL, "Przycisk: %d", przycisk ); if ( al_current_time() >= timer+0.1 ) if ( ++numerklatki >= 6 ) numerklatki = 0; timer = al_current_time(); al_draw_bitmap_region( ludzik, 47*numerKlatki, 0, 47, 152, 298, 164, NULL ); if ( al_key_down(&key_state, ALLEGRO_KEY_1) ) al_set_mouse_xy(0,0); if ( al_key_down(&key_state, ALLEGRO_KEY_2) ) al_set_mouse_z(0); if ( al_key_down(&key_state, ALLEGRO_KEY_3) ) al_set_mouse_range(100,100,540,380); if ( al_key_down(&key_state, ALLEGRO_KEY_4) ) al_set_mouse_range(0,0,640,480); al_draw_bitmap( kursor, x, y, NULL ); al_flip_display(); al_destroy_bitmap( kursor ); al_destroy_bitmap( ludzik );
5.Analiza. al_install_mouse(); To pierwsza nieznana jeszcze nam linijka kodu. Odpowiada ona za zainstalowanie systemu myszki. Jeśli chcemy korzystać z myszki to musi ona być wywołana raz na początku programu. ALLEGRO_BITMAP *kursor = al_load_bitmap("kursor.bmp"); if (!kursor ) std::cout << "Nie udalo sie wczytac obrazka kursor.bmp" << std::endl; Fragment ten zapewne jest Ci juŝ znany z poprzedniej części. Wspomnę tylko, Ŝe w tym miejscu wczytujemy bitmapę która będzie naszym kursorem myszki. ALLEGRO_MOUSE_STATE mouse_state; //mouse al_get_mouse_state(&mouse_state); W tych linijkach kodu kolejno widzimy stworzenie struktury która przechowywać będzie nasz stan myszki czyli informację o połoŝeniu myszki, przyciskach itp. W drugiej linijce widzimy funkcje al_get_mouse_state() pobiera ona stan myszki przyjmując jako parametr wskaźnik na strukturę, która będzie ten stan przechowywać. al_hide_mouse_cursor(); Tą funkcją chowamy standardowy kursor gdyŝ będziemy rysować swój jeśli chcesz uŝywać standardowego kursora to nie wywołujesz tej funkcji i nie rysujesz później bitmapy własnego kursora. double timer = al_current_time(); //timer Tutaj widzimy nasz timer! Jest to zmienna typu double która przechowywać będzie moment rozpoczęcia liczenia czasu. ( Czyli spojrzy na zegarek i zapamięta obecny czas ). Zrobi to dzięki funkcji al_current_time() która zwraca miniony czas od uruchomienia allegro - w sekundach. int numerklatki = 0; Ta zmienna przechowywać nam będzie numer aktualnej klatki animacji ( będziemy animować ludzika z uŝyciem timera ) int x = mouse_state.x; int y = mouse_state.y; int z = mouse_state.z; int przycisk = mouse_state.buttons; Tutaj pobieramy stan myszki do naszych zmiennych aby było wygodniej. Kolejne pola struktury mouse_state oznaczają: mouse_state.x mouse_state.y mouse_state.z mouse_state.buttons Współrzędna X połoŝenia kursora na ekranie. Współrzędna Y połoŝenia kursora na ekranie. Współrzędna Z, która oznacza odchylenie kółka na myszce ( nie kaŝde myszki go posiadają ). Pole przechowujące który przycisk jest naciśnięty. 0 Ŝaden 1 lewy 2 prawy 3 środkowy al_draw_textf( font, 0, 0, NULL, "X: %d Y: %d Z: %d", x, y, z ); Zaś tu z pozoru widzimy znajomą funkcje rysującą tekst. Lecz jest to trochę inna funkcja równieŝ rysująca tekst ale pozwalająca podać jakieś parametry/zmienne do narysowania. ( odpowiedniczka printf ). Jak widzimy nazwa jest trochę inna bo na końcu jest jeszcze literka f al_draw_textf.
Wyświetlanie zmiennych za pomocą tej funkcji odbywa się na podstawie specjalnych oznaczeń w podanym tekście. Bowiem w miejsce %d wstawiona zostanie zmienna którą podaliśmy zaraz po podaniu tekstu. Tak więc w miejsce pierwszej %d zostanie wstawiona zmienna x w miejsce drugiej zmienna y a w miejsce trzeciej zmienna z kolejno. Przedstawię 3 podstawowe znaczniki bez których ani rusz: %d oznaczenie dla liczb całkowitych zmiennej int. %s oznaczenie dla łańcuchów C zmienna char* lub char[] %f oznaczenie liczb zmiennoprzecinkowych float albo double. if ( al_current_time() >= timer+0.1 ) if ( ++numerklatki >= 6 ) numerklatki = 0; timer = al_current_time(); Tutaj zaś mamy obsługę naszego timera. Jest to warunek który patrzy w kaŝdym obrocie pętli na zegarek ( al_current_time() ) i sprawdza czy czas który widzi na tym zegarku nie jest juŝ większy lub równy naszej zapamiętanej godzinie plus jedna dziesiąta sekundy. Jeśli tak to zwiększa numer klatki sprawdzając równocześnie czy zmienna numerklatki nie przekroczyła maksymalnej ilości klatek jeśli tak to ustawia numerklatki na pierwszą czyli zerową. Następnie timer jest zerowany - czyli ponownie spogląda na zegarek i zapamiętuje obecny czas. al_draw_bitmap_region( ludzik, 47*numerKlatki, 0, 47, 152, 298, 164, NULL ); Tą linijkę juŝ zapewne teŝ znacie. Jest to funkcja do rysowania fragmentu bitmapy. W tym wypadku uŝywamy ją aby narysować animację wybierając odpowiedni fragment odpowiedniej klatki animacji z bitmapy. al_set_mouse_xy(0,0); Ta funkcja ustawia połoŝenie myszki jakie podamy w parametrach funkcji gdzie kolejno pierwszy parametr to współrzędna X a drugi to współrzędna Y. al_set_mouse_z(0); Ta zaś funkcja ustawia odchylenie kółka na myszce. Jej parametr przyjmuje odchylenie. al_set_mouse_range(100,100,540,380); A ta oto funkcja ustawia pole myszki po jakim moŝe ona się poruszać. Innymi słowy moŝemy ograniczyć miejsce na ekranie po którym moŝemy poruszać myszką. Jej parametry to: int x1 int y1 int x2 int y2 Współrzędna X prostokąta(pola) lewego górnego Współrzędna Y prostokąta(pola) lewego górnego Współrzędna X prostokąta(pola) prawego dolnego Współrzędna Y prostokąta(pola) prawego dolnego al_draw_bitmap( kursor, x, y, NULL ); W tej linijce rysujemy nasz kursor a konkretnie bitmapę która go zawiera. Rysujemy go na podstawie współrzędnych myszki tak aby nasz kursor był myszką. To koniec analizy i jak zwykle wyjaśnienie co program robi. :) Program wyświetla połoŝenie myszki, odchylenie kółka, i wciśnięty przycisk myszki. Wyświetla takŝe animującego się ludzika. Jeśli naciśniemy 1 to połoŝenie myszki zmieni się na 0,0 czyli lewy górny róg ekranu. Jeśli naciśniemy 2 to odchylenie kółka się wyzeruje jeśli zaś naciśniemy 3 to ograniczymy pole myszki do prostokąta wewnątrz ekranu. Naciskając 4 przywracamy początkowe pole myszki czyli cały ekran.
I to juŝ koniec tej części. Ale zapraszam do kolejnej no i jak pewnie się juŝ domyślacie do dokumentacji równieŝ. Tak więc do zobaczenia. :) http://alleg.sourceforge.net/a5docs/refman/index.html