Ir ao conteúdo
  • Cadastre-se

C++ Jogo c++ multiplayer tutorial


Posts recomendados

Olá para ajudar algumas pessoas, eu vou postar um jogo multiplayer em c++ completamente puro e em ascii que fiz e explicá-lo

Sou um estudante de programação e não sei muito, mas acho que posso ajudar alguém

Bem, vamos começar do começo

#include<windows.h>
#include<stdio.h>
#include<conio.h>
#include <stdlib.h>

vamos precisar dessas bibliotecas

e para facilitar vamos usar essas 3 funções

void gotoxy(int x, int y) {
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),(COORD) {
		x,y
	});
}
void insquadxy(int x, int y){
	gotoxy(x,y);
	printf("%c",219);
}
void trancolor( int c){	
 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), c);
}

gotoxy vai para uma coordenada x y na tela 

insquadxy põe um quadrado em uma coordenada na tela

e trancolor muda a cor das letras de um texto

ele deixa as cores na cor colocada até que se coloque outro trancolor

aqui uma tabela de cores para facilitar

0  preto

1  azul

2  verde 

3  ciano

4  vermelho

5  magenta

6  marrom

7  cinza claro

8  cinza escuro

9  azul claro

10  verde claro

11  ciano claro

12  vermelho claro

13  magenta claro

14  amarelo

15  branco

o número que você pôr no parenteses do trancolor é o número da cor nessa tabela

vamos entrar no principal agora

int main(){
		int x=78,y=23,a=1,p=1,n=0,m=0,e=79,q=24,pothpa=3,pothpd,hpd=100,hpa=100,pr;

vamos usar essas variaveis

for(pr=0;pr<25;pr++)
 { gotoxy(0,pr); //vertical esquerda.//
 printf("%c",219);
 }
 for(pr=0;pr<80;pr++)
 { gotoxy(pr,0); //horizontal ssuperior//
 printf("%c",219);
 }
 for(pr=0;pr<25;pr++)
 { gotoxy(79,pr); //vertical direita//
 printf("%c",219);
 }
 for(pr=0;pr<80;pr++)
 { gotoxy(pr,24); //horizontal inferior.//
 printf("%c",219);
 }

assim nós delimitamos a arena

system("color EF");

aqui nós mudamos o fundo para amarelo e as letras para branco, que fará as paredes

as outras cores vamos mudar com trancolor

for(;;){
		n=a;
		m=p;
    	e=x;
		q=y;
		if(GetAsyncKeyState(0x41))a--;
		if(GetAsyncKeyState(0x44))a++;
	    if(GetAsyncKeyState(0x53))p++;
	     if(GetAsyncKeyState(0x57))p--;
         if(GetAsyncKeyState(0x51)){
         	if(pothpa>0 and hpa<86){
         	pothpa--;
         	hpa+=15;
		 }
	}
	if(GetAsyncKeyState(0x45)){
	if(x==a-1 or x==a+1 or x==a){
	if(y==p-1 or y==p+1 or y==p){
			hpd-=20;
		}	
		}
	}	
		if(GetAsyncKeyState(VK_RIGHT))x++;
		if(GetAsyncKeyState(VK_LEFT))x--;
		if(GetAsyncKeyState(VK_DOWN))y++;
		if(GetAsyncKeyState(VK_UP))y--; 
 	             if(GetAsyncKeyState(0x23)){
         	if(pothpd>0 and hpd<86){
         	pothpd--;
         	hpd+=15;
		 }
	}	 
	if(GetAsyncKeyState(0x2E)){
		if(a==x-1 or a==x+1 or a==x){
		if(p==y-1 or p==y+1 or p==y){
			hpa-=20;
		}	
		}
	}

aqui vem a parte legal, onde repetimos infinitamente, com for(;;), e se a pessoa clicar nas setas, lemos e mudamos x ou y, se clica em w,a,s ou d, mudamos a ou p(coordenadas do 1 e segundo personagem) se clica em end, regeneramos e gasta 1 pot do player 1, se clica em del, ataca o player 2 se ele estiver próximo, se for E  ataca o player 1 se estiver próximo, e se for Q regenera o player 2

se n clicar em nada, continua o programa

(lemos tudo com virtual keys pesquise no google sobre isso)

for(pr=0;pr<25;pr++)
 { if(x==0 and y==pr)x=e; //vertical esquerda.//
 if(a==0 and p==pr)a=n;
 }
 for(pr=0;pr<80;pr++)
 {  if(p==0 and a==pr)p=m; //horizontal ssuperior//
    if(y==0 and x==pr)y=q; 
 }
 for(pr=0;pr<25;pr++)
 { if(x==79 and y==pr)x=e;
 if(a==79 and p==pr)a=n; //vertical direita//
 }
 for(pr=0;pr<80;pr++)
 { if(y==24 and x==pr)y=q;  //horizontal inferior.//
    if(p==24 and a==pr)p=m;
 }

aqui nós simplesmente impedimos as pessoas de passarem por cima da parede

if(hpa>0){
trancolor(14)
		insquadxy(n,m);
  trancolor(13)
 insquadxy(a,p);
}
 if(hpd>0){
trancolor(14)
insquadxy(e,q);
trancolor(1)
	insquadxy(x,y);
}

aqui imprimos os personagens, e se eles se moveram, apagamos o que estava antes dele com as coordenadas E e Q para o player 1 e N e M para o 2

	Sleep(100);
trancolor(4)
	gotoxy(63,5);
	printf("                ");
	gotoxy(63,5);
	printf("HP PLAYER 1: %d",hpd);
	gotoxy(63,7);
	printf("                ");
	gotoxy(63,7);
	printf("HP PLAYER 2: %d",hpa);

aqui imprimimos a hp de cada um

  

if(hpa<=0){
	    trancolor(14);
		insquadxy(a,p);
	    trancolor(2);
		gotoxy(63,9);
		printf("JOGADOR 1 GANHOU"); 
	hpa=0;
	a=p=0;
	}
	if(hpd<=0){
	    trancolor(14);
		insquadxy(x,y);
	    trancolor(2);
		gotoxy(63,9);
		printf("JOGADOR 2 GANHOU"); 
	hpd=0;
	x=y=0;
	}
	}

}

aqui terminamos fazendo com que não se ataque mais o outro player depois de morto e que se mostre que ele morreu

o código completo

#include<windows.h>
#include<stdio.h>
#include<conio.h>
#include <stdlib.h>
void gotoxy(int x, int y) {
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),(COORD) {
		x,y
	});
}
void insquadxy(int x, int y){
	gotoxy(x,y);
	printf("%c",219);
}
void trancolor( int c){	
 SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), c);
}
int main(){
		int x=78,y=23,a=1,p=1,n=0,m=0,e=79,q=24,pothpa=3,pothpd,hpd=100,hpa=100,pr;
		 for(pr=0;pr<25;pr++)
 { gotoxy(0,pr); //vertical esquerda.//
 
 printf("%c",219);
 }
 for(pr=0;pr<80;pr++)
 { gotoxy(pr,0); //horizontal ssuperior//
 printf("%c",219);
 }
 for(pr=0;pr<25;pr++)
 { gotoxy(79,pr); //vertical direita//
 printf("%c",219);
 }
 for(pr=0;pr<80;pr++)
 { gotoxy(pr,24); //horizontal inferior.//
 printf("%c",219);
 }
		system("color EF");
	for(;;){
		n=a;
		m=p;
    	e=x;
		q=y;
		if(GetAsyncKeyState(0x41))a--;
		if(GetAsyncKeyState(0x44))a++;
	    if(GetAsyncKeyState(0x53))p++;
	     if(GetAsyncKeyState(0x57))p--;
         if(GetAsyncKeyState(0x51)){
         	if(pothpa>0 and hpa<86){
         	pothpa--;
         	hpa+=15;
		 }
	}
	if(GetAsyncKeyState(0x45)){
	if(x==a-1 or x==a+1 or x==a){
	if(y==p-1 or y==p+1 or y==p){
			hpd-=20;
		}	
		}
	}	
		if(GetAsyncKeyState(VK_RIGHT))x++;
		if(GetAsyncKeyState(VK_LEFT))x--;
		if(GetAsyncKeyState(VK_DOWN))y++;
		if(GetAsyncKeyState(VK_UP))y--; 
 	             if(GetAsyncKeyState(0x23)){
         	if(pothpd>0 and hpd<86){
         	pothpd--;
         	hpd+=15;
		 }
	}	 
	if(GetAsyncKeyState(0x2E)){
		if(a==x-1 or a==x+1 or a==x){
		if(p==y-1 or p==y+1 or p==y){
			hpa-=20;
		}	
		}
	}
	 				 for(pr=0;pr<25;pr++)
 { if(x==0 and y==pr)x=e; //vertical esquerda.//
 if(a==0 and p==pr)a=n;
 }
 for(pr=0;pr<80;pr++)
 {  if(p==0 and a==pr)p=m; //horizontal ssuperior//
    if(y==0 and x==pr)y=q; 
 }
 for(pr=0;pr<25;pr++)
 { if(x==79 and y==pr)x=e;
 if(a==79 and p==pr)a=n; //vertical direita//
 }
 for(pr=0;pr<80;pr++)
 { if(y==24 and x==pr)y=q;  //horizontal inferior.//
    if(p==24 and a==pr)p=m;
 }
	 if(hpa>0){
trancolor(14);
		insquadxy(n,m);
 trancolor(13);
 insquadxy(a,p);
}
 if(hpd>0){
trancolor(14);
insquadxy(e,q);
trancolor(1);
	insquadxy(x,y);
}
	Sleep(100);
trancolor(4);
	gotoxy(63,5);
	printf("                ");
	gotoxy(63,5);
	printf("HP PLAYER 1: %d",hpd);
	gotoxy(63,7);
	printf("                ");
	gotoxy(63,7);
	printf("HP PLAYER 2: %d",hpa);
	if(hpa<=0){
	    trancolor(14);
		insquadxy(a,p);
	    trancolor(2);
		gotoxy(63,9);
		printf("JOGADOR 1 GANHOU"); 
	hpa=0;
	a=p=0;
	}
	if(hpd<=0){
	    trancolor(14);
		insquadxy(x,y);
	    trancolor(2);
		gotoxy(63,9);
		printf("JOGADOR 2 GANHOU"); 
	hpd=0;
	x=y=0;
	}
	}

}

 

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

@Daniel Bittencourt Legal sua ideia, mas proponho algumas melhorias...

Olhe o que me aparece quando compilo:

image.png.41030dd98d8f4770745496271f69785b.png

Basta converter x e y para SHORT, ou talvez substituir o que está dentro dessa função gotoxy por isso daqui que eu costumo usar:

void gotoxy(int x, int y)
{
    HANDLE hCon;
    COORD dwPos;

    dwPos.X = x;
    dwPos.Y = y;
    hCon = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleCursorPosition(hCon,dwPos);
}

Vai dar no mesmo.

 

Outra coisa são esses caracteres da ASCII estendida que você está usando. Têm muitas variáveis que implicam em quais caracteres serão impressos, como a codepage, a codepage de saída, a fonte em uso na console, etc, então pode acabar saindo diferente na tela da console ou na tela do IDE ou no Terminal do Windows, é bem chatinho isso daí.

 

Outra coisa são as instruções do jogo. Imagina um usuário que não tem ideia de que se trata esse jogo, e se depara com isso:

image.png.7f4e5085d365ca0167ab7e4c4155cba8.png

Meio complicado de adivinhar de que se trata logo de cara. Talvez seja interessante imprimir as instruções e aguardar o usuário pressionar ENTER para o jogo começar.

 

Talvez você queira adicionar efeitos sonoros também? Do jeito mais simples, com a função Beep(), ou talvez reproduzir arquivos .wav, com a função PlaySound().

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

Olá, infelizmente eu não consegui testar o seu programa e também não entendi muito bem o proposito do mesmo.

Eu recomendaria não usar conio (mas a maioria aqui no fórum simplesmente ignora), porque não é mais suportado por sistemas modernos.

 

Eu tenho esse exemplo de base para um jogo rpg em texto que pode ajudar, eu dei uma modificada para ficar mais de acordo com o tópico.

Spoiler

#include <stdlib.h>
#include <ncurses.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>


/* Constantes */
#define T_NOME_PERSONAGEM 10
#define Q_JOGADORES 2

#define MAX_MAPA_X 80
#define MAX_MAPA_Y 20

#define COR_JOGADOR1 1

enum valor_jogadores {JOGADOR1, JOGADOR2};

enum constantes_boteos {BT_CIMA, BT_BAIXO, BT_ESQUERDA, BT_DIREITA,
                        BT_A, BT_B, BT_C, BT_D};

const char botões[] ={'W', 'S', 'A', 'D',
                      'Y', 'U', 'H', 'J'};

struct local_xy
{
   unsigned short x,y;
};

struct personagem_atributos
{
   char nome[T_NOME_PERSONAGEM];
   struct local_xy local;
   unsigned short hp;
   unsigned short xp;
};

struct local_xy local_xy(unsigned short x, unsigned short y)
{
   struct local_xy l;
   l.x = x;
   l.y = y;
   return(l);
}

int main(void)
{
   int tecla;
   struct personagem_atributos jogadores[Q_JOGADORES];
   /* Inicia ncurses */
   initscr();
   /* Checa se o terminal suporta cores */
   if (has_colors() == FALSE)
   {
      endwin();
      printf("O seu terminal não suporta cores!");
      exit(EXIT_FAILURE);
   }

   /* Inicia as cores do terminal */
   start_color();

   /* Oculta os caracteres do terminal */
   noecho();

   /* Inicia o JOGADOR1 */
   jogadores[JOGADOR1].local=local_xy(10, 10);
   jogadores[JOGADOR1].hp = 100;
   jogadores[JOGADOR1].xp = 30;
   strcpy(jogadores[JOGADOR1].nome, "JOGADOR1");

   /* Não espera uma tecla ser pressionada */
   nodelay(stdscr, TRUE);

   /* Define a cor do jogador */
   init_pair(COR_JOGADOR1, COLOR_RED, COLOR_BLACK);
   
   /* Loop principal do jogo */
   do {
      clear();
      /* Atualiza o jogador */
      tecla = toupper(getch());
      if (tecla == botões[BT_CIMA])
      {
         if (jogadores[JOGADOR1].local.y > 0)
            jogadores[JOGADOR1].local.y--;
         else
            jogadores[JOGADOR1].local.y = MAX_MAPA_Y;
      }
      else if (tecla == botões[BT_BAIXO])
      {
         if (jogadores[JOGADOR1].local.y < MAX_MAPA_Y)
            jogadores[JOGADOR1].local.y++;
         else
            jogadores[JOGADOR1].local.y = 0;
      }
      else if (tecla == botões[BT_ESQUERDA])
      {
         if (jogadores[JOGADOR1].local.x > 0)
            jogadores[JOGADOR1].local.x--;
         else
            jogadores[JOGADOR1].local.x = MAX_MAPA_X;
      }
      else if (tecla == botões[BT_DIREITA])
      {
         if (jogadores[JOGADOR1].local.x < MAX_MAPA_X)
            jogadores[JOGADOR1].local.x++;
         else
            jogadores[JOGADOR1].local.x = 0;
      }
      /* Desenha o jogo */
      attron(COLOR_PAIR(COR_JOGADOR1));   /* Define a cor do jogador */
      move(jogadores[JOGADOR1].local.y, jogadores[JOGADOR1].local.x);
      printw("@");
      attroff(COLOR_PAIR(COR_JOGADOR1));

      /* Mostra o status do jogador */
      move(20, 0);
      printw("Jogador:%s|Hp:%hu|Xp:%hu\t|Pressione %c para sair.",jogadores[JOGADOR1].nome, jogadores[JOGADOR1].hp , jogadores[JOGADOR1].xp, botões[BT_C]);

      refresh();
      /* Substituir pelo calculo do tempo delta */
      usleep(4000);
   } while (tecla != botões[BT_C]);
   /* Finazila ncurses */
   endwin();
   return(0);
}

 

para compilar pelo console basta digitar gcc "NOME_DO_ARQUIVO" -o "NOME_DO_EXECUTAVEL" -lncurses

  • Obrigado 1
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!