程序设计大作业-贪吃蛇 C语言

这个贪吃蛇里有俩种模式,第一种可以按空格加速,第二种不能按空格加速,但每吃一个食物都后悔加速,直至极限速度,到达极限速度后吃食物则不再加速。

界面效果

游戏内效果图

废话不多说,直接上代码:

#include<stdio.h>
#include<time.h>
#include<stdlib.h>
#include<conio.h>
#include<windows.h>
#include<string.h>
#define HEIGHT 45
#define WIDTH 100
#include<mmstream.h>
#pragma comment(lib,"winmm.lib") 

void gamestart1();
void gamestart2();
int score=0;
int offset_X;//X的移动 
int offset_Y;//y的移动 
//尾巴的坐标 
int tail_X;
int tail_Y;
int hot; 
int sleeptime=200;
struct BODY//蛇身的结构体 
{
	int x;
	int y; 
};
struct SNAKE//整条蛇的结构体 
{
	struct BODY body[(HEIGHT-2)*(WIDTH-2)];//蛇的数组
	int size;//蛇的长度 
}snake;
struct FOOD//食物的结构体 
{
	int x;
	int y;
}food;
void initsnake(){//蛇初始化 
	snake.size=3;//蛇刚开始为三个身段(包括头) 
	snake.body[0].x=WIDTH/2;
	snake.body[0].y=HEIGHT/2;
	snake.body[1].x=WIDTH/2-1;
	snake.body[1].y=HEIGHT/2;
	snake.body[2].x=WIDTH/2-2;
	snake.body[2].y=HEIGHT/2;
} 
void w1(){//墙的初始化 
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),12);//设置墙的颜色 
	for(int i=0;i<HEIGHT;i++){
		for(int j=0;j<WIDTH;j++){
			if(i==0||j==0||i==HEIGHT-1||j==WIDTH-1){
				printf("*");
			}
			else{
				printf(" ");
			}
		}
		if(i==5) printf("		    贪吃蛇游玩提示");
		if(i==6) printf("			上: w");
		if(i==7) printf("			下: s");
		if(i==8) printf("			左: a");
		if(i==9) printf("			右: d"); 
		if(i==11) printf("			关爱老年人玩家的匠心制作");
		if(i==12) printf("			独特主观延迟能力降低难度");
		if(i==13) printf("			按下空格即可体验上帝模式");
		printf("\n");
	}
	
}
void w2(){//墙的初始化 
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),12);//设置墙的颜色 
	for(int i=0;i<HEIGHT;i++){
		for(int j=0;j<WIDTH;j++){
			if(i==0||j==0||i==HEIGHT-1||j==WIDTH-1){
				printf("*");
			}
			else{
				printf(" ");
			}
		}
		if(i==5) printf("		    贪吃蛇游玩提示");
		if(i==6) printf("			上: w");
		if(i==7) printf("			下: s");
		if(i==8) printf("			左: a");
		if(i==9) printf("			右: d"); 
		if(i==11) printf("			适合高手操作的加速系统");
		if(i==12) printf("			根据小青的身长均匀加速");
		if(i==13) printf("			当然有最高速度限制着,不必过分紧张");
		printf("\n");
	}
	
}
void gotoxy(int x,int y){ //光标转变位置 
	if(x==0&&y==0){
		return;
	} 
	COORD coord;
	coord.X=x;
	coord.Y=y;
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),coord);
}
void xianshi(){//显示蛇和食物 
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),11);//蛇的颜色 
	for(int i=0;i<snake.size;i++){
		gotoxy(snake.body[i].x,snake.body[i].y);//移动光标
		if(i==0){
			printf("@");//头 
		}
		else{
			printf("#");//身子 
		}
	}
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),14);//食物的颜色 
	gotoxy(food.x,food.y);
	printf("*");
	if(tail_X!=0&&tail_Y!=0){//防止第一次进入时果子生成在墙旁(画完食物后立马画空格,会导致墙一部分消失) 
		gotoxy(tail_X,tail_Y);//将运动前的蛇尾变为空格 
		printf(" ");}
	if(hot){
		gotoxy(snake.body[0].x,snake.body[0].y);
		putchar('@');
	}
	gotoxy(0,HEIGHT+1);
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),10);//得分的颜色 
		printf("得分=%d",score);
}
void initfood(){//食物初始化 
	while(1){
		int flag=0;
		food.x=(rand()%(WIDTH-2))+1;
		food.y=(rand()%(HEIGHT-2))+1;
	
		for(int i=0;i<snake.size;i++){
			if(snake.body[i].x==food.x&&snake.body[i].y==food.y){
				flag=1;//食物和蛇的坐标重复 
				break;
			}
		}
		if(flag==0) break;//没有重复 
	}
}
void gameover(int mode){//死亡检测 
	if(mode==1){
		gotoxy(snake.body[0].x,snake.body[0].y);
		putchar('#');
		gotoxy(0,HEIGHT+1);
	}
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),12);//结束时出现的字的颜色 
	gotoxy(0,HEIGHT+2);
	printf("Game Over!!!\n");
	return;

} 
void gamestart1(){
	CONSOLE_CURSOR_INFO cci;
	cci.bVisible = FALSE;
	cci.dwSize = sizeof(cci);
	SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cci);
	
	srand((unsigned int)time(NULL));
	w1();
	initsnake();
	initfood(); 
	xianshi();
	
	//先记录一下蛇移动的方向 
	char key='d'; 
	char prekey = 'd';//记录上一次方向 
	int p=0;
	 
	//运动循环 
	while(snake.body[0].x>=1&&snake.body[0].x<=WIDTH-2&&snake.body[0].y>=1&&snake.body[0].y<=HEIGHT-2){
		if(_kbhit()){
			key=getch();
			if(key==32){
				sleeptime=30;
				p+=1;
			}
			if(p==2){
				p=0;
				sleeptime=200;
			}
		}
		if(key=='d'&&prekey=='a'||key=='a'&&prekey=='d'||key=='w'&&prekey=='s'||key=='s'&&prekey=='w'){
			key=prekey;
		}
		else{
			prekey=key;
		}
		
		switch(key)//上下左右移动 
		{
			case 'a':
				offset_X=-1;
				offset_Y=0;
				break;
			case 'd':
				offset_X=1;
				offset_Y=0;
				break;
			case 'w':
				offset_X=0;
				offset_Y=-1;
				break;
			case 's':
				offset_X=0;
				offset_Y=1;
				break;
		}
	
		for(int z=1;z<snake.size;z++){
			if(snake.body[0].x==snake.body[z].x&&snake.body[0].y==snake.body[z].y){//蛇吃了自己 
			gameover(1);
			return ;
			}
		}
		if(snake.body[0].x==food.x&&snake.body[0].y==food.y){
			snake.size++;
			score++;
			initfood();//随机新食物坐标 
		}
		tail_X=snake.body[snake.size-1].x;
		tail_Y=snake.body[snake.size-1].y;
		for(int i=snake.size-1;i>0;i--){
			snake.body[i].x = snake.body[i-1].x;
			snake.body[i].y = snake.body[i-1].y;
		}
		snake.body[0].x+=offset_X;
		snake.body[0].y+=offset_Y;
		
		//防止蛇出现环状时,头既是头又是尾,此时头显示为#,而不是@
		if(snake.body[0].x==tail_X&&snake.body[0].y==tail_Y){
			 hot=1;
		}
		else{
			hot=0; 
		}
		
		xianshi();
		
		Sleep(sleeptime);//行动停留 
	}
	

	gameover(2);
}
/*
	字符拼成英文图案
*/
void printsnake()
{
	system("color a");
	printf("                                                                                         \n");
	printf("                       __________       ___                                              \n");
	printf("                      /          \\     / \\ \\    |____      __\\__                     \n");
	printf("                     /  ________  \\   / ___ \\  _/ __     | |   /                       \n");
	printf("                     |  |      |__|     _/_   |_|  /    [|] |/                           \n");
	printf("                     |  |              | | |      /     _|_ \\__/                        \n");
	printf("                     \\  \\_______        / \\      |___/        ____                    \n");
	printf("                      \\         \\    ____ ____      ____   __ |  |  ___   ______       \n");
	printf("                       \\_______  \\   |  |/    \\    /    \\_/ / |  | /  /  /      \\   \n");
	printf("                               \\  \\  |    ___  \\  / ____   /  |  |/  /  /  ____  \\   \n");
	printf("                     __        |  |  |   /   \\  \\ | |  |  /   |     /  |  /____\\  |   \n");
	printf("                    \\  \\_______|  |  |  |    |  | | |__|  |   |     \\  |  ________/   \n");
	printf("                     \\            /  |  |    |  |  \\       \\  |  |\\  \\  \\  \\____  \n");
	printf("                      \\__________/   |__|    |__|   \\___/\\__\\ |__| \\__\\  \\______/ \n");	
}
void gamestart2(){
	CONSOLE_CURSOR_INFO cci;
	cci.bVisible = FALSE;
	cci.dwSize = sizeof(cci);
	SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE),&cci);
	
	srand((unsigned int)time(NULL));
	w2();
	initsnake();
	initfood(); 
	xianshi();
	
	//先记录一下蛇移动的方向 
	char key='d'; 
	char prekey = 'd';//记录上一次方向 
	int p=0;
	 
	//运动循环 
	while(snake.body[0].x>=1&&snake.body[0].x<=WIDTH-2&&snake.body[0].y>=1&&snake.body[0].y<=HEIGHT-2){
		if(_kbhit()){
			key=getch();
		
		}
		if(key=='d'&&prekey=='a'||key=='a'&&prekey=='d'||key=='w'&&prekey=='s'||key=='s'&&prekey=='w'){
			key=prekey;
		}
		else{
			prekey=key;
		}
		
		switch(key)//上下左右移动 
		{
			case 'a':
				offset_X=-1;
				offset_Y=0;
				break;
			case 'd':
				offset_X=1;
				offset_Y=0;
				break;
			case 'w':
				offset_X=0;
				offset_Y=-1;
				break;
			case 's':
				offset_X=0;
				offset_Y=1;
				break;
		}
	
		for(int z=1;z<snake.size;z++){
			if(snake.body[0].x==snake.body[z].x&&snake.body[0].y==snake.body[z].y){//蛇吃了自己 
			gameover(1);
			return ;
			}
		}
		if(snake.body[0].x==food.x&&snake.body[0].y==food.y){
			snake.size++;
			if(sleeptime>=40){
				sleeptime-=10;
			}
			score++;
			initfood();//随机新食物坐标 
		}
		tail_X=snake.body[snake.size-1].x;
		tail_Y=snake.body[snake.size-1].y;
		for(int i=snake.size-1;i>0;i--){
			snake.body[i].x = snake.body[i-1].x;
			snake.body[i].y = snake.body[i-1].y;
		}
		snake.body[0].x+=offset_X;
		snake.body[0].y+=offset_Y;
		
		//防止蛇出现环状时,头既是头又是尾,此时头显示为#,而不是@
		if(snake.body[0].x==tail_X&&snake.body[0].y==tail_Y){
			 hot=1;
		}
		else{
			hot=0; 
		}
		
		xianshi();
		
		Sleep(sleeptime);//行动停留 
	}
	gameover(2);

}

int main(){

	start:printf("\n\n\n				*********小青の奇妙冒险*********\n\n");
	printsnake();
	printf("\n\n					1、开始游戏1\n\n\n");
	printf("					2、开始游戏2\n\n\n");
	printf("					3、游戏说明\n\n\n"); 
	printf("					4、退出游戏\n"); 
	int choice;
	scanf("%d",&choice);
	switch(choice){
		case 1: system("cls");gamestart1();Sleep(1000);printf("\t\t按任意键返回主页面");getch();system("cls");sleeptime=200;score=0;goto start;break;
		case 2: system("cls");gamestart2();Sleep(1000);printf("\t\t按任意键返回主页面");getch();system("cls");sleeptime=200;score=0;goto start;break;
		case 3:
			system("cls");
			printf("游戏一:关爱老年人玩家的匠心制作\n");
			printf("		独特主观延迟能力降低难度\n");
			printf("		按下空格即可体验上帝模式\n\n\n");
			printf("游戏二:适合高手操作的加速系统\n");
			printf("		根据小青的身长均匀加速\n");
			printf("		当然有最高速度限制着,不必过分紧张\n\n");
			printf("按任意键返回主页面");
			getch();
			system("cls");
			goto start;
		case 4: exit(1);break;
	}
	if(choice!=1&&choice!=2&&choice!=3&&choice!=4){
		printf("输入错误,请重新输入!");
		Sleep(3000); 
		system("cls");
		goto start;
	}
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值