我卡在使用ncurses做贪吃蛇游戏时,无法让蛇持续移动。

huangapple go评论87阅读模式
英文:

I'm stuck doing the snake game with ncurses, I can't get the snake to move continuously

问题

I see you're working on implementing a snake game in C and you're having issues with the movement logic. To help you with the code, I'll focus on the part you've mentioned:

void movement(){
  var = getch_noblock();
  var = tolower(var);
  if (var == 'd' || var == 'a' || var == 'w' || var == 's') {
    dir=var; 
  }
  if (dir == 'd'){
    y++;
    Head++;
    Field[x][y]=Head;
  }
  if (dir == 'a'){
    y--;
    Head++;
    Field[x][y]=Head;
  }
  if (dir == 'w'){
    x--;
    Head++;
    Field[x][y]=Head;
  }
  if (dir == 's'){
    x++;
    Head++;
    Field[x][y]=Head;
  }
}

This code appears to handle the movement of the snake based on keyboard input. If you're experiencing issues with the snake not moving continuously or not responding to keyboard input as expected, here are a few suggestions to consider:

  1. Ensure that the getch_noblock() function is correctly implemented to capture keyboard input without blocking.

  2. Check that the terminal environment and the curses library are set up correctly for non-blocking input.

  3. Make sure that the logic for updating the x and y coordinates and the Field array is correct. Ensure that you're properly updating the position of the snake's head based on the direction (dir) and that the tail is also updated accordingly.

  4. Debug the code step by step to identify where it might be going wrong. You can print debugging statements to see the values of variables and how the logic flows.

  5. Double-check that the dir variable is being set correctly based on keyboard input.

By carefully reviewing and debugging these parts of the code, you should be able to resolve the issues you're facing with the snake's movement.

英文:

i am trying to implement this snake tutorial https://www.youtube.com/watch?v=XdahrXxX5zE&list=PL3pKgZpYZLjmNpbeZrcL8pBSq3YPb-8G6&index=14, and i stuck trying to make the snake move by itself in the direction that i pressed (a,w,s,d), and i am in the part of the tutoria where the guy says that i need to reemmplaze the var with the dir variable in order to make the continuis movemento of the snake this is where my programs have odd errors, first the snake does not move continously and y already did the part in the tutorial that makes that, and when i keep press one of the keys it do start to move continuisly but it stop to answering to the keyboard
> weird bugs
i have also more odd bugs like that segment violation or the fack that i need to press a key to make the frog appears but this is not that bad as the first bug describe at the begiinit it does not allowme to continue the program

here is my code


#include <cctype>
#include <cstdlib>
#include <curses.h>
#include <stdio.h>
#include <wchar.h>
#include <locale.h>
#include <stdlib.h>
#include <ncurses.h>
#include <ctime>
#include <time.h>
#include <errno.h>
#define N 20
#define M 40
int i,j,Field[N][M],x,y,gy,Head,Tail,Game,Frogs,a ,b,var,dir;
void snakeInitialization(){
  for(i=0;i<N;i++){
    for(j=0;j<M;j++){
      Field [i][j]=0;
    }
  }
  x=N/2;
  y=M/2;
  Head=5;
  Tail=1;
  gy=y;
  Game = 0;
  Frogs = 0;
  a = 0;
  b = 0;
  var = 0;
  for(i=0;i<Head;i++)
  {
    gy++;
    Field[x][gy-Head]=i+1;
  }
}
int kbhit(void)    /* comment */
{
    int ch, r;

    // turn off getch() blocking and echo
    nodelay(stdscr, TRUE);
    noecho();

    // check for input
    ch = getch();
    if( ch == ERR)      // no input
            r = FALSE;
    else                // input
    {
            r = TRUE;
            ungetch(ch);
    }

    // restore block and echo
    nodelay(stdscr, FALSE);
    return(r);
}
int msleep(long msec)
{
    struct timespec ts;
    int res;

    if (msec < 0)
    {
        errno = EINVAL;
        return -1;
    }

    ts.tv_sec = msec / 1000;
    ts.tv_nsec = (msec % 1000) * 1000000;

    do {
        res = nanosleep(&ts, &ts);
    } while (res && errno == EINTR);

    return res;
}

void print()
{
  wchar_t RDC = 0x255D;//right down corner simbol
  wchar_t LDC = 0x255A;//left down corner unicode simbol
  wchar_t VW = 0x2551;//vertical wall simbol
  wchar_t HW = 0x2550;//Horizontal wall simbol
  wchar_t RUC = 0x2557;//right up corner simbol
  wchar_t LUC = 0x2554;//left up corner simbol
  wchar_t HS = 0x2593;
  wchar_t BS = 0x2591;
  wchar_t Frg = 0x1318F;//frog
  // wprintf(L"unicode code  255A prints  %lc\n", LDC);
  // wprintf(L"unicode code 2551 prints %lc\n",VW);
  // wprintf(L"unicode code 2550 prints %lc\n",HW);
  // wprintf(L"unicode code 255D prints %lc\n",RDC);
  // wprintf(L"unicode code 2557 prints %lc\n",RUC);

  // printf ("asscii of 188 gives: %c\n\n",188);
  // printf("%c", 65);
  for (i=0;i<=M+1;i++)
  {
    if(i==0)
    {
      printw("%lc",LUC);
    }
    else if (i==M+1){
      printw("%lc",RUC);
    }
    else{
      printw("%lc",HW);
    }
  }
  printw("\n");
  for(i=0;i<N;i++)
  {
    printw("%lc",VW);
    for (j=0;j<M;j++)
    {
      if(Field[i][j]==0) printw(" ");
      if(Field[i][j]>0&&Field[i][j]!=Head) printw("%lc",BS);
      if(Field[i][j]==Head) printw("%lc",HS);
      if(Field[i][j]==-1) printw("%lc",Frg);
      if(j==M-1) printw("%lc\n",VW);
    }
  }
  for (i=0;i<=M+1;i++)
  {
    if(i==0)
    {
      printw("%lc",LDC);
    }
    else if (i==M+1){

      printw("%lc",RDC);
    }
    else{
      printw("%lc",HW);
    }
  }
}
void ResetScreenPosition(){
  move(0, 0);
}
void Random (){
  srand(time(0));
  a = 1 + rand() % 18;
  b = 1 + rand() % 38;
  if (Frogs == 0 && Field[a][b]==0) {
    Field[a][b] = -1;
    Frogs = 1;
  }
}
long int getch_noblock(){
  if(!kbhit())
    return getch();
  else
    return -1;
}
void movement(){
  var = getch_noblock();
  var = tolower(var);
  if (var == 'd' || var == 'a' || var == 'w' || var == 's') {
    dir=var; 
  }
  if (dir == 'd'){
    y++;
    Head++;
    Field[x][y]=Head;
  }
  if (dir == 'a'){
    y--;
    Head++;
    Field[x][y]=Head;
  }
  if (dir == 'w'){
    x--;
    Head++;
    Field[x][y]=Head;
  }
  if (dir == 's'){
    x++;
    Head++;
    Field[x][y]=Head;
  }
}
int main (int argc, char *argv[]) {
  setlocale(LC_CTYPE, "");
  snakeInitialization();  // moving cursor, x = 20, y = 10
  initscr();
  while (Game == 0) {
    print();
    ResetScreenPosition();
    Random();
    movement();
    msleep(99);
    refresh();

  }
  endwin();
  return 0;
}

and here is the full snake code from the tutorial https://github.com/pawanprjl/Snake-Game-in-C

i thought it could be the kbhit implemetation but i cant figure out.
and this is the part of the code that i cant figure out how to make it work as i see in the video

    void movement(){
  var = getch_noblock();
  var = tolower(var);
  if (var == 'd' || var == 'a' || var == 'w' || var == 's') {
    dir=var; 
  }
  if (dir == 'd'){
    y++;
    Head++;
    Field[x][y]=Head;
  }
  if (dir == 'a'){
    y--;
    Head++;
    Field[x][y]=Head;
  }
  if (dir == 'w'){
    x--;
    Head++;
    Field[x][y]=Head;
  }
  if (dir == 's'){
    x++;
    Head++;
    Field[x][y]=Head;
  }
}

答案1

得分: 1

Your getch_noblock function is making a blocking call to getch if kbhit returns zero.

  if(!kbhit())
    return getch();

That would be fine if a zero return-value from kbhit means that there's something to read. But that's not the case.

The "standard" kbhit function returns non-zero when a key-press is available, and zero otherwise. It appears your implementation does, too:

    ch = getch();
    if( ch == ERR)      // no input
            r = FALSE;
    else                // input
    {
            r = TRUE;
            ungetch(ch);
    }

And so your non-blocking read function is broken. This is the correct way:

long int getch_noblock(){
  if(kbhit())
    return getch();
  else
    return -1;
}
英文:

Your getch_noblock function is making a blocking call to getch if kbhit returns zero.

  if(!kbhit())
    return getch();

That would be fine if a zero return-value from kbhit means that there's something to read. But that's not the case.

The "standard" kbhit function returns non-zero when a key-press is available, and zero otherwise. It appears your implementation does, too:

    ch = getch();
    if( ch == ERR)      // no input
            r = FALSE;
    else                // input
    {
            r = TRUE;
            ungetch(ch);
    }

And so your non-blocking read function is broken. This is the correct way:

long int getch_noblock(){
  if(kbhit())
    return getch();
  else
    return -1;
}

huangapple
  • 本文由 发表于 2023年6月6日 11:16:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/76411233.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定