用c语言 在控制台 打印一个简单的贪吃蛇游戏

好久没这么舒服了,在家什么也不用干,一家人简单的在一起吃饭,感觉都挺好的。

这次的疫情十分严重,不知道什么才能出门。

那就在家写一个C语言的贪吃蛇吧!!

磨磨唧唧写了四五天,,,大概三百行,算是完成了,放上来供大家参考

仅限刚学C语言的新手,老鸟请鄙视之。。。

话不多说,先上代码:

1、main.cpp文件

#include "stdio.h"
#include "stdlib.h"
#include "funtion.h"
#pragma comment(lib,"Winmm.lib")

unsigned int timerIDsnake;

//上下左右按键返回值(返回两个字节)(第一个字节都为224,第二个字节如下):
//上:72
//下:80
//左:75
//右:77

//a:ascll:97

void HideCursor()	//隐藏光标
{
	CONSOLE_CURSOR_INFO cursor_info = { 1, 0 };
	SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}


int main(int argc, char * argv[])
{
	HideCursor();
	showscore();
	wallinit();
	snakeinit();
	goto_xy(45, 10);
	printf("贪吃蛇游戏");
	goto_xy(44, 11);
	printf("按箭头键开始");
	_getch();
	goto_xy(45, 10);
	printf("          ");
	goto_xy(44, 11);
	printf("            ");
	timerIDsnake = timeSetEvent(200, 1, (LPTIMECALLBACK)move, 0 , TIME_PERIODIC);
	food_generate();
	while (1)
	{
		keyscan();
	}
	return 0;
}

2、funtion.cpp文件

#include "funtion.h"

extern unsigned int timerIDsnake;

bool over_f = 0;
int key;
int lastkey;
bool key_valid = 1;
unsigned char score_cnt = 0;
unsigned char Food_x, Food_y;
unsigned char snake[100][2];	//蛇的长度,节坐标,和食物计数,都从0开始

unsigned char snakelength;
unsigned char tempheadx = 1, tempheady = 2;

#define Length_BK	100
#define Height_BK	25

void goto_xy(short x, short y)//定位光标位置到指定坐标
{
	HANDLE hOut;
	hOut = GetStdHandle(STD_OUTPUT_HANDLE);
	COORD pos = { x,y };
	SetConsoleCursorPosition(hOut, pos);
}

void showscore(void)
{
	goto_xy(107, 2);
	printf("分数:%4d",score_cnt);
}

void snakeinit(void)
{
	unsigned char i;
	snakelength = 2;
	lastkey = keydown;
	for (i = 0; i < 100; i++)
	{
		snake[i][0] = 0;
		snake[i][1] = 0;
	}
	snake[0][0] = 1;
	snake[0][1] = 2;
	goto_xy(snake[0][0], snake[0][1]);
	putchar(64);//@
	snake[1][0] = 1;
	snake[1][1] = 1;
	goto_xy(snake[1][0], snake[1][1]);
	putchar(64);//@
}

void wallinit(void)
{
	unsigned char i;
	for (i = 0; i <= Length_BK; i++)
	{
		goto_xy(i, 0);
		printf("#");
	}
	for (i = 0; i <= Height_BK; i++)
	{
		goto_xy(0, i);
		printf("#");
	}
	for (i = 0; i <= Length_BK; i++)
	{
		goto_xy(i, Height_BK);
		printf("#");
	}
	for (i = 0; i <= Height_BK; i++)
	{
		goto_xy(Length_BK, i);
		printf("#");
	}
}

void deletesnake(void)
{
	unsigned char i;
	for (i = 0; i < snakelength; i++)
	{
		goto_xy(snake[i][0], snake[i][1]);
		putchar(32);
	}
	goto_xy(tempheadx, tempheady);
	putchar(32);//删除旧蛇头
	goto_xy(Food_x, Food_y);
	putchar(32);//删除食物
}

void gameinit(void)
{
	score_cnt = 0;
	deletesnake();
	snakeinit();
	wallinit();
	srand((unsigned)time(NULL));
	food_generate();
}

void keyscan(void)
{
	key = _getch();			//按键上下左右开始游戏
	if (key == 224)
	{
		key = _getch();
		if (over_f)
		{
			gameinit();
			over_f = 0;
			timerIDsnake = timeSetEvent(200, 1, (LPTIMECALLBACK)move, 0, TIME_PERIODIC);
			goto_xy(45, 26);
			printf("          ");
			goto_xy(42, 27);
			printf("                ");
		}
		if (key_valid)
		{
			switch (key)//限制不能反向移动
			{
			case keyup:
				if (snake[0][1] && (lastkey != keydown))
					lastkey = key;
				break;
			case keydown:
				if (snake[0][1] <= 255 && (lastkey != keyup))
					lastkey = key;
				break;
			case keylift:
				if (snake[0][0] && (lastkey != keyright))
					lastkey = key;
				break;
			case keyright:
				if (snake[0][0] <= 255 && (lastkey != keylift))
					lastkey = key;
				break;
			}
			key_valid = 0;
		}
	}
}

bool foodok(void)
{
	unsigned char i;
	for (i = 0; i < snakelength; i++)
	{
		if (snake[i][0] == Food_x && snake[i][1] == Food_y)
		{
			return 0;
		}
	}
	return 1;
}

void food_generate(void)
{
	do
	{
		Food_x = rand() % 99 + 1;
		Food_y = rand() % 24 + 1;
	} while (!foodok());
	goto_xy(Food_x, Food_y);
	putchar(97); //a
}

void movedetection(void)
{
	unsigned char i;
	for (i = 0; i <= Length_BK; i++)
	{
		if (snake[0][1] == 0 || snake[0][1] == Height_BK)
			over_f = 1;
	}
	for (i = 0; i < Height_BK; i++)
	{
		if (snake[0][0] == 0 || snake[0][0] == Length_BK)
			over_f = 1;
	}
	for (i = 0; i < (snakelength-2); i++)
	{
		if (snake[0][0] == snake[i + 1][0] && snake[0][1] == snake[i + 1][1])
			over_f = 1;
	}

	if (over_f)
	{
		timeKillEvent(timerIDsnake);
		goto_xy(45, 26);
		printf("游戏结束!");
		goto_xy(42, 27);
		printf("按箭头键重新开始");
	}
}

void move(void)
{
	unsigned char i, tempa, tempb;
	tempheadx = snake[0][0];
	tempheady = snake[0][1];
	switch (lastkey)		//移动
	{
	case keyup:
		snake[0][1] --;
		break;
	case keydown:
		snake[0][1] ++;
		break;
	case keylift:
		snake[0][0] --;
		break;
	case keyright:
		snake[0][0] ++;
		break;
	}
	movedetection();
	if (snake[0][0] == Food_x && snake[0][1] == Food_y)
	{
		snake_growup();
		food_generate();
	}
	else if(!over_f)
	{
		goto_xy(snake[snakelength-1][0], snake[snakelength-1][1]);
		putchar(32); //space	//清除蛇尾
		for (i = 0; i < (snakelength - 1); i++)
		{
			tempa = snake[i+1][0];
			tempb = snake[i+1][1];
			snake[i+1][0] = tempheadx;
			snake[i+1][1] = tempheady;
			tempheadx = tempa;
			tempheady = tempb;
		}
	}
	if(!over_f)
		snake_draw();
	key_valid = 1;
}

void snake_growup(void)	
{
	unsigned char i, tempa, tempb;
	snake[snakelength][0] = snake[snakelength - 1][0];
	snake[snakelength][1] = snake[snakelength - 1][1];
	for (i = 0; i < (snakelength - 1); i++)
	{
		tempa = snake[i + 1][0];
		tempb = snake[i + 1][1];
		snake[i + 1][0] = tempheadx;
		snake[i + 1][1] = tempheady;
		tempheadx = tempa;
		tempheady = tempb;
	}
	snakelength++;
	score_cnt++;
}

void snake_draw(void)
{
	unsigned char i;
	for (i = 0; i < snakelength; i ++)
	{
		goto_xy(snake[i][0], snake[i][1]);
		putchar(64);//@
	}
	showscore();
}

3、function.h文件

#include "windows.h"
#include "time.h"
#include "stdio.h"
#include "conio.h"

#define keyup	72
#define keydown	80
#define keylift	75
#define keyright	77

extern unsigned char Food_x, Food_y;

extern int key;
extern int lastkey;

void showscore(void);
void wallinit(void);
void snakeinit(void);
void gameinit(void);
void goto_xy(short x, short y);	//定位光标位置到指定坐标
void food_generate(void);	//食物生成
void snake_draw(void);		//蛇身绘制
void snake_growup(void);	//长大
void keyscan(void);			//按键扫描
void move(void);

感觉逻辑还是很简单的,没有用到高级的语法和算法,用一个二维数组来表示蛇的身体坐标,

然后每移动一次就让坐标都向身体方向移动一次,

吃到食物时也移动一次,然后增加一段身体。

吃到自己和墙检查蛇头的坐标,然后多测试几遍没什么大bug就ok了

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值