文章目录
- 实现原理
- 代码实现(详见注释)
实现原理
- 首先拿到所有桌面APP的路径。
- 然后将它们都存进结构体,并存入指针数组(前面的指向后面的)。
- 后面直接每次随机生成食物并且每次判断是否KO就行了。
- 感兴趣也可以看看C++贪吃蛇无尽模式。
代码实现(详见注释)
#include <bits/stdc++.h>
#include <windows.h>
#include <commctrl.h>
#include <shlobj.h>
#define get GetAsyncKeyState
#define send SendMessageA
#define LVM LVM_SETITEMPOSITION
#define msg MessageBox
// 大小与速度(速度越小越快)
const int S = 100, V = 300;
// 桌面
HWND D;
// 蛇的结构体
typedef struct Snake {// 位置 int x, y;// 蛇的第几节int idx;// 下一节struct Snake* nxt;
} node;
// 蛇头
node* head;
node* t;
// 目前食物的位置
POINT food;
// 目前吃了多少食物
int cnt, idx;
// 分辨率
int w, h;
// 共有多少食物
int sum;
// 找路径
char* Get() {LPITEMIDLIST pidl;LPMALLOC pShellMalloc;char s[200];if (SUCCEEDED(SHGetMalloc(&pShellMalloc))) {if (SUCCEEDED(SHGetSpecialFolderLocation(NULL, CSIDL_DESKTOP, &pidl))) {SHGetPathFromIDListA(pidl, s);pShellMalloc -> Free(pidl);}pShellMalloc -> Release();}return s;
}
// 初始化
void init() {srand((unsigned int)time(0));HWND grand = FindWindowA("Progman", "Program Manager"), fa = FindWindowExA(grand, NULL, "SHELLDLL_DefView", NULL);D = FindWindowExA(fa, 0, "SysListView32", "FolderView");sum = send(D, LVM_GETITEMCOUNT, 0, 0);w = GetSystemMetrics(SM_CXSCREEN);h = GetSystemMetrics(SM_CYSCREEN);head = (node*) malloc (sizeof head);head -> x = rand() % (w / S) * S;head -> y = rand() % (h / S) * S;head -> idx = 0;head -> nxt = NULL;for (int i = 0; i < sum; ++i) {send(D, LVM, i, (h << 16) + w);}
}
// 游戏界面
void Game() {// 输出蛇头 send(D, LVM, head -> idx, (head -> y << 16) + head -> x);
A:food.x = rand() % (w / S) * S;food.y = rand() % (h / S) * S;// 如果新生成的食物位置和蛇头位置重合就重生成 if (head -> x == food.x && head -> y == food.y) {goto A;}// 输出食物 send(D, LVM, 1, (food.y << 16) + food.x);// 移动方向,最开始向右 node move; move.x = 1;move.y = 0;// 都吃了就成功了 while (cnt < sum) {if (get(VK_UP)) {move.x = 0;move.y = -1;} if (get(VK_DOWN)) {move.x = 0;move.y = 1;}if (get(VK_LEFT)) {move.x = -1;move.y = 0;}if (get(VK_RIGHT)) {move.x = 1;move.y = 0;}if (get(VK_ESCAPE)) {msg(D, TEXT("再见,下次再来玩呦~"), TEXT(""), MB_OK | MB_ICONEXCLAMATION);exit(0);}if (get(VK_SPACE)) {while (true) {Sleep(500);if (get(VK_SPACE)) {break;} }}if (head -> x == food.x && head -> y == food.y) {++idx;++cnt;node* T;T = (node*) malloc (sizeof(node));T -> x = food.x;T -> y = food.y;T -> idx = idx;T -> nxt = NULL;t = head;while (t -> nxt != NULL) {t = t -> nxt;}t -> nxt = T;t = head;t -> x += move.x * S;t -> y += move.y * S;while (t != NULL) {send(D, LVM, t -> idx, (t -> y << 16) + t -> x);t = t -> nxt;}B:food.x = rand() % (w / S) * S;food.y = rand() % (h / S) * S;if (head -> x == food.x && head -> y == food.y) {goto B;}send(D, LVM, idx + 1, (food.y << 16) + food.x);} else {node t1, t2;t = head;t1.x = t -> x;t1.y = t -> y;t -> x += move.x * S;t -> y += move.y * S;send(D, LVM, t -> idx, (t -> y << 16) + t -> x);t = head -> nxt;while (t != NULL) {t2.x = t -> x;t2.y = t -> y;t -> x = t1.x;t -> y = t1.y;send(D, LVM, t -> idx, (t -> y << 16) + t -> x);t1.x = t2.x;t1.y = t2.y;t = t -> nxt;}if (head -> x > w || head -> x < 0 || head -> y > h || head -> y < 0) {msg(D, TEXT("孩纸你撞到墙了,重来吧"), TEXT(""), MB_OK | MB_ICONEXCLAMATION);exit(0);}t = head -> nxt;while (t != NULL) {if (t -> x == head -> x && t -> y == head -> y) {msg(D, TEXT("孩纸你撞到自己了,重来吧"), TEXT(""), MB_OK | MB_ICONEXCLAMATION);exit(0);}t = t -> nxt;}}Sleep(V);}
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) {init();msg(D, TEXT("游戏规则:↑↓←→控制方向,空格暂停,再按一次空格继续,Esc退出。要好好记住哦~"), TEXT(""), MB_OK | MB_ICONEXCLAMATION);msg(D, TEXT("准备开始游戏..."), TEXT(""), MB_OK | MB_ICONEXCLAMATION);Game();return 0;
}