Agora que já sabemos usar timers, vamos ver como fazer para que um objeto se movimente em uma taxa pré-definida.
Para isso, iremos utilizar o conceito de taxa de atualização de tela aprendido anteriormente. O objetivo desta lição é criar um quadrado vermelho, e fazer com que ele se movimente pela tela com uma velocidade fixa. Com isso, podemos demonstrar como criar animações sem que a velocidade destas sejam afetadas pelo desempenho do computador as executando.
#include <allegro5/allegro.h> #include <allegro5/allegro_native_dialog.h> //fps = frames per second = atualizacoes de tela por segundo #define FPS 60.0 #define LARGURA_TELA 640 #define ALTURA_TELA 480 ALLEGRO_DISPLAY *janela = NULL; ALLEGRO_EVENT_QUEUE *fila_eventos = NULL; ALLEGRO_TIMER *timer = NULL; ALLEGRO_BITMAP *quadrado = NULL; void error_msg(char *text){ al_show_native_message_box(NULL,"ERRO", "Ocorreu o seguinte erro e o programa sera finalizado:", text,NULL,ALLEGRO_MESSAGEBOX_ERROR); } int inicializar(){ if (!al_init()){ error_msg("Falha ao inicializar a Allegro"); return 0; } //cria o timer com o intervalo de tempo que ele ira disparar timer = al_create_timer(1.0 / FPS); if(!timer) { error_msg("Falha ao criar temporizador"); return 0; } janela = al_create_display(LARGURA_TELA, ALTURA_TELA); if(!janela) { error_msg("Falha ao criar janela"); al_destroy_timer(timer); return 0; } al_set_window_title(janela, "Testando FPS"); quadrado = al_create_bitmap(50, 50); if (!quadrado){ error_msg("Falha ao criar bitmap"); al_destroy_timer(timer); al_destroy_display(janela); return 0; } al_set_target_bitmap(quadrado); al_clear_to_color(al_map_rgb(255, 0, 0)); al_set_target_bitmap(al_get_backbuffer(janela)); fila_eventos = al_create_event_queue(); if(!fila_eventos) { error_msg("Falha ao criar fila de eventos"); al_destroy_timer(timer); al_destroy_display(janela); al_destroy_bitmap(quadrado); return 0; } al_register_event_source(fila_eventos, al_get_display_event_source(janela)); al_register_event_source(fila_eventos, al_get_timer_event_source(timer)); al_clear_to_color(al_map_rgb(0,0,0)); al_flip_display(); al_start_timer(timer); return 1; } int main(void){ //define quando a tela sera atualizada int desenha = 1; //quando o loop principal deve encerrar int sair = 0; //posicao do quadrado e quanto ele andara a cada disparo do timer, para coordenada X e Y int posx=50, dir_x=5; int posy=100, dir_y=5; if (!inicializar()){ return -1; } while(!sair){ ALLEGRO_EVENT evento; al_wait_for_event(fila_eventos, &evento); /* -- EVENTOS -- */ //se o tipo do evento for o disparo de um timer if(evento.type == ALLEGRO_EVENT_TIMER){ posx+=dir_x; posy+=dir_y; //se passou das bordas, inverte a direcao if (posx<=10 || posx>=LARGURA_TELA-60) dir_x*=-1; if (posy<=10 || posy>=ALTURA_TELA-60) dir_y*=-1; desenha=1; } else if(evento.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { sair = 1; } /* -- ATUALIZA TELA -- */ if(desenha && al_is_event_queue_empty(fila_eventos)) { al_clear_to_color(al_map_rgb(0,0,0)); //desenha o quadrado na tela nas posicoes X e Y al_draw_bitmap(quadrado, posx, posy, 0); al_flip_display(); //zera flag para nao entrar aqui no proximo loop desenha = 0; } } al_destroy_bitmap(quadrado); al_destroy_timer(timer); al_destroy_display(janela); al_destroy_event_queue(fila_eventos); return 0; }
Na linha 12 declaramos o bitmap que representará o quadrado vermelho que ficará se movendo na tela, e na linha 42 criamos ele com as dimensões 50x50 pixels.
Na linha 49 mudamos o bitmap alvo para o quadrado, colorimos ele com a cor vermelha na linha 50 e na linha 51 mudamos o alvo de volta para o backbuffer da janela.
O timer timer, que como explicado anteriormente serve para controlar a taxa de atualização da tela possui a frequencia de disparo de 60 Hz (60 vezes por segundo, ou 1/60s). Ele é criado na linha 11, seu tempo é definido na linha 27, ele é adicionado na fila de eventos na linha 63 e iniciado na linha 66
90-99
105-116