```
你用的什么编译器?看着像Visual Studio ,我用的Visual Studio 2022(win 10 系统),没有出现你的第一个问题(我这里是程序启动后,黑窗口闪了一下就消失了!!)。如果你也是vs2022,可能是项目属性设置的问题。尝试以下几种方法:
(1)把main函数中的 hwnd = initgraph(640, 480); 改成 hwnd = initgraph(640, 480,0); 清理项目,重新生成,运行。
(2)如果(1)不可以,参考下面链接中的方法。
第2个、第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 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和自己的思路:好的,我会尽力回答你的问题。
关于点击黑框控制和关闭黑框结束的问题,我建议你将游戏的代码嵌入到一个窗口程序中。这样,你就可以自己设计一个窗口来控制游戏的启停和结束了。可以参考一下Win32 API或者MFC框架。
要实现吃5个食物后自动加速,你可以在吃掉第5个食物的时候,将每次移动的时间间隔缩短一半,然后在吃掉第10个食物,第15个食物的时候,继续缩短时间间隔。你可以设置一个变量来记录当前游戏的状态,根据状态来调整时间间隔。
要实现游戏结束后点击确认关闭程序,你可以在游戏结束时,弹出一个提示框,询问玩家是否退出程序。可以使用Win32 API的MessageBox函数来实现。如果玩家选择是,就调用exit函数退出程序,如果选择否,就返回游戏界面。
A:雇员之间通过消息传递进行通信:在该例中,消息为订单、食物和袋子。在UNIX中,该4个进程通过管道连接。
回答:
针对优化贪吃蛇游戏:
解决控制游戏需要点击黑框的问题,可以通过给游戏窗口添加事件监听器来实现。具体实现可以使用Python的Pygame模块或者Java的AWT/Swing等GUI库,根据具体的开发语言和框架不同而异。
关于关闭游戏需要关闭黑框的问题,在游戏结束时添加一个按钮或者键盘事件来触发退出游戏的功能。在Pygame中,可以通过检测QUIT事件或者打开窗口时返回的QUIT变量来关闭游戏窗口。在Java中,可以通过调用窗口的dispose()方法或者System.exit()方法来退出游戏。
关于实现吃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表示大端字节序。
针对贪吃蛇游戏中的逻辑:
在蛇吃到食物时,需要将新的节点插入到链表的尾部来增加蛇的长度。在移动蛇的时候,只需要新增一个节点,不需要删除原来的节点。
吃完食物后,食物不应该消失,应该在屏幕上重新生成一个新的食物。
当蛇碰到墙壁或者自己的身体时,应该重新初始化蛇的位置和长度,而不是直接结束游戏。
代码如下(C语言实现):
void moveSnake() { addNode(); // 增加节点显示贪吃蛇身体 if(hasFood()) { initFood(); // 生成新的食物 } else { // 不删除节点,保持蛇的长度不变 } if(ifSnakeDie()) { initSnake(); // 重新初始化蛇的位置和长度 } }
在Python中使用Pygame库或者Java中使用AWT/Swing等GUI库可以实现更加丰富的游戏交互逻辑,可以参考官方文档进行学习和开发。