【小游戏】C++手工制作贪吃蛇



//
#include<stdio.h>
//键盘敲击
#include <conio.h>
//屏幕渲染周期,clock函数
#include <time.h>
//
#include <stdlib.h> 

//刷新周期,控制游戏速度
#define Period 100
//地图宽度
#define _width 25
//地图高度
#define _height 18
//点 结构
typedef struct point
{
	int x;
	int y;
};

//----------------全局变量----------------

//地图数组
char g_map[_height][_width];
//蛇长度,初始化为两个
int g_snakeLen = 2;
//蛇:一系列点
struct point g_snake[(_width - 1)*(_height - 1)] = { { _height / 2, _width / 2 }, { 1, 1 } };
//食物坐标
struct point g_food;

//----------------函数声明----------------

//欢迎界面
void Welcome();
//置字符
void SetChars();
//设置食物
void ResetFood();
//处理蛇移动
int JugeSnake(char c);
//空格填充
void Padding(int =0);

//--------------------------------------
int main()
{
	//当前时间,上一次刷新时间,单位为ms(毫秒)
	long timeNow, timeLast = 0;
	int i, j,//计数变量
		keyLast = 'd',
		keyNow = 'd';
	
	
	//显示欢迎界面
	Welcome();

	//置随机数种子
	srand((unsigned)time(NULL));
	//初始化食物位置
	ResetFood();
	
	do
	{
		//***********************渲染开始***********************
		//获取当前时间
		timeNow = clock();
		//判断是否满足刷新条件
		if (timeNow - timeLast >= Period)
		{
			//记录本次刷新时间
			timeLast = clock();
			//清屏
			system("cls");
			//1. 显示图像
			//----------------初始化地图界面----------------
			for (i = 0; i<_height; i++)
			{
				for (j = 0; j<_width; j++)
				{
					g_map[i][j] = ' ';
					if (i == 0 || i == _height - 1 || j == 0 || j == _width - 1)
						g_map[i][j] = '*';
				}
			}
			//----------------初始化地图界面----------------
			//空格填充
			Padding(-10);
			printf("----------当前长度%d,已游戏时间%ds-----------\n", g_snakeLen, timeNow / 1000);
			int resJuge = JugeSnake(keyLast);
			//此处若用switch,则不能跳出最外层的do-while循环
			//为了避免用goto语句,所以用if-else处理juge结果
			if (resJuge == 0)
			{
				printf("游戏结束!");
				break;
			}
			else if (resJuge == 2)
			{
				printf("恭喜你打穿游戏了!");
				break;
			}
			SetChars();

			for (i = 0; i<_height; i++)
			{
				//空格填充
				Padding();
				for (j = 0; j<_width; j++)
				{
					printf("%c", g_map[i][j]);
				}
				if (i<_height - 1)
					printf("\n");
			}


		}

		//2. 处理键盘事件
		if (kbhit() == 1)
		{
			//
			keyNow = getch();
			if (keyNow == 'd'&&keyLast == 'a')
				keyLast = 'a';
			else if (keyNow == 'a'&&keyLast == 'd')
				keyLast = 'd';
			else if (keyNow == 'w'&&keyLast == 's')
				keyLast = 's';
			else if (keyNow == 's'&&keyLast == 'w')
				keyLast = 'w';
			else
			{
				keyLast = keyNow;
			}
		}

		//***********************渲染结束***********************
	} while (1);

	system("pause");

}
//
//判断 蛇的移动 并 处理 移动效果
//
int JugeSnake(char c)
{
	int i;
	int x, y;//目标位置
	struct point last;
	last = g_snake[g_snakeLen - 1];//记录移动前的尾巴位置
	x = g_snake[0].x;
	y = g_snake[0].y;
	switch (c)
	{
	case 'w':case 'W':
		x--;
		break;
	case 's':case 'S':
		x++;
		break;
	case 'a':case 'A':
		y--;
		break;
	case 'd':case 'D':
		y++;
		break;
	}
	//在这里说明移动成功了
	if (x <= 0 || x >= _height - 1)
		return 0;
	if (y <= 0 || y >= _width - 1)
		return 0;


	for (i = g_snakeLen - 1; i>0; i--)//除头以外都移动
		g_snake[i] = g_snake[i - 1];
	//动完之后判断目标位置和移动后的躯体是否重合
	for (i = 1; i<g_snakeLen; i++)
	{
		if (g_snake[i].x == x&&g_snake[i].y == y)
			return 0;//重合就撞了,撞了就GG了
	}
	//没GG。。。
	g_snake[0].x = x;
	g_snake[0].y = y;

	if (g_snake[0].x == g_food.x &&g_snake[0].y == g_food.y)//卧槽吃到食物了
	{
		g_snakeLen++;
		g_snake[g_snakeLen - 1] = last;
		ResetFood();
	}
	if (g_snakeLen == (_width - 1)*(_height - 1))
		return 2;

	return 1;

}
//
//设置蛇的字和食物字符
//
void SetChars()
{
	int i;
	g_map[g_snake[0].x][g_snake[0].y] = 'M';
	for (i = 1; i<g_snakeLen; i++)
		g_map[g_snake[i].x][g_snake[i].y] = 'm';
	g_map[g_food.x][g_food.y] = 'O';
}
//
//重置食物位置
//
void ResetFood()
{
	do
	{
		g_food.x = rand() % _height;
		g_food.y = rand() % _width;
	} while (g_food.x == 0 || g_food.x == _height - 1 || g_food.y == 0 || g_food.y == _width - 1);
}
//
//欢迎界面
//
void Welcome()
{
	Padding(-10);printf("欢迎来到贪吃世界!\n");
	Padding(-10);printf("上下左右为wsad键(请调整输入法),感受这款经典游戏带来的快感吧!\n");
	Padding(-10);printf("                           长沙理工大学 何健伟 QQ:296036136\n");
	system("pause");
}
//
//显示一定数量的空格
//参数1:相对偏移
void Padding(int shift)
{
	int total=20;
	total+=shift;
	for(int i=0;i<total;i++)
	{
		putchar(' ');
	}
}

转载于:https://www.cnblogs.com/tinyjian/p/6550722.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值