貪吃蛇遊戲,基於C語言,vs2010平臺
阿新 • • 發佈:2019-01-31
參考網上其他C語言貪吃蛇原始碼,自己在VS2010平臺上覆現。並優化了部分程式碼。
/** ****************************************************************************** * @file snaker.c * @author A Big Cat * @version V1.0 * @date 2017-2-26 * @brief My FIRST GAME application program based on C Langugage, of course, I referred to other programs on the Internet. ****************************************************************************** **/ #include <Windows.h>//包含WinCon.h #include <stdio.h> #include <time.h> #include <stdlib.h> /* ***巨集定義 */ #define MAP_WIDTH 30 #define MAP_HEIGHT 30 #define UP 1 #define DOWN 2 #define LEFT 3 #define RIGHT 4 /* ***結構體 */ typedef struct snake//蛇身的一個節點 { unsigned int x, y; struct snake *next; }SNAKE; /* ***全域性變數 */ unsigned int Score = 0, Score_Add =10; unsigned int Direction, Time_sleep = 300; SNAKE *head, *food;//蛇頭指標, 食物指標 SNAKE *q;//遍歷和判斷蛇的時候用到的指標 unsigned char Game_status = 0;// 遊戲結束的情況:1:撞到牆;2:咬到自己;3:主動退出遊戲。 /* ***函式宣告 */ void Pos_Set(unsigned int x, unsigned int y); void Map_Create(void); void Snake_Init(void); void Pause(void); void Game_Control(void); void Game_Init(void); void Game_End(void); void Wall_Cross(SNAKE *s); void Snake_Move(void); unsigned char Bit_Self(SNAKE *s); void Debug(void); /* ***主函式 */ unsigned char main() { Game_Init(); Game_Control(); //Game_End(); return 0; } /**************************************************************** * Function Name: Pos_Set * Description : 設定游標位置 * Parameter : unsigned int x, unsigned int y * Return : void ***************************************************************/ void Pos_Set(unsigned int x, unsigned int y) { COORD pos; HANDLE houtput; pos.X = x; pos.Y = y; houtput = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleCursorPosition(houtput,pos); } /**************************************************************** * Function Name: Map_Create * Description : 建立地圖 * Parameter : void * Return : void ***************************************************************/ void Map_Create(void) { unsigned int i = 0; for (i = 0; i <= MAP_WIDTH; i++) // 上下邊框 { Pos_Set(2 * i, 0); printf("■"); Pos_Set(2 * i, MAP_HEIGHT); printf("■"); } for (i = 0; i <= MAP_HEIGHT; i++) { Pos_Set(0, i); printf("■"); Pos_Set(2 * MAP_WIDTH, i ); printf("■"); } } /**************************************************************** * Function Name: Snake_Init() * Description : 蛇的初始化 * Parameter : void * Return : void ***************************************************************/ void Snake_Init(void) { SNAKE *tail; unsigned int i = 0; head = (SNAKE *)malloc(sizeof(SNAKE)); head->x = 12*2; head->y = 12; head->next = NULL; q = head; for (i = 1;i <=1; i++) { tail = (SNAKE *)malloc(sizeof(SNAKE)); tail->x = 12*2+2*i; tail->y = 12; q->next = tail; //上一節點的next指向tail q = q->next;//or q = tail //q移動指向tail q充當指揮者 } tail->next = NULL; q = head;//q 指向頭 while(q != NULL) { Pos_Set(q->x, q->y); printf("■"); q = q->next; } } /**************************************************************** * Function Name: Food_Create() * Description : 創造食物 * Parameter : void * Return : void ***************************************************************/ void Food_Create(void) { SNAKE *food_1; srand((unsigned )time(NULL)); food_1 =(SNAKE *)malloc(sizeof(SNAKE)); food_1->x = 2*(rand()%(MAP_WIDTH - 1)+1); food_1->y = rand()%(MAP_HEIGHT -1)+1; q = head; while(q != NULL) { if (q->x == food_1->x && q->y == food_1->y) { food_1->x = 2*(rand()%(MAP_WIDTH - 1)+1); food_1->y = rand()%(MAP_HEIGHT -1)+1; q = head; } else { q = q->next; } } Pos_Set(food_1->x, food_1->y); printf("★"); food = food_1; } /**************************************************************** * Function Name: Wall_Cross * Description : 判斷是否撞牆 * Parameter : SNAKE *s * Return : void ***************************************************************/ void Wall_Cross(SNAKE *s) { if (s->x == 0 || s->x == MAP_WIDTH*2 || s->y == 0 || s->y== MAP_HEIGHT ) { Game_status = 1; Game_End(); } } /**************************************************************** * Function Name: Bit_Self * Description : 判斷蛇是否要到自己 * Parameter : SNAKE *s * Return : 0 沒有咬到自己 : 1 咬到自己 ***************************************************************/ unsigned char Bit_Self(SNAKE *s) { q = head; while (q != NULL) { if ((q->x == s->x) && (q->y == s->y)) { return 1; } q = q->next; } return 0; } /**************************************************************** * Function Name: Snake_Move() * Description : 蛇的運動:上UP 下DOWN 左LEFT右RIGHT * Parameter : void * Return : void ***************************************************************/ void Snake_Move(void) { SNAKE * head_next; head_next = (SNAKE *)malloc(sizeof(SNAKE)); if(Direction == UP) { head_next->x = head->x; head_next->y = head->y - 1; } else if (Direction == DOWN) { head_next->x = head->x; head_next->y = head->y + 1; } else if(Direction == LEFT) { head_next->x = head->x - 2; head_next->y = head->y; } else if(Direction == RIGHT) { head_next->x = head->x + 2; head_next->y = head->y; } Wall_Cross(head_next);//是否撞牆 if (Bit_Self(head_next)==1)//是否咬到自己 { Game_status = 2; Game_End(); } if (head_next->x == food->x && head_next->y == food->y)//有食物 { head_next->next = head; head = head_next; q = head; while(q !=NULL)//加上新蛇頭,全都畫 { Pos_Set(q->x, q->y); printf("■"); q = q->next; } Score += Score_Add; Food_Create(); if(Time_sleep >20) { Time_sleep -= 20; Score_Add += 5; } } else//沒有食物 { head_next->next = head; head = head_next; q = head; while (q ->next->next != NULL)//加上新蛇頭,最後一個尾巴不畫 { Pos_Set(q->x, q->y); printf("■"); q = q->next; } Pos_Set(q->next->x, q->next->y); printf(" "); free(q->next); q->next = NULL; } } /**************************************************************** * Function Name: Game_Control * Description : 控制遊戲 * Parameter : void * Return : void ***************************************************************/ void Game_Control(void) { Pos_Set(64, 14); printf("撞牆---->dead、咬到自己---->dead"); Pos_Set(64, 15); printf("用↑、↓、←、→控制貪吃蛇運動方向"); Pos_Set(64, 16); printf("ESC: 退出遊戲, SPACE: 暫停遊戲"); Direction = DOWN; while (1) { Pos_Set(64, 10); printf("得分: %d分", Score); Pos_Set(64, 11); printf("每個食物得分: %d", Score_Add); if (GetAsyncKeyState(VK_UP) && (Direction != DOWN)) { Direction = UP; } else if (GetAsyncKeyState(VK_DOWN) && (Direction != UP)) { Direction = DOWN; } else if (GetAsyncKeyState(VK_LEFT) && (Direction != RIGHT)) { Direction = LEFT; } else if (GetAsyncKeyState(VK_RIGHT) && (Direction != LEFT)) { Direction = RIGHT; } else if (GetAsyncKeyState(VK_SPACE) ) { Pause(); } else if (GetAsyncKeyState(VK_ESCAPE)) { Game_status = 3; } Sleep(Time_sleep); Snake_Move(); } } /**************************************************************** * Function Name: Pause * Description : 暫停 * Parameter : void * Return : void ***************************************************************/ void Pause(void) { while (1) { Sleep(300); if(GetAsyncKeyState(VK_SPACE)) { break; } } } /**************************************************************** * Function Name: WelcomeToGame * Description : 開始介面 * Parameter : void * Return : void ***************************************************************/ void WelcomeToGame(void) { Pos_Set(40, 12); //system("title C語言程式遊戲之<貪吃蛇>"); Pos_Set(40, 25); printf("作者: 一隻大貓\n"); system("pause"); system("cls"); Pos_Set(25, 13); printf("蛇身越長,速度越快。\n"); system("pause"); system("cls"); } /**************************************************************** * Function Name: Game_End * Description : 遊戲結束 * Parameter : void * Return : void ***************************************************************/ void Game_End(void) { system("cls"); Pos_Set(24, 12); if (Game_status == 1) { printf("對不起。您裝到牆了,遊戲結束,北北...\n"); } else if (Game_status == 2) { printf("對不起。您咬到自己了,遊戲結束,北北..."); } else if (Game_status == 3) { printf("遊戲結束,北北..."); } Pos_Set(24,13); printf("您的得分是: %d 分", Score); system("pause"); exit(0); } /**************************************************************** * Function Name: Game_Init * Description : 遊戲初始化 * Parameter : void * Return : void ***************************************************************/ void Game_Init(void) { system("mode con cols=100 lines=100"); WelcomeToGame(); Map_Create(); Snake_Init(); Food_Create(); }