欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

酷炫贪食蛇小游戏

程序员文章站 2022-07-13 08:29:32
...

这是小白我上了一节公开课后(顿开教育,非常感谢,还是学到了很多有用的东西)敲的代码,认为很有意思,以此记录我的第一条博客。
相关知识:C编程,图形库运用,数组,结构体
废话不多说,上代码分析:

1.数据分析:基本数据成员分析
1.1坐标属性

 1. typedef struct pointXY
 2.  { 	
 3. int x; 	int y; 
 4. }MYPOINT;
   		 1.2蛇属性
   		 		  1.2.1蛇的节数
   		 		  1.2.2蛇初始化的方向
struct Snake
{
	int num;    //蛇的节数
	MYPOINT xy[100];    //蛇最多有一百节
	char postion;     //方向
}snake;

   		 1.3食物属性
   		 		 1.3.1食物的坐标
   		 		 1.3.2食物的分数
   		 		 1.3.3食物是否存在
struct Food
{
	MYPOINT fdxy;   //食物的x和y坐标
	int eatgrade;   //吃了食物有多少分
	int flag;    //食物是否存在
}food;

按键接收、控制蛇的运动方向

//把方向枚举出来,小键盘的键码值
enum movePosition{right = 72,left = 75,down = 77,up = 80};
   	2.过程分析:函数分析
   		初始化蛇:initSnake
		画蛇:drawSnake
		移动蛇:moveSnake
		按键处理:keyDown
		初始化食物:initFood
		画食物:drawFood
		吃食物:eatFood
		蛇挂掉:snakeDie
		
   	3.函数模块
//初始化蛇
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;	//初始化分数开始为0
}

//画蛇

void drawSnake()
{
	for (int i = 0; i < snake.num; i++)
	{
		setlinecolor(BLACK);     //设置矩形边框线的颜色
		//setfillcolor(GREEN);	//设置矩形填充颜色
		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);	//画矩形需要知道左上角和右下角的坐标, 10*10像素的蛇节点

	}
}

//移动蛇

void moveSnake()
{
	//除了第一节之外,后面的每一节的坐标都是前面一节的坐标
	for (int i = snake.num - 1; i > 0; i--)         //-1表示去掉第一节
	{
		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:   //case 72也可以
		if (snake.postion != down)
		{
			snake.postion = up;
		}
		break;
	case left:
		if (snake.postion != right)
		{
			snake.postion = left;
		}
		break;
	case down:
		if (snake.postion != left)
		{
			snake.postion = right;
		}
		break;
	case up:
		if (snake.postion != up)
		{
			snake.postion = down;
		}
		break;
	default:
		break;
	}
}

//食物的主要模块
//食物随机出现

void initFood()
{
	food.fdxy.x = rand() % 65*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()
{
	fillrectangle(food.fdxy.x,food.fdxy.y,food.fdxy.x+10,food.fdxy.y+10);
	setlinecolor(BLACK);     //设置矩形边框线的颜色
	setfillcolor(GREEN);	//设置矩形填充颜色
}

//吃食物

void eatFood()
{
	//1.蛇变长了
	//2.食物要重新生成
	//3.分数要增加
	if (snake.xy[0].x == food.fdxy.x&&snake.xy[0].y == food.fdxy.y)
	{
		snake.num++;
		food.eatgrade += 10;
		food.flag = 0;
		printf("\a");     //吃到食物的提示音
	}
}

//蛇死掉

int snakeDie()
{
	//撞墙死
	if (snake.xy[0].x > 640 || snake.xy[0].x<0 || snake.xy[0].y>480 || snake.xy[0].y < 0)
	{
		printf("\a");
		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)
		{
			printf("\a");
			outtextxy(200, 200, "撞自己了!");
			MessageBox(hwnd, "GameOver!", "自杀警告!", MB_OK);
			return 1;
		}
	}
	return 0;
}

//展示分数

void showGrade()
{
	char grade[100] = "";
	sprintf(grade,"%d",food.eatgrade);        //这个窗口界面只能显示字符串,所以要把分数先转成字符串形式
	setbkmode(TRANSPARENT);    //设置背景为透明
	settextcolor(LIGHTBLUE);   //设置文字颜色为浅蓝色
	outtextxy(560, 20, "分数:");
	outtextxy(560+50,20,grade);

}

//暂停键设置

void pauseMoment()
{
	if (_getch() == 32)
	{
		while (_getch() != 32);     //停在这里
	}
}

//主函数

int main()
{
	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);    //蛇跑太快了,作减速处理
	}
	getchar();			//防止闪屏
	closegraph();
	return 0;
}

效果图
酷炫贪食蛇小游戏