C/C++制作简易版贪吃蛇游戏

C/C++制作简易版贪吃蛇游戏

一、开发环境

使用Visual Stdio 2019,Visual Studio即可生成基于本机和托管基于MSBuild的应用程序的工具。安装此程序时,可以选择安装C ++编译器和库。

二、设计逻辑

请添加图片描述
蛇身体初始有三节,记录对应的蛇每一节的x和y坐标.通过键盘来控制蛇的身体的坐标的相应变化,从而在屏幕上呈现蛇的身体移动。食物将通过随机数来产生相应的食物坐标。

三、代码块

3.1 使用initgraph()函数

初始化屏幕大小 在有文件#include<graphics.h>下使用initgraph()函数对屏幕显示的大小和颜色进行调整。

`void Initialization_show()
{
	initgraph(HEIGHT, WEIGHT);/*设置屏幕大小*/
	
}`

​其中的WEIGHT和WEIGHT是我对高度和宽度进行的宏定义,这里也可以直接输入整形变量。因为graphics.h是tc所特有的函数库,在vc和vs中是没有的,所以要借助插件Easyx图形库。
1、打开官网http://www.easyx.cn,选择下载
2、下载好后点击打开,它会自动识别vs2019的,然后按照下图操作
请添加图片描述

3.2定义蛇和食物的结构体


	//蛇的结构
struct Snake
{
public:
	int size;
	int dir;
	int speed;
	POINT coor[MAX];
};

//食物的结构
struct Snake_Food
{
public:
	int Food_x;
	int Food_y;
	int Food_r;/*食物大小*/
	bool Food_flag;/*判断被吃条件*/
	DWORD Food_color;/*食物颜色*/
};

蛇和食物将通过绘制圆的方法实现,需要的是圆的半径和对应的圆心坐标,同样食物也是如此。其中蛇的身体需要定义有多少段,食物则定义了颜色和判断被吃条件。

3.3随机产生食物的坐标以及定义初始化的蛇的数据

Snake snake;
Snake_Food food;
void Food_Property()
{
	srand((int)time(0));
	food.Food_r = rand() % 10 + 5;
	food.Food_x = rand() % (HEIGHT - food.Food_r);
	food.Food_y = rand() % (WEIGHT - food.Food_r);
	food.Food_color = RGB(rand() % 256, rand() % 256, rand() % 256);
	food.Food_flag = true;
}

void Initialization_data()
{
	snake.size = 3;
	snake.speed =10;
	snake.dir=RIGHT;
	//初始化食物 rand()随机产生一个整数
	Food_Property();
	for (int i=0; i <snake.size;i++)
	{
		snake.coor[i].x =40-10*i;
		snake.coor[i].y = 10;
	}

}

随机数可以是用#include <time.h>头文件下的rank和srand函数,
其中 srand((int)time(0));  // 产生随机种子,
rank()%(数字m),表示对产生的随机数进行区域,来控制随机数的上限。

3.3绘制对象

void GameDraw()
{
	/*双缓冲绘制*/
	BeginBatchDraw();
	setbkcolor(RGB(28, 115, 119));/*设置颜色*/
	cleardevice();
	setfillcolor(RED);/*蛇的颜色*/
   //绘制食物
	if (food.Food_flag )
	{
		solidcircle(food.Food_x,food.Food_y,food.Food_r);
	}

	for (int i=0;i<snake.size;i++)
	{
		solidcircle(snake.coor[i].x, snake.coor[i].y, 5);
	}
	EndBatchDraw();
}
通过使用GameDraw()函数对蛇和食物进行绘制。

3.4 食物被吃和产生新的食物

void Eat_Food()
{

	if (food.Food_x - food.Food_r <= snake.coor[0].x && snake.coor[0].x <= food.Food_x + food.Food_r &&
		food.Food_y - food.Food_r <= snake.coor[0].y && snake.coor[0].y <= food.Food_y + food.Food_r &&
		food.Food_flag)

	{
		food.Food_flag = false;
		snake.size ++;
	}
	if (food.Food_flag == false)
	{
		Food_Property();
	}
}

判断蛇头的坐标是否在食物构成的圆类,当蛇头坐标到达圆内同时食物还未被吃将执行蛇身体加长,重新调用食物属性函数随机产生食物。

3.5 按键控制

enum DIR
{
	UP,
	DOWN,
	LEFT,
	RIGHT,
};

void keyControl_S()/*不可调转*/
{
	if (_kbhit()) /*判断有没有按键按下*/
	{


		switch (_getch())
		{
		case'W':
		case'w':
		case 72:if(snake.dir !=DOWN)
			    snake.dir = UP;
			    break;
		case'S':
		case's':
		case 80:if(snake.dir!=UP)
			    snake.dir = DOWN;
			    break;
		case'A':
		case'a':
		case 75:if(snake.dir != RIGHT)
			     snake.dir = LEFT;
			     break;
		case'D':
		case'd':
		case 77:if (snake.dir != LEFT)
			    snake.dir = RIGHT;
			    break;
		case ' ':
			     while (true)
			     {
					 if (_getch() == ' ')
					 {
						 return;
					 }
				 }
				 break;
		}
	}
}
通过使用按键按下的字符,给蛇方向变量进行赋值,枚举定义四个方向变量。

3.6 蛇的移动


void SnakeMove_Nodead()/*可以穿墙不死*/
{
	int times = 200;

	for (int i = snake.size - 1; i > 0; i--)/*身体跟着头移动*/
	{
		snake.coor[i] = snake.coor[i - 1];
	}switch (snake.dir)
	{
	case RIGHT:
		snake.coor[0].x += snake.speed;
		if (snake.coor[0].x - 10 >= HEIGHT)
		{
			snake.coor[0].x = 0;
		}
		Sleep(times);
		break;
	case LEFT:
		snake.coor[0].x -= snake.speed;
		if (snake.coor[0].x + 10 <= 0)
		{
			snake.coor[0].x = HEIGHT;
		}
		Sleep(times);
		break;
	case UP:
		snake.coor[0].y -= snake.speed;
		if (snake.coor[0].y+10 <= 0)
		{
			snake.coor[0].y = WEIGHT;
		}
		Sleep(times);
		break;
	case DOWN:
		snake.coor[0].y += snake.speed;
		if (snake.coor[0].y - 10 >= WEIGHT)
		{
			snake.coor[0].y = 0;
		}
		Sleep(times);
		break;
	}

}

通过刷新坐标对蛇进行移动,对按键获取到的键执行对应的坐标变换操作,对蛇头坐标变换后,蛇第二节取得之前蛇头坐标,蛇的第三节取得第二节的坐标…,依次进行对坐标的刷新

四、源代码下载

#include<iostream>
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#include<graphics.h>
#include<time.h>
#include<mmsystem.h>
#pragma comment(lib,"winmm.lib")
#define MAX 500
#define HEIGHT 940
#define WEIGHT 580
using namespace std;

enum DIR
{
	UP,
	DOWN,
	LEFT,
	RIGHT,
};


void Initialization_show()/*初始化*/
{
	//mciSendString("open /Users/MI/Desktop/背景音乐/东京不太热.mp3   alias BGM", 0, 0, 0);
	//mciSendString("play BGM repeat", 0, 0, 0);
	initgraph(HEIGHT, WEIGHT/*,SHOWCONSOLE*/);/*设置屏幕大小*/
	//cout << "**********游戏开始***********" << endl;
}
//蛇的结构
struct Snake
{
public:
	int size;
	int dir;
	int speed;
	POINT coor[MAX];
};

//食物的结构
struct Snake_Food
{
public:
	int Food_x;
	int Food_y;
	int Food_r;/*食物大小*/
	bool Food_flag;/*判断被吃条件*/
	DWORD Food_color;/*食物颜色*/
};

Snake snake;
Snake_Food food;
void Food_Property()
{
	srand((int)time(0));
	food.Food_r = rand() % 10 + 5;
	food.Food_x = rand() % (HEIGHT - food.Food_r);
	food.Food_y = rand() % (WEIGHT - food.Food_r);
	food.Food_color = RGB(rand() % 256, rand() % 256, rand() % 256);
	food.Food_flag = true;
}
void Initialization_data()
{
	snake.size = 3;
	snake.speed =10;
	snake.dir=RIGHT;
	//初始化食物 rand()随机产生一个整数
	Food_Property();

	for (int i=0; i <snake.size;i++)
	{
		snake.coor[i].x =40-10*i;
		snake.coor[i].y = 10;
	}

}


void GameDraw()
{
	/*双缓冲绘制*/
	BeginBatchDraw();
	setbkcolor(RGB(28, 115, 119));/*设置颜色*/
	cleardevice();
	setfillcolor(RED);/*蛇的颜色*/
   //绘制食物
	if (food.Food_flag )
	{
		solidcircle(food.Food_x,food.Food_y,food.Food_r);
	}

	for (int i=0;i<snake.size;i++)
	{
		solidcircle(snake.coor[i].x, snake.coor[i].y, 5);
	}
	EndBatchDraw();
}

void Eat_Food()
{
	//cout << snake.coor[0].x << endl;
	//cout << food.Food_x << endl;
	if (food.Food_x - food.Food_r <= snake.coor[0].x && snake.coor[0].x <= food.Food_x + food.Food_r &&
		food.Food_y - food.Food_r <= snake.coor[0].y && snake.coor[0].y <= food.Food_y + food.Food_r &&
		food.Food_flag)

	{
		food.Food_flag = false;
		snake.size ++;
	}
	if (food.Food_flag == false)
	{
		Food_Property();
	}
}


//void SnakeMove()/*不能穿墙*/
//{
//	int times = 200;
//		
//	for (int i = snake.size - 1; i > 0; i--)/*身体跟着头移动*/
//		{
//			snake.coor[i] = snake.coor[i - 1];
//		}
//			switch(snake.dir)
//           {
//			case RIGHT:
//				       snake.coor[0].x+=snake.speed;
//				       Sleep(times);
//				       break;
//			case LEFT:
//				       snake.coor[0].x-=snake.speed;
//				       Sleep(times);
//				       break;
//			case UP:
//				       snake.coor[0].y-=snake.speed;
//				       Sleep(times);
//				       break;
//			case DOWN:
//				       snake.coor[0].y+=snake.speed;
//				       Sleep(times);
//				       break;
//
//		    }
//		
//
//	
//	
//}

void SnakeMove_Nodead()/*可以穿墙不死*/
{
	int times = 200;

	for (int i = snake.size - 1; i > 0; i--)/*身体跟着头移动*/
	{
		snake.coor[i] = snake.coor[i - 1];
	}
	switch (snake.dir)
	{
	case RIGHT:
		snake.coor[0].x += snake.speed;
		if (snake.coor[0].x - 10 >= HEIGHT)
		{
			snake.coor[0].x = 0;
		}
		Sleep(times);
		break;
	case LEFT:
		snake.coor[0].x -= snake.speed;
		if (snake.coor[0].x + 10 <= 0)
		{
			snake.coor[0].x = HEIGHT;
		}
		Sleep(times);
		break;
	case UP:
		snake.coor[0].y -= snake.speed;
		if (snake.coor[0].y+10 <= 0)
		{
			snake.coor[0].y = WEIGHT;
		}
		Sleep(times);
		break;
	case DOWN:
		snake.coor[0].y += snake.speed;
		if (snake.coor[0].y - 10 >= WEIGHT)
		{
			snake.coor[0].y = 0;
		}
		Sleep(times);
		break;
	}

}
//通过按键改变蛇的移动方向
//void keyControl()/*可以调转*/
//{
//	if (_kbhit()) /*判断有没有按键按下*/
//	{	
//	switch (_getch())
//	{
//	  case'W':
//	  case'w':
//	  case 72:snake.dir = UP;
//			  break;
//	  case'S':
//	  case's':
//	  case 80:snake.dir = DOWN;
//		      break;
//	  case'A':
//	  case'a':
//	  case 75:snake.dir = LEFT;
//		      break;
//	  case'D':
//	  case'd':
//	  case 77:snake.dir = RIGHT;
//		      break;
//	}
//	}
//}


void keyControl_S()/*不可调转*/
{
	if (_kbhit()) /*判断有没有按键按下*/
	{


		switch (_getch())
		{
		case'W':
		case'w':
		case 72:if(snake.dir !=DOWN)
			    snake.dir = UP;
			    break;
		case'S':
		case's':
		case 80:if(snake.dir!=UP)
			    snake.dir = DOWN;
			    break;
		case'A':
		case'a':
		case 75:if(snake.dir != RIGHT)
			     snake.dir = LEFT;
			     break;
		case'D':
		case'd':
		case 77:if (snake.dir != LEFT)
			    snake.dir = RIGHT;
			    break;
		case ' ':
			     while (true)
			     {
					 if (_getch() == ' ')
					 {
						 return;
					 }
				 }
				 break;
		}
	}
}

void test01()
{
	   while (true)
	   {
		   GameDraw();
		   SnakeMove_Nodead();
		   keyControl_S();
		   Eat_Food();

	   }
}

int main()
{
	Initialization_show();/*显示屏初始化*/
	Initialization_data();/*数据初始化后*/
	GameDraw();
	SnakeMove_Nodead();
	
	test01();
	
	system("pause");
	return 0;
}

其中使用了mciSendString函数进行了游戏背景音乐的添加。我也是刚接触C++两个多星期,本次设计是根据b站视频学的加以自己的理解,所表述可能存在问题。

  • 6
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值