Ir ao conteúdo

Posts recomendados

Postado

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
Postado

@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 .

Postado
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
Postado

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.

 

Postado

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 '='

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...

LANÇAMENTO!

eletronica2025-popup.jpg


CLIQUE AQUI E BAIXE AGORA MESMO!