彩色的贪吃蛇实现,功能强大,有等级模块,道具功能,后面有效果预览,先上代码:
console.h
#include <windows.h> //颜色定义 #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 <windows.h> //界面图案设定 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<stdio.h> #include<conio.h> #include<stdlib.h> #include<time.h> #include<string.h> #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; }
预览图: