Atirando com Allegro

Muita gente tem dificuldade com criação em tiros, em um jogo de Naves, por exemplo. Pra ajudar, eu criei um tutorial BEM simples de como fazer uma nave, em um jogo de shooter, atirar. É um shooter vertical, bem simples de fazer. Utilizei aqui C, nada de Orientação a Objetos, porque acho que isso aqui estimula a idéia do que fazer, depois basta transformar isso em objetos pra criar o seu com C++.

Bom, primeiro de tudo, este sistema utiliza um vetor de tiros com tamanho limitado. Ou seja, você vai ter um número máximo de tiros simultâneos. Também seria possível fazer isso utilizando uma lista, para que os tiros fossem ilimitados, mas acho que este método é bem eficaz, se você setar um número máximo certo.

#define MAX_TIROS                    10

Eu setei 10, porque para este caso foi o suficiente, mas se você achar que está sendo pouco, vai colocando mais, até ver que está legal. Depois disso, vamos criar uma estrutura, que vai conter as informações de cada tiro e um BITMAP, que é a imagem 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;

// Enum que contém os estados de ativo
enum
{
    ATIVO,
    NAO_ATIVO
};

Muito bem, ela contém as coordenadas de cada bala, sua velocidade, e uma flag para verificar se ela está ativa, vamos criar uma função para inciar todos os tiros, assim:

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);
}

Essa função define que todos os tiros estão não ativos e também carrega a imagem do tiro, eu, no caso, só "desenhei".

Ok, agora nós temos que criar uma função que irá exibir os tiros ativos na tela, e atualizá-los quanto às suas posições. Lá vai:

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;
            }
        }
    }
}

O que ela faz? Ela percorre pelo array de tiros e nos que estiverem ativos, ela exibe na tela, e verifica se ela ainda se encontra na parte visível da tela, caso sim, atualiza sua posição incrementando sua coordenada X pela sua velocidade, caso ela não esteja mais visível, ela já sumiu, então ele defini-a como não ativa. É claro que, quando você tiver inimigos, você vai ter que testar a colisão delas com esses inimigos também.

Vamos também criar uma função que cria um tiro, ou seja, que atira quando você pressiona a tecla de tiro.

void atirar()
{
    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;
        }
    }
}

Essa é bem simples. Ela percorre o array até o primeiro tiro que não estiver ativo. Então ela o ativa e seta sua coordenada inicial como a coordenada da nave (aqueles números adicionais são para achar a coordenada do ponto que é a saída do tiro na nave).

Pronto. A estrutura é essa. Muito simples, não? Basta você agora colocar na incialização do jogo a função iniciar_tiros(), que vai inicializar todos os tiros, colocar no loop principal a função show_tiros(), que vai atualizar os tiros, e verificar quando o usuário pressiona uma tecla de tiro e coloca a função atirar().

Eu criei um exemplo bem simples e prático aqui, o arquivo está totalmente comentado, bem simples de entender. Só baixar, ele está como anexo.


ċ
main.c
(4k)
Bruno Croci,
1 de jul de 2009 03:58
Comments