文章目錄
- 運行效果
- 實作原理
- 代碼實作(詳見注釋)
運行效果
傳送
實作原理
- 首先拿到所有桌面APP的路徑,
- 然后將它們都存進結構體,并存入指標陣列(前面的指向后面的),
- 后面直接每次隨機生成食物并且每次判斷是否KO就行了,
- 感興趣也可以看看普通的貪吃蛇,
代碼實作(詳見注釋)
#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;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/296591.html
標籤:其他
