用C实现贪吃蛇,看看你的C学得怎样?(三)

写在开始

上一篇博客的链接为:用C实现贪吃蛇,看看你的C学得怎样?(二)

任务清单

本次项目的任务清单暂定如下:
1.创建地图和起始界面(已完成)
2.创建蛇,食物、超级食物投放(已完成)
3.通过键盘控制蛇的移动
4.基本功能(蛇吃食物,蛇的增长等)
5.判断游戏是否结束
6.计算游戏时长
7.加入最高纪录功能
8.游戏等级进度
9.游戏重新开始

代码实现

//定义头文件
#include<stdio.h> 
#include<conio.h>
#include<stdlib.h>
#include<time.h>
#include<windows.h>

//宏定义声明
#define X 23       //定义地图大小
#define Y 50

#define UP 0              //0为上,1为下,2为左,3为右                       
#define DOWN 1                           
#define LEFT 2                           
#define RIGHT 3

char map[X][Y];          //地图数组

int s[X*Y][2];          //蛇身坐标数组
int sLength;           //蛇的长度
int direction;         //蛇的方向

//定义主函数
int main() 
{
	init();                 //初始化
	menu();					//生成界面
	system("cls");          //清除屏幕内容
	draw_map();            //画地图
	food();                     //画食物
	s_food();
	while (1)
		{
			draw_snake();                //画蛇
			Sleep(delay);           //等待一段时间
			key();
			move();                //移动蛇(主要是修改蛇身数组的数据)
		}//定义函数
void init()         //程序开始时的初始化操作
{
	CONSOLE_CURSOR_INFO cursor_info = { 1, 0 };
	SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);    //隐藏关标
	int i, j;
	for (i = 0; i<X; i++)
	{
		map[i][0] = 1;          //让第一列为1
		map[i][Y - 1] = 1;        //让最后一列为1
	}
	for (j = 0; j<Y; j++)
	{
		map[0][j] = 1;      //让第一行为1
		map[X - 1][j] = 1;    //让最后一行为1
	}
	sLength = 4;          //让蛇的最初长度为4
	s[0][0] = X / 2;
	s[0][1] = Y / 2;        //给蛇头坐标赋值
	for (i = 1; i<4; i++)
	{
		s[i][0] = s[0][0] + i;
		s[i][1] = s[0][1];   //给刚开始的蛇身几个初始坐标
	}
}

void gotoxy(int i, int j)        //移动光标
{
	COORD position = { j, i };
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), position);
}

void draw_map()   //创建地图   
{
	gotoxy(0, 0);
	int i, j;
	for (i = 0; i<X; i++)    //两重for循环遍历数组
	{
		for (j = 0; j<Y; j++)         
		{
			if (map[i][j] == 0)          //为0输出空格
				printf(" ");
			else if(map[i][j]==1)       //为1输出#
				printf("#");
		}
		printf("\n");               //别忘了换行
	}
}

void menu()         //初始菜单界面
{
	printf("\n\n\n\n\n\n\t\t\t********************贪吃蛇(实验版)******************\t\t\t\n\n");
	printf("\t\t\t********************欢迎参与游戏测试******************\t\t\t\n\n");
	printf("\t\t\t********************按任意键开始游戏******************\t\t\t\n\n");
	printf("\t\t\t\t\t      职业工具人\n\n");
	printf("\t\t\t\t请先确保处于英语输入法,否则无法进行游戏");
	_getch();    //保持界面获取字符
}

int check(int ii, int jj)        //判断这个点能不能放食物,可以放返回1,不能放返回0
{
	if (map[ii][jj] == 1)        //如果有障碍物,返回0
		return 0;
	int i;
	for (i = 0; i<sLength; i++)
	{
		if (ii == s[i][0] && jj == s[i][1])      //如果和其中一个蛇身重合,就返回0
			return 0;
	}
	if (ii == 0 || ii == X - 1 || jj == 0 || jj == Y - 1)      //如果在边界上面,返回0
		return 0;
	if(map[ii][jj]==-1)             //若该点有食物,则不生成超级食物                
		return 0;
	return 1;                       //最后筛选 过后的是符合条件的点
}

void food()  //生成食物
{
	int i, j;
	do
	{
		i = rand() % X;                 //生成0~X-1之间的一个数
		j = rand() % Y;                 //生成0~Y-1之间的一个数
	} 
	while (check(i, j) == 0);           //生成点直到满足条件
	map[i][j] = -1;                     //标记为食物
	gotoxy(i, j);
	printf("*");                    //画出食物
}

void s_food()  //生成超级食物
{
	int i, j;
	do
	{
		i = rand() % X;
		j = rand() % Y;
	} 
	while (check(i, j) == 0);
	map[i][j] = 2;
	gotoxy(i, j);
	printf("$");
}

void draw_snake()                //画蛇
{
	int i;
	for (i = 0; i<sLength; i++)
	{
		gotoxy(s[i][0], s[i][1]);        //移动关标到蛇的坐标
		printf("@");                    //在这个位置画蛇
	}
}

void key()       //定义key,用于接受按键键值
{
	if (_kbhit() != 0)          //如果有键盘输入
	{
		char in;
		while (!_kbhit() == 0)  //如果玩家输入了多个按键,以最后一个按键为准
			in = _getch();
		switch (in)
		{
		case 'w':
		case 'W':
			if (direction != DOWN)         //不能后退
				direction = UP;
			break;
		case 's':
		case 'S':
			if (direction != UP)
				direction = DOWN;
			break;
		case 'a':
		case 'A':
			if (direction != RIGHT)
				direction = LEFT;
			break;
		case 'd':
		case 'D':
			if (direction != LEFT)
				direction = RIGHT;
			break;
		}
	}
}

void move()                    //控制蛇的移动
{
	int i;
	gotoxy(s[sLength - 1][0], s[sLength - 1][1]);
	printf(" ");                            //在尾巴上面画空格以擦除尾巴
	for (i = sLength - 1; i > 0; i--)  //从尾巴开始,每一个点的位置等于它前面一个点的位置
	{
		s[i][0] = s[i - 1][0];
		s[i][1] = s[i - 1][1];
	}
	switch (direction)
	{
	case UP:
		s[0][0]--;
		break;
	case DOWN:
		s[0][0]++;
		break;
	case LEFT:
		s[0][1]--;
		break;
	case RIGHT:
		s[0][1]++;
		break;
	}
}

总结

本次实现的功能点主要使用的是switch分支语句,通过监听键盘输入,从而转换为方向变量来进行相关的数组操作,完成蛇的移动。

下一次的博客完成整个贪吃蛇的基本架构,使它变成一个完整的游戏。

结语

如果说这篇文章有让你学到一定的知识的话,不妨点个赞和关注,让博主能够看到,如果讲解中有什么错误和疏忽,也劳烦在评论中指出或提问,博主会第一时间进行更新和答复,谢谢!

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值