|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
学了一个多月,花了几天时间,查了一些资料,撸了几百行代码。
用了线程和回调函数,有点四不像。
有个程序猿看了代码说像shi一样。请大家指点一下,什么问题。
另外,有时候不产生食物,不知道问题出在哪。
工具:VS2013
- #include <stdio.h>
- #include <time.h>
- #include <windows.h>
- #include <stdlib.h>
- #include <conio.h>
- #include <stdbool.h>
- #include <stdint.h>
- #include <string.h>
- ///////////////////////////////////////////////////////////////////////
- #define printBeginUIPos 40
- #define printPoolUIPos 75
- //////////////////////////////////////////////////////////////////////
- typedef struct SNAKE //定义蛇的结构
- {
- POINT snakeHeadPos; //蛇头坐标
- int Len; //蛇身长度
- char direction; //当前行动方向
- int score; //游戏得分
- struct SNAKE *next; //指向下一个节点的指针
- }Snake;
- typedef struct FOOD //定义食物的坐标
- {
- int x;
- int y;
- }food;
- food *Food;
- int gameStatus = 1; //定义当前游戏状态
- //1、正常游戏;2、退出游戏;3、暂停游戏;4、撞到墙壁;5、吃到自己
- HWND g_hConsoleOutPut; //控制台句柄
- Snake *head,*p;
- HANDLE hThread;
- DWORD ThreadID;
- //HHOOK glhHook = NULL;
- //HINSTANCE glhInstance;
- /////////////////////////////------函数声明-------//////////////////////////////////
- void initBeginUI(); //初始化开始界面
- void printGamePool(); //打印游戏池
- void gotoxy(short x, short y); //鼠标移动到 x,y
- void initGame(); //初始化游戏
- void createFood(); //产生食物
- int playGame();
- void decideDirection(key); //由按键字母得到方向
- void moveSnake();
- void endGame();
- void CALLBACK TimeProc(HWND,UINT,UINT,DWORD); //时间类的回调函数
- //void CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam);
- void threadMoveSnake(); //线程--蛇移动
- /////////////////////////////----Main----////////////////////////
- int main()
- {
- initBeginUI();
- initGame();
- playGame();
- system("pause > nul");
- system("cls");
- return 0;
- }
- ///////////////////////////////////////////////////////////////////////
- void initBeginUI() //初始化开始界面
- {
- g_hConsoleOutPut = GetStdHandle(STD_OUTPUT_HANDLE);
- CONSOLE_CURSOR_INFO cursorInfo = { 1, false };
- SetConsoleCursorInfo(g_hConsoleOutPut,&cursorInfo);
- SetConsoleTitleA("Snake---By fpx");
- system("mode con cols=100 lines=30");
- SetConsoleTextAttribute(g_hConsoleOutPut, 0x0F); //API设置控制台窗口字体颜色和背景色的函数
- gotoxy(printBeginUIPos, 5);
- printf("┏━━━━━━━┓");
- gotoxy(printBeginUIPos, 6);
- printf("┃ %2s%s%2s ┃", "", "-贪吃蛇-", "");
- gotoxy(printBeginUIPos, 7);
- printf("┗━━━━━━━┛");
- gotoxy(printBeginUIPos, 10);
- printf(" Made By fpx");
- gotoxy(printBeginUIPos-2, 12);
- printf("Press any key to continue...");
- while (1)
- {
- if (_kbhit())
- {
- break;
- }
- }
- //fflush(stdin); //清除标准输入设备(即键盘)的缓冲区。
- _getch();
- system("cls");
- printGamePool();
- }
- void printGamePool() //打印游戏池
- {
- int i;
- for (i = 0; i < 70; i += 2)
- {
- gotoxy(i, 0);
- printf("■");
- gotoxy(i, 29);
- printf("■");
- }
- for (i = 0; i < 30; i++)
- {
- gotoxy(0, i);
- printf("■");
- gotoxy(70, i);
- printf("■");
- }
- SetConsoleTextAttribute(g_hConsoleOutPut, 0xB);
- gotoxy(printPoolUIPos, 8);
- printf("□向左移动:← A");
- gotoxy(printPoolUIPos, 10);
- printf("□向右移动:→ D");
- gotoxy(printPoolUIPos, 12);
- printf("□向下移动:↓ S");
- gotoxy(printPoolUIPos, 14);
- printf("□向下移动:↑ W");
- gotoxy(printPoolUIPos, 16);
- printf("□Score : 0");
- gotoxy(printPoolUIPos, 18);
- printf("■By: fpx 15.11.18");
- }
- void gotoxy(short x, short y)
- {
- COORD pos = { x, y };
- SetConsoleCursorPosition(g_hConsoleOutPut, pos);
- }
- ///////////////////////////////////////////////////////////////////////
- void initGame() //初始化游戏
- {
- int i;
- Snake *tail;
- tail = (Snake *)malloc(sizeof(Snake)); //定义蛇尾
- tail->next = NULL;
- tail->snakeHeadPos.x = 20;
- tail->snakeHeadPos.y = 5;
- for (i = 0; i < 2; i++)
- {
- head = (Snake *)malloc(sizeof(Snake));
- head->next = tail;
- head->snakeHeadPos.x = 20 + 2 * (i+1); head->snakeHeadPos.y = 5;
- tail = head;
- }
- head = tail;
- head->direction = 'D';
- head->Len = 3;
- head->score = 0;
- while (tail != NULL)
- {
- gotoxy(tail->snakeHeadPos.x, tail->snakeHeadPos.y);
- printf("■");
- tail = tail->next;
- }
- createFood();
- }
- void createFood() //产生食物
- {
- food *food_1;
- srand((unsigned)time(NULL));
- food_1 = (food *)malloc(sizeof(food));
- while ((food_1->x % 2) != 0 || food_1->x < 2) //保证食物的横坐标为2的偶数
- {
- food_1->x = rand() % 67 + 2;
- }
- food_1->y = rand() % 28 + 1;
- p = head;
- while (p->next != NULL)
- {
- if (food_1->x == p->snakeHeadPos.x && food_1->y == p->snakeHeadPos.y)
- {
- createFood();
- return 0;
- }
- p = p->next;
- }
- Food = food_1;
- gotoxy(food_1->x, food_1->y);
- printf("☆");
- }
- //////////////////////////////////////////////////////////////////////
- int playGame()
- {
- char direction,key;
- //clock_t clockNow, clockLast;
- //clockLast = clock();
- hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)threadMoveSnake, NULL, 0, &ThreadID);
-
- while (1)
- {
- key = _getch();
- if (key == 27)
- {
- gameStatus = 2;
- }
- if (gameStatus > 2)
- {
- return 0;
- }
- decideDirection(key);
- Sleep(150);
- }
- }
- void decideDirection(key) //由按键字母得到方向
- {
- char returnValue;
- switch (key)
- {
- case 'W':
- case 'w':
- case 72:
- if (head->direction != 'S')
- {
- head->direction = 'W';
- }
- break;
- case 'S':
- case 's':
- case 80:
- if (head->direction != 'W')
- {
- head->direction = 'S';
- }
- break;
- case 'A':
- case 'a':
- case 75:
- if (head->direction != 'D')
- {
- head->direction = 'A';
- }
- break;
- case 'D':
- case 'd':
- case 77:
- if (head->direction != 'A')
- {
- head->direction = 'D';
- }
- break;
- default:
- head->direction = head->direction;
- break;
- }
- }
- void moveSnake()
- {
- //1、判断是否撞墙
- //2、由方向确定坐标的变化
- //3、判断下一个是否为食物,若是,则加长;否则移动蛇身
- //4、判断是否吃到自己
- int x, y;
- if (head->snakeHeadPos.x < 2 || head->snakeHeadPos.x > 68 || head->snakeHeadPos.y < 1 || head->snakeHeadPos.y > 29)
- {
- gameStatus = 4;
- endGame();
- }
- x = head->snakeHeadPos.x;
- y = head->snakeHeadPos.y;
- Snake *nextsnake,*q;
- nextsnake = (Snake *)malloc(sizeof(Snake));
- q = (Snake *)malloc(sizeof(Snake));
- //ZeroMemory(&p,sizeof(p)); //清空结构体
- switch (head->direction)
- {
- case 'W':y--; break;
- case 'S':y++; break;
- case 'A':x -= 2; break;
- case 'D':x += 2; break;
- }
- nextsnake->snakeHeadPos.x = x; //对新节点赋值
- nextsnake->snakeHeadPos.y = y;
- nextsnake->Len = head->Len;
- nextsnake->direction = head->direction;
- nextsnake->score = head->score;
- nextsnake->next = head;
- if (nextsnake->snakeHeadPos.x == Food->x && nextsnake->snakeHeadPos.y == Food->y)
- {
- head = nextsnake;
- p = head;
- while (p != NULL)
- {
- gotoxy(p->snakeHeadPos.x, p->snakeHeadPos.y);
- printf("■");
- p = p->next;
- }
- head->Len += 1;
- head->score += 10;
- gotoxy(printPoolUIPos, 16);
- printf("□Score : %d",head->score);
- createFood();
- }
- else
- {
- head = nextsnake;
- p = head;
- while (p->next->next != NULL)
- {
- gotoxy(p->snakeHeadPos.x, p->snakeHeadPos.y);
- printf("■");
- p = p->next;
- }
- gotoxy(p->next->snakeHeadPos.x, p->next->snakeHeadPos.y);
- printf(" ");
- p->next = NULL;
- }
- q = head->next;
- while (q)
- {
- if (head->snakeHeadPos.x == q->snakeHeadPos.x && head->snakeHeadPos.y == q->snakeHeadPos.y)
- {
- gameStatus = 5;
- endGame();
- }
- q = q->next;
- }
- }
- void CALLBACK TimeProc(HWND hwnd, UINT message, UINT idTimer, DWORD dwTime)
- {
- moveSnake();
- }
- //void CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
- //{
- // switch (wParam)
- // {
- // case VK_UP:
- // case 'W':
- // case 'w':
- // case 72:
- // if (head->direction != 'S')
- // {
- // head->direction = 'W';
- // }
- // break;
- // case VK_DOWN:
- // case 'S':
- // case 's':
- // case 80:
- // if (head->direction != 'W')
- // {
- // head->direction = 'S';
- // }
- // break;
- // case VK_LEFT:
- // case 'A':
- // case 'a':
- // case 75:
- // if (head->direction != 'D')
- // {
- // head->direction = 'A';
- // }
- // break;
- // case VK_RIGHT:
- // case 'D':
- // case 'd':
- // case 77:
- // if (head->direction != 'A')
- // {
- // head->direction = 'D';
- // }
- // break;
- // //default:
- // // head->direction = head->direction;
- // //break;
- // }
- //}
- void threadMoveSnake() //线程中移动蛇身
- {
- SetTimer(NULL, 1, 300, TimeProc);
- MSG msg;
- while (GetMessage(&msg, NULL, 0, 0))
- {
- if (msg.message == WM_TIMER)
- {
- DispatchMessage(&msg);
- }
- //if (msg.message == WM_KEYDOWN)
- //{
- // TranslateMessage(&msg);
- // DispatchMessage(&msg);
- //}
- }
- }
- ////////////////////////////////////////////////////////////////////////////
- void endGame()
- {
- /*TerminateThread(hThread, 0);*/
-
- KillTimer(g_hConsoleOutPut,1);
- system("cls");
- gotoxy(40, 12);
- switch (gameStatus)
- {
- case 2:
- printf("您的已经结束了游戏。"); break;
- case 4:
- printf("您撞到墙了。游戏结束."); break;
- case 5:
- printf("您咬到自己了。游戏结束."); break;
- }
- gotoxy(40, 15);
- printf("您的得分是 %d\n", head->score);
- //ExitThread(0);
- system("pause > nul");
- /*system("cls");*/
- exit(0);
- }
复制代码 |
|