【贪吃蛇】C语言 指针 + 链表 简单实现

贪吃蛇

本蒟蒻初学代码用C++制作的第一个小游戏-贪吃蛇具体见代码
本来考虑是用STL制作核心部分的, 后面发现链表加指针出奇地香, 于是乎…

控制光标部分

void SetPos(int x,int y) {//设置光标位置 可参考//https://blog.csdn.net/qq_38241045/article/details/69941464 
 	COORD pos;
 	//HANDLE hOutput;
 	pos.X=x;//光标要设置的位置x
 	pos.Y=y;//光标要设置的位置y
 	HANDLE hOutput=GetStdHandle(STD_OUTPUT_HANDLE);//使用GetStdHandle(STD_OUTPUT_HANDLE)来获取标准输出的句柄
 	SetConsoleCursorPosition(hOutput,pos);//设置光标位置
}
/*
typedef struct _COORD {
	SHORT X;
	SHORT Y;
} COORD, *PCOORD;
*/

宏定义部分

typedef struct Snake {
	int x;
	int y;
	struct Snake *next; 
}snake;
int ops;//每次动作的指令, 为了让蛇在没指令的情况下继续运动 
int score;//得分 
int flag;//失败情况
int add_score = 15;//每次加分 
snake *head, *food;//
snake *q;//遍历蛇的时候用到的指针
int circle_time = 150;

欢迎界面部分

void Welcome_Screen() {//欢迎界面 
	Printsnake(); 
	system("color F4");
	SetPos(45, 20);
	printf("Welcome To Snaker             o(* ̄▽ ̄*)o\n\n\n\n\n\n\n                                             ");
	system("pause");//冻结屏幕 
	system("cls");//清空屏幕 
	SetPos(38, 20);
	printf("tips:请通过↑、↓、←、→分别控制蛇的移动");
	Dynamic_graph_1();
	system("pause");//冻结屏幕 
	system("cls");//清空屏幕 
}

循环部分

void Game_Circle() {//GetAsyncKeyState函数:https://baike.baidu.com/item/GetAsyncKeyState/918387?fr=aladdin
	SetPos(70, 14);
 	printf("  不能触碰到墙,也不能咬到自己.");
 	SetPos(70, 16);
 	printf("请使用↑、↓、←、→控制蛇的移动.");
 	SetPos(70, 17);
 	printf("     Q 为加速,E 为减速.");
 	SetPos(70, 18);
 	printf("ESC :退出游戏  SPACE:暂停游戏.");
 	SetPos(70, 20);
 	printf("      By  Turm_Xsk  ");
 	SetPos(66, 22);
 	printf("          АБВГРСТУДЕЁЛ");
 	SetPos(66, 24);
 	printf("          МНОПЗИЙКЦЧШЦ");
	while(1) {//注意不能向身后移动 //上-1;下-2;左-3;右-4 
 		SetPos(70, 10);
 		printf("             得分:%d ",score);
 		SetPos(70, 11);
 		printf("        每个食物得分:%d分",add_score);
 		if(GetAsyncKeyState(VK_UP) && ops!=2)	ops=1;
 		else if(GetAsyncKeyState(VK_DOWN)&&ops!=1)	ops=2;
 		else if(GetAsyncKeyState(VK_LEFT)&&ops!=4)	ops=3;
 		else if(GetAsyncKeyState(VK_RIGHT)&&ops!=3)	ops=4;
 		else if(GetAsyncKeyState(VK_SPACE))	Pause();
 		else if(GetAsyncKeyState(VK_ESCAPE))	break;
 		else if(GetAsyncKeyState(0x51))	{ //Q所对应按键 https://blog.csdn.net/by_mxy/article/details/9866473
 			add_score += 1; 
 			circle_time -= 40;
 		} 
 		else if(GetAsyncKeyState(0x45))	{ //E所对应按键 https://blog.csdn.net/by_mxy/article/details/9866473
 			add_score -= 1;
 			circle_time += 40;
 		} 
 		Sleep(circle_time);
 		Snake_Move();
 	}
} 

移动部分

void Snake_Move() {
	snake *next_head;
	Check_Wall();
	next_head=(snake*)malloc(sizeof(snake));
	if(ops == 1) {//上 
		system("color 0A");
		next_head -> x = head -> x;
 		next_head -> y = head -> y - 1;//坐标是倒的 
	} else if(ops == 2) {//下
		system("color 0B");
	 	next_head -> x = head -> x;
 		next_head -> y = head -> y + 1;
	} else if(ops == 3) {//左
		system("color 0C"); 
		next_head -> x = head -> x - 2;
 		next_head -> y = head -> y;
	} else if(ops == 4) {//右 
		system("color 0E");
		next_head -> x = head -> x + 2;
 		next_head -> y = head -> y;
	}
	if(next_head -> x == food -> x&&next_head -> y == food -> y) {//遇见食物 
		next_head -> next = head;//对接上 
		head = next_head;//从新位置开始遍历 
		q = head;
		int k = 1;
		while(q != NULL) {
			SetPos(q -> x, q -> y);
			if(k) {
				printf("@");
				k = 0; 
			}else	printf("O");
			q = q -> next;
		}
		score += add_score;
		Init_Food();
	} else {//没有遇见食物 
		next_head -> next = head;
		head = next_head;
		q = head;
		int k = 1;
		while(q -> next -> next != NULL) {//提前结束, 覆盖最后的蛇尾 
 			SetPos(q -> x, q -> y);
 			if(k) {
			 	printf("@");
				k = 0; 
			}else	printf("O");
 			q = q -> next; 
 		}
 		SetPos(q -> next -> x,q -> next -> y);
 		printf(" ");
 		free(q -> next);
 		q -> next = NULL;
	}
	if(Check_Bite())	Game_End();
} 

随机食物部分

void Init_Food() {//随机生成食物 srand函数:https://blog.csdn.net/jx232515/article/details/51510336 
	snake *next_food;
	srand((unsigned)time(NULL));//之后用rand()提取随机数
	next_food = (snake*)malloc(sizeof(snake));
	//是食物与蛇头纵向对齐 
	next_food -> x = rand()%58 + 2;//防止食物生成在边缘 
	while(next_food -> x%2 != 0)	next_food -> x = rand()%58 + 2;	//这里卡的千百回, 终于改对了
	while(next_food -> x == 30)	next_food -> x = rand()%58 + 2; 
	next_food -> y = rand()%33 + 1;//
	while(next_food -> y == 17)	next_food -> y = rand()%33 + 1;
	q = head;//遍历蛇的全身,防止食物生成在蛇身上 
	while(q -> next == NULL) {
		if(q -> x == next_food -> x&&q -> y == next_food -> y) {//当食物重合蛇身时 
 			free(next_food);//释放内存空间 
 			Init_Food();//再来 
 		}
	}
	q = q -> next;//?
	SetPos(next_food -> x, next_food -> y);
 	food = next_food;
 	printf("$"); 
 	SetPos(70, 13);
 	printf("当前食物位置:%d    %d", food -> x, food -> y);
}

以上都是核心程序。具体步骤都在代码中体现, 本蒟蒻就不多余文字复述了~
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值