简易的贪吃蛇游戏

本文档描述了一个使用C语言在Visual C++ 6.0环境下编写的贪吃蛇游戏程序。项目目标包括实现蛇的生命周期、分数统计和死亡判断。游戏设计中,蛇在限定区域内移动,吃食物增加分数,碰到边框或自身则死亡。文章详细介绍了游戏的整体设计、流程、结构体定义以及各个功能模块,如界面初始化、蛇的移动、食物生成和死亡判断等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

项目基本分析

1.项目目标:

通过参考文献《贪吃蛇游戏用户开发与使用》文献和参考网上代码,编写一个能够在Visual C++ 6.0环境下运行的贪吃蛇游戏程序。

2.项目功能:

包括以下几个方面:蛇的生命周期、分数统计、是否死亡。

  1. 蛇的运动范围是在边框内,这里我想用坐标来限制,周期的话就是蛇的长度;
  2. 分数统计就直接定义一个数来储存,然后但蛇吃到食物的时候就更新分数;
  3. 死亡情况的话,有两种:一是碰到边框,二是碰到自己

一.整体设计

  1. 函数分快

  1. 主函数

int main()
{
//打印初始化界面
    printf_JM();
    printf_snake();
    printf_foot();
  while(1)
  {
   YX();   //运行
   if (!died())  
		break;   //如果死了就跳出while(1)循环
   creatfood();   //判断是否是否被吃,然后产生食物
   control_xy(82,5);     
   printf("sorce:%d\n",sorce);
   Sleep(snake.speed);//变速
  }
  control_xy(30, 26);
	printf("Game Over!\n");
	control_xy(40, 26);
	printf("本次游戏得分为:%d\n", sorce);
	Sleep(500);
  return 0;
}

一.详细流程

1.整体流程

2.各模块流程

  • 用结构体定义属性
  • 初始化界面
  •  移动蛇
  • 判断食物是否产生
  • 死亡情况

 

 四.公用结构体说明

1.coord函数的用法:

来自<Windows.h>里的一个函数

作用:表示文字在控制台的坐标,俗称坐标结构

//将光标移到控制台的(x,y)位置
void control_xy(int x, int y)
{
    COORD coord;
    coord.X = x;
    coord.Y = y;
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}

 2.定义食物、蛇的属性

//食物的坐标
struct
{
   int x;  //前边已经有过光标在控制台的定义的函数,所以这里的坐标只需要用x和y来就好
   int y;
}food;

//蛇的属性
struct 
{
  int speed;//蛇的速度
  int len;//蛇的长度
  int x[snakesize];//蛇的每一节的坐标
  int y[snakesize];//
}snake;
 

3.申明全局变量宏定义

#define snakesize 100  //蛇的最长长度
#define width 78     //主边框宽度
#define total 108   //总宽
#define height 24   //主边框高度
#define width1 30   //显示分数的边框宽度

int i;
int sorce; //来记录学生的分数
int PD;    //来判断食物是不是被蛇吃掉了
int key=72;   /*来存键值,一开始默认方向向上
                上:72
                下:80
                左:75
                右:77
                */

五.各函数模块

1.界面的初始化

//打印原始游戏界面
void printf_JM()
{     
	 //打印上下边框
	for (i = 0; i <= total; i += 2)//i+=2是因为横向占用的是两个位置
	{
		control_xy(i, 0);
		printf("■");
		control_xy(i, height);
		printf("■");
	}

	//打印左右边框
	for (i = 1; i < height; i++)
	{
		control_xy(0, i);//第一条
		printf("■");
		control_xy(width, i);//第二条
		printf("■");
		control_xy(total, i);//第三条
		printf("■");
	}

	//在第二个边框输出分数和规则
    //control_xy(82,5);
	//printf("sorce:%d",sorce);
    control_xy(82,8);
	printf("【游戏规则】");
	control_xy(82,10);
	printf("键盘上的方向键控制蛇运动");
	control_xy(82,12);
	printf("吃到一个食物得10分");
	control_xy(82,14);
	printf("当蛇碰到边框或蛇身则死亡\n");
	
}


  //打印蛇身
void printf_snake()
{
	//初始化蛇的属性
	snake.len = 3;
	snake.speed = 200;

	//在屏幕中间生成蛇头
	snake.x[0] = width / 2 + 1;//x坐标为偶数
	snake.y[0] = height / 2;

	//打印蛇头
	control_xy(snake.x[0], snake.y[0]);
	printf("■");

	//生成初试的蛇身
	for (i = 1; i < snake.len; i++)
	{
		//蛇身的打印,纵坐标不变,横坐标为上一节蛇身的坐标值+2
		snake.x[i] = snake.x[i - 1] + 2;
		snake.y[i] = snake.y[i - 1];
		control_xy(snake.x[i], snake.y[i]);
		printf("■");
	}
	control_xy(width / 2, 10);
	return;
}
//随机生成食物
void printf_foot()
{
    // printf_JM();
     //printf_snake();
     while (1)
	 {
		srand((unsigned int)time(NULL));        //利用srand函数随机产生坐标
		food.x = rand() % (width - 4) + 2;   
		food.y = rand() % (height - 2) + 1;
		if (food.x % 2 == 0)
			break;
	 }

      //将光标移到食物的坐标处打印食物
	 control_xy(food.x,food.y);
     printf("■");

	 //打印完食物后将光标移到屏幕最下方,避免光标在蛇身处一直闪烁
	control_xy(width - 2, 27);
	return;
}

2.开始运行,通过方向键移动蛇身

void YX()
{
	int pre_key = key;//用来存放前一个键值,因为蛇移动的值不能和原来的相反,所以要根据这个去判断
	if (_kbhit())
	{
		fflush(stdin);//清空缓冲区的字符
		key = _getch();//返回0或者224
		key = _getch();//返回实际值
	}
	//如果食物没有被次,这蛇尾消除
	if (PD == 0)
	{
		control_xy(snake.x[snake.len - 1], snake.y[snake.len - 1]);
		printf("  ");//在蛇尾处输出空格即擦去蛇尾
	}
	for (i = snake.len - 1; i > 0; i--)
	{
		snake.x[i] = snake.x[i - 1];
		snake.y[i] = snake.y[i - 1];
	}
	//蛇当前移动的方向不能和前一次的方向相反,比如蛇往左走的时候不能直接按右键往右走
	//如果当前移动方向和前一次方向相反的话,把当前移动的方向改为前一次的方向
	if (pre_key == 72 && key == 80)
		key = 72;
	if (pre_key == 80 && key == 72)
		key = 80;
	if (pre_key == 75 && key == 77)
		key = 75;
	if (pre_key == 77 && key == 75)
		key = 77;
	//判断蛇头应该往哪个方向移动
	switch (key)
	{
	case 75:
		snake.x[0] -= 2;//往左
		break;
	case 77:
		snake.x[0] += 2;//往右
		break;
	case 72:
		snake.y[0]--;//往上
		break;
	case 80:
		snake.y[0]++;//往下
		break;
	}
	control_xy(snake.x[0], snake.y[0]);	//打印出蛇头
	printf("■");
	control_xy(width - 2, 0);
	PD = 0;//由于目前没有吃到食物,PD值为0
	return;
}

 5.是否重生成食物

void creatfood()
{
  	if (snake.x[0] == food.x && snake.y[0] == food.y)//蛇头碰到食物
	{
		//蛇头碰到食物即为要吃掉这个食物了,因此需要再次生成一个食物
		while (1)
		{
			int flag = 1;
			srand((unsigned int)time(NULL));
			food.x = rand() % (width - 4) + 2;
			food.y = rand() % (height - 2) + 1;

			//随机生成的食物不能在蛇的身体上
			for (i = 0; i < snake.len; i++)
			{
				if (snake.x[i] == food.x && snake.y[i] == food.y)
				{
					flag = 0;
					break;
				}
			}
			if (flag && food.x % 2 == 0)
				break;
		}

		//绘制食物
		control_xy(food.x, food.y);
		printf("■");
		snake.len++;//吃到食物,蛇身长度加1
		sorce += 10;//每个食物得10分
		snake.speed -= 5;变速
	    PD = 1;
	}
	return;
}

6.蛇死亡情况

//蛇死亡情况
bool died()
{
	if (snake.y[0] == 0 || snake.y[0] == height)//上下边界
		return 0;
	if (snake.x[0] == 0 || snake.x[0] == width)//左右边界
		return 0;
	for (i = 1; i < snake.len; i++)//自己碰自己
	{
		if (snake.x[i] == snake.x[0] && snake.y[i] == snake.y[0])
			return 0;
	}
	return 1;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值