用Visual Studio做的贪吃蛇,为啥我的贪吃蛇的食物会出现两个,但是有一个就是闪一下就消失,还有我的弹出窗口有时候要点击两次或者三次才能进行下一步操,请问这些bug该怎么解决?
#include<stdio.h>
#include<graphics.h>
#include<time.h>
#include<conio.h>//使用getch()
#include<windows.h>//这个头文件要放在graphics.h的下面
#include<mmsystem.h>//包含多媒体设备接口头文件,用于播放音乐
#pragma comment(lib,"winmm.lib")//加载静态库
static unsigned int count;//用于判断蛇的速度等级
unsigned int speed;//蛇的具体速度,用于控制Sleep函数
#define MAX_Snake_Size 200
#define _CRT_SECURE_NO_WARNINGS
unsigned int Gameflag;//游戏运行情况,1表示正在运行,0表示暂停
unsigned int Musicflag;//音乐播放状态,1正在播放,0暂停播放
unsigned int Snakeflag;//蛇的状态,1表示存活,0表示死亡
enum
{
UP, DOWN, LEFT, RIGHT
};
//建立简单的蛇结构
struct Snake
{
int size;//蛇的节数
int speed;//蛇每个单位的速度
int dir;//蛇的方向
POINT coor[MAX_Snake_Size];//蛇每个单位的坐标coordinate
}snake;
//建立简单食物结构
struct Food
{
int x;//食物的x轴坐标
int y;//y坐标
int r;//食物尺寸大小
bool flag;//食物的状态,存在为true,被吃为false
int score;//分数
}food;
//游戏初始化
void InitGame()
{
srand((unsigned int)time(NULL));
//初始化游戏状态
Gameflag = 1;
//Musicflag = 1;
Snakeflag = 1;
//初始化蛇
snake.size = 3;
snake.speed = 10;
snake.dir = RIGHT;
for (int i = 0; i < snake.size; i++)
{
snake.coor[i].x = 40 - 10 * i;
snake.coor[i].y = 10;
}
snake.coor[0].x += snake.speed;
//初始化食物
food.x = rand() % 295 + 5;
food.y = rand() % 295 + 5;
food.r = rand() % 7 + 5;
//设立一个值表示食物的状态
food.flag = 0;//flag为1的时候是食物存在窗口内,0的时候是被吃掉了
food.score = 0;//起始得分为0
//蛇初始吃的食物数量
count = 0;
}
//绘制图形
void DrawGame()
{
BeginBatchDraw();
setbkcolor(WHITE);//建立窗口底色
cleardevice();
//绘制蛇
setfillcolor(GREEN);
for(int i = 0; i < snake.size; i++)
{
solidcircle(snake.coor[i].x, snake.coor[i].y, 5);
}
//EndBatchDraw();
//绘制食物
if (food.flag)
{
setfillcolor(GREEN);
solidcircle(food.x, food.y, food.r);
}
//绘制记分系统
setfillcolor(LIGHTBLUE);
solidrectangle(300, 0, 400, 300);
char score[100];
sprintf_s(score, "%d", food.score);//因为我们的分数是int类型,而我们outtextxy在窗口上输出的是char类型,所以要使用sprintf去把会时刻变化的int类型数改变为char类型
setbkmode(TRANSPARENT);
settextcolor(BLACK);
outtextxy(320, 20, "得分:");
outtextxy(370, 20, score);
//绘制提示语录
char arr1[15] = "提示信息:";
char arr2[15] = "Esc键 退出";
char arr3[18] = "空格键 暂停";
settextstyle(18, 0, "楷体");
outtextxy(310, 50, arr1);
outtextxy(305, 80, arr2);
outtextxy(300, 110, arr3);
FlushBatchDraw();
}
//游戏运行
void MoveGame()
{
//蛇的移动
for (int i = snake.size - 1; i > 0; i--)
{
snake.coor[i] = snake.coor[i - 1];
}
//下面标注的是另一种移动方式,但是我还没有解决让他自己移动的问题
/if (GetAsyncKeyState(VK_UP))
{
snake.coor[0].y -= snake.speed;
if (snake.coor[0].y <= 0)
snake.coor[0].y = 300;
}
if (GetAsyncKeyState(VK_DOWN))
{
snake.coor[0].y += snake.speed;
if (snake.coor[0].y >= 300)
snake.coor[0].y = 0;
}
if (GetAsyncKeyState(VK_LEFT))
{
snake.coor[0].x -= snake.speed;
if (snake.coor[0].x <= 0)
snake.coor[0].x = 300;
}
if (GetAsyncKeyState(VK_RIGHT))
{
snake.coor[0].x += snake.speed;
if (snake.coor[0].x >= 300)
snake.coor[0].x = 0;
}/
switch (snake.dir)
{
case DOWN:
snake.coor[0].y += snake.speed;
if (snake.coor[0].y >= 300)
snake.coor[0].y = 0;
break;
case UP:
snake.coor[0].y -= snake.speed;
if (snake.coor[0].y <= 0)
snake.coor[0].y = 300;
break;
case LEFT:
snake.coor[0].x -= snake.speed;
if (snake.coor[0].x <= 0)
snake.coor[0].x = 300;
break;
case RIGHT:
snake.coor[0].x += snake.speed;
if (snake.coor[0].x >= 300)
snake.coor[0].x = 0;
break;
}
//食物的移动
if (snake.coor[0].x - food.x <= food.r && food.x - snake.coor[0].x <= food.r && snake.coor[0].y - food.y <= food.r && food.y - snake.coor[0].y <= food.r)
{
snake.size++;
food.flag = 0;
count++;
food.score += 10;
}
if (food.flag == 0)
{
food.x = rand() % 295 + 5;
food.y = rand() % 295 + 5;
food.r = rand() % 7 + 5;
food.flag = 1;
}
//控制蛇的死亡
for (int i = 1; i < snake.size; i++)//如果蛇碰到自己就死
{
if (snake.coor[0].x == snake.coor[i].x && snake.coor[0].y == snake.coor[i].y)
Snakeflag = 0;
//绘制蛇死亡时的弹出窗口
if (Snakeflag == 0)
{
HWND window_control = GetHWnd();
printf("\a");
int isok=MessageBox(NULL, "你已死亡,点击确认重新开始,点击取消关闭游戏游戏", "游戏提示:", MB_OKCANCEL);
if (isok == IDOK);//选择了OK
if (isok == IDCANCEL)//选择了CANCEL
{
closegraph();
Gameflag = 0;
}
}
}
}
//播放音乐
void BGM()
{
mciSendString("open ./贪吃蛇背景音乐.mp3", 0, 0, 0);
if (Musicflag == 1)
{
mciSendString("play ./贪吃蛇背景音乐.mp3 repeat", 0, 0, 0);
}
if (Musicflag == 0)
{
mciSendString("close ./贪吃蛇背景音乐.mp3", 0, 0, 0);
mciSendString("stop ./贪吃蛇背景音乐.mp3 repeat", 0, 0, 0);
}
}
//键盘参数
void KeySystem()
{
if (_kbhit())
{
switch (_getch())
{
case 72:
case 'w':
case 'W':
if (snake.dir != DOWN)
snake.dir = UP;
break;
case 80:
case 's':
case 'S':
if (snake.dir != UP)
snake.dir = DOWN;
break;
case 75:
case 'a':
case 'A':
if (snake.dir != RIGHT)
snake.dir = LEFT;
break;
case 77:
case 'd':
case 'D':
if (snake.dir != LEFT)
snake.dir = RIGHT;
break;
case 27://加中括号的目的是避免default造成的无法读取window_control数值初始化问题
{
closegraph();
HWND window_control = GetHWnd();
printf("\a");
MessageBox(window_control, "游戏结束", "游戏提示:",MB_OKCANCEL);
Musicflag = 0;
Gameflag = 0;
break;
}
case ' ':
{
HWND window_control = GetHWnd();
printf("\a");
MessageBox(window_control, "游戏暂停", "游戏提示:", MB_OKCANCEL);
Musicflag = 0;
break;
}
default:snake.dir = snake.dir; break;
}
}
}
//蛇的速度控制
void snake_speed()
{
if (count < 10)
speed = 200 - count * 5;
else if (count < 20)
speed = 155 - (count - 10) * 4;
else if (count < 30)
speed = 119 - (count - 10) * 3;
else if (count < 40)
speed = 92 - (count - 10) * 2;
else
speed = speed;
}
int main()
{
initgraph(400, 300, SHOWCONSOLE);
InitGame();
while (Gameflag)
{
InitGame();
while(1)
{
KeySystem();
//BGM();
MoveGame();
DrawGame();
snake_speed();
Sleep(speed);
if (Snakeflag == 0)
break;
if (Gameflag == 0)
break;
}
rewind(stdin);
}
return 0;
}