在C++吧发现2个贪吃蛇源码:
#include<iostream> #include<windows.h> #include<conio.h> #include<time.h> #include<stdlib.h> using namespace std; int GameOver=0; struct Body//蛇身(链表结构) { int x,y;//蛇身结点坐标 Body *next;//下一个结点 }; void SetPos(int i,int j)//设定光标位置 { COORD pos={i-1,j-1};//坐标变量 HANDLE Out=GetStdHandle(STD_OUTPUT_HANDLE);//获取输出句柄 SetConsoleCursorPosition(Out,pos);//设定光标位置 } class Sneak//贪吃蛇类 { private: Body *head;//蛇头指针 int Direction;//移动方向。1,2,3,4对应上左下右 int Count;//蛇长 int Speed;//速度(等级) int FoodExist;//食物存在标记 int Food_x;//食物X坐标 int Food_y;//食物Y坐标 public: Sneak(int a=3,int b=4,int c=1,int d=0)//构造函数 { FoodExist=d;//起始不存在食物 Body *temp1,*temp2; head=new(Body);//申请起始蛇身3节 head->x=4; head->y=2; temp1=new(Body); temp1->x=3; temp1->y=2; temp2=new(Body); temp2->x=2; temp2->y=2; head->next=temp1; temp1->next=temp2; temp2->next=NULL; Direction=b;//方向为右 Count=a;//长为3 Speed=c;//等级1 } void Map();//画界面函数 void Paint();//画蛇身函数 void Food();//生成食物 int Over();//判断游戏是否结束 void Gaming();//游戏进程函数 void Move();//移动 }; void Sneak::Map()//使用 { int i; for(i=1;i<=50;i++) { SetPos(i,1); cout<<"-"; } for(i=2;i<=25;i++) { SetPos(1,i); cout<<"|"; SetPos(50,i); cout<<"|"; } for(i=1;i<=50;i++) { SetPos(i,25); cout<<"-"; } SetPos(54,3); cout<<"贪吃蛇"; SetPos(54,5); cout<<"长度:"<<Count; SetPos(54,7); cout<<"LEVEL:"<<Speed; } void Sneak::Food() { Body *p; int InBody=0; //判断食物是否产生在蛇体内 srand((int)time(0));//用系统时间来做随机数种子 while(1) { Food_x=rand()%48+2;//随机出食物的坐标 Food_y=rand()%23+2; p=head; while(p!=NULL)//判断食物是否产生在蛇体内 { if(p->x==Food_x&&p->y==Food_y) { InBody=1; break; } p=p->next; } if(InBody==0)//食物不在蛇身。生成成功 break; InBody=0; } } int Sneak::Over() { Body *p; p=head; if((head->x)>=50||(head->x)<=1||(head->y)<=1||(head->y)>=25)//是否撞到边缘 return 1; p=head->next; while(p!=NULL)//是否撞到蛇身 { if((head->x==p->x)&&(head->y==p->y)) return 1; p=p->next; } return 0; } void Sneak::Paint() { Body *p; p=head; while(p!=NULL) { SetPos(p->x,p->y); cout<<"*"; p=p->next; } SetPos(Food_x,Food_y); cout<<"*"; } void Sneak::Move() { Body *New; New=new(Body);//新的蛇身结点 if(Direction==1)//确定新蛇头的坐标 { New->x=head->x; New->y=head->y-1; New->next=head; head=New; } if(Direction==2) { New->x=head->x-1; New->y=head->y; New->next=head; head=New; } if(Direction==3) { New->x=head->x; New->y=head->y+1; New->next=head; head=New; } if(Direction==4) { New->x=head->x+1; New->y=head->y; New->next=head; head=New; } } void Sneak::Gaming() { system("cls");//刷新屏幕 char x; Body *p; Map();//画界面的先 Paint();//再画蛇身 while(1) { if(_kbhit())//_kbhit()判断是否有键盘操作 { x=_getch();//重缓冲区读出一个字符赋给x if((x=='W'||x=='w')&&Direction!=3)//改变蛇的方向(不可以是反方向) Direction=1; if((x=='S'||x=='s')&&Direction!=1) Direction=3; if((x=='A'||x=='a')&&Direction!=4) Direction=2; if((x=='D'||x=='d')&&Direction!=2) Direction=4; while(_kbhit())//读掉这之后所有的键盘输入 _getch(); } if(FoodExist==0)//如果食物被吃了或刚开始游戏,要生成新的食物 { Food(); FoodExist=1; } Move();//移动蛇 if(head->x==Food_x&&head->y==Food_y)//如果蛇吃到了食物 { FoodExist=0; Count++;//蛇身+1 SetPos(54,5); cout<<"长度:"<<Count;//改变界面信息 if(Count%10==0)//每十个蛇身升一级 { Speed++; SetPos(54,7); cout<<"LEVEL:"<<Speed; } if(Speed==10)//最高等级达成。退出游戏 break; } Paint();//画新的蛇身 if(FoodExist==1)//如果没有吃到食物,需要删除蛇尾。 { p=head; while((p->next)->next!=NULL) p=p->next; SetPos(p->next->x,p->next->y); cout<<" "; delete(p->next); p->next=NULL; } if(Over())//判断是否游戏结束 break; Sleep(500-Speed*50);//等待,具体时间和等级有关 } system("cls"); if(Speed==10)//通关 { SetPos(25,25); cout<<"碉堡-_-||你通关了"<<endl; system("pause"); } else//失败 { SetPos(25,10); cout<<"-0- ~~你挂了,最终长度为 "<<Count<<endl; system("pause"); } } int main() { Sneak game; system("cls"); cout<<"*****************************************************"<<endl; cout<<"* 贪吃蛇 *"<<endl; cout<<"*****************************************************"<<endl; cout<<"* 说明 *"<<endl; cout<<"* W,A,S,D控制移动 *"<<endl; cout<<"* 每10节蛇身升一级,并提高速度,10级通关 *"<<endl; cout<<"*****************************************************"<<endl; cout<<"* 何某人制作,百度ID:HapHapYear *"<<endl; cout<<"********* 任意键开始 **********************"<<endl; _getch(); game.Gaming(); return 0; }
#include<windows.h> #include<tchar.h> #include<time.h> #include<list> #define ID_TIMER 1 #define ID_START 2 #define ID_PAUSE 3 #define ID_HELP 4 #define ID_RESTART 5 #define ID_QUIT 6 #define ID_COMBOBOX 7 #define LEFT 8 #define UP 9 #define RIGHT 10 #define DOWN 11 #define ID_ESC 27 HWND hHelp; //帮助信息对话框句柄 HINSTANCE hInst; //实例句柄 RECT rtSnakeHead, rtSnakeNeck, rtSnakeTail, rtFood, rtScore; //重绘区域 RECT rtMap; //地图区域 unsigned int score = 0; //得分 int nextDirection; //蛇头的下一运动方向 bool foodFlag = false; //标记食物是否还存在 bool gameOver = true; //标记游戏是否结束 //蛇身结点定义 typedef struct{ int left; int top; int right; int bottom; int currentDirection; }SnakeNode; std::list<SnakeNode>snake; //整个蛇身 // 此代码模块中包含的函数的前向声明: ATOM MyRegisterClass(HINSTANCE hInstance); //注册窗口类 BOOL InitInstance(HINSTANCE, int); //初始化窗口各种控件 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); //主窗口回调函数 VOID DrawSurroundings(HDC hdc, HWND hWnd, RECT rtFood); //绘制地图 VOID DrawTheSnake(HDC hdc, HWND hWnd); //绘制蛇身 VOID GetTimerElapse(int cursel, unsigned int& timerElapse);//获取用户选择的速度 VOID SnakeMove(RECT rtFood, int timerElapse); //蛇身移动 RECT CreateFood(HDC hdc); //生成食物 BOOL JudgeGameOver(SnakeNode headNode); //判断是否达到游戏结束条件 INT_PTR CALLBACK Help(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); //帮助信息对话框回调函数 //程序入口 int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { srand((UINT)time(0)); //时间作为随机数种子 MSG msg; MyRegisterClass(hInstance); // 执行应用程序初始化: if (!InitInstance (hInstance, nCmdShow)) { return FALSE; } // 主消息循环: while (GetMessage(&msg, NULL, 0, 0)) { SnakeNode& headNode = snake.back(); //获取蛇头所在结点 //获取方向键消息 switch(msg.wParam) { case VK_LEFT: if(headNode.currentDirection != RIGHT) nextDirection = LEFT; break; case VK_UP: if(headNode.currentDirection != DOWN) nextDirection = UP; break; case VK_RIGHT: if(headNode.currentDirection != LEFT) nextDirection = RIGHT; break; case VK_DOWN: if(headNode.currentDirection != UP) nextDirection = DOWN; break; } if (!TranslateMessage(&msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } return (int) msg.wParam; } //注册窗口类 ATOM MyRegisterClass(HINSTANCE hInstance) { WNDCLASSEX wcex; wcex.cbSize = sizeof(wcex); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION); wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wcex.lpszMenuName = NULL; wcex.lpszClassName = _T("贪吃蛇"); wcex.hIconSm = NULL; return RegisterClassEx(&wcex); } BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { HWND hWnd; hInst = hInstance; // 将实例句柄存储在全局变量中 hWnd = CreateWindowExA(0, "贪吃蛇", "贪吃蛇蛋疼版", WS_OVERLAPPED|WS_SYSMENU|WS_MINIMIZEBOX, 380, 90, 606, 568, NULL, NULL, hInstance, NULL); CreateWindowA("button", "开始游戏", WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON, 20, 10, 100, 30, hWnd, (HMENU)ID_START, hInstance, NULL); CreateWindowA("button", "暂停/继续", WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON, 150, 10, 100, 30, hWnd, (HMENU)ID_PAUSE, hInstance, NULL); CreateWindowA("button", "帮助", WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON, 280, 12, 40, 25, hWnd, (HMENU)ID_HELP, hInstance, NULL); CreateWindowA("button", "重玩一局", WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON, 350, 10, 100, 30, hWnd, (HMENU)ID_RESTART, hInstance, NULL); CreateWindowA("button", "退出游戏", WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON, 480, 10, 100, 30, hWnd, (HMENU)ID_QUIT, hInstance, NULL); CreateWindowA("ComboBox", "速度选择", WS_CHILD|WS_VISIBLE|CBS_DROPDOWNLIST, 60, 55, 55, 200, hWnd, (HMENU)ID_COMBOBOX, hInstance, NULL); //创建帮助信息对话框 static DLGTEMPLATE Dlg; Dlg.cdit = 0; Dlg.cx = 200; Dlg.cy = 140; Dlg.dwExtendedStyle = 0; Dlg.style = WS_POPUPWINDOW|WS_CAPTION; Dlg.x = 50; Dlg.y = 60; hHelp = CreateDialogIndirect(hInst, &Dlg, hWnd, Help); SetWindowTextA(hHelp, "帮助"); ShowWindow(hHelp, SW_HIDE); //注册快捷键 RegisterHotKey(hWnd, ID_START, MOD_CONTROL, VK_RIGHT); RegisterHotKey(hWnd, ID_PAUSE, NULL, VK_SPACE); RegisterHotKey(hWnd, ID_RESTART, MOD_CONTROL|MOD_SHIFT, VK_SPACE); RegisterHotKey(hWnd, ID_HELP, NULL, VK_F1); RegisterHotKey(hWnd, ID_ESC, NULL, VK_ESCAPE); SendMessageA(GetDlgItem(hWnd,ID_COMBOBOX), CB_ADDSTRING, NULL, (LPARAM)("特快")); SendMessageA(GetDlgItem(hWnd,ID_COMBOBOX), CB_ADDSTRING, NULL, (LPARAM)("较快")); SendMessageA(GetDlgItem(hWnd,ID_COMBOBOX), CB_ADDSTRING, NULL, (LPARAM)("普通")); SendMessageA(GetDlgItem(hWnd,ID_COMBOBOX), CB_ADDSTRING, NULL, (LPARAM)("缓慢")); SendMessageA(GetDlgItem(hWnd,ID_COMBOBOX), CB_ADDSTRING, NULL, (LPARAM)("龟速")); SendMessageA(GetDlgItem(hWnd,ID_COMBOBOX), CB_SETCURSEL, 2, NULL); //默认选择第三项 EnableWindow(GetDlgItem(hWnd, ID_PAUSE), false); //游戏未开始【暂停/继续】按钮无效 //初始化蛇身长度及位置 for(int i=rtMap.left+40;i<140;i+=20) { SnakeNode node; node.left = i; node.top = rtMap.top+40; node.right = i+20; node.bottom = rtMap.top+60; node.currentDirection = RIGHT; snake.push_back(node); } if (!hWnd) { return FALSE; } ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); return TRUE; } LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { int wmId, wmEvent; static bool bPause; //游戏是否暂停 static unsigned int timerElapse; //定时器时间间隔 PAINTSTRUCT ps; HDC hdc; switch (message) { case WM_CREATE: RECT rtClient; int xBrickAmount,yBrickAmount; //X轴、Y轴砖块数量(每块砖的边长为20) GetClientRect(hWnd, &rtClient); //获取客户区域大小 xBrickAmount = (rtClient.right-rtClient.left)/20; yBrickAmount = (rtClient.bottom-rtClient.top)/20; rtMap.left = rtClient.left; rtMap.top = rtClient.top+80; rtMap.right = rtClient.left+xBrickAmount*20; rtMap.bottom = rtClient.top+yBrickAmount*20; //输出得分的区域 rtScore.left = 260; rtScore.top = rtMap.top-29; rtScore.right = 400; rtScore.bottom = rtMap.top-1; break; case WM_COMMAND: wmId = LOWORD(wParam); wmEvent = HIWORD(wParam); switch (wmId) { case ID_START: { bPause = false; gameOver = false; nextDirection = RIGHT; //初始方向向右 int cursel = SendMessage(GetDlgItem(hWnd, ID_COMBOBOX), CB_GETCURSEL, NULL, NULL); //获取用户选择的速度索引号 GetTimerElapse(cursel, timerElapse); SetTimer(hWnd, ID_TIMER, timerElapse, NULL); EnableWindow(GetDlgItem(hWnd,ID_COMBOBOX), false); EnableWindow(GetDlgItem(hWnd, ID_PAUSE), true); EnableWindow(GetDlgItem(hWnd, ID_START), false); } break; case ID_PAUSE: { if(!gameOver) { if(bPause) { SetTimer(hWnd, ID_TIMER, timerElapse, NULL); bPause = false; } else { KillTimer(hWnd, ID_TIMER); bPause = true; } } } break; case ID_RESTART: { KillTimer(hWnd, ID_TIMER); snake.clear(); //清空蛇身所有结点 //重新初始化蛇身长度及位置 for(int i=rtMap.left+40; i<140; i+=20) { SnakeNode node; node.left = i; node.top = rtMap.top+40; node.right = i+20; node.bottom = node.top+20; node.currentDirection = RIGHT; snake.push_back(node); } gameOver = true; score = 0; EnableWindow(GetDlgItem(hWnd, ID_START), true); EnableWindow(GetDlgItem(hWnd, ID_PAUSE), false); EnableWindow(GetDlgItem(hWnd, ID_COMBOBOX), true); InvalidateRect(hWnd, &rtMap, true); InvalidateRect(hWnd, &rtScore, true); } break; case ID_HELP: { if(!bPause) { SendMessage(hWnd, WM_COMMAND, ID_PAUSE, NULL); } ShowWindow(hHelp, SW_SHOWNORMAL); } break; case ID_QUIT: SendMessage(hWnd, WM_CLOSE, NULL, NULL); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } break; case WM_PAINT: hdc = BeginPaint(hWnd, &ps); //食物被吃掉后重绘分数并再次生成食物 if(!foodFlag) { InvalidateRect(hWnd, &rtScore, true); rtFood = CreateFood(hdc); InvalidateRect(hWnd, &rtFood, true); } DrawSurroundings(hdc, hWnd, rtFood); DrawTheSnake(hdc, hWnd); EndPaint(hWnd, &ps); break; //热键消息处理 case WM_HOTKEY: { if((wParam == ID_ESC) && (hHelp == GetActiveWindow())) ShowWindow(hHelp, SW_HIDE); else if(hWnd == GetActiveWindow()) //判断窗口是否处于激活状态 { switch(wParam) { case ID_START: if(IsWindowEnabled(GetDlgItem(hWnd, ID_START))) SendMessage(hWnd, WM_COMMAND, ID_START, NULL); break; case ID_PAUSE: SendMessage(hWnd, WM_COMMAND, ID_PAUSE, NULL); break; case ID_RESTART: SendMessage(hWnd, WM_COMMAND, ID_RESTART, NULL); break; case ID_HELP: SendMessage(hWnd, WM_COMMAND, ID_HELP, NULL); break; case ID_ESC: SendMessage(hWnd, WM_CLOSE, NULL, NULL); break; } } } break; //定时器消息处理 case WM_TIMER: SnakeMove(rtFood, timerElapse); InvalidateRect(hWnd, &rtSnakeHead, true); InvalidateRect(hWnd, &rtSnakeNeck, false); InvalidateRect(hWnd, &rtSnakeTail, true); break; //处理窗口最小化的消息 case WM_SIZE: wmId = LOWORD(wParam); if(wmId == SIZE_MINIMIZED) { if(!gameOver && !bPause) SendMessage(hWnd, WM_COMMAND, ID_PAUSE, NULL); } break; //处理关闭窗口的消息 case WM_CLOSE: { if(!gameOver) { KillTimer(hWnd, ID_TIMER); if(MessageBoxA(hWnd, "游戏正在进行,确认退出?", "提醒", MB_OKCANCEL|MB_ICONQUESTION) == IDOK) { DestroyWindow(hWnd); PostQuitMessage(0); } else if(!bPause && !gameOver) SetTimer(hWnd, ID_TIMER, timerElapse, NULL); } if(gameOver && MessageBoxA(hWnd, "确认退出贪吃蛇蛋疼版?", "提醒", MB_OKCANCEL|MB_ICONQUESTION) == IDOK) { DestroyWindow(hWnd); PostQuitMessage(0); } } break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } VOID DrawSurroundings(HDC hdc, HWND hWnd, RECT rtFood) { //绘制分割线 MoveToEx(hdc, rtMap.left, rtMap.top-30, NULL); LineTo(hdc, rtMap.right, rtMap.top-30); TextOutA(hdc, 23, rtMap.top-22, "速度:", strlen("速度:")); TextOutA(hdc, 480, rtMap.top-22, "By:非洲小白脸", strlen("By:非洲小白脸")); //自定义字体并输出得分 char szScore[10]; LOGFONT font; memset(&font, 0, sizeof(font)); font.lfWidth = 11; font.lfHeight = 20; font.lfWeight = FW_HEAVY; lstrcpy(font.lfFaceName, _T("宋体")); HFONT hFont = CreateFontIndirect(&font); SelectObject(hdc, hFont); wsprintfA(szScore, "得分:%d", score); SetTextColor(hdc, RGB(0,99,201)); TextOutA(hdc, 260, rtMap.top-24, szScore, strlen(szScore)); DeleteObject(hFont); //绘制地图(砖块边长为20) HBRUSH hBrush = CreateSolidBrush(RGB(139,69,19)); SelectObject(hdc, hBrush); for(int i=rtMap.left; i<rtMap.right; i+=20) { Rectangle(hdc, i, rtMap.top, i+20, rtMap.top+20); Rectangle(hdc, i, rtMap.bottom-20, i+20, rtMap.bottom); } for(int j=rtMap.top; j<rtMap.bottom; j+=20) { Rectangle(hdc, rtMap.left, j, rtMap.left+20, j+20); Rectangle(hdc, rtMap.right-20, j, rtMap.right, j+20); } //绘制食物 hBrush = CreateSolidBrush(RGB(255,0,0)); SelectObject(hdc, hBrush); Ellipse(hdc, rtFood.left, rtFood.top, rtFood.right, rtFood.bottom); DeleteObject(hBrush); } VOID GetTimerElapse(int cursel, unsigned int& timerElapse) { switch(cursel) { case 0: timerElapse = 50; break; case 1: timerElapse = 100; break; case 2: timerElapse = 200; break; case 3: timerElapse = 400; break; case 4: timerElapse = 600; break; } } VOID DrawTheSnake(HDC hdc, HWND hWnd) { //画蛇身 HBRUSH hBrush = CreateSolidBrush(RGB(124,252,0)); SelectObject(hdc, hBrush); std::list<SnakeNode>::iterator sIter = snake.begin(); for(unsigned int i=0; i<snake.size()-1; i++,sIter++) Rectangle(hdc, sIter->left, sIter->top, sIter->right, sIter->bottom); //画蛇头 SnakeNode headNode = snake.back(); switch(headNode.currentDirection) { case LEFT: { POINT ptHead[] = {sIter->left,sIter->top+5, sIter->right,sIter->top, sIter->right,sIter->bottom, sIter->left,sIter->bottom-5}; Polygon(hdc, ptHead, 4); } break; case UP: { POINT ptHead[] = {sIter->left+5,sIter->top, sIter->right-5,sIter->top, sIter->right,sIter->bottom, sIter->left,sIter->bottom}; Polygon(hdc, ptHead, 4); } break; case RIGHT: { POINT ptHead[] = {sIter->left,sIter->top, sIter->right,sIter->top+5, sIter->right,sIter->bottom-5, sIter->left,sIter->bottom}; Polygon(hdc, ptHead, 4); } break; case DOWN: { POINT ptHead[] = {sIter->left,sIter->top, sIter->right,sIter->top, sIter->right-5,sIter->bottom, sIter->left+5,sIter->bottom, }; Polygon(hdc, ptHead, 4); } break; } //判断游戏结束 if(!gameOver) { if(JudgeGameOver(headNode)) { KillTimer(hWnd, ID_TIMER); EnableWindow(GetDlgItem(hWnd, ID_PAUSE), false); MessageBoxA(hWnd, "Game Over!", "提醒", MB_OK); } } } VOID SnakeMove(RECT rtFood, int timerElapse) { SnakeNode headNode = snake.back(); //获取蛇颈区域 rtSnakeNeck.left = headNode.left; rtSnakeNeck.top = headNode.top; rtSnakeNeck.right = headNode.right; rtSnakeNeck.bottom = headNode.bottom; SnakeNode node; //根据蛇头的下一方向算出蛇头的新位置 switch(nextDirection) { case LEFT: node.left = headNode.left-20; node.top = headNode.top; node.right = headNode.left; node.bottom = headNode.bottom; node.currentDirection = LEFT; snake.push_back(node); break; case UP: node.left = headNode.left; node.top = headNode.top-20; node.right = headNode.right; node.bottom = headNode.top; node.currentDirection = UP; snake.push_back(node); break; case RIGHT: node.left = headNode.right; node.top = headNode.top; node.right = headNode.right+20; node.bottom = headNode.bottom; node.currentDirection = RIGHT; snake.push_back(node); break; case DOWN: node.left = headNode.left; node.top = headNode.bottom; node.right = headNode.right; node.bottom = headNode.bottom+20; node.currentDirection = DOWN; snake.push_back(node); break; } //获取蛇头区域 headNode = snake.back(); rtSnakeHead.left = headNode.left; rtSnakeHead.top = headNode.top; rtSnakeHead.right = headNode.right; rtSnakeHead.bottom = headNode.bottom; //未吃到食物 if(!(headNode.left==rtFood.left && headNode.top==rtFood.top)) { std::list<SnakeNode>::iterator iTail = snake.begin(); rtSnakeTail.left = iTail->left; rtSnakeTail.top = iTail->top-1; rtSnakeTail.right = iTail->right; rtSnakeTail.bottom = iTail->bottom+1; snake.pop_front(); } //吃到食物 else { switch(timerElapse) { case 50: score+=100; break; case 100: score+=60; break; case 200: score+=40; break; case 400: score+=20; break; case 600: score+=10; break; } foodFlag = false; } } RECT CreateFood(HDC hdc) { RECT rtFood; //食物所在区域 int xNumber, yNumber; //食物所在处对应的砖块序号 int xBrickAmount,yBrickAmount; //X轴、Y轴砖块总量 xBrickAmount = (rtMap.right-rtMap.left)/20; yBrickAmount = (rtMap.bottom-rtMap.top)/20; //随机生成砖块序号 xNumber = rand()%(xBrickAmount-2); yNumber = rand()%(yBrickAmount-2); //根据砖块序号确定食物位置 rtFood.left = rtMap.left+(xNumber+1)*20; rtFood.right = rtFood.left+20; rtFood.top = rtMap.top+(yNumber+1)*20; rtFood.bottom = rtFood.top+20; foodFlag = true; return rtFood; } BOOL JudgeGameOver(SnakeNode headNode) { //碰到墙则游戏结束 if(headNode.left==rtMap.left || headNode.top==rtMap.top || headNode.right==rtMap.right || headNode.bottom==rtMap.bottom) { gameOver = true; return true; } //咬到自己身体则游戏结束 else { SnakeNode head = snake.back(); std::list<SnakeNode>::iterator sIter = snake.begin(); for(unsigned int i=0; i<snake.size()-1; i++,sIter++) if(head.left==sIter->left && head.top==sIter->top) { gameOver = true; return true; } } return false; } INT_PTR CALLBACK Help(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_COMMAND: if(LOWORD(wParam) == IDCANCEL) { ShowWindow(hDlg, SW_HIDE); return (INT_PTR)TRUE; } break; case WM_PAINT: { PAINTSTRUCT dPs; HDC hdc = BeginPaint(hDlg, &dPs); LOGFONT font; memset(&font, 0, sizeof(font)); font.lfWidth = 8; font.lfHeight = 16; font.lfWeight = FW_HEAVY; lstrcpy(font.lfFaceName, _T("宋体")); HFONT hFont = CreateFontIndirect(&font); SelectObject(hdc, hFont); SetTextColor(hdc, RGB(111,55,155)); SetBkColor(hdc, GetSysColor(COLOR_3DFACE)); TextOutA(hdc, 5, 5, "游戏规则:", sizeof("游戏规则:")); std::string str = "1.通过方向键上、下、左、右控制蛇游动的方向。"; TextOutA(hdc, 5, 25, str.c_str(), str.size()); str = "2.该蛇有五种游动速度可供玩家选择。"; TextOutA(hdc, 5, 45, str.c_str(), str.size()); str = "3.吃到食物后身体会增长一节并获得相应的分数。"; TextOutA(hdc, 5, 65, str.c_str(), str.size()); str = "4.不同游动速度下食物的分值不同,越快则越高。"; TextOutA(hdc, 5, 85, str.c_str(), str.size()); str = "5.蛇头碰到自身身体或围墙则游戏结束。"; TextOutA(hdc, 5, 105, str.c_str(), str.size()); TextOutA(hdc, 5, 135, "快捷键:", sizeof("快捷键:")); str = "开始游戏:Ctrl+右方向键"; TextOutA(hdc, 5, 155, str.c_str(), str.size()); str = "暂停/继续游戏:Space(空格键)"; TextOutA(hdc, 5, 175, str.c_str(), str.size()); str = "重玩一局:Ctrl+Shift+Space"; TextOutA(hdc, 5, 195, str.c_str(), str.size()); str = "退出游戏:Esc"; TextOutA(hdc, 5, 215, str.c_str(), str.size()); str = "帮助:F1"; TextOutA(hdc, 5, 235, str.c_str(), str.size()); DeleteObject(hFont); EndPaint(hDlg, &dPs); } break; } return (INT_PTR)FALSE; }