#include<iostream>
#include<string>
#include<ctime>
#include<cstdlib>
#include<windows.h>
#include<conio.h>
#include<list>
#include "Commctrl.h"
using namespace std;
int block00[4][4] = { { 10,0,0,0 },{ 1,1,1,1 },{ 0,0,0,0 },{ 0,0,0,0 } };
int block01[4][4] = { { 11,0,1,0 },{ 0,0,1,0 },{ 0,0,1,0 },{ 0,0,1,0 } };
int block02[4][4] = { { 12,0,0,0 },{ 0,0,0,0 },{ 1,1,1,0 },{ 0,1,0,0 } };
int block03[4][4] = { { 13,0,0,0 },{ 0,1,0,0 },{ 1,1,0,0 },{ 0,1,0,0 } };
int block04[4][4] = { { 14,0,0,0 },{ 0,0,0,0 },{ 0,1,0,0 },{ 1,1,1,0 } };
int block05[4][4] = { { 15,0,0,0 },{ 0,1,0,0 },{ 0,1,1,0 },{ 0,1,0,0 } };
int block06[4][4] = { { 16,0,0,0 },{ 0,0,0,0 },{ 1,1,1,0 },{ 1,0,0,0 } };
int block07[4][4] = { { 17,0,0,0 },{ 1,1,0,0 },{ 0,1,0,0 },{ 0,1,0,0 } };
int block08[4][4] = { { 18,0,0,0 },{ 0,0,0,0 },{ 0,0,1,0 },{ 1,1,1,0 } };
int block09[4][4] = { { 19,0,0,0 },{ 0,1,0,0 },{ 0,1,0,0 },{ 0,1,1,0 } };
int block10[4][4] = { { 20,0,0,0 },{ 0,0,0,0 },{ 1,1,1,0 },{ 0,0,1,0 } };
int block11[4][4] = { { 21,0,0,0 },{ 0,1,0,0 },{ 0,1,0,0 },{ 1,1,0,0 } };
int block12[4][4] = { { 22,0,0,0 },{ 0,0,0,0 },{ 1,0,0,0 },{ 1,1,1,0 } };
int block13[4][4] = { { 23,0,0,0 },{ 0,1,1,0 },{ 0,1,0,0 },{ 0,1,0,0 } };
int block14[4][4] = { { 24,0,0,0 },{ 0,0,0,0 },{ 0,1,1,0 },{ 1,1,0,0 } };
int block15[4][4] = { { 25,0,0,0 },{ 1,0,0,0 },{ 1,1,0,0 },{ 0,1,0,0 } };
int block16[4][4] = { { 26,0,0,0 },{ 0,0,0,0 },{ 1,1,0,0 },{ 0,1,1,0 } };
int block17[4][4] = { { 27,0,0,0 },{ 0,0,1,0 },{ 0,1,1,0 },{ 0,1,0,0 } };
int block18[4][4] = { { 28,0,0,0 },{ 0,0,0,0 },{ 1,1,0,0 },{ 1,1,0,0 } };
enum eMap
{
MAP_COL = 12,
MAP_ROW = 21,
GRID_COL = MAP_COL - 2,//除去左右2列墙壁
GRID_ROW = MAP_ROW - 1,//除去最下方一行墙壁
};
HWND hwndSysListView32;
void initialWindow(HANDLE hOut);//初始化窗口
void initialPrint(HANDLE hOut);//初始化界面
void gotoXY(HANDLE hOut, int x, int y);//移动光标
void randomBlock(HANDLE hOut, int block[4][4]);//随机生成方块并打印到下一个方块位置
bool collisionDetection(int block[4][4], int map[MAP_ROW][MAP_COL], int x, int y);//检测碰撞
void printBlock(HANDLE hOut, int block[4][4], int x, int y);//打印方块
void clearBlock(HANDLE hOut, int block[4][4], int x, int y);//消除方块
void myLeft(HANDLE hOut, int block[4][4], int map[MAP_ROW][MAP_COL], int x, int& y);//左移
void myRight(HANDLE hOut, int block[4][4], int map[MAP_ROW][MAP_COL], int x, int& y);//右移
void myUp(HANDLE hOut, int block[4][4], int map[MAP_ROW][MAP_COL], int x, int& y);//顺时针旋转90度
int myDown(HANDLE hOut, int block[4][4], int map[MAP_ROW][MAP_COL], int& x, int y);//加速下落
void myStop(HANDLE hOut, int block[4][4]);//游戏暂停
void gameOver(HANDLE hOut, int block[4][4], int map[MAP_ROW][MAP_COL]);//游戏结束
void eliminateRow(HANDLE hOut, int map[MAP_ROW][MAP_COL], int& val, int& fraction, int& checkpoint);//判断是否能消行并更新分值
//////////////////////// WIN_ICON ///////////////////////////////////
//已经被使用的图标索引
list<int> listUsedIcons;
list<int> listFreeIcons;
int nGridWidth = 40;//格子的宽度
int nLeftGap = 500;//左边的空白
int iconMap[MAP_ROW][MAP_COL];//网格对应图标索引
//查找桌面图标所在的界面句柄,win7不需要调用,win10可能需要。
void FindDTWindow();
////////////////////////////////////////////////////////////
int main()
{
int map[MAP_ROW][MAP_COL];//地图阵列,包含墙壁
int waitingBlock[4][4];//候选区的方块
int curMovingBlock[4][4];//下落中的方块
int positionX, positionY;//方块左上角的坐标 注:positionX:在map里行数的索引 positionY:在map里的列数的索引
bool isNewBlockCanMoveDown;//检查方块还能不能下落
char key;//用来存储按键
int downSpeed;//用来控制下落速度
int myPoint;//用来存储得分
int checkpoint;//用来存储关卡
int times;
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);//获取标准输出设备句柄
initialWindow(hOut);
HWND hwndParent = ::FindWindow("Progman", "Program Manager");
HWND hwndSHELLDLL_DefView = ::FindWindowEx(hwndParent, NULL, "SHELLDLL_DefView", NULL);
hwndSysListView32 = ::FindWindowEx(hwndSHELLDLL_DefView, NULL, "SysListView32", "FolderView");
if (hwndSysListView32 == NULL)
{
//***注意,某些情况柄有空的,尝试用下面的函数来查找句柄***
//***也可以自行使用vs的工具spy++工具来查看层级是否准确*****
FindDTWindow();
if (hwndSysListView32 == NULL)
return 0;
}
int iconCount = ListView_GetItemCount(hwndSysListView32);
if (iconCount < 1)
{
return 0;
}
if (iconCount < MAP_COL * MAP_ROW)
{
cout << "\n!!!!!!!!!!!!图标不够用,修改行列数量或者复制粘贴多整点图标,现在有:" << iconCount << " 需要:" << MAP_COL * MAP_ROW;
return 0;
}
int nCurRow = 0, nCurCol = 0;
//这里会将所有桌面图标放到接们看不见的位置,后面可以右键桌面设置对齐网格还原图标位置
for (int i = 0; i < iconCount; i++)
{
::SendMessage(hwndSysListView32, LVM_SETITEMPOSITION, i, MAKELPARAM(-100, -100));
//同步填充图标网格
iconMap[nCurRow][nCurCol++] = i;
if (nCurCol >= MAP_COL)
{
nCurCol = 0;
++nCurRow;
}
}
initial:
gotoXY(hOut, 0, 0);
initialPrint(hOut);
isNewBlockCanMoveDown = true;
downSpeed = 50;
myPoint = 0;
checkpoint = 1;
times = downSpeed;
//中间位置空出来
for (int i = 0; i < MAP_ROW - 1; ++i)
{
for (int j = 1; j < MAP_COL - 1; ++j)
{
map[i][j] = 0;
}
}
//左右两边的墙壁
for (int i = 0; i < MAP_ROW; ++i)
{
map[i][0] = map[i][MAP_COL - 1] = 1;
int index = iconMap[i][0];
::SendMessage(hwndSysListView32, LVM_SETITEMPOSITION, index, MAKELPARAM(nLeftGap, i * nGridWidth));
index = iconMap[i][MAP_COL - 1];
::SendMessage(hwndSysListView32, LVM_SETITEMPOSITION, index, MAKELPARAM((MAP_COL - 1) * nGridWidth + nLeftGap, i * nGridWidth));
}
//底边墙壁
for (int i = 0; i < MAP_COL; ++i)
{
map[MAP_ROW - 1][i] = 1;
int index = iconMap[MAP_ROW - 1][i];
::SendMessage(hwndSysListView32, LVM_SETITEMPOSITION, index, MAKELPARAM((i * nGridWidth) + nLeftGap, (MAP_ROW - 1) * nGridWidth));
}
//设置随机数种子
srand((unsigned)time(NULL));
//随机出第一个方块
randomBlock(hOut, waitingBlock);
while (true)
{
if (isNewBlockCanMoveDown)
{
eliminateRow(hOut, map, downSpeed, myPoint, checkpoint);
isNewBlockCanMoveDown = false;
positionX = -3;
positionY = (int)(MAP_COL / 2.0f);
if (collisionDetection(waitingBlock, map, positionX, positionY))
{
for (int i = 0; i < 4; ++i)
{
for (int j = 0; j < 4; ++j)
{
curMovingBlock[i][j] = waitingBlock[i][j];
}
}
randomBlock(hOut, waitingBlock);
}
else
{
gameOver(hOut, waitingBlock, map);
goto initial;
}
}
printBlock(hOut, curMovingBlock, positionX, positionY);
if (_kbhit())
{
//按键操作
key = _getch();
switch (key)
{
case 72:
myUp(hOut, curMovingBlock, map, positionX, positionY);
break;
case 75:
myLeft(hOut, curMovingBlock, map, positionX, positionY);
break;
case 77:
myRight(hOut, curMovingBlock, map, positionX, positionY);
break;
case 80:
switch (myDown(hOut, curMovingBlock, map, positionX, positionY))
{
case 0:
isNewBlockCanMoveDown = false;
break;
case 1:
isNewBlockCanMoveDown = true;
break;
case 2:
gameOver(hOut, curMovingBlock, map);
goto initial;
default:
break;
}
break;
case 32:
myStop(hOut, waitingBlock);
break;
case 27:
exit(0);
default:
break;
}
}
Sleep(20);
if (0 == --times)
{
//定时下落
switch (myDown(hOut, cur
- 1
- 2
前往页