1.目标
打开游戏,单击开始按钮游戏开始,按照事先选好的下棋顺序,将显示当前棋手的执子颜色与步数,并且允许当前棋色落子,同时伴随落子音效,也在检测是否选手获得胜利,一旦胜利,立马提示胜利方。棋盘大小可以根据窗口大小改变。与常玩的五子棋游戏一致。
2.实现步骤
2.1构建棋盘
将棋盘的逻辑(即棋盘)与下棋的逻辑(主界面)分开,棋盘可以响应鼠标事件发出当前坐标信号,主界面接收坐标信号,并利用棋盘提供的刷新棋盘的方法,刷新棋盘。每下一步棋,刷新棋盘,判断是否胜利,切换角色方等。
- 1.在.pro中添加多媒体模块以便于读QSound的使用,在chessplate.h文件中添加用到类的头文件,如下:
QT += multimedia
- 2.创建不带ui界面的棋盘类
创建chessplate类,继承自QWidget,虽然不带ui界面,但在main中实例化该对象并调用show方法,会显示出界面,这是因为它继承自widget。 - 3.用QPainter画棋盘
①画背景图
②画棋盘线。将棋盘格子、起始、结束点定义成成员变量, 当窗口发生改变的时候,触发resize事件,在resize事件中改变上述三个变量的大小,同时resize又将触发QPainter事件,进行界面重绘,那么将实现棋盘会随着窗口大小的改变而改变。
③画定位点,可以使用brush在四个点画圆,也可以在固定位置画图片。
④画棋子,使用二维数组存储当前棋盘的状态,例如1代表黑色。使用鼠标点击事件,点击生成坐标,坐标信息结合当前角色刷新存储阵列,调用update()重绘图片,将根据最新的存储阵列刷新棋盘状态。为了能与其他模块交互,进行如下设计,在鼠标点击的时候,将坐标信息(不是真实的坐标,而是经过转换的格子的坐标)当成信号发出,其他类(主要指主界面)收到这个信息,刷新主界面中的存储阵列p,将p作为参数传递给棋盘类提供的刷新棋盘的方法中,完成模块之间的交互,完成界面的刷新。除此之外,还应注意,棋子应该画到棋盘横竖线的交叉点上。 - 4.鼠标事件
单击鼠标,记录当前的坐标信息,将其划分到格子中,即获取用户是想在哪个位置落子的信息,将这个格子的坐标当作信号发出。如果想做细致,应该考虑约束鼠标点击事件的响应方位,例如应限制在交叉点的多少半径范围之内才进行响应,避免用户不小心点错。 - 5.resizeEvent
每次resize会自动触发QPainter重绘,那么在resize的事件中只需要,重新回去当前的界面大小信息,随后计算在这个界面大小的情况下,棋盘格子应该为多大,将这些计算好之后QPainter将依据这个数据重新绘制,确保棋盘大小随着界面大小动态变化。但是考虑到棋盘的美观性,应该对界面能拉大缩小的范围有所限制,当然这个限制是在调用它的主界面中做的。 - 6.对外提供方法
提供修改背景图片的方法,提供修改棋盘线粗、线风格、线颜色的方法,提供刷新棋盘状态的方法。当一个类想对外提供修改某些东西的方法时,应该添加类成员变量,然后利用对外方法函数的参数来改变类成员变量的值,而这些个成员变量同时被”要修改的内容“当作参数使用。这就使得,外部类通过提供新的参数来改变这个类的东西。
//提供修改背景图片的方法
void setBackGroundPic(const QString filename);
//修改棋盘线风格
void setPlateLine(const QColor color,const Qt::PenStyle style,const int width);
//刷新棋盘
void setChessStatus(void *p);
2.2创建主界面
将绘制界面和界面元素的初始化分开逻辑更为清晰。所谓界面是指frame、背景、标题、界面大小等内容;界面元素是指例如为combox添加item等。在主界面中核心问题是,处理鼠标事件确保当前棋子落在准确位置,并提示用户角色切换;还有就是判断游戏胜利。
- 7.init初始化界面
使用QPainter画界面背景,在ui设计师中添加frame和界面元素部件,通过样式表对按钮进行美化;使用gridLayout添加棋盘widget;设置窗口title;设置”五子棋“标题;设置显示黑棋、白棋;ui设计师中 界面如下,看代码时找对应关系。
- 8.界面元素初始化
- 9.配置按钮音效,清空(初始化)棋盘,设置角色,连接鼠标信号(棋盘)与刷新界面函数,刷新界面函数将保存坐标信息到二维数组中,以此二维数组为参数调用棋盘类提供的刷新棋盘的方法,从而使得界面得到刷新。同时应该切换角色,为落子添加配音。判断玩家是否胜利。一旦有玩家胜利, 弹出对话框,恭喜玩家。
- 10.判断玩家是否胜利
思路:红绿线代表双层循环,红线代表内存循环,绿线代表外层循环。因此在遍历时将按照从上到下从左到右的顺序遍历。因此若每个棋子当作”五子连珠“的首棋子,那就只需检测四个方向的”五子连珠“,如图蓝线所示。一旦检测到有”五子连珠“立马停止遍历,返回胜利玩家。 - 11单击退出游戏或者”X“时,将提示是否退出,点是即刻退出,点否则不退出。
3.效果
程序完成之后,实操效果如下,感兴趣的朋友可以在此基础上自己编写算法,做一个“人机对战模式”;也可以在此基础上结合网口编程,实现公网对战。
4.传送门
END |
🎏文章原创,首发于CSDN论坛。
🎏欢迎点赞❤❤收藏⭐⭐打赏💴💴!
🎏欢迎评论区或私信指出错误❌,提出宝贵意见或疑问❓。