最近写了一个C++桌面图标游戏系列之一【贪吃蛇】。

https://blog.csdn.net/Yang9325/article/details/111031297

没想到还挺受欢迎,那么系列之二【俄罗斯方块】就顺理成章的出现了。

先看看视频:

C++桌面图标玩游戏系列之二【俄罗斯方块】

俄罗斯方块本身的逻辑我直接用这位兄弟的代码了,就是里面的变量名和一些定义实在是一言难尽,有不少冗余的地方可以优化,最重要的是很少注释,属于自己看的懂,别人看的头疼的那种。

类似游戏的宽高,第几行第几列这种都是直接用数字写死的 。

为了方便自己和大家查看,很多地方我改了变量名字和定义,加上了注释,例如map[21][12] => map[MAP_ROW][MAP_COL]。

当然这里没有diss的意思,这兄弟应该只是打算写给自己看的,下面是他的文章链接。

https://blog.csdn.net/qq_42846735/article/details/100046164

我在这里的基础上,将逻辑同步到桌面图标。

以下是控制图标的代码:

发送消息,改变图标的位置

::SendMessage(hwndSysListView32, LVM_SETITEMPOSITION, i, MAKELPARAM(-100, -100));

查找图标层的句柄

HWND  hwndParent = ::FindWindow("Progman", "Program Manager");
HWND  hwndSHELLDLL_DefView = ::FindWindowEx(hwndParent, NULL, "SHELLDLL_DefView", NULL);
 hwndSysListView32 = ::FindWindowEx(hwndSHELLDLL_DefView, NULL, "SysListView32", "FolderView");

贴出核心代码。

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, curMovingBlock, map, positionX, positionY)){case 0:isNewBlockCanMoveDown = false;break;case 1:isNewBlockCanMoveDown = true;break;case 2:gameOver(hOut, curMovingBlock, map);goto initial;default:break;}times = downSpeed;}}cin.get();return 0;
}

如果你想隐藏控制台,网上方法挺多的,或者评论问我也可以。

如果你愿意看到这或者点收藏,证明我写的东西对你有点用,那么顺手点个赞吧,赠人玫瑰手留余香,先行谢过。

有需要的话,下面是完整的代码文件,用vs创建控制台程序再复制到主文件就行。需要花点小钱(1.9元),毕竟要恰饭。

https://download.csdn.net/download/Yang9325/13724660

C++桌面图标游戏系列之二【俄罗斯方块】相关推荐

  1. win7怎么把计算机放到桌面6,win7系统如何设置更改桌面图标?

    其实,很多朋友在使用电脑的时候,都喜欢更改图标,比如说不喜欢现在的图标,想要改一个更加有意思的图标.有时候,桌面的图标突然就变大或者变小了,看起来很不美观,也想要更改桌面图标,那么应该怎么操作呢?下面 ...

  2. 如何将计算机恢复到桌面快捷方式,电脑桌面图标都没了?解答如何轻松恢复桌面图标...

    有时候我们设置电脑桌面壁纸会一不小心把桌面的图标弄没了,无论是重新设置壁纸还是重启电脑,电脑桌面图标依然没有恢复,难道电脑中病毒了吗?解决不了的小伙伴都有这样的想法,那该怎么办呢?下面小编提供了几种针 ...

  3. 桌面图标有蓝色阴影终极解决方法

    桌面图标有蓝色阴影        桌面图标背景出现蓝色阴影是怎么回事呢?通常情况下桌面图标变成蓝色背景是由于一些错误的设置而导致的,虽然它不影响系统的正常运行,但是看起来总是不舒服的.网上也有很多处理 ...

  4. Microsoft Hyper-V Server 2008 R2和SCVMM2012部署XenDesktop 5.6桌面虚拟化系列之二准备虚拟桌面模板...

    Microsoft Hyper-V Server 2008 R2和SCVMM2012 部署XenDesktop 5.6桌面虚拟化系列 之二准备虚拟桌面模板 接着上一篇文章内容<Microsoft ...

  5. C++用桌面图标系列之三【整理-时钟】

    他来了,他来了,桌面图标一百种玩法第三种,桌面时钟. 学会了就发给女朋友玩吧,效果炫酷,学不了吃亏,学不了上当,走过路过不要错过. 老规矩,先看看视频效果. C++用桌面图标系列之三[整理-时钟] 核 ...

  6. 跨平台应用开发进阶(十二) :uni-app 实现应用桌面图标角标提示及应用跳转

    文章目录 一.前言 二.实现 2.1 集成极光实现 2.1.1 通道支持 2.1.2 iOS 角标 2.1.3 华为角标 2.1.4 小米角标 2.1.5 vivo 角标 2.2 H5+实现 三.遇到 ...

  7. win10扩展屏幕后 桌面图标在屏幕一和屏幕二上乱了

    win10扩展屏幕后 桌面图标在屏幕一和屏幕二上乱了,怎么处理? 今天偶然发现电脑屏幕在扩展之后,图标乱了,一部分在屏幕二上一部分在屏幕一上,查了很多回答都说是注册表的问题.终于找到了正确的解决方案. ...

  8. 用桌面图标模拟FlappyBird游戏

    实现效果 操作说明 注意需要先把自动排列图标和将图标与网格对齐关闭,运行后可能会打乱图标排列. 空格控制开始与游戏中的跳跃. ESC键结束程序. 实现逻辑 首先需要了解一下桌面图标的一些api,例如获 ...

  9. 单机游戏制作系列之二——基本框架

    单机游戏制作系列之二--基本框架 笔者个人的想法,是打算将这个系列的文章写成通用性的,不局限于某一种语言,也不局限于某一种引擎,但是水平有限,预计是达不到这个效果.以下仅以C++来举例,如果其他的语言 ...

最新文章

  1. Java学习总结:1
  2. 液晶显示屏怎么显示泰文_液晶显示屏概念股大涨 液晶显示屏概念股一览表
  3. java基础提升篇:深入浅出Java多线程
  4. poj2823 线段树模板题 点修改(也可以用单调队列)
  5. MyEclipse:Available memory is low解决办法
  6. .NET定时任务执行管理器开源组件–FluentScheduler
  7. 联想计算机BIOS开启Intel-vx,如何在计算机BIOS或UEFI固件中启用Intel VT-x | MOS86
  8. codeforces:65
  9. pythonspark实践_基于Python的Spark Streaming Kafka编程实践
  10. Linux systemd limits
  11. Normalizing Flows Tutorial(标准化流教程)第一部分
  12. flex代码辅助工具sourceMate
  13. python中计算DataFrame,Series的数据频率
  14. Java实现简易四则运算器
  15. Redis管理及监控工具treeNMS
  16. Mac 设置终端命令快捷方式
  17. 日期时间类-Date,Calendar和日期格式化
  18. session自动登录抽屉网(自动携带cookie)
  19. ORACLE ODBC驱动安装
  20. 研发质量管理工作经验总结(二)----质量管理技能

热门文章

  1. 聊聊身边的嵌入式,自拍神器自拍杆
  2. TOP100summit:【分享实录-华为】微服务场景下的性能提升最佳实践
  3. Matlab中plot画图线型、标记和颜色
  4. 【转载】透视“专利恶霸”系列之二 蜕变后的苹果有了新玩法
  5. 解决中国菜刀连接失败问题
  6. 信号与系统复习与总结
  7. 手撕自动驾驶算法——无迹卡尔曼滤波(UKF)
  8. 【每日一题】备战冲击蓝桥杯国赛——Python程序设计 | Day03 | 跑步锻炼 | 真题代码解析
  9. STM32(六)——串口通信原理
  10. 实现类似微信视频聊天的功能