C语言实现贪吃蛇小游戏1.0

C语言实现贪吃蛇小游戏1.0

贪吃蛇游戏要有三个东西:边框、蛇、食物
还有两个灵魂的东西:光标的移动与按键监控

一、光标的移动

在我看来在控制台上移动光标画图是实现这个小游戏的灵魂了,在这之前我一直以为控制台上的输出只能一行一行地往下…

//功能:给到两个int参数,将控制台地光标移动到指定位置
	void gotoxy(int x, int y) {
	//调用win32 API去设置控制台的光标
	//找到控制台的窗口
	HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
	//光标的结构体
	COORD coord;
	coord.X = x;
	coord.Y = y;
	SetConsoleCursorPosition(handle, coord);
	}
二、边框:

规定地图的大小,用“· ”组成

void initmap() {
	for (int i = 0; i <= LENGTHSIZE; i+=2) {
		gotoxy(i, 0);
		printf("·");
		gotoxy(i, WIDETHSIZE);
		printf("·");
	}
	for (int i = 0; i <= WIDETHSIZE; i++) {
		gotoxy(0, i);
		printf("·");
		gotoxy(LENGTHSIZE, i);
		printf("·");
	}
}

代码第二行的i+=2是因为“·”符号占两个字符

三、蛇:

定义蛇的结构体

typedef struct {
	int x[SNAKESIZE];
	int y[SNAKESIZE];
	int length;
	int speed;
	int position;
}Snake;
Snake snake;

初始化一条蛇

//游戏开始前生成一条蛇并初始化它各项属性
void initsnake() {
	snake.length = 3;
	snake.speed = 150;
	snake.position = 'w';
	snake.x[0] = LENGTHSIZE / 2;
	snake.y[0] = WIDETHSIZE / 2;
	gotoxy(snake.x[0], snake.y[0]);
	printf("*");
	for (int i = 1; i < snake.length; i++) {
		printf("*");
		snake.x[i] = snake.x[i - 1] + 1;
		snake.y[i] = snake.y[i - 1];
	}
}

蛇身:用“*”号表示,并用两个int数组存放每节蛇身的坐标
移动:擦去尾巴,添上头,
方向(按键操作):导入头文件conio.h,也是小游戏灵魂啊~
吃:增长一节

//对按键做出的反应
//w向上走,s向下,a向左,d向右
void keycope(int key) {
	switch (key) {
	case 'W':
	case 'w':
		snake.y[0]--;
		break;
	case 's':
	case 'S':
		snake.y[0]++;
		break;
	case 'D':
	case 'd':
		snake.x[0]++;
		break;
	case 'A':
	case 'a':
		snake.x[0]--;
		break;
	default:
		break;
	}
}
int snake_move() {
	int key = snake.position;//无按键输入按原方向走
	gotoxy(snake.x[snake.length - 1], snake.y[snake.length - 1]);
	//保存蛇尾坐标,是为了如果吃到食物就长大一节,长大的那一节就放在这个坐标上
	int endx = snake.x[snake.length - 1];
	int endy = snake.y[snake.length - 1];
	printf(" ");//删除/覆盖蛇尾
	//按键监控
	if (_kbhit()) {
		fflush(stdin);
		key = _getch();//把输入的按键保存下来
		snake.position = key;//改变方向
	}//有按键输入改变方向
	for (int i = snake.length - 1; i > 0;i--) {
		snake.x[i] = snake.x[i - 1];
		snake.y[i] = snake.y[i - 1];
	}
	keycope(key);//改变蛇头坐标
	gotoxy(snake.x[0], snake.y[0]);
	printf("*");
	gotoxy(LENGTHSIZE + 1, WIDETHSIZE + 1);
	if (snake_eat()) {
		snake.x[snake.length - 1] = endx;
		snake.y[snake.length - 1] = endy;
		gotoxy(endx, endy);
		printf("*");
	}//吃到吃的,长大
	return 1;
}

速度:用函数Sleep(unsigned long)控制。其中,Sleep()里面的单位,是以毫秒为单位的。

int main() {
	initmap();
	do {
		snake_move();
		Sleep(snake.speed);//速度的设置
		gotoxy(0,WIDETHSIZE+1);
		for (int i = 0; i < snake.length - 1; i++)
			printf("%d,%d ",snake.x[i], snake.y[i]);
		printf("\n长度:%d",snake.length);
	
	} while (gameover());
	gotoxy(0, WIDETHSIZE + 1);
	return 0;
}
四、食物:

用“@”表示随机生成(生成范围应该在地图内,且不能生成在蛇身上)

int food_app() {
	int x, y;
	do {
		srand((unsigned)time(NULL));//播种
		x = rand() % (LENGTHSIZE - 1) + 2;//表示生成1到WIDETHSIZE-1之间的随机数
		y = rand() % (WIDETHSIZE - 1) + 1;
	} while (!food_est(x, y));//判断食物在不在蛇身上
	gotoxy(x, y);
	printf("@");//放在循环外面,否则不符合条件的食物/光标也会显示
	food.x = x;
	food.y = y;
	return 1;
}
五、结束:

1.胜利(蛇的长度达到设定值)
2.失败(撞墙/吃到自己)
嗯,我知道我的英语emm…
会不断学习的…

int gameover() {
	//撞墙
	if (snake.x[0] == 0 || snake.x[0] == LENGTHSIZE || snake.y[0] == WIDETHSIZE || snake.y[0] == 0) {
		gotoxy(LENGTHSIZE / 2 - 8, WIDETHSIZE / 2);
		printf("gameover! you fail!");
		return 0;
	}
	//吃到自己
	else if (!eatitself()) {
		gotoxy(LENGTHSIZE / 2 - 8, WIDETHSIZE / 2);
		printf("gameover! you eat yourself!");
		return 0;
	}
	//胜利
	else if (snake.length >= SNAKESIZE) {
		gotoxy(LENGTHSIZE / 2 - 4, WIDETHSIZE / 2);
		printf("you win!");
		return 0;
	}
	else return 1;
}
六、完整代码
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<windows.h>
#include<conio.h>
#define LENGTHSIZE 50
#define WIDETHSIZE 25
#define SNAKESIZE 30
///设计一个贪吃蛇小游戏/
typedef struct {
	int x[SNAKESIZE];
	int y[SNAKESIZE];
	int length;
	int speed;
	int position;
}Snake;
Snake snake;
typedef struct {
	int x;
	int y;
}FOOD;
FOOD food;
//光标移动/
void gotoxy(int x, int y) {
	//调用win32 API去设置控制台的光标
	//找到控制台的窗口
	HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
	//光标的结构体
	COORD coord;
	coord.X = x;
	coord.Y = y;
	SetConsoleCursorPosition(handle, coord);
}
/画地图/

//初始化一条蛇
void initsnake() {
	snake.length = 3;
	snake.speed = 150;
	snake.position = 'w';
	snake.x[0] = LENGTHSIZE / 2;
	snake.y[0] = WIDETHSIZE / 2;
	gotoxy(snake.x[0], snake.y[0]);
	printf("*");
	for (int i = 1; i < snake.length; i++) {
		printf("*");
		snake.x[i] = snake.x[i - 1] + 1;
		snake.y[i] = snake.y[i - 1];
	}
}
//画吃的
//判断位置是否合法
int food_est(int x, int y) {
	for (int i = 0; i < snake.length; i++)
		if (snake.x[i] == x && snake.y[i] == y)
			return 0;
	return 1;
}
//生成食物
int food_app() {
	int x, y;
	do {
		srand((unsigned)time(NULL));//播种
		x = rand() % (LENGTHSIZE - 1) + 1;//表示生成1到WIDETHSIZE-1之间的随机数
		y = rand() % (WIDETHSIZE - 1) + 1;
	} while (!food_est(x, y));
	gotoxy(x, y);
	printf("@");//放在循环外面,否则不符合条件的食物/光标也会显示

	food.x = x;
	food.y = y;
	return 1;
}
//圈地
void initmap() {
	for (int i = 0; i <= LENGTHSIZE; i+=2) {
		gotoxy(i, 0);
		printf("·");
		gotoxy(i, WIDETHSIZE);
		printf("·");
	}
	for (int i = 0; i <= WIDETHSIZE; i++) {
		gotoxy(0, i);
		printf("·");
		gotoxy(LENGTHSIZE, i);
		printf("·");
	}
	initsnake();
	food_app();
}
//对按键的反应
void keycope(int key) {
	switch (key) {
	case 'W':
	case 'w':
		snake.y[0]--;
		break;
	case 's':
	case 'S':
		snake.y[0]++;
		break;
	case 'D':
	case 'd':
		snake.x[0]++;
		break;
	case 'A':
	case 'a':
		snake.x[0]--;
		break;
	default:
		break;
	}
}
//长大
int snake_eat() {
	if (food.x == snake.x[0] && food.y == snake.y[0]) {
		snake.length++;
		food_app();//继续生成食物
		return 1;
	}
	else return 0;
}
//蛇的移动
int snake_move() {
	int key = snake.position;//无按键输入按原方向走
	gotoxy(snake.x[snake.length - 1], snake.y[snake.length - 1]);
	//保存蛇尾坐标
	int endx = snake.x[snake.length - 1];
	int endy = snake.y[snake.length - 1];
	printf(" ");//删除蛇尾
	if (_kbhit()) {
		fflush(stdin);
		key = _getch();
		snake.position = key;
	}//有按键输入改变方向
	for (int i = snake.length - 1; i > 0;i--) {
		snake.x[i] = snake.x[i - 1];
		snake.y[i] = snake.y[i - 1];
	}
	keycope(key);
	gotoxy(snake.x[0], snake.y[0]);
	printf("*");
	gotoxy(LENGTHSIZE + 1, WIDETHSIZE + 1);
	if (snake_eat()) {
		snake.x[snake.length - 1] = endx;
		snake.y[snake.length - 1] = endy;
		gotoxy(endx, endy);
		printf("*");
	}//吃到吃的
	return 1;
}
//游戏状态
int eatitself() {
	for (int i = 1; i < snake.length; i++) {
		if (snake.x[0] == snake.x[i]&& snake.y[0]==snake.y[i]) {
			return 0;
		}
	}
	return 1;
}
int gameover() {
	//撞墙
	if (snake.x[0] == 0 || snake.x[0] == LENGTHSIZE || snake.y[0] == WIDETHSIZE || snake.y[0] == 0) {
		gotoxy(LENGTHSIZE / 2 - 8, WIDETHSIZE / 2);
		printf("gameover! you fail!");
		return 0;
	}
	//吃到自己
	else if (!eatitself()) {
		gotoxy(LENGTHSIZE / 2 - 8, WIDETHSIZE / 2);
		printf("gameover! you eat yourself!");
		return 0;
	}
	//胜利
	else if (snake.length >= SNAKESIZE) {
		gotoxy(LENGTHSIZE / 2 - 4, WIDETHSIZE / 2);
		printf("you win!");
		return 0;
	}
	else return 1;
}

int main() {
	initmap();
	do {
		snake_move();
		Sleep(snake.speed);
		gotoxy(0,WIDETHSIZE+1);
		printf("长度:%d",snake.length);
	
	} while (gameover());
	gotoxy(0, WIDETHSIZE + 1);
	return 0;
}
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值