博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
功能超级丰富的彩色贪吃蛇,有道具,有等级!
阅读量:7304 次
发布时间:2019-06-30

本文共 17057 字,大约阅读时间需要 56 分钟。

彩色的贪吃蛇实现,功能强大。有等级模块。道具功能,后面有效果预览。先上代码:

console.h

#include 
//颜色定义#define FWHITE FOREGROUND_INTENSITY|FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE //白色前景#define FRED FOREGROUND_INTENSITY|FOREGROUND_RED //红色前景#define FBLUE FOREGROUND_INTENSITY|FOREGROUND_BLUE //蓝色前景#define FGREEN FOREGROUND_INTENSITY|FOREGROUND_GREEN //绿色前景#define FYELLOW FOREGROUND_INTENSITY|FOREGROUND_RED|FOREGROUND_GREEN //黄色前景#define FPURPLE FOREGROUND_INTENSITY|FOREGROUND_RED|FOREGROUND_BLUE //紫色前景#define FBLACK NULL //黑色前景#define BBLACK NULL //黑色背景#define BWHITE BACKGROUND_INTENSITY|BACKGROUND_RED|BACKGROUND_GREEN|BACKGROUND_BLUE //白色背景#define BRED BACKGROUND_INTENSITY|BACKGROUND_RED //红色背景#define BBLUE BACKGROUND_INTENSITY|BACKGROUND_BLUE //蓝色背景#define BGREEN BACKGROUND_INTENSITY|BACKGROUND_GREEN //绿色背景#define BYELLOW BACKGROUND_INTENSITY|BACKGROUND_RED|BACKGROUND_GREEN //黄色背景#define BPURPLE BACKGROUND_INTENSITY|BACKGROUND_RED|BACKGROUND_BLUE //紫色背景void xSetCursor(int x,int y){ COORD c; c.X = x - 1; c.Y = y - 1; SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),c);}void HideCursor(){ CONSOLE_CURSOR_INFO cursor_info = {1, 0}; SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);}void xSetColor(WORD color){ SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),color);}/* int SetConsoleTitle(char *title)*/int ShowConsoleInfo(){ int ret; HANDLE hWin = GetStdHandle(STD_OUTPUT_HANDLE); CONSOLE_SCREEN_BUFFER_INFO csbiInfo; ret = GetConsoleScreenBufferInfo(hWin, &csbiInfo); if (ret) { printf("Buffer Size: [X]%d - [Y]%d\n", csbiInfo.dwSize.X, csbiInfo.dwSize.Y); printf("Cursor Pos : [X]%d - [Y]%d\n", csbiInfo.dwCursorPosition.X, csbiInfo.dwCursorPosition.Y); printf("Attributes : %d\n", csbiInfo.wAttributes); printf("Current Win: [L]%d - [R]%d - [T]%d - [B]%d\n", \ csbiInfo.srWindow.Left, csbiInfo.srWindow.Right, csbiInfo.srWindow.Top, csbiInfo.srWindow.Bottom); printf("Maximum Win: [X]%d - [Y]%d\n", csbiInfo.dwMaximumWindowSize.X, csbiInfo.dwMaximumWindowSize.Y); puts("Over."); } return ret;}


setting.h

#include 
//界面图案设定char sharp[][3] = {"","■","□","◎","◆"};#define SnakeHead 0#define SnakeBody 1#define Wall 1#define White 2#define SnakeEnd 3#define SFood 4#define StartSnakeLen 8//游戏设定#define MAP_WIDTH 24#define MAP_HIGH 22#define CTRLWNDLEFT 5#define CTRLWNDWIDTH 10#define CTRLWNDHIGH MAP_HIGH#define MINSPEED 400#define MAXSPEED 200//蛇定义struct Snake{ int x,y; struct Snake *next,*front;};struct Snake *Snake_Head;struct Snake *Snake_End =NULL;struct Snake *Snake_OldEnd =NULL;struct Snake Food;struct Snake *ExtraFood[5];struct Snake temp;enum direct {LEFT,RIGHT,UP,DOWN};enum direct Direct;//食物enum styfood {FOOD_NORMAL,FOOD_GETDEF,FOOD_FIVEFOOD};enum styfood FoodStyle;enum styfood ExtraFoodStyle[5];//定义属性long int Score = 0;int IsPause = 0;int EatNum = 0;int LEVEL = 0;long int EXP = 0;int SPEED = MINSPEED;int Tool_Defense = 0;int Tool_FiveFood = 0;/*初始化数据*/ void Init(){ Snake_Head = (struct Snake*)malloc(sizeof(struct Snake)); int i; for (i = 0 ; i < 5; i++) { ExtraFood[i] = (struct Snake*)malloc(sizeof(struct Snake)); ExtraFood[i]->next = NULL; } temp.x=0; temp.y=0; Score = 0; IsPause = 0; EatNum = 0; LEVEL = 0; EXP = 0; SPEED = MINSPEED; Direct = RIGHT; Tool_Defense = 10; Tool_FiveFood = 10;}


snake.h

#include
#include
#include
#include
#include
#include"setting.h"#include"console.h"/*函数声明*//* 开场画面 */void BeginImage();/*初始化,画蛇,画食物*/void Start(); /*移动。包含蛇的描绘*/void Move(); /*画地图*/void Draw_Map(); /*画所有蛇*/void Draw_Snake(); /*输出成绩*/void Draw_Score();/*画食物*/void Draw_Food();/*画控制区域*/void Draw_CtrlWnd();/*输出游戏中提示*/void Draw_Play();/*输出升级提示*/void Draw_UpLevel();/*输出工具信息*/void Draw_Tool();/*推断是否死亡*/int IsDeath(); /*推断输入是否是游戏控制按键*/int IsGameCtrl(unsigned char ch); /*生成食物*/int CreateFood(int count); /*食物被吃,包含画食物*/int EatFood(); ///*对蛇的操控*/int Snake_Ctrl(unsigned char ch);/*蛇不死*/int Snake_Defense();/*游戏暂停*/void Game_Pause();/*游戏结束*/void Game_Over();/*计算并输出分数*/void CalcScore(int num);/*清空控制区域*/void Cls_CtrlWnd();/*控制区域闪烁型提示*/void CtrlWnd_Flash(char *a,char *b,int loc,int);void BeginImage(){ //开场画面 HideCursor(); xSetColor(FGREEN); printf(" \n\n /^\/^\\\ \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"); printf(" ! \\ ~-____-~ _-~ ~-_ ~-_-~ /\ \n"); printf(" ~-_ _-~ ~-_ _-~ \ \n"); printf(" ~--______-~ ~-___-~\ \n"); printf(" \n"); int t = getch(); if (t == 0 || t==224) getch(); //特殊输入会输入两个字符,如F1~F12和控制键 system("cls");}void Start(){ Snake_Head->x = MAP_WIDTH/3*4 - 1 ; //蛇头坐标 Snake_Head->y = MAP_HIGH / 4*1; Snake_Head->front = NULL; struct Snake *ps = Snake_Head, *p; int m; for (m = 2; m <= StartSnakeLen; m++) //蛇身坐标 { p = (struct Snake *)malloc(sizeof(struct Snake)); p->x = MAP_WIDTH/3*4 - m*2 +1; p->y = MAP_HIGH / 4*1; p->next = NULL; p->front = ps; ps->next = p; ps = p; } Snake_End = Snake_Head; while(Snake_End->next != NULL) Snake_End = Snake_End->next; Draw_Map(); Draw_CtrlWnd(); Draw_Snake(); Draw_Score(); Draw_Tool(); Draw_Play(); xSetColor(FPURPLE); xSetCursor(MAP_WIDTH/2*2-7,MAP_HIGH/2); printf(" 随意键開始! "); int t = getch(); if (t == 0 || t==224) getch(); //特殊输入会输入两个字符,如F1~F12和控制键 xSetColor(FGREEN); xSetCursor(MAP_WIDTH/2*2-7,MAP_HIGH/2); for (m = 1 ; m <= 8; m++) printf("%2s",sharp[White]); srand(time(NULL)); CreateFood(0); Draw_Food();}void Draw_Map(){ //描绘地图 xSetColor(FGREEN); int m,n; for (m = 1; m <= MAP_HIGH; m++) { for (n = 1; n <= MAP_WIDTH; n++) printf("%s",sharp[White]); xSetCursor(1,m+1); } for (m = 1; m <= MAP_HIGH; m++) { xSetCursor(1,m); printf("%s",sharp[Wall]); xSetCursor(MAP_WIDTH * 2 - 1,m); printf("%s",sharp[Wall]); } for (m = 1; m <= MAP_WIDTH; m++) { xSetCursor(m * 2 - 1,1); printf("%s",sharp[Wall]); xSetCursor(m * 2 - 1,MAP_HIGH); printf("%s",sharp[Wall]); }}void Draw_Snake(){ //画所有蛇 xSetColor(FRED); struct Snake *ps = Snake_Head; for (;ps != NULL; ps = ps->next) { xSetCursor(ps->x , ps->y); if (ps == Snake_Head) printf("%s",sharp[SnakeHead]); else if (ps->next == NULL) printf("%s",sharp[SnakeEnd]); else printf("%s",sharp[SnakeBody]); }}int IsDeath(){ struct Snake *ps = Snake_Head ; switch(Direct) //与蛇身相撞 { case LEFT: for (;ps != NULL; ps = ps->next) if ((Snake_Head->y == ps->y) && (Snake_Head->x - 2 == ps->x) ) return 1; if (Snake_Head->x - 2 <= 2) return 1; break; case RIGHT: for (;ps != NULL; ps = ps->next) if ((Snake_Head->y == ps->y) && (Snake_Head->x + 2 == ps->x) ) return 1; if (Snake_Head->x + 2 >= MAP_WIDTH*2-1) return 1; break; case UP: for (;ps != NULL; ps = ps->next) if ((Snake_Head->y - 1 == ps->y) && (Snake_Head->x == ps->x) ) return 1; if (Snake_Head->y - 1 <= 1) return 1; break; case DOWN: for (;ps != NULL; ps = ps->next) if ((Snake_Head->y + 1 == ps->y) && (Snake_Head->x == ps->x) ) return 1; if (Snake_Head->y + 1 >= MAP_HIGH) return 1; break; } return 0;}void Move() { //移动 struct Snake *ps = (struct Snake*)malloc(sizeof(struct Snake)); //初始化新蛇头 switch(Direct) { case LEFT: ps->x = Snake_Head->x - 2; ps->y = Snake_Head->y ; break; case RIGHT: ps->x = Snake_Head->x + 2; ps->y = Snake_Head->y ; break; case UP: ps->x = Snake_Head->x ; ps->y = Snake_Head->y - 1 ; break; case DOWN: ps->x = Snake_Head->x ; ps->y = Snake_Head->y + 1; break; } ps->front = NULL; ps->next = Snake_Head; Snake_Head->front = ps; Snake_Head = ps; //填补地图 xSetColor(FGREEN); //地图颜色 xSetCursor(Snake_End->x,Snake_End->y); printf("%2s",sharp[White]); //画蛇 xSetColor(FRED); //蛇颜色 xSetCursor(Snake_Head->x,Snake_Head->y); //画蛇头 printf("%2s",sharp[SnakeHead]); xSetCursor(Snake_Head->next->x,Snake_Head->next->y); //画第二节蛇身 printf("%2s",sharp[SnakeBody]); xSetCursor(Snake_End->front->x,Snake_End->front->y); //画蛇尾 printf("%2s",sharp[SnakeEnd]); Snake_End = Snake_End->front; free(Snake_End->next); //删除最后一个节点 Snake_End->next = NULL; }int CreateFood(int count){ //生成食物 int Success = 0; struct Snake *ps; int num,i; if (count == 0) { while(!Success) { Food.x = rand()%(MAP_WIDTH - 3) * 2 + 3; Food.y = rand()%(MAP_HIGH - 2) + 2 ; for (ps = Snake_Head; ps != NULL; ps = ps->next) if ((ps->x == Food.x) && (ps->y == Food.y)) { Success = 0; break; } if (ps == NULL) Success = 1; } if (Success) //食物样式 { num = rand()%16; if (num == 1) FoodStyle = FOOD_GETDEF; else if (num == 2) FoodStyle = FOOD_FIVEFOOD; else FoodStyle = FOOD_NORMAL; } } else { for (i = 0; i < 5; i++) { Success = 0; while(!Success) { //随机食物位置 ExtraFood[i]->x = rand()%(MAP_WIDTH - 3) * 2 + 3; ExtraFood[i]->y = rand()%(MAP_HIGH - 2) + 2 ; for (ps = Snake_Head; ps != NULL; ps = ps->next) if ((ps->x == ExtraFood[i]->x) && (ps->y == ExtraFood[i]->y)) { Success = 0; break; } if (ps == NULL) Success = 1; } if (Success) //食物样式 { ExtraFood[i]->next = &temp; //避免NULL值 num = rand()%20; if (num == 1) ExtraFoodStyle[i] = FOOD_GETDEF; else if (num == 2) ExtraFoodStyle[i] = FOOD_FIVEFOOD; else ExtraFoodStyle[i] = FOOD_NORMAL; } } } return Success;}int EatFood(){ int success = 0; struct Snake *ps = (struct Snake*)malloc(sizeof(struct Snake)); if (Snake_Head->x == Food.x && Snake_Head->y == Food.y) { //食物被吃 ps->x = Food.x; ps->y = Food.y; ps->next = Snake_Head; ps->front = NULL; Snake_Head->front = ps; Snake_Head = ps; //生成食物 CreateFood(0); //描绘食物 xSetColor(FWHITE); xSetCursor(Food.x,Food.y); printf("%2s",sharp[SFood]); success = 1; if (FoodStyle == FOOD_GETDEF) Tool_Defense++; if (FoodStyle == FOOD_FIVEFOOD) Tool_FiveFood++; } int i; for (i = 0; i < 5; i++) //额外食物 { if (ExtraFood[i]->next != NULL) { if (Snake_Head->x == ExtraFood[i]->x && Snake_Head->y == ExtraFood[i]->y) { ps = (struct Snake*)malloc(sizeof(struct Snake)); ps->x = ExtraFood[i]->x; ps->y = ExtraFood[i]->y; ps->next = Snake_Head; ps->front = NULL; Snake_Head->front = ps; Snake_Head = ps; if (ExtraFoodStyle[i] == FOOD_GETDEF) Tool_Defense++; if (ExtraFoodStyle[i] == FOOD_FIVEFOOD) Tool_FiveFood++; ExtraFood[i]->next = NULL; success = 1; } } } Draw_Tool(); return success;}int Snake_Ctrl(unsigned char ch){ switch(ch) //方向改变返回1 用于Sanke_Defense() { case 224: Snake_Ctrl(getch()); break; case 72: case 119: if (Direct != DOWN ) Direct = UP; return 1; case 80: case 115: if (Direct != UP) Direct = DOWN; return 1; case 77: case 100: if (Direct != LEFT) Direct = RIGHT; return 1; case 75: case 97: if (Direct != RIGHT) Direct = LEFT; return 1; case 32: IsPause = 1; break; case 49: if (Tool_FiveFood > 0) { CreateFood(5); Draw_Food(); Tool_FiveFood--; Draw_Tool(); } default: while(kbhit()) { if (IsGameCtrl(ch)) Snake_Ctrl(getch()); else ch = getch(); } } return 0;}int Snake_Defense(){ if (Tool_Defense > 0) { CtrlWnd_Flash("撞车了!","无敌护罩开启!",4,1); CtrlWnd_Flash("撞车了!","无敌护罩开启!",4,1); CtrlWnd_Flash("撞车了!","无敌护罩开启!",4,1); CtrlWnd_Flash("赶紧跑!","换个方向继续!",6,1); CtrlWnd_Flash("赶紧跑!","换个方向继续!",6,0); while(IsDeath()) { if (Snake_Ctrl(getch()) && !IsDeath()) break; } CtrlWnd_Flash(" "," ",6,0); Tool_Defense--; Draw_Play(); Draw_Tool(); return 1; } return 0;}void Draw_Score(){ xSetColor(FGREEN); xSetCursor(MAP_WIDTH * 2 + CTRLWNDLEFT + 4, 3); printf("等级:%8d",LEVEL); xSetCursor(MAP_WIDTH * 2 + CTRLWNDLEFT + 4, 4); if (Score == 0) printf("经验:%8d",EXP); else printf("经验:%6d/%d",EXP,(LEVEL+1)*30); xSetCursor(MAP_WIDTH * 2 + CTRLWNDLEFT + 4, 5); printf("吞噬:%8d",EatNum); xSetCursor(MAP_WIDTH * 2 + CTRLWNDLEFT + 4, 6); printf("分数:%8d",Score); } void Draw_CtrlWnd(){ //画控制面板 int m,n; //xSetColor(BBLACK|FBLUE); xSetCursor(MAP_WIDTH*2 + CTRLWNDLEFT,1); for (n = 1; n <= CTRLWNDWIDTH; n++) { printf("%2s",sharp[Wall]); } xSetCursor(MAP_WIDTH*2 + CTRLWNDLEFT , CTRLWNDHIGH); for (n = 1; n <= CTRLWNDWIDTH; n++) { printf("%2s",sharp[Wall]); } for (m = 1; m <= CTRLWNDHIGH; m++) { xSetCursor(MAP_WIDTH*2 + CTRLWNDLEFT, m); printf("%2s",sharp[Wall]); xSetCursor(MAP_WIDTH*2 + CTRLWNDLEFT + CTRLWNDWIDTH*2, m ); printf("%2s",sharp[Wall]); }}int IsGameCtrl(unsigned char ch){ switch(ch) { case 49: //1 case 97: //a case 100: //d case 115: //s case 119: //w case 224: //控制 case 72: //上 case 75: //左 case 80: //下 case 77: //右 case 32: //空格 return 1; default: return 0; }}void Game_Pause(){ int m; xSetColor(FPURPLE); xSetCursor(MAP_WIDTH/2*2-6,MAP_HIGH/2); printf(" 暂停中! "); while(IsPause) { CtrlWnd_Flash("暂停中!","按随意键继续!",4,1); if (kbhit()) { if (getch() == 224) getch(); IsPause = 0; } } xSetColor(FGREEN); xSetCursor(MAP_WIDTH/2*2-7,MAP_HIGH/2); for (m = 1 ; m <= 8; m++) printf("%2s",sharp[White]); Draw_Snake(); Draw_Play();}void Game_Over(){ Cls_CtrlWnd(); Draw_Score(); xSetColor(FPURPLE); xSetCursor(MAP_WIDTH/2*2-10,MAP_HIGH/2); printf(" GAME OVER! SCORE = %d ",Score); CtrlWnd_Flash("已阵亡!","按回车再来一把!",9,0); xSetCursor(MAP_WIDTH*2 + CTRLWNDLEFT + 3,CTRLWNDHIGH - 12); printf("终于得分: %d",Score); while(getch() != 13); Cls_CtrlWnd();}void CalcScore(int num){ Score= Score + num*5 + rand()%3; EatNum++; EXP = EXP + (LEVEL + 1)*3 + num*5 + rand()%4; if (EXP >= (LEVEL+1)*30) Draw_UpLevel(); while (EXP >= (LEVEL+1)*30) { EXP = EXP - (LEVEL+1)*30; LEVEL++; if (EXP < 0 ) EXP = 0; if (SPEED - 10 > MAXSPEED) SPEED = SPEED - 10; } Draw_Score(); }void Draw_Play(){ CtrlWnd_Flash("游戏中!","按空格键暂停!",4,0);}void Draw_Food(){ //描绘食物 xSetColor(FWHITE); xSetCursor(Food.x,Food.y); printf("%2s",sharp[SFood]); int i; for (i=0; i<5; i++) { if (ExtraFood[i]->next != NULL) { xSetColor(FWHITE); xSetCursor(ExtraFood[i]->x,ExtraFood[i]->y); printf("%2s",sharp[SFood]); } }}void Cls_CtrlWnd(){ int m,n; //xSetColor(BBLACK); for (m = 2; m < CTRLWNDHIGH; m++) { xSetCursor(MAP_WIDTH*2 + CTRLWNDLEFT + 2 , m); for (n = 2; n < CTRLWNDWIDTH; n++) printf("11"); }}void Draw_UpLevel(){ CtrlWnd_Flash(" "," ",4,0); CtrlWnd_Flash("升级了!","速度有所提升!",7,1); CtrlWnd_Flash("升级了!","速度有所提升!",7,1); CtrlWnd_Flash("游戏中!","按空格键暂停!",4,0); }void Draw_Tool(){ xSetColor(FGREEN); xSetCursor(MAP_WIDTH*2 + CTRLWNDLEFT + 4,8); printf("道具: "); if (Tool_Defense > 0) { xSetCursor(MAP_WIDTH*2 + CTRLWNDLEFT + 7,9); printf("无敌护罩:%-4d",Tool_Defense); } if (Tool_FiveFood > 0) { xSetCursor(MAP_WIDTH*2 + CTRLWNDLEFT + 4,10); printf("[1]食物爆发:%-4d",Tool_FiveFood); } if (Tool_Defense <= 0 && Tool_FiveFood <= 0) { xSetCursor(MAP_WIDTH*2 + CTRLWNDLEFT + 11,8); printf("无"); CtrlWnd_Flash(" "," ",CTRLWNDHIGH - 10,0); }}/*控制区域闪烁型提示*/void CtrlWnd_Flash(char *a,char *b,int loc,int isflash){ int t; xSetColor(FGREEN); xSetCursor(MAP_WIDTH*2 + CTRLWNDLEFT + 3,CTRLWNDHIGH - 1 - loc); printf("%s",a); if (b != NULL) { xSetCursor(MAP_WIDTH*2 + CTRLWNDLEFT + 3,CTRLWNDHIGH - loc); printf("%s",b); } if (isflash) { Sleep(500); xSetCursor(MAP_WIDTH*2 + CTRLWNDLEFT + 3,CTRLWNDHIGH - 1 - loc); t = strlen(a); for (; t > 0 ; t--) printf(" "); if (b != NULL) { xSetCursor(MAP_WIDTH*2 + CTRLWNDLEFT + 3,CTRLWNDHIGH - loc); t = strlen(b); for (; t > 0 ; t--) printf(" "); } Sleep(500); }}


main.c

/*  	wsad或方向键控制上下左右	取消多线程	修正死亡时钻入墙中	修正与自身相撞漏洞	修正非法输入时失控 	增加開始画面 	增加控制面板显示区域 */#include"snake.h"  int main() {	SetConsoleTitle("贪吃蛇V3.0       QQ:836663997  WSAD或方向键控制 1键使用道具");	BeginImage();	while(1)		//一次循环一次游戏 	{		/*游戏初始准备*/		system("cls");		Init();		Start();		while(1)		//游戏主体           		{			Move(); 			Sleep(SPEED);				if (kbhit())	Snake_Ctrl(getch());			if (EatFood())	CalcScore(1);			if (IsPause)	Game_Pause();			if (IsDeath())				if (Snake_Defense()) ;				else break; 		}		Game_Over();	}    return 0;}


预览图:

本文转自mfrbuaa博客园博客,原文链接:http://www.cnblogs.com/mfrbuaa/p/5230847.html,如需转载请自行联系原作者

你可能感兴趣的文章