/* * Alltirando - by CrociDB * http://crocidb.wordpress.com/ * * Shooter simples, para demonstração de tiros. */ #include #include // Definimos qual é o número máximo de tiros simultâneos #define MAX_TIROS 10 // Função para incializar o allegro e outras coisas void init(); // Função que renderiza as coisas na tela void render(); // Função que atualiza a lógica do jogo void update(); // Função que inicia a nossa nave void iniciar_nave(); // Função que inicia os tiros; void iniciar_tiros(); // Função que atira void atirar(); // Função para atualizar os tiros void show_tiros(); // Responsável pelo DoubleBuffering BITMAP *buffer; // A Struct da nave struct Nave { // As coordenadas da nave int x, y; // Velocidade da nave int vel; // Bitmap com a imagem da nossa nave BITMAP *img; }nave; // A Struct do tiro struct Tiro { // Coordenadas int x, y; // Velocidade int vel; // O Tiro está ativo? int ativo; }tiro[MAX_TIROS]; // BITMAP do tiro... como todos os tiros são iguiais, agente só cria um BITMAP *img_tiro; // Essa flag ajuda que não sejam soltos Vários tiros ao mesmo tempo, e sim // um por clique int flag_tiro; // Enum que contém os estados de ativo enum { ATIVO, NAO_ATIVO }; int main() { init(); iniciar_nave(); iniciar_tiros(); // Loop principal while(!key[KEY_ESC]) { // Não faça isso em seus jogos. O certo é criar um // controlador de FPS. Só estou usando nesse caso // para o jogo não usar muitos recursos, porque o // nosso foco não é esse. Mostrarei isso em algum // tutorial futuro. rest(30); update(); render(); } return 0; }END_OF_MAIN() void init() { // Inicia o Allegro allegro_init(); // Seta a profundidade de cores set_color_depth(32); // Inicia a janela do modo gráfico set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0); // Instala o Teclado install_keyboard(); // Vamos inicializar o Buffer para usarmos o Double Buffering buffer = create_bitmap(640, 480); } void render() { // Exibindo a nave na tela draw_sprite(buffer, nave.img, nave.x, nave.y); // Exibe os tiros na tela E os atualiza show_tiros(); blit(buffer, screen, 0, 0, 0, 0, 640, 480); clear(buffer); } void update() { // Vamos então movimentar a nave if (key[KEY_UP]) { nave.y -= nave.vel; } else if (key[KEY_DOWN]) { nave.y += nave.vel; } if (key[KEY_RIGHT]) { nave.x += nave.vel; } else if (key[KEY_LEFT]) { nave.x -= nave.vel; } // Vamos atirar if (key[KEY_SPACE]) { if (flag_tiro == 0) { flag_tiro = 1; atirar(); } } else { flag_tiro = 0; } } void iniciar_nave() { // As coordenadas nave.x = 10; nave.y = 10; // Velocidade nave.vel = 8; // Aqui eu posso carregar uma imagem, mas no caso vou desenhar uma nave nave.img = create_bitmap(80, 50); clear_to_color(nave.img, 0xFF00FF); int vertices[6] = {0, 0, 80, 25, 0, 50}; polygon(nave.img, 3, vertices, 0xAFEAC8); } void iniciar_tiros() { int i; for (i = 0; i < MAX_TIROS; i++) { // Primeiro de tudo setar que todos os tiros não estão ativos tiro[i].ativo = NAO_ATIVO; // Velocidade do tiro tiro[i].vel = 40; } // Você pode carregar uma imagem do tiro, mas eu vou "desenhá-la" img_tiro = create_bitmap(15, 2); clear_to_color(img_tiro, 0xFFFFFF); flag_tiro = 0; } void atirar() { // Temos que percorrer o array até achar um tiro que não está ativo, assim: int i; for (i = 0; i < MAX_TIROS; i++) { if (tiro[i].ativo == NAO_ATIVO) { tiro[i].ativo = ATIVO; // Setamos a coordenada que ele vai sair tiro[i].x = nave.x + 75; tiro[i].y = nave.y + 25; break; } } } void show_tiros() { // Essa função não só mostra os tiros na tela, como os atualiza. // Vai mudando sua posição e verifica se ele sai da tela (desativa-o). int i; for (i = 0; i < MAX_TIROS; i++) { if (tiro[i].ativo == ATIVO) { draw_sprite(buffer, img_tiro, tiro[i].x, tiro[i].y); if (tiro[i].x < buffer->w) { tiro[i].x += tiro[i].vel; } else { tiro[i].ativo = NAO_ATIVO; } } } }