Ir ao conteúdo
  • Cadastre-se

C Pegar um caractere no buffer por coordenada.


Posts recomendados

Oi, sou novo no fórum, e estou aprendendo a usar C, como meu primeiro projeto, eu estou fazendo um simples rpg, eu gostaria de implementar uma colisão precisa, então eu precisaria pegar um caractere em uma coordenada do buffer, teria como fazer? Agradeço!
Na foto pode se ver o personagem (P) e um soldado (S), precisaria achar o S no buffer, para fazer o sistema de diálogo e colisão. 

image.png.dc6c95f1bd61a57281b38398dfd30d97.png

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

Aqui: 

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
int a, b, x, y, dx, dy, fx, fy, maxx, maxy, ox, oy, gam, player, kkey;
player = "P";
x = 1;
y = 3;
dx = 1;
dy = 1;
ox = 0;
oy = 0;
fy = 3;
int main()
{
    CONSOLE_SCREEN_BUFFER_INFO csbi;
    GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
    maxx = csbi.srWindow.Right - csbi.srWindow.Left + 1;
    maxy = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
    gam = 1;
    while ((fx - 1) != maxx) {
        gotoxy(fx, 2);printf("=");
        fx++;
    }
    fx = 0;
    while ((fx - 1) != maxx) {
        gotoxy(fx, maxy - 1);printf("=");
        fx++;
    }
    while (gam == 1){
    gotoxy(3, 5);printf("S");
    gotoxy(1, maxy);printf("Life: 100/100; Mana: 50/50; Press <I> to open the inventory.");
    gotoxy(dx, dy);printf("x = %d; y = %d; ox = %d; oy = %d; key = %d               ", x,y,ox,oy,b); //Esse espaço extra é pra apagar possíveis vestígios.

    hidecursor();
    gotoxy(x, y);printf(player);
    b = _getch();
    if(b == 224){
        a = _getch();
        b = a;
    }
    kkey = checka(b);
    }
}
void checka(int c) {
    switch (c){
    case 72:
        if(y - 1 == 2){
            return;
        } else {
            y = y - 1;
            oy = y + 1;
            gotoxy(x, oy);printf(" ");
            return;
        }
        break;
    case 80:
        //gotoxy(dx, dy);printf("Baixo");
        if(y == maxy - 2){
            return;
        } else {
            y = y + 1;
            oy = y - 1;
            gotoxy(x, oy);printf(" ");
            return;
        }
        break;
    case 77:
        //gotoxy(dx, dy);printf("Direita");
        if(x + 1 > maxx){
            return;
        } else {
            x = x + 1;
            ox = x - 1;
            gotoxy(ox, y);printf(" ");
            return;
        }
        break;
    case 75:
        //gotoxy(dx, dy);printf("Esquerda");
        if(x - 1 == 0){
            return;
        } else {
            x = x - 1;
            ox = x + 1;
            gotoxy(ox, y);printf(" ");
            return;
        }
        break;
    case 105:
        drawinv();
        break;
    default:
        return 5;
    break;
    }
}
void gotoxy(int x, int y){
     SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),(COORD){x-1,y-1});
}
void hidecursor()
{
   HANDLE consoleHandle = GetStdHandle(STD_OUTPUT_HANDLE);
   CONSOLE_CURSOR_INFO info;
   info.dwSize = 100;
   info.bVisible = FALSE;
   SetConsoleCursorInfo(consoleHandle, &info);
}

 

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

@mrfrustrationman Você está usando qual compilador?

 

Já pensou em fazer assim?

Spoiler

#include <stdio.h>
#include <string.h>

/* Constantes */
#define T_NOME 10
#define Q_INIMIGOS 3

/* Tipos */
typedef struct
{
  char nome[T_NOME];
  int linha,coluna;
  unsigned long xp;
  float dinheiro;
}personagem_t;

int main(void)
{
  int cont,aux;
  personagem_t jogador,inimigos[Q_INIMIGOS];
    /* Inicia os monstros */
  for(cont=0; cont<Q_INIMIGOS; cont++)
  {
    inimigos[cont].dinheiro=132.40;
    inimigos[cont].xp=302;
    inimigos[cont].linha=cont+10;
    inimigos[cont].coluna=cont+10;
    strcpy(inimigos[cont].nome,"Gargola.");
  }
  printf("\nPosição dos monstros!");
  for(cont=0; cont<Q_INIMIGOS; cont++)
  {
    printf("\nNome:\t%s",inimigos[cont].nome);
    printf("\nEstá na Linha %i e coluna %i",inimigos[cont].linha,inimigos[cont].coluna);
  }
  /* Inicia o jogador */
  printf("\nDigite o nome do jogador:\t");
  scanf("%s%*c",jogador.nome);
  printf("\nDigite em que linha o jogador está:\t");
  scanf("%i%*c",&jogador.linha);
  printf("\nDigite a coluna:\t");
  scanf("%i%*c",&jogador.coluna);
  printf("\nDigite o xp do jogador:\t");
  scanf("%lu%*c",&jogador.xp);
  printf("\nDigite o dinheiro do jogador:\t");
  scanf("%f%*c",&jogador.dinheiro);
  /* Checa colisão */
  aux=0;
  for(cont=0; cont<Q_INIMIGOS; cont++)
  {
    if(jogador.linha==inimigos[cont].linha && jogador.coluna==inimigos[cont].coluna)
      aux++;
  }
  if(aux>0)
    printf("\nOuve %i colisões.\n",aux);
  else
    printf("\nNão ouve colisões.\n");
  getchar();    /* Pausa o programa */
  return(0);
}

 

Se quiser eu dou um exemplo de como ficaria na tela.

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

||=== Build file: "no target" in "no project" (compiler: unknown) ===|
....c|5|warning: data definition has no type or storage class|
....c|5|warning: type defaults to 'int' in declaration of 'player' [-Wimplicit-int]|
....c|5|warning: initialization of 'int' from 'char *' makes integer from pointer without a cast [-Wint-conversion]|
....c|5|error: initializer element is not computable at load time|
....c|6|warning: data definition has no type or storage class|
....c|6|warning: type defaults to 'int' in declaration of 'x' [-Wimplicit-int]|
....c|7|warning: data definition has no type or storage class|
....c|7|warning: type defaults to 'int' in declaration of 'y' [-Wimplicit-int]|
....c|8|warning: data definition has no type or storage class|
....c|8|warning: type defaults to 'int' in declaration of 'dx' [-Wimplicit-int]|
....c|9|warning: data definition has no type or storage class|
....c|9|warning: type defaults to 'int' in declaration of 'dy' [-Wimplicit-int]|
....c|10|warning: data definition has no type or storage class|
....c|10|warning: type defaults to 'int' in declaration of 'ox' [-Wimplicit-int]|
....c|11|warning: data definition has no type or storage class|
....c|11|warning: type defaults to 'int' in declaration of 'oy' [-Wimplicit-int]|
....c|12|warning: data definition has no type or storage class|
....c|12|warning: type defaults to 'int' in declaration of 'fy' [-Wimplicit-int]|
....c||In function 'main':|
....c|21|warning: implicit declaration of function 'gotoxy' [-Wimplicit-function-declaration]|
....c|42|warning: implicit declaration of function 'hidecursor'; did you mean 'GetCursor'? [-Wimplicit-function-declaration]|
....c|44|warning: passing argument 1 of 'printf' makes pointer from integer without a cast [-Wint-conversion]|
...w32\include\stdio.h|509|note: expected 'const char * restrict' but argument is of type 'int'|
....c|45|warning: implicit declaration of function '_getch'; did you mean '_getws'? [-Wimplicit-function-declaration]|
....c|52|warning: implicit declaration of function 'checka'; did you mean 'cdecl'? [-Wimplicit-function-declaration]|
....c|55|warning: conflicting types for 'checka'|
....c|52|note: previous implicit declaration of 'checka' was here|
....c||In function 'checka':|
....c|116|warning: implicit declaration of function 'drawinv'; did you mean 'rewind'? [-Wimplicit-function-declaration]|
....c|120|warning: 'return' with a value, in function returning void|
....c|55|note: declared here|
....c|124|warning: conflicting types for 'gotoxy'|
....c|21|note: previous implicit declaration of 'gotoxy' was here|
....c|127|warning: conflicting types for 'hidecursor'|
....c|42|note: previous implicit declaration of 'hidecursor' was here|
||=== Build failed: 1 error(s), 27 warning(s) (0 minute(s), 1 second(s)) ===|

esse programa roda?

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

agora, KXSY disse:

Mas é o mingw32 ou o que já vem com o code blocks?

mingw32

adicionado 0 minutos depois
2 minutos atrás, KXSY disse:

Isso já está genérico!

É como o @vangodp mencionou "esse é o caminho mais complicado".

Sim.. Esse programa é uma "transcrição" de um parecido que fiz em batch

adicionado 1 minuto depois

Tem muito pra mudar ainda, estava lendo sobre COORD, para tentar usar.

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

@mrfrustrationman Se você consegui instalar a ncurses aqui vai um exemplo.

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

/* Constantes */
#define T_NOME 10
#define Q_INIMIGOS 3

/* Tipos */
typedef struct
{
  char nome[T_NOME];
  int linha,coluna,vida;
  unsigned long xp;
  float dinheiro;
}personagem_t;

void ColocaNaTela(personagem_t *p, int quant, char c);

int main(void)
{
  int cont,tecla;
  personagem_t jogador,inimigos[Q_INIMIGOS];
    /* Inicia os monstros */
  for(cont=0; cont<Q_INIMIGOS; cont++)
  {
    inimigos[cont].dinheiro=132.40;
    inimigos[cont].xp=302;
    inimigos[cont].vida=3000;
    inimigos[cont].linha=cont+10;
    inimigos[cont].coluna=cont+10;
    strcpy(inimigos[cont].nome,"Gargola.");
  }
  initscr();    /* Inicia ncurses */
  clear();      /* Limpa a tela */
  /* Inicia o jogador */
  printw("\nDigite o nome do jogador:\t");
  refresh();    /* Atualiza o console */
  scanw("%s%*c",jogador.nome);
  refresh();    /* Atualiza o console */
  printw("\nDigite o xp do jogador:\t");
  refresh();    /* Atualiza o console */
  scanw("%lu%*c",&jogador.xp);
  printw("\nDigite a quantidade de vida do jogador:\t");
  refresh();    /* Atualiza o console */
  scanw("%i%*c",&jogador.vida);
  printw("\nDigite o dinheiro do jogador:\t");
  refresh();    /* Atualiza o console */
  scanw("%f%*c",&jogador.dinheiro);
  jogador.linha=jogador.coluna=4;
  /* loop principal */
  noecho();     /* Retira o curso do console */
  nodelay(stdscr,TRUE);    /* Não espera a resposta do getch() */
  do
  {
    clear();
    ColocaNaTela(inimigos,Q_INIMIGOS,'M');
    ColocaNaTela(&jogador,1,'J');
    move(18,0);
    /* Faz uma barra na tela */
    for(cont=0; cont<79; cont++)
      printw("=");
    printw("\nNome:%s|Vida:%i|Xp:%lu|Dinheiro:%.2fCr$|X:%i-Y:%i|Pressione C para sair.",jogador.nome,jogador.vida,jogador.xp,jogador.dinheiro,jogador.coluna,jogador.linha);
    /* Controla o personagem */
    tecla=getch();
    switch(toupper(tecla))
    {
      case 'S':
        if(jogador.linha<17)
          jogador.linha++;
        else
          jogador.linha=0;
      break;
      case 'W':
        if(jogador.linha>0)
          jogador.linha--;
        else
          jogador.linha=17;
      break;
      case 'D':
        if(jogador.coluna<80)
          jogador.coluna++;
        else
          jogador.coluna=0;
      break;
      case 'A':
        if(jogador.coluna>0)
          jogador.coluna--;
        else
          jogador.coluna=80;
      break;
    }
  /* Checa a colisão */
  for(cont=0; cont<Q_INIMIGOS; cont++)
  {
    if(jogador.linha==inimigos[cont].linha && jogador.coluna==inimigos[cont].coluna)
    {
      move(0,0);
      printw("Colisão entre o jogador e um %s.",inimigos[cont].nome);
      /* Reduz a vida do jogador */
      jogador.vida--;
    }
  }
  refresh();    /* Atualiza o console */
  /* Reduz o flick */
  usleep(7000);    /* Atrasa a execução */
  }while(toupper(tecla)!='C' && jogador.vida>0);
  nodelay(stdscr,FALSE);
  clear();
    if(jogador.vida<=0)
    {
      printw("Você morreu!");
      move(19,0);
      printw("Pressione qualquer teclar para continuar...");
      refresh();
      getch();
    }
  endwin();   /* Finaliza a ncurses */
  return(0);
}

void ColocaNaTela(personagem_t *p, int quant, char c)
{
  int cont;
  for(cont=0; cont<quant; cont++)
  {
    move(p[cont].linha,p[cont].coluna);
    printw("%c",c);
  }
}

Ela é bem parecida com os comandos da stdio.h mas tem vários comandos para usar o console.

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

6 minutos atrás, vangodp disse:

Mas por que você ta insistindo no ncurses? o que ele precisa saber são vetores matrizes e structs....

Disso eu sei, mas brincar um pouco com o console não faz mal a ninguém ;)

fora que isso pode ser uma motivação a mais para aprender sobre o próprio C.

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

Todas as estruturas e chamadas da console estão bem descritas em https://docs.microsoft.com/en-us/windows/console/console-reference eu acho.

 

Mas eu acho que você não deve usar essas estruturas diretamente para armazenar status do jogo. Crie uma estrutura pequena que representa o que você precisa. É mais versátil. E a partir do seu mapa você cria as funções de comando. E aí vai incluindo a interface de entrada com as teclas que vai aceitar, e a de saída com as mudanças na tela no decorrer do jogo. E a de controle que salva o estado do jogo, para, reinicia e tal. E assim fica mais fácil de portar o jogo de uma solução para outra, como por exemplo se desistir do modo caracter e for usar uma interface gráfica.

 

De todo modo, para ler o buffer de entrada você usa antes de tudo PeekConsoleInput() e na saida acho que GetConsoleScreenBufferInfoEx() e outras. Estou escrevendo de memória. Postei muitos códigos sobre isso aqui nos últimos meses, em C ou C++.  Se precisa de algo específico posso procurar nos programas depois, ou você pode ver aqui na pesquisa por conteúdo por autor no forum.

 

 

 

 

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