这个贪吃蛇要怎么改才能提升

  1. 运行时需要点击黑框才能控制,关闭时也要关闭黑框才能结束
  2. 怎么实现吃5个食物后自动加速
  3. 怎么实现游戏结束后点击确认后关闭程序
    ```
    #undef UNICODE#undef _UNICODE//为了使用outtextxy函数#define _CRT_SECURE_NO_WARNINGS//为了使用sprintf函数#include<stdio.h>#include<stdlib.h>#include<conio.h>#include<time.h>//随机函数头文件#include<graphics.h>//easyx里的头文件/********************** 坐标属性* 蛇属性* 食物属性**********************/typedef struct pointXY//坐标属性{ int x; int y;}MYPOINT;struct Snake{ int num;//节数 MYPOINT xy[100];//蛇最多100节 char postion;//方向}snake;struct Food{ MYPOINT fdxy;//食物的x,y坐标 int eatgrade; int flag;}food;HWND hwnd = NULL;//表示主窗口enum movPostion{ UP = 72, DOWN = 80, LEFT = 75, RIGHT = 77};//void initSnake();//初始化蛇void drawSnake();//画蛇void moveSnake();//移动蛇void keyDown();//按键处理void initFood();void drawFood();void eatFood();void showGrade();//展示分数int snakeDie();//蛇死掉void pauseMoment();//暂停函数//int main()//int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) //游戏程序的主体部分{ srand((unsigned int)time(NULL));//随机函数种子 hwnd = initgraph(640, 480); setbkcolor(WHITE);//设置窗口颜色 initSnake(); while (1) { cleardevice();//刷新 if (food.flag == 0) { initFood(); } drawFood(); drawSnake(); if (snakeDie()) { break; } eatFood(); showGrade(); moveSnake(); while (_kbhit()) { pauseMoment(); keyDown(); } Sleep(100);//多少ms移动一单位 } //getchar();//防止闪退 closegraph(); return 0;}void initSnake(){ snake.xy[2].x = 0; snake.xy[2].y = 0; snake.xy[1].x = 10; snake.xy[1].y = 0; snake.xy[0].x = 20; snake.xy[0].y = 0; snake.num = 3; snake.postion = RIGHT; food.flag = 0; food.eatgrade = 0;}void drawSnake(){ for (int i = 0; i < snake.num; i++) { setlinecolor(BLACK);//矩形边框颜色黑色 setfillcolor(RGB(rand() % 255, rand() % 255, rand() % 255));//炫彩蛇 fillrectangle(snake.xy[i].x, snake.xy[i].y, snake.xy[i].x + 10, snake.xy[i].y + 10); //画矩,写形左上与右下的坐标 }}void moveSnake(){ //除了第一节,后的每一节都是前面的坐标 for (int i = snake.num - 1; i > 0; i--) { snake.xy[i].x = snake.xy[i - 1].x; snake.xy[i].y = snake.xy[i - 1].y; } //第一节处理 switch (snake.postion) { case RIGHT: snake.xy[0].x += 10; break; case LEFT: snake.xy[0].x -= 10; break; case DOWN: snake.xy[0].y += 10; break; case UP: snake.xy[0].y -= 10; break; default: break; }}void keyDown(){ char userkey = 0; userkey = _getch(); switch (userkey) { case RIGHT: if (snake.postion != LEFT) snake.postion = RIGHT; break; case LEFT: if (snake.postion != RIGHT) snake.postion = LEFT; break; case DOWN: if (snake.postion != UP) snake.postion = DOWN; break; case UP: if (snake.postion != DOWN) snake.postion = UP; break; }}void initFood()//食物的设计{ food.fdxy.x = rand() % 65 * 10;//产生食物坐标为10的倍数 food.fdxy.y = rand() % 48 * 10; food.flag = 1;//食物存在 //如果食物出现在蛇身上,食物重新生成 for (int i = 0; i > snake.num; i++) { if (food.fdxy.x == snake.xy[i].x && food.fdxy.y == snake.xy[i].y) { food.fdxy.x = rand() % 65 * 10; food.fdxy.y = rand() % 48 * 10; } }}void drawFood(){ setlinecolor(BLACK); setfillcolor(RGB(rand() % 255, rand() % 255, rand() % 255)); fillrectangle(food.fdxy.x, food.fdxy.y, food.fdxy.x + 10, food.fdxy.y + 10);}void eatFood(){ //蛇边长,分数增加,食物重新生成 if (snake.xy[0].x == food.fdxy.x && snake.xy[0].y == food.fdxy.y) { snake.num++; food.eatgrade += 10; food.flag = 0; }}int snakeDie(){ if (snake.xy[0].x > 640 || snake.xy[0].x < 0 || snake.xy[0].y>480 || snake.xy[0].y < 0) { outtextxy(200, 200, "你撞墙了"); MessageBox(hwnd, "Gameover!", "撞墙警告", MB_OK); return 1;//返回1结束 } for (int i = 1; i < snake.num; i++) { if (snake.xy[0].x == snake.xy[i].x && snake.xy[0].y == snake.xy[i].y) { outtextxy(200, 200, "你撞自己了"); MessageBox(hwnd, "Gameover!", "自杀警告", MB_OK); return 1; } } return 0;}void showGrade(){ char grade[100] = "0"; sprintf(grade, "%d", food.eatgrade);//将整形转化为字符串 setbkmode(TRANSPARENT);//设置为透明的方式 settextcolor(LIGHTBLUE);//颜色为青蓝 outtextxy(560, 20, "分数:"); outtextxy(580 + 30, 20, grade);}void pauseMoment(){ if (_getch() == 32)//空格暂停 { while (_getch() != 32); }}

```

你用的什么编译器?看着像Visual Studio ,我用的Visual Studio 2022(win 10 系统),没有出现你的第一个问题(我这里是程序启动后,黑窗口闪了一下就消失了!!)。如果你也是vs2022,可能是项目属性设置的问题。尝试以下几种方法:
(1)把main函数中的 hwnd = initgraph(640, 480); 改成 hwnd = initgraph(640, 480,0); 清理项目,重新生成,运行。
(2)如果(1)不可以,参考下面链接中的方法。

第2个、第3个问题给你修改了。圈出来了加速部分,以及关闭时的二次询问窗口。
下面是我的运行截图:

img

代码修改如下:

#undef UNICODE#undef _UNICODE //为了使用outtextxy函数
#define _CRT_SECURE_NO_WARNINGS //为了使用sprintf函数
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <time.h> //随机函数头文件
#include <graphics.h> //easyx里的头文件
/********************** 坐标属性* 蛇属性* 食物属性**********************/
typedef struct pointXY//坐标属性
{
    int x;
    int y;
}MYPOINT;
struct Snake
{
    int num;//节数 
    MYPOINT xy[100];//蛇最多100节 
    char postion;//方向
}snake;
struct Food
{
    MYPOINT fdxy;//食物的x,y坐标 
    int eatgrade;
    int flag;
}food;
HWND hwnd = NULL;//表示主窗口
enum movPostion
{
    UP = 72,
    DOWN = 80,
    LEFT = 75,
    RIGHT = 77
};
void initSnake();//初始化蛇
void drawSnake();//画蛇
void moveSnake();//移动蛇
void keyDown();//按键处理
void initFood();
void drawFood();
void eatFood();
void showGrade();//展示分数
int snakeDie();//蛇死掉
void pauseMoment();//暂停函数
int end_mode(HWND startwindow);//结束模块
int g_nmb = 0; //吃了多少个
int g_sleep = 200; //初始化移动间隔

int main()//int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) //游戏程序的主体部分
{
    srand((unsigned int)time(NULL));//随机函数种子 
    hwnd = initgraph(640, 480,0);
    setbkcolor(WHITE);//设置窗口颜色 
    initSnake();
    while (1)
    {
        cleardevice();//刷新 
        if (food.flag == 0)
        {
            initFood();
        }
        drawFood();
        drawSnake();
        if (snakeDie())
        {
            if (end_mode(hwnd))
                break;
            else
                initSnake(); 
        }
        eatFood();
        showGrade();
        moveSnake();
        while (_kbhit())
        {
            pauseMoment();
            keyDown();
        }
        Sleep(g_sleep);//多少ms移动一单位 
    }
    //getchar();//防止闪退 
    closegraph();
    return 0;
}
void initSnake()
{
    snake.xy[2].x = 0;
    snake.xy[2].y = 0;
    snake.xy[1].x = 10;
    snake.xy[1].y = 0;
    snake.xy[0].x = 20;
    snake.xy[0].y = 0;
    snake.num = 3;
    snake.postion = RIGHT;
    food.flag = 0; food.eatgrade = 0;
}
void drawSnake()
{
    for (int i = 0; i < snake.num; i++)
    {
        setlinecolor(BLACK);//矩形边框颜色黑色 
        setfillcolor(RGB(rand() % 255, rand() % 255, rand() % 255));//炫彩蛇 
        fillrectangle(snake.xy[i].x, snake.xy[i].y, snake.xy[i].x + 10, snake.xy[i].y + 10); //画矩,写形左上与右下的坐标 
    }
}

void moveSnake()
{
    //除了第一节,后的每一节都是前面的坐标 
    for (int i = snake.num - 1; i > 0; i--)
    {
        snake.xy[i].x = snake.xy[i - 1].x;
        snake.xy[i].y = snake.xy[i - 1].y;
    }
    //第一节处理
    switch (snake.postion)
    {
    case RIGHT:
        snake.xy[0].x += 10;
        break;
    case LEFT:
        snake.xy[0].x -= 10;
        break;
    case DOWN:
        snake.xy[0].y += 10;
        break;
    case UP:
        snake.xy[0].y -= 10;
        break;
    default: break;
    }
}

void keyDown()
{
    char userkey = 0;
    userkey = _getch();
    switch (userkey)
    {
    case RIGHT:
        if (snake.postion != LEFT)
            snake.postion = RIGHT;
        break;
    case LEFT:
        if (snake.postion != RIGHT)
            snake.postion = LEFT;
        break;
    case DOWN:
        if (snake.postion != UP)
            snake.postion = DOWN;
        break;
    case UP:
        if (snake.postion != DOWN)
            snake.postion = UP;
        break;
    }
}
void initFood()//食物的设计
{
    food.fdxy.x = rand() % 65 * 10;//产生食物坐标为10的倍数 
    food.fdxy.y = rand() % 48 * 10; food.flag = 1;//食物存在
    //如果食物出现在蛇身上,食物重新生成
    for (int i = 0; i < snake.num; i++)
    {
        if (food.fdxy.x == snake.xy[i].x && food.fdxy.y == snake.xy[i].y)
        {
            food.fdxy.x = rand() % 65 * 10; food.fdxy.y = rand() % 48 * 10;
        }
    }
}
void drawFood()
{
    setlinecolor(BLACK);
    setfillcolor(RGB(rand() % 255, rand() % 255, rand() % 255));
    fillrectangle(food.fdxy.x, food.fdxy.y, food.fdxy.x + 10, food.fdxy.y + 10);
}
void eatFood()
{
    //蛇边长,分数增加,食物重新生成 
    if (snake.xy[0].x == food.fdxy.x && snake.xy[0].y == food.fdxy.y)
    {
        snake.num++; food.eatgrade += 10; food.flag = 0;

        g_nmb++;
        if (g_nmb % 5 == 0)
        {
            if (g_sleep > 100) //设置最快速度
                g_sleep -= 20; //每吃5个,速度加快20ms
        }
        if (g_nmb >= 1000)
            g_nmb = 0;
    }
}
int snakeDie()
{
    if (snake.xy[0].x > 640 || snake.xy[0].x < 0 || snake.xy[0].y>480 || snake.xy[0].y < 0)
    {
        outtextxy(200, 200, "你撞墙了");
        MessageBox(hwnd, "Gameover!", "撞墙警告", MB_OK);
        return 1;//返回1结束 
    }
    for (int i = 1; i < snake.num; i++)
    {
        if (snake.xy[0].x == snake.xy[i].x && snake.xy[0].y == snake.xy[i].y)
        {
            outtextxy(200, 200, "你撞自己了");
            MessageBox(hwnd, "Gameover!", "自杀警告", MB_OK); 
            return 1;
        }
    }
    return 0;
}
void showGrade()
{
    char grade[100] = "0"; sprintf(grade, "%d", food.eatgrade);//将整形转化为字符串 
    setbkmode(TRANSPARENT);//设置为透明的方式 
    settextcolor(LIGHTBLUE);//颜色为青蓝 
    outtextxy(560, 20, "分数:");
    outtextxy(580 + 30, 20, grade);
}
void pauseMoment()
{
    if (_getch() == 32)//空格暂停 
    {
        while (_getch() != 32);
    }
}


int end_mode(HWND startwindow)//结束模块
{
    int answer = MessageBox(startwindow, "是否结束游戏?", "贪吃蛇", MB_OKCANCEL);//添加选择框内容
    if (answer == IDOK)
    {
        closegraph();//结束游戏
        return 1;
    }
    else if (answer == IDCANCEL)//回到游戏界面
    {
        return 0;
    }
    return 0;
}

参考GPT和自己的思路:好的,我会尽力回答你的问题。

  1. 关于点击黑框控制和关闭黑框结束的问题,我建议你将游戏的代码嵌入到一个窗口程序中。这样,你就可以自己设计一个窗口来控制游戏的启停和结束了。可以参考一下Win32 API或者MFC框架。

  2. 要实现吃5个食物后自动加速,你可以在吃掉第5个食物的时候,将每次移动的时间间隔缩短一半,然后在吃掉第10个食物,第15个食物的时候,继续缩短时间间隔。你可以设置一个变量来记录当前游戏的状态,根据状态来调整时间间隔。

  3. 要实现游戏结束后点击确认关闭程序,你可以在游戏结束时,弹出一个提示框,询问玩家是否退出程序。可以使用Win32 API的MessageBox函数来实现。如果玩家选择是,就调用exit函数退出程序,如果选择否,就返回游戏界面。

  • 这篇博客: 现代操作系统 第二章 进程与线程 习题中的 36.一个快餐店有四类雇员:(1) 领班,接收顿客点的菜单;(2)厨师,准备饭菜;(3)打包工,将饭菜装在袋子里;(4) 收银员,将食品袋交给顾客并收钱。每个雇员可被看作一个进行通信的顺序进程。它们采用的进程间通信方式是什么?请将这个模型与UNIX中进程联系起来。 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • A:雇员之间通过消息传递进行通信:在该例中,消息为订单、食物和袋子。在UNIX中,该4个进程通过管道连接。


  • 以下回答由chatgpt基于相关博客总结生成:

    回答:

    针对优化贪吃蛇游戏:

    1. 解决控制游戏需要点击黑框的问题,可以通过给游戏窗口添加事件监听器来实现。具体实现可以使用Python的Pygame模块或者Java的AWT/Swing等GUI库,根据具体的开发语言和框架不同而异。

    2. 关于关闭游戏需要关闭黑框的问题,在游戏结束时添加一个按钮或者键盘事件来触发退出游戏的功能。在Pygame中,可以通过检测QUIT事件或者打开窗口时返回的QUIT变量来关闭游戏窗口。在Java中,可以通过调用窗口的dispose()方法或者System.exit()方法来退出游戏。

    3. 关于实现吃5个食物后自动加速的功能,可以通过控制游戏帧率来实现。在Pygame中,可以使用clock对象来控制帧率,每吃到一定数量的食物后就调用clock对象的tick()方法来提高帧率。在Java中,可以使用Timer对象来控制帧率,同样可以在吃到一定数量的食物后设置Timer对象的延迟时间来提高帧率。

    针对判断当前机器的大小端:

    可以使用一个函数来判断当前机器的大小端。首先声明一个整型变量a,并将其赋值为1。然后将a的地址强制转换成char类型的指针,并通过指针访问内存中的第一个字节,判断第一个字节的内容即可确定当前机器的大小端。

    代码如下(C语言实现):

    int check_system() { int a = 1; char p = (char )&a; return (int)*p; }

    该函数返回值为1表示小端字节序,返回值为0表示大端字节序。

    针对贪吃蛇游戏中的逻辑:

    1. 在蛇吃到食物时,需要将新的节点插入到链表的尾部来增加蛇的长度。在移动蛇的时候,只需要新增一个节点,不需要删除原来的节点。

    2. 吃完食物后,食物不应该消失,应该在屏幕上重新生成一个新的食物。

    3. 当蛇碰到墙壁或者自己的身体时,应该重新初始化蛇的位置和长度,而不是直接结束游戏。

    代码如下(C语言实现):

    void moveSnake() { addNode(); // 增加节点显示贪吃蛇身体 if(hasFood()) { initFood(); // 生成新的食物 } else { // 不删除节点,保持蛇的长度不变 } if(ifSnakeDie()) { initSnake(); // 重新初始化蛇的位置和长度 } }

    在Python中使用Pygame库或者Java中使用AWT/Swing等GUI库可以实现更加丰富的游戏交互逻辑,可以参考官方文档进行学习和开发。

您好,我是有问必答小助手,您的问题已经有小伙伴帮您解答,感谢您对有问必答的支持与关注!
PS:问答VIP年卡 【限时加赠:IT技术图书免费领】,了解详情>>> https://vip.csdn.net/askvip?utm_source=1146287632