Ir ao conteúdo
  • Cadastre-se

C Não consigo fazer o inimigo ir atrás do meu boneco Allegro 5 C


pardorio

Posts recomendados

Olá, não consigo ter a mínima ideia de como fazer um sistema de atração do inimigo ao meu personagem por isso não postei o codigo, alguém pode me dar uma luz ? Eu já fiz o sistema de colisão que quando se colidem meu boneco perde vida ,mas não consigo fazer o inimigo se mover até o meu personagem

  • Amei 1
Link para o comentário
Compartilhar em outros sites

@pardorio      sem um código fica difícil dar algum palpite ,  pode postar alguma coisa mesmo que seja um rascunho , e seu personagem tem uma posição coluna / linha da tela e o inimigo também , assim decremente as coordenadas do inimigo até ficar igual as coordenadas de seu personagem e ele ficarão no mesmo ponto da tela .

Link para o comentário
Compartilhar em outros sites

17 horas atrás, devair1010 disse:

@pardorio      sem um código fica difícil dar algum palpite ,  pode postar alguma coisa mesmo que seja um rascunho , e seu personagem tem uma posição coluna / linha da tela e o inimigo também , assim decremente as coordenadas do inimigo até ficar igual as coordenadas de seu personagem e ele ficarão no mesmo ponto da tela .

#include <stdio.h>
#include <allegro5/allegro.h>
#include <allegro5/allegro_image.h>
#include <allegro5/allegro_font.h>
#include <allegro5/allegro_ttf.h>
#include <allegro5/allegro_primitives.h>
#include <allegro5/allegro_audio.h>
#include <allegro5/allegro_acodec.h>
#include <stdlib.h>
#include <time.h>


#include "main.h"

    const int ZOMBIES1         = 10;
    const int AKPENTE           = 40;
    const int   largura         = 717;
    const int   altura          = 664;
    const float FPS             = 60.0;
    const float FPSsprite       = 5.0;
    int i,z;


    bool keys[8]={false,false,false,false,false,false,false,false};
    enum KEYS{UP, DOWN, LEFT, RIGHT, SPACE, ESCAPE, J, B};

    enum FASES{MENU,TUTORIAL,APOCALIPSE,YOU_LOSE};

int main(void)
{
bool redraw = true;
bool acaba = false;
int fases = MENU;


    ALLEGRO_DISPLAY *display = NULL;
    ALLEGRO_EVENT_QUEUE *fila = NULL;
    ALLEGRO_TIMER *timer = NULL;
    ALLEGRO_TIMER *timersprite = NULL;

    ALLEGRO_BITMAP *tutorialimg = NULL;
    ALLEGRO_BITMAP *becomimg = NULL;
    ALLEGRO_BITMAP *menuimg = NULL;
    ALLEGRO_BITMAP *Akplayer      = NULL;
    ALLEGRO_BITMAP *Akplayer_esquerda = NULL;
    ALLEGRO_BITMAP *zombie_direita = NULL;
    ALLEGRO_BITMAP *zombie_esquerda = NULL;

if(!al_init())
{fprintf(stderr, "falhou ao inicializar o Allegro!\n");return -1;}


 display = al_create_display(largura,altura);

if(!display)
{fprintf(stderr, "falhou ao inicializar o Allegro!\n");return -1;}

 al_init_primitives_addon();
 al_install_keyboard();
 al_init_image_addon();
 al_init_font_addon();
 al_init_ttf_addon();
 al_init_acodec_addon();
 al_install_audio();


 fila = al_create_event_queue();
 timer = al_create_timer(1.0/FPS);
 timersprite = al_create_timer(1.0/FPSsprite);

 tutorialimg = al_load_bitmap("img/tutorialimg.png");
 becomimg = al_load_bitmap("img/becoimg.png");
 menuimg = al_load_bitmap("img/zombiemenu.png");
 Akplayer = al_load_bitmap("img/player_ak1.png");
 Akplayer_esquerda = al_load_bitmap("img/player_ak_esquerda.png");
 zombie_direita = al_load_bitmap("img/zombie1");
 zombie_esquerda = al_load_bitmap("img/zombie_esquerda");

 al_register_event_source(fila,al_get_keyboard_event_source());
 al_register_event_source(fila,al_get_display_event_source(display));
 al_register_event_source(fila, al_get_timer_event_source(timer));
 al_register_event_source(fila, al_get_timer_event_source(timersprite));

 al_start_timer(timersprite);
 al_start_timer(timer);
 srand(time(NULL));

for(i = 0; i < AKPENTE; i++)
	{

		akbala[i].v = 5;
		akbala[i].ativo = false;
	}

for(i=0;i<ZOMBIES1;i++)
    {
      zombie1[i].v = 2;
      zombie1[i].larg_x = 32;
      zombie1[i].alt_y = 26;
      zombie1[i].vidas = 100;
      zombie1[i].dir = 1;
      zombie1[i].cur=0;
      zombie1[i].dano=50;

    }



while(!acaba)
{
    ALLEGRO_EVENT ev;
    al_wait_for_event(fila,&ev);

 fases = APOCALIPSE;

    if(ev.type == ALLEGRO_EVENT_TIMER)
   {
        redraw = true;
   if(!(keys[RIGHT])&&!(keys[LEFT])&&!(keys[UP])&&!(keys[DOWN])) {swat.cur=0;}





       if(swat.vidas>0)
       {
           swat.y -= keys[UP] *swat.vup;
           swat.x -= keys[LEFT] *swat.vleft;
           swat.y += keys[DOWN] *swat.vdown;
           swat.x += keys[RIGHT] *swat.vright;
       }
       if(swat.y < 150){swat.y = 150;}
       if(swat.y > 620){swat.y = 620;}
       if(swat.x < 28){swat.x = 28;}
       if(swat.x > 540){swat.x = 540;}

    for(i=0;i< AKPENTE;i++)
    {
            if(!akbala[i].ativo)
            {
                if(swat.dir==1)
                {
                    akbala[i].dir = 1;
                }
            }

            if(!akbala[i].ativo)
            {
                if(swat.dir==0)
                {
                    akbala[i].dir = 0;
                }
            }

            if((akbala[i].ativo) && (akbala[i].dir == 1))
		{

			akbala[i].x += akbala[i].v;

			if(akbala[i].x > largura)
				akbala[i].ativo = false;}

	        if((akbala[i].ativo) && (akbala[i].dir==0))
		{

			akbala[i].x -= akbala[i].v;

			if(akbala[i].x < 0)
				akbala[i].ativo = false;}

	        if(akbala[i].ativo)
            {
                for(z=0;z<ZOMBIES1;z++)
                {
                    if(zombie1[z].vidas>0)
                    {
                        if(akbala[i].x < (zombie1[z].x + zombie1[z].larg_x) && akbala[i].x > (zombie1[z].x - zombie1[z].larg_x) &&
                           akbala[i].y < (zombie1[z].y + zombie1[z].alt_y) && akbala[i].y > (zombie1[z].y - zombie1[z].alt_y))
                         {
                              zombie1[z].vidas -= swat.dano;
                              akbala[i].ativo=false;

                             if(zombie1[z].vidas<=0)
                             {swat.pontos += 10;
                             akbala[i].ativo=false;
                             zombie1[z].vivo=false;}
                         }



                    }

                }

            }


	}

    for(z=0;z<ZOMBIES1;z++)
{
            if(!zombie1[z].vivo)
    {
                 if(rand() % 500 == 0)
                {
                  zombie1[z].vivo=true;
                  zombie1[z].x = largura;
                  zombie1[z].y = 270 + rand() % (altura - 500);
                }
    }
}
    for(z=0;z<ZOMBIES1;++z)
{
    if(zombie1[z].vivo)
    {
        zombie1[z].x -= zombie1[z].v;

        if(zombie1[z].x<0)
        {
            zombie1[z].vivo=false;
        }
    }

     if(zombie1[z].vivo)
     {
         if((swat.x + swat.larg_x) > (zombie1[z].x - zombie1[z].larg_x)&&(swat.x - swat.larg_x) < (zombie1[z].x + zombie1[z].larg_x) &&
             (swat.y + swat.alt_y) > (zombie1[z].y - zombie1[z].alt_y)&&(swat.y - swat.alt_y) < (zombie1[z].y + zombie1[z].alt_y))
         {
             swat.vidas -= zombie1[z].dano;
             zombie1[z].semdano = true;

             if(zombie1[z].semdano)
             {
                 zombie1[z].dano = 0;
                 zombie1[z].semdano = false;
             }


         }

     }

}

   }

    if(ev.type == ALLEGRO_EVENT_KEY_DOWN)
    {
        switch(ev.keyboard.keycode)
    {
                case ALLEGRO_KEY_ESCAPE:
                keys[ESCAPE] = true;
                break;

                case ALLEGRO_KEY_UP:
                keys[UP] = true;
                break;

                case ALLEGRO_KEY_DOWN:
                keys[DOWN] = true;
                break;

                case ALLEGRO_KEY_RIGHT:
                keys[RIGHT] = true;
                swat.dir= 1;

                break;

                case ALLEGRO_KEY_LEFT:
                keys[LEFT] = true;
                swat.dir= 0;
                break;

                case ALLEGRO_KEY_SPACE:
                swat.disp= 1;

               for(i=0;i<AKPENTE;i++)
    {

            if((!akbala[i].ativo) && (akbala[i].dir==0))
        {
            akbala[i].x = swat.x - 17;
            akbala[i].y = swat.y + 20;
            akbala[i].ativo = true;


            break;
        }
           if((!akbala[i].ativo) && (akbala[i].dir==1))
        {
            akbala[i].x = swat.x + 17;
            akbala[i].y = swat.y + 20;
            akbala[i].ativo = true;


            break;
        }


    }

    }
}

    else if (ev.type == ALLEGRO_EVENT_KEY_UP)
        {
            switch(ev.keyboard.keycode)
            {

                case ALLEGRO_KEY_UP:
                keys[UP] = false;
                break;

                case ALLEGRO_KEY_ESCAPE:
                keys[ESCAPE] = false;
                break;

                case ALLEGRO_KEY_DOWN:
                keys[DOWN] = false;
                break;

                case ALLEGRO_KEY_RIGHT:
                keys[RIGHT] = false;
                break;

                case ALLEGRO_KEY_LEFT:
                keys[LEFT] = false;
                break;

                case ALLEGRO_KEY_SPACE:
				keys[SPACE] = false;
				break;



      }
    }
             else if(ev.timer.source==timersprite)
            {

                swat.cur += keys[DOWN];
                swat.cur += keys[UP];
                swat.cur+= keys[LEFT];
                swat.cur+= keys[RIGHT];

                if(swat.dir==1 && swat.cur>=4){swat.cur=1;}

                if(swat.dir==0 && swat.cur>=4){swat.cur=1;}

}


//PARA PODER FECHAR O JOGO
else if(ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE)
   {
    acaba=true;
   }
//=============================GAME STATES=======================================================//
else if(ev.type==ALLEGRO_EVENT_TIMER)
   {
      if(ev.timer.source==timer)
     {


       if(fases == MENU)
       {
           if(keys[SPACE])
           {fases = TUTORIAL;}
           if(keys[ESCAPE])
           {acaba=true;}

        al_draw_bitmap(menuimg,0,0,0);
       }

       if(fases == TUTORIAL)
       {
           if(keys[SPACE])
           {fases = APOCALIPSE;}
           if(keys[ESCAPE])
           {acaba=true;}

        al_draw_bitmap(tutorialimg,0,0,0);
       }


       if(fases == APOCALIPSE)
       {
           if(keys[ESCAPE])
           {acaba=true;}

       al_draw_bitmap(becomimg,0,0,0);
           }
        if(fases == YOU_LOSE)
       {
           if(keys[SPACE] || keys[ESCAPE])
           {acaba=true;}


       }




     }


   }

if(redraw && al_is_event_queue_empty(fila))
		{
			redraw = false;




          for(i=0;i<AKPENTE;i++)
          {

                if(akbala[i].ativo)
                al_draw_filled_circle(akbala[i].x, akbala[i].y, 1, al_map_rgb(255, 255, 255));


          }
          for(i=0;i<ZOMBIES1;i++)
          {
              if(zombie1[i].vivo)
              {
                  al_draw_filled_circle(zombie1[i].x,zombie1[i].y,10,al_map_rgb(255,0,255));
              }

          }

              if(swat.vidas>0)
            {

               if(swat.dir==1)
               { al_draw_bitmap_region(Akplayer,31*swat.cur,0,32,31,swat.x,swat.y,0);

               }
               if(swat.dir==0)
              {al_draw_bitmap_region(Akplayer_esquerda,31*swat.cur,0,32,31,swat.x,swat.y,0);}

             }




            al_flip_display();
		    al_clear_to_color(al_map_rgb(0,0,0));
		}
		}

    al_destroy_bitmap(becomimg);
    al_destroy_bitmap(tutorialimg);
    al_destroy_bitmap(Akplayer_esquerda);
    al_destroy_bitmap(menuimg);
    al_destroy_bitmap(Akplayer);
    al_destroy_event_queue(fila);
	al_destroy_timer(timer);
	al_destroy_display(display);





return 0;





}


 


 

//BONECOS CONTROLADOS
struct PLAYER
{
int x,
y,
vidas,
vleft,
vright,
vup,
vdown,
larg_x,
alt_y,


cur,
dir,
disp,
dano,
pontos;

};

struct PLAYER swat={400,200,100,5,5,5,5,32,31,0,0,45,50};

//PROJETEIS
struct PROJETEIS
{
    bool ativo;
    int v,
     x,
     y,
     dir;

};

struct PROJETEIS akbala[5];


struct ZOMBIES
{
    bool vivo;
    int x,
        y,

        v,
        larg_x,
        alt_y,
        dir,
        cur,
        dano,
        vidas;
        bool semdano;

};

struct ZOMBIES zombie1[10];

 

Estou com 2 problemas nele ,operar com lógica de GameStates e com a inteligencia artificial dos zumbis

 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Acho que é pelo menos a segunda vez que vejo um tópico do gênero neste fórum.

Vou fazer uma resposta diferente, assim ficamos com duas que é melhor que só uma:

Basicamente é o seguinte: a grosso modo, toda força na física é um vetor. Num plano 2d como o canvas de uma janela, temos o vetor com componentes X e Y.

Como você já deve saber (eu espero) pra mover um sprite na tela você precisa adiciona/remover um valor da posição X e/ou Y e então ele move. Mesma coisa é com um vetor, só que nesse caso você tem uma struct específica só pra trabalhar com vetor (matemático, não confunda com vetor de dados).

 

Vamos a um algoritmo simples:

//vel é um vetor (struct) com membros x e y (floats de preferência)

//dentro do loop principal

player.x += player.x + vel.x;

Observe o seguinte: no código acima, dependendo do sinal da variável vel.x, o player vai mover pra esquerda ou para direita.

Se vel.x < 0, então, player vai mover pra esquerda

Se vel.x > 0, então, player vai mover pra direita

Se vel.x == 0, player fica parado

 

Ou seja, a posição do player dentro do jogo depende apenas de modificar os valores da velocidade.

 

Agora veja esse outro:

//obs: direcao é outra struct com x e y (um vetor também)

player.x += player.x + MAX_VEL_X * direcao.x;

Agora troquei vel.x por MAX_VEL_X * direcao.x.

Nesse caso, para onde o player vai na horizontal, vai depender tanto do sinal de direcao.x como do valor dela.

Sendo assim se temos MAX_VEL_X==100 e direcao.x = -0.02, o player vai mover pra esquerda 2 pixels (100 * (-0.02))

E o inverso ocrre se for direcao = +0.02. Só que, como eu disse, o quanto o player move pra esquerda our pra direita depende do valor atual de direcao.x.

Se direcao.x == +5, então, player vai mover 500px pra direita por iteração do loop.

Se direcao.x == +0.5 então, player vai mover 50px pra direita por iteração do loop.

E assim vai conforme o valor que você der ao direcao.x.

 

E finalmente, a base pra você mover numa direção:

//faça isso dentro do loop principal

player.x += player.x + MAX_VEL_X * direcao.x;

player.y += player.y + MAX_VEL_Y * direcao.y;

MAX_VELX e _Y são dois valores constantes (qualquer valor)

direcao.x e .y são o vetor de direção pra onde mover.

 

Pra você mover o inimigo numa posição atual x,y pra outra final fx,fy, numa certa direção, basta você identificar primeiro qual a direção que você quer mover o inimigo e a posição final pra onde ele vai.

 

Ficaria melhor se eu desenhasse mas agora tô sem vontade de fazer isso.

é só imaginar assim:

Sair do ponto A para o ponto B é uma seta que vai de A para B (um vetor)

O vetor que vai de A para B pode ser apenas a subtração da posição B com a posição A.

[Por que não de posição A menos posição B?]

Porque isso mudaria os sinais do vetor!

 

Calculando a direção:

A direção é na verdade o vetor unitário (vetor de comprimento 1.0), ou melhor, é a hipotenusa de um triangulo retangulo feito da posição atual até a posição final que você quer que o inimigo siga:

//dentro do loop

//cateto da base do triangulo retangulo

//observe que é player menos inimigo e não o inverso

//o inimigo é como se fosse a origem de onde sai a direção

float x = player.x - inimigo.x;

//altura

float y = player.y - inimigo.y;

float h = sqrt(x * x + y * y);

//agora, vamos converter para um vetor unitário

//não esqueça de verificar se h é zero, se for, x e y serão zero também

//aqui é o cosseno

x = x / h;

//aqui é o seno

y = y / h;

//até aqui, x e y são o seu vetor direcao

//agora basta pegar aquela fórmula de mover e trocar tudo:

inimigo.x += inimigo.x + MAX_VEL_X * x;

inimigo.y += inimigo.y + MAX_VEL_Y * y;

//fim dentro do loop

 

Por que eu troquei o player pelo inimigo?

Porque você quer mover o inimigo e não o player.

Se desejar mover o player para a posição do inimigo, basta inverter tudo: onde tem player menos inigmio, vai ficar inimigo menos player.

 

Tem que atualizar o vetor direção apenas quando o player mover. Por exemplo, se o player mover sua posição, você deve recalcular a direção, caso não, ela continua o último valor calculado.

 

Link para o comentário
Compartilhar em outros sites

Falha minha num ponto ali n fórmula de mover:

Onde tem isso:

inimigo.x += inimigo.x + MAX_VEL_X * x;

inimigo.y += inimigo.y + MAX_VEL_Y * y;

É pra ser isso:

inimigo.x = inimigo.x + MAX_VEL_X * x;

inimigo.y = inimigo.y + MAX_VEL_Y * y;

Basta apenas remover o opoerador '+=' e trocar por '='

Link para o comentário
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

Ebook grátis: Aprenda a ler resistores e capacitores!

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!