一个简简单单的贪吃蛇(c语言)

在学习完c语言基础之后,我们就可以利用c语言来写一个小游戏----贪吃蛇

下面为所需用到的头文件

#include <stdio.h>
#include <windows.h>
#include <time.h>
#include <conio.h>

原理

贪吃蛇无非就是在一个有限的地图上进行运动,通过到达一个特定地点(吃食物)来增加体型的游戏;

  • 首先,你进去得先有个场啊,不然在哪跑呢(地图初始化);
  • 有场地了,肯定得有蛇啊,不然玩啥呢(蛇的初始化);
  • 再还有就是吃的了,没吃的,游戏也玩不了啊(食物的更新);
  • 那现在啥都有了,蛇,你得动起来啊,(蛇的运动);
  • 蛇开始动了,万一,它碰到啥旮旮角角的,凉了,游戏不就结束了嘛(蛇死亡判断);
  • 如果,还想来点花哨的,你也可以加个速度控制系统;

具体实现

-从第一个开始, 如何打印地图
开始使用我们的第一个函数—(光标位置函数)

void gotoxy(int x, int y)
{
	HANDLE hout;
	COORD cor;
	hout = GetStdHandle(STD_OUTPUT_HANDLE);
	cor.X = y;
	cor.Y = x;
	SetConsoleCursorPosition(hout, cor);
}

这里的x,y分别对应着小黑框的坐标,x代表第几行,y代表第几列;
这里的行和列与二维数组一样,都是从0开始的;
所以我们只需要利用for循环,将光标转移去合适的地方,打印出地图即可
这里我#define MAP_LEN 20;

	for (int j = 0; j < MAP_LEN; j++)
	{
		gotoxy(0, j);
		printf("#");
		gotoxy(MAP_LEN - 1, j);
		printf("#");
	}
	for (int j = 0; j < MAP_LEN; j++)
	{
		gotoxy(j, 0);
		printf("#");
		gotoxy(j, MAP_LEN - 1);
		 printf("#");
	}

就像这样;

然后就是蛇的初始化,那蛇都有什么性质呢?

  1. 蛇的大小,及蛇每个节点的坐标位置;
  2. 蛇的长度;
  3. 蛇的速度;
    我们可以利用struct来将其整理在一起
    定义 int len 为蛇的长度
    int speed 为蛇的速度
    用两个数组来表示蛇每个节点的横坐标和纵坐标;
    int x[MAX],y[MAX];
    就像这样:
struct Snake
{
	int x[50];
	int y[50];
	int len;
	int speed;
}snake;

接着,再把蛇打印出来;

snake.x[0] = (MAP_LEN) / 2;
	snake.y[0] = (MAP_LEN) / 2;
	gotoxy(snake.x[0], snake.y[0]);
	printf("*");
	snake.len = 3;
	snake.speed = 200;
	for (int k = 1; k < snake.len; k++)
	{
		snake.x[k] = snake.x[k - 1] + 1;
		snake.y[k] = snake.y[k - 1];
		gotoxy(snake.x[k], snake.y[k]);
		printf("*");
	}

初始化写好了,不妨我们运行试一试
在这里插入图片描述

然后,我们开始写食物;

struct Food
{
	int x;
	int y;
}food;

使用rand 函数,在地图随机生成食物

srand(time(NULL));
	food.x = rand() % (MAP_LEN - 5) + 2;
	food.y = rand() % (MAP_LEN - 5) + 2;
	gotoxy(food.x, food.y);
	printf("֍");

现在,所有的初始化都已经写完了,接着看蛇的运动
snake.x[0]和snake.y[0]表示蛇头对应的坐标

这是,需要使用新的函数kbhit()
kbhit() 非阻塞的响应键盘输入时间 C++函数

功能和返回值:检查是否有键盘输入 ,有返回非0 ,无返回0
当键盘没有输入的时候,程序就会一直运行下去,
使用getch不会回显的特点来判断

if (kbhit())
		ch = getch();
		switch (ch)
	{
	case 'w':snake.x[0]--; break;
	case 's':snake.x[0]++; break;
	case 'a':snake.y[0]--; break;
	case 'd':snake.y[0]++; break;
	default:break;
	}

如果我们此时没有吃到食物,那么后面一个节点就会移向前一个节点,
我们只需要将光标移动到最后一个节点,打印空格将其覆盖,这样就实现了,蛇的移动;

if (!flag)
	{
		gotoxy(snake.x[snake.len - 1], snake.y[snake.len - 1]);
		printf(" ");
	}

完整写法:

void move_snake()
{

	if (kbhit())
		ch = getch();
	if (!flag)
	{
		gotoxy(snake.x[snake.len - 1], snake.y[snake.len - 1]);
		printf(" ");
	}
	for (int k = snake.len - 1; k > 0; k--)
	{
		snake.x[k] = snake.x[k - 1];
		snake.y[k] = snake.y[k - 1];
	}
	switch (ch)
	{
	case 'w':snake.x[0]--; break;
	case 's':snake.x[0]++; break;
	case 'a':snake.y[0]--; break;
	case 'd':snake.y[0]++; break;
	default:break;
	}
	gotoxy(snake.x[0], snake.y[0]);
	 printf("*");
	flag = 0;
}

最后,我们判断蛇头的位置,当他撞墙的时候,游戏结束,即退出循环

int live()
{
	if (snake.x[0] == 0 || snake.x[0] == MAP_LEN - 1 || snake.y[0] == MAP_LEN - 1 || snake.y[0] == 0)
		return 0;
	for (int i = snake.len; i > 0; i--)
	{
		if (snake.x[0] == snake.x[i] && snake.y[0] == snake.y[i])
		{
			return 0;
		}
	}		
		return 1;
}

接着,控制蛇的速度;
Sleep函数

功能: 执行挂起一段时间,也就是等待一段时间在继续执行,
通过暂停时间的大小控制速度;
最后,简简单单的整合一下

#include <stdio.h>
#include <windows.h>
#include <time.h>
#include <conio.h>
#define MAP_LEN 27
struct Food
{
	int x;
	int y;
}food;
struct Snake
{
	int x[50];
	int y[50];
	int len;
	int speed;
}snake;
int ch,flag;
void gotoxy(int x, int y)
{
	HANDLE hout;
	COORD cor;
	hout = GetStdHandle(STD_OUTPUT_HANDLE);
	cor.X = y;
	cor.Y = x;
	SetConsoleCursorPosition(hout, cor);
}
void color(short x)	//自定义函根据参数改变颜色 
{
	if (x >= 0 && x <= 15)//参数在0-15的范围颜色
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), x);	//只有一个参数,改变字体颜色 
	else//默认的颜色白色
		SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);
}
void inti_map()
{
	//初始化食物
	srand(time(NULL));
	food.x = rand() % (MAP_LEN - 5) + 2;
	food.y = rand() % (MAP_LEN - 5) + 2;
	gotoxy(food.x, food.y);
	printf("֍");
	//初始化蛇
	snake.x[0] = (MAP_LEN) / 2;
	snake.y[0] = (MAP_LEN) / 2;
	gotoxy(snake.x[0], snake.y[0]);
	printf("*");
	snake.len = 3;
	snake.speed = 200;
	for (int k = 1; k < snake.len; k++)
	{
		snake.x[k] = snake.x[k - 1] + 1;
		snake.y[k] = snake.y[k - 1];
		gotoxy(snake.x[k], snake.y[k]);
		printf("*");
	}
	//初始化地图
	for (int j = 0; j < MAP_LEN; j++)
	{
		gotoxy(0, j);
		printf("#");
		gotoxy(MAP_LEN - 1, j);
		printf("#");
	}
	for (int j = 0; j < MAP_LEN; j++)
	{
		gotoxy(j, 0);
		printf("#");
		gotoxy(j, MAP_LEN - 1);
		 printf("#");
	}
}
void move_snake()
{

	if (kbhit())
		ch = getch();
	if (!flag)
	{
		gotoxy(snake.x[snake.len - 1], snake.y[snake.len - 1]);
		printf(" ");
	}
	for (int k = snake.len - 1; k > 0; k--)
	{
		snake.x[k] = snake.x[k - 1];
		snake.y[k] = snake.y[k - 1];
	}
	switch (ch)
	{
	case 'w':snake.x[0]--; break;
	case 's':snake.x[0]++; break;
	case 'a':snake.y[0]--; break;
	case 'd':snake.y[0]++; break;
	default:break;
	}
	gotoxy(snake.x[0], snake.y[0]);
	 printf("*");
	flag = 0;
}
void updatefood()
{
	if (snake.x[0] == food.x && snake.y[0] == food.y)
	{
		srand(time(NULL));
		food.x = rand() % (MAP_LEN - 5) + 3;
		food.y = rand() % (MAP_LEN - 5) + 3;
		gotoxy(food.x, food.y);
		 printf("֍");
		snake.len++;
		flag = 1;
	}
}
int live()
{
	if (snake.x[0] == 0 || snake.x[0] == MAP_LEN - 1 || snake.y[0] == MAP_LEN - 1 || snake.y[0] == 0)
		return 0;
	for (int i = snake.len; i > 0; i--)
	{
		if (snake.x[0] == snake.x[i] && snake.y[0] == snake.y[i])
		{
			return 0;
		}
	}		
		return 1;
}
int main()
{
	inti_map();
	system("pause");
	while (1)
	{
		updatefood();
		move_snake();
		if (live() == 0)
			break;
		Sleep(snake.speed);
	}
	gotoxy(MAP_LEN + 1, 0);
	printf("GAME OVER");
	return 0;
}



  • 25
    点赞
  • 59
    收藏
    觉得还不错? 一键收藏
  • 12
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值