c语言小游戏--贪吃蛇

本文详细介绍了使用C语言设计贪吃蛇游戏的过程,包括数据设计如地图宽高、蛇的最大长度、食物和蛇的结构体,以及模块化设计如地图绘制、按键处理、食物生成等关键功能。此外,还提供了游戏的终止判断和主函数的实现。
摘要由CSDN通过智能技术生成

贪吃蛇设计流程:

(1)数据设计

  • 辅助宏定义

游戏地图的宽和高,以及蛇的最大长度

  • 食物结构体

食物在地图上x和y上的显示

  • 蛇结构体

蛇的长度,蛇得每一节的坐标存储,蛇的移动速度

  • 辅助全局变量

蛇是否变化,蛇的初始移动方向

(2)模块化设计

  • 地图设计

void drawMap();//绘制游戏地图

  • 按键处理

void keyDown();//按键处理

  • 食物设计

voidcreateFood();//产生食物

  • 辅助函数

void gotoxy(int x,int y);//cmd移动辅助函数

  • 终止游戏

int snakeStaus();//蛇状态

(3)具体实现
1.辅助函数:void gotoxy(int x,int y);//cmd移动辅助函数

//
//			cmd移动辅助函数
void gotoxy(int x, int y)
{
	//获取cmd窗口句柄
	HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
	//光标坐标
	COORD coord;
	//设置窗口坐标
	coord.X = x;
	coord.Y = y;
	SetConsoleCursorPosition(handle, coord);
}

2.地图设计: void drawMap();//绘制游戏地图


//	  绘制游戏地图
void drawMap()
{
	srand((unsigned int)time(NULL));
	//食物
	//1.食物属性
	food.x = rand() % (MAPWIDTH - 4/*食物图标占用2个字符*/) + 2;
	food.y = rand() % (MAPHEIGHT - 2) + 1;
	//2.画食物
	gotoxy(food.x, food.y);
	printf("⊙");
	//蛇
	//1.蛇属性
	mysnake.x[0] = MAPWIDTH / 2;	//定位在中间
	mysnake.y[0] = MAPHEIGHT / 2;
	//2.画蛇
	gotoxy(mysnake.x[0], mysnake.y[0]);
	printf("■");
	mysnake.len = 3;
	mysnake.speed = 100;
	for (int k = 1; k<mysnake.len; k++)
	{
		mysnake.x[k] = mysnake.x[k - 1] + 2;
		mysnake.y[k] = mysnake.y[k - 1];
		gotoxy(mysnake.x[k], mysnake.y[k]);
		printf("■");
	}
	//边框
	//1.左右
	for (int i = 0; i <= MAPHEIGHT; i++)
	{
		gotoxy(0, i);
		printf("■");
		gotoxy(MAPWIDTH, i);
		printf("■");
	}
	//2.上下
	for (int i = 0; i <= MAPWIDTH; i += 2)
	{
		gotoxy(i, 0);
		printf("■");
		gotoxy(i, MAPHEIGHT);
		printf("■");
	}
}

3.按键处理:void keyDown();//按键处理

												
//	  按键处理
void keyDown()
{

	//无按键处理蛇要移动
	if (_kbhit())
	{
		fflush(stdin);
		key = _getch();
	}
	//没变化
	if (!changeFlag)
	{
		gotoxy(mysnake.x[mysnake.len - 1], mysnake.y[mysnake.len - 1]);
		printf("  ");
	}
	//后面的节数处理:往前移动
	for (int i = mysnake.len - 1; i > 0; i--)
	{
		mysnake.x[i] = mysnake.x[i - 1];
		mysnake.y[i] = mysnake.y[i - 1];
	}
	//有按键处理
	switch (key)
	{
	case 'w':
	case 'W':
	case 72:
		mysnake.y[0]--;
		break;
	case 's':
	case 'S':
	case 80:
		mysnake.y[0]++;
		break;
	case 'a':
	case 'A':
	case 75:
		mysnake.x[0] -= 2;
		break;
	case 'd':
	case 'D':
	case 77:
		mysnake.x[0] += 2;
		break;
	}
	gotoxy(mysnake.x[0], mysnake.y[0]);
	printf("■");
	changeFlag = 0;
	gotoxy(MAPHEIGHT + 2, 0);
}

4.食物设计:voidcreateFood();//产生食物


//	  产生食物
void createFood()			//产生食物
{
	//产生条件:食物被吃
	if (mysnake.x[0] == food.x&&mysnake.y[0] == food.y)
	{
		//完整版本:食物不能是在蛇身
		srand((unsigned int)time(NULL));
		//x必须为偶数 	
		while (1)
		{
			int flag = 1;
			food.x = rand() % (MAPWIDTH - 4) + 2;
			food.y = rand() % (MAPHEIGHT - 2) + 1;
			for (int k = 0; k < mysnake.len; k++)
			{
				if (mysnake.x[k] == food.x&&mysnake.y[k] == food.y)
				{
					flag = 0;
					break;
				}
			}
			//食物坐标要为偶数并且不能再蛇身上
			if (flag&&food.x % 2 == 0)
			{
				break;
			}
		}
		gotoxy(food.x, food.y);
		printf("⊙");
		mysnake.len++;
		changeFlag = 1;
	}
}

5.终止游戏: int snakeStaus();//蛇状态

int  snakeStaus()		//蛇状态
{
	if (mysnake.x[0] == 0 || mysnake.x[0] == MAPHEIGHT - 2 || mysnake.y[0] == MAPWIDTH - 2 || mysnake.y[0] == 0)
		return 0;
	for (int k = 1; k<mysnake.len; k++)
	if (mysnake.x[k] == mysnake.x[0] && mysnake.y[k] == mysnake.y[0])
		return 0;
	return 1;
}

6.主函数

int main()
{
	drawMap();
	while (1)
	{
		createFood();
		Sleep(mysnake.speed);
		keyDown();
		if (!snakeStaus())
		{
			break;
		}
	}
	printf("\nGameOver");
	system("pause");
	return 0;
}

完整代码

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <conio.h>
#include <windows.h>
//⊙  ■
///
//		地图的长和宽
#define MAPHEIGHT 25
#define MAPWIDTH 60
#define SNAKESIZE 50
///
//		数据设计
int changeFlag = 0;//蛇变形标记
int key = 'w';
struct food
{
	//食物的位置
	int x;
	int y;
}food;
struct snake
{
	int x[SNAKESIZE]; 	//蛇坐标
	int y[SNAKESIZE];
	int len;			//当前长度
	int speed;			//移动速度
}mysnake;		//mysnake[0] 蛇头
/
//		模块化设计
void drawMap();			//绘制游戏地图
void createFood();		//产生食物
void keyDown();			//按键处理
int  snakeStaus();		//蛇状态
void gotoxy(int x, int y);	//cmd移动辅助函数
int main()
{
	drawMap();
	while (1)
	{
		createFood();
		Sleep(mysnake.speed);
		keyDown();
		if (!snakeStaus())
		{
			break;
		}
	}
	printf("\nGameOver");
	system("pause");
	return 0;
}
//
//			cmd移动辅助函数
void gotoxy(int x, int y)
{
	//获取cmd窗口句柄
	HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
	//光标坐标
	COORD coord;
	//设置窗口坐标
	coord.X = x;
	coord.Y = y;
	SetConsoleCursorPosition(handle, coord);
}

//	  绘制游戏地图
void drawMap()
{
	srand((unsigned int)time(NULL));
	//食物
	//1.食物属性
	food.x = rand() % (MAPWIDTH - 4/*食物图标占用2个字符*/) + 2;
	food.y = rand() % (MAPHEIGHT - 2) + 1;
	//2.画食物
	gotoxy(food.x, food.y);
	printf("⊙");
	//蛇
	//1.蛇属性
	mysnake.x[0] = MAPWIDTH / 2;	//定位在中间
	mysnake.y[0] = MAPHEIGHT / 2;
	//2.画蛇
	gotoxy(mysnake.x[0], mysnake.y[0]);
	printf("■");
	mysnake.len = 3;
	mysnake.speed = 100;
	for (int k = 1; k<mysnake.len; k++)
	{
		mysnake.x[k] = mysnake.x[k - 1] + 2;
		mysnake.y[k] = mysnake.y[k - 1];
		gotoxy(mysnake.x[k], mysnake.y[k]);
		printf("■");
	}
	//边框
	//1.左右
	for (int i = 0; i <= MAPHEIGHT; i++)
	{
		gotoxy(0, i);
		printf("■");
		gotoxy(MAPWIDTH, i);
		printf("■");
	}
	//2.上下
	for (int i = 0; i <= MAPWIDTH; i += 2)
	{
		gotoxy(i, 0);
		printf("■");
		gotoxy(i, MAPHEIGHT);
		printf("■");
	}
}

//	  产生食物
void createFood()			//产生食物
{
	//产生条件:食物被吃
	if (mysnake.x[0] == food.x&&mysnake.y[0] == food.y)
	{
		//完整版本:食物不能是在蛇身
		srand((unsigned int)time(NULL));
		//x必须为偶数 	
		while (1)
		{
			int flag = 1;
			food.x = rand() % (MAPWIDTH - 4) + 2;
			food.y = rand() % (MAPHEIGHT - 2) + 1;
			for (int k = 0; k < mysnake.len; k++)
			{
				if (mysnake.x[k] == food.x&&mysnake.y[k] == food.y)
				{
					flag = 0;
					break;
				}
			}
			//食物坐标要为偶数并且不能再蛇身上
			if (flag&&food.x % 2 == 0)
			{
				break;
			}
		}
		gotoxy(food.x, food.y);
		printf("⊙");
		mysnake.len++;
		changeFlag = 1;
	}
}
												
//	  按键处理
void keyDown()
{

	//无按键处理蛇要移动
	if (_kbhit())
	{
		fflush(stdin);
		key = _getch();
	}
	//没变化
	if (!changeFlag)
	{
		gotoxy(mysnake.x[mysnake.len - 1], mysnake.y[mysnake.len - 1]);
		printf("  ");
	}
	//后面的节数处理:往前移动
	for (int i = mysnake.len - 1; i > 0; i--)
	{
		mysnake.x[i] = mysnake.x[i - 1];
		mysnake.y[i] = mysnake.y[i - 1];
	}
	//有按键处理
	switch (key)
	{
	case 'w':
	case 'W':
	case 72:
		mysnake.y[0]--;
		break;
	case 's':
	case 'S':
	case 80:
		mysnake.y[0]++;
		break;
	case 'a':
	case 'A':
	case 75:
		mysnake.x[0] -= 2;
		break;
	case 'd':
	case 'D':
	case 77:
		mysnake.x[0] += 2;
		break;
	}
	gotoxy(mysnake.x[0], mysnake.y[0]);
	printf("■");
	changeFlag = 0;
	gotoxy(MAPHEIGHT + 2, 0);
}
int  snakeStaus()		//蛇状态
{
	if (mysnake.x[0] == 0 || mysnake.x[0] == MAPHEIGHT - 2 || mysnake.y[0] == MAPWIDTH - 2 || mysnake.y[0] == 0)
		return 0;
	for (int k = 1; k<mysnake.len; k++)
	if (mysnake.x[k] == mysnake.x[0] && mysnake.y[k] == mysnake.y[0])
		return 0;
	return 1;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值