Qt-十字消除小游戏

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_37474728/article/details/81262498

这是我很久以前玩过的一一款游戏,前天突然想起来了,就想着自己能不能实现一下。

上几张网页上游戏的图片:

 

游戏窗口如下:

可以看到,“Refresh”按钮在初始状态下是不可用的,这里默认刚开始生成的游戏界面不会存在“无法消除”的情况。

 如图,下图出现了“不可消除”的情况,灰色色块被绿色和橙色色块挡住,橙色色块被红色色块挡住,红色色块被橙色色块挡住……

 

点击“Refresh”按钮,会弹出一个对话框:点击“Yes”,会刷新游戏窗口。

 

这时,就可以继续消除了。 当所有色块均被消除时,会弹出Congratulations对话框。

 

游戏的编写过程主要分为以下几步:

  • 绘制界面
    • 界面比较简单,可以直接实例化控件,采用setGeometry()的方式固定其位置及大小。
    • 响应鼠标点击的矩阵是一个QPushButton数组,一次性将所有按钮实例化。
  • 用彩色色块填充界面
    • 这里需要考虑彩色色块放置的问题。根据对已有的小游戏“十字消除”进行数据统计,空白色块占比大概处于43%~44%。简单起见,这里设置为40%。
    • 首先遍历整个数组,将随机颜色的色块成对的加入按钮中,这里我采用的是一种比较直接的方法,将下标为i的按钮与下标为count-i的按钮处的色块设置为相同的色块,这样可以保证生成的每种色块都为偶数个。
    • 接下来就是放空白色块了。空白色块的数目之前已经确定好,是count的40%。这里,我产生一个无重复的随机数组。代码如下:
      int* getRandValueNoRepeat(int max, int count) {
          int *res = new int[count];
          qsrand(time(NULL)); //因为是用Qt编写的,所以用的是qsrand()和qrand()函数
          int index = 0;
      
          for(int i = 0; i < max; ++i) {
              if(qrand() % (max - i) < count) {
                  res[index++] = i;
                  --count;
              }
          }
      
          return res;
      }

       

    • 用随机数组的元素作为下标,向按钮数组中添加空白色块。同样地,为了使最后生成的彩色色块“不落单”,必须使得一对空白色块覆盖一对颜色相同的彩色色块,方法和上面相同。

疑问:这样做会不会使得中间始终为空白呢?

解释:

//一共有308个色块,下标为0~307
//第一步,用彩色色块成对的填充所有按钮。
for(int i = 0; i < 154; i++) {
    btns[i]...
    btns[307 - i]...
}
//i最大为153,307-i最小为154,不存在重复填充的情况。这样能够保证彩色色块“不落单”。

//第二步,用空白色块随机填充部分按钮。

int *randArray = getRandValueNoRepeat(154, 62);
for(int i = 0; i < 62; i++) {
    int index = randArray[i];
    btns[index]...
    btns[307 - index]...
}
delete []randArray;

//308 * 0.4 = 123.2,这里选择填充124个空白色块。
//从0~154中随机产生62个不重复的数,最大值为153。
同理,index最大值为154,307-index的最小值为154,不会重复填充空白色块,也保证了彩色色块“不落单”。
 
  • 根据点击位置判断色块是否消失
    • 首先根据点击的位置求出当前按钮在数组中的下标。
    • 接下来分别向上、下、左、右四个方向寻找,看是否有相同的彩色色块。如果有,则将相同的彩色色块变成空白色块,如果没有,不作任何响应。(四个方向中如果有三个彩色色块相同,一次只将两个色块变为空白色块,这样也是为了保证彩色色块“不落单”。)
    • 彩色色块消失后,要实时更新彩色色块的数目,当数目小至一定值时,“Refresh”按钮变为可用。当遇到“不可消除”的情况时,用户点击“Refresh”按钮,会根据当前的彩色色块数目,重绘出相同数目的彩色色块(与原来色块布局不同),从而实现了刷新。

至此,游戏完成。

展开阅读全文

没有更多推荐了,返回首页