英文:
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:
-
Ensure that the
getch_noblock()
function is correctly implemented to capture keyboard input without blocking. -
Check that the terminal environment and the curses library are set up correctly for non-blocking input.
-
Make sure that the logic for updating the
x
andy
coordinates and theField
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. -
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.
-
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;
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论