Mr Single 2018-10-25 02:17 采纳率: 100%
浏览 922
已采纳

大神求助,贪吃蛇自动移动出现问题?

问题应该出在main函数中的那个死循环里,我想的是判断按键按下时改变ch的值否则ch一直保持不变。但是运行时就能变成开始时自动移动,但我按下按键后,必须每按一次蛇cai'neng移动一格。

#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<windows.h>
#include<ctype.h>
#include<time.h> //引用头文件
//预处理
#define WIDTH 40
#define HEIGHT 20
typedef struct line{
    int x;
    int y;
    struct line*next;
    struct line*before;
}snake;
struct  {
    int x;
    int y;
}food;
int snakesize=0;
struct {
    snake *head;
    snake *tail;
}mark;
void initialization();
void gotoxy(int, int);
void creatfood();
void snakegrown();
void showsnake();
void snakemove(int,int);
void eatfood();
int judge();

int main(void)
{
    char ch = 'A';
    initialization();
        while (1)
    {
            switch (ch)
            {
            case'W':
                snakemove(0, -1);
                break;
            case'A':snakemove(-2, 0);
                break;
            case'S':snakemove(0, 1);
                break;
            case'D':snakemove(2, 0);
                break;
            default:
                break;
            }
            if (_kbhit())
                ch = toupper(_getch());         
}
    gotoxy(0, HEIGHT + 1);
    system("pause");
    return 0;
}

void initialization()
{
    int x, y;
    mark.head = (snake*)malloc(sizeof(snake));
    mark.tail = mark.head;
    mark.head->x = WIDTH / 2;
    mark.head->y = HEIGHT / 2;
    mark.head->before = NULL;
    mark.head->next = NULL;//snakesize=1
    snakesize++;
    for (x = 0; x <= WIDTH; x += 2)
    {
        gotoxy(x, 0);
        printf("█");
        gotoxy(x, HEIGHT);
        printf("█");
    }
    for (y = 0; y <= HEIGHT; y++)
    {
        gotoxy(0, y);
        printf("█");
        gotoxy(WIDTH,y );
        printf("█");
    }
    while(snakesize <3)
        snakegrown();

    showsnake();
    creatfood();
    gotoxy(0, HEIGHT+1);
    puts("按下任意按键开始游戏");
}

void gotoxy(int x, int y)
{
    COORD pos;
    pos.X = x;
    pos.Y = y;
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}

void creatfood()
{
    snake* pc;
    srand((unsigned int)time(NULL));
    food.x = (rand()*2) % (WIDTH - 4) + 2;
    food.y = rand() % (HEIGHT - 2) + 1;     //限定刷新范围
    for(pc=mark.head;pc!=NULL;pc=pc->next)  //不能刷新在蛇身
        if (pc->x == food.x&&pc->y == food.y)
        {
            food.x = (rand() * 2) % (WIDTH - 4) + 2;
            food.y = rand() % (HEIGHT - 2) + 1;
            continue;
        }
    gotoxy(food.x, food.y);
    printf("回");
}

void snakegrown()
{
    struct line* pa;
    if (snakesize < 3)
    {
        pa = (snake*)malloc(sizeof(struct line));
        pa->next = NULL;
        pa->before = mark.tail;
        pa->x =mark.tail->x+2;
        pa->y = mark.tail->y;
        mark.tail->next = pa;
        mark.tail = mark.tail->next;
    }
    else
    {

        pa = (snake*)malloc(sizeof(struct line));
        pa->next = NULL;
        pa->before = mark.tail;
        pa->x = mark.tail->x;
        pa->y = mark.tail->y;
        mark.tail->next = pa;
        mark.tail = mark.tail->next;
    }
    snakesize++;
}
void snakemove(int i,int j)
{
    snake*pc;
    pc = mark.tail;
        while (pc->before != NULL)
        {
            gotoxy(mark.tail->x, mark.tail->y);
            printf("  ");
            pc->x = pc->before->x;
            pc->y = pc->before->y;
            pc = pc->before;
        }
        mark.head->x += i;
        mark.head->y += j;
        showsnake();
        if (judge() == 1)
        {
            gotoxy(WIDTH / 2, HEIGHT / 2);
            printf("你的分数为%d\n", snakesize - 3);
            gotoxy(WIDTH / 2, HEIGHT / 2 + 1);
            system("pause");
            exit(0);
        }
        Sleep(200);

}
void eatfood()
{
    if (food.x == mark.head->x&&food.y == mark.head->y)
    {
        snakegrown();
        creatfood();
    }
}
int judge()
{
    snake*pc;
    if (mark.head->x < 2 || mark.head->x > WIDTH || mark.head->y < 1 || mark.head->y >=HEIGHT)
        return 1;
    for (pc = mark.head->next; pc != NULL; pc = pc->next)
        if (mark.head->x == pc->x&&mark.head->y == pc->y)
            return 1;
    return 0;
}
void showsnake() 
{
    snake*pc;
    int i = 1;
    for (pc = mark.head; pc!= NULL; pc = pc->next)
    {
        gotoxy(pc->x, pc->y);
        printf("█");
    }
    eatfood();
}
  • 写回答

2条回答

  • Italink 2018-10-25 02:52
    关注

    楼主再修改一下。
    用一个tmp先接受键盘输入,你想按下其他按键,ch保持不变,可以筛选输入,如果为WASD,且没有反向,改变ch,否则ch不变,也就是继续移动。

    另外程序有个小bug,贪吃蛇可以移动到右边界上,甚至可以把右边界吃了..

    strchr 头文件 string.h

     int main(void)
    {
        char ch = 'A';
        char tmp;
        initialization();
        while (1)
        {
            switch (ch)
            {
            case'W':
                snakemove(0, -1);
                break;
            case'A':snakemove(-2, 0);
                break;
            case'S':snakemove(0, 1);
                break;
            case'D':snakemove(2, 0);
                break;
            default:
                break;
            }
            if (_kbhit()) {
                tmp = toupper(_getch());
                if (strchr("WASD", tmp) != NULL && !((ch == 'W'&&tmp == 'S') || (ch == 'S'&&tmp == 'W') || (ch == 'A'&&tmp == 'D') || (ch == 'D'&&tmp == 'A')))
                    ch = tmp;
            }
        }
        gotoxy(0, HEIGHT + 1);
        system("pause");
        return 0;
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 delta降尺度计算的一些细节,有偿
  • ¥15 Arduino红外遥控代码有问题
  • ¥15 数值计算离散正交多项式
  • ¥30 数值计算均差系数编程
  • ¥15 redis-full-check比较 两个集群的数据出错
  • ¥15 Matlab编程问题
  • ¥15 训练的多模态特征融合模型准确度很低怎么办
  • ¥15 kylin启动报错log4j类冲突
  • ¥15 超声波模块测距控制点灯,灯的闪烁很不稳定,经过调试发现测的距离偏大
  • ¥15 import arcpy出现importing _arcgisscripting 找不到相关程序