中国象棋游戏的棋盘绘制主要是在 chessarea.cpp 中的 paintEvent 重绘事件中实现 ,主要用到 QPainter 类的画笔,在画棋盘的线之前,我们先调整一下棋盘的背景颜色。
在开始添加代码之前,先看一下 chessarea.h 里面的成员定义和需要添加的基本头文件 。
#ifndef CHESSAREA_H
#define CHESSAREA_H
#include <QWidget> // 基本窗口widget
#include <QPen> // 画笔
#include <QBrush> // 画刷
#include <QPainter> // 画布
#include <QPoint> // 点
#include <QColor> // 颜色
#include <QColorDialog> // 颜色Dialog
#include <QMouseEvent> // 鼠标事件
#include <QPaintEvent> // 绘画事件
#include "chess.h"
class ChessArea : public QWidget
{
public:
//构造函数
explicit ChessArea(QWidget *parent = NULL);
// 重绘事件,用来画棋盘线
void paintEvent(QPaintEvent *);
private:
int chessArea; // 这个用来定义棋盘线之间的宽度,这里初始化为60
};
#endif // CHESSAREA_H
1. 首先在chessarea.cpp的构造函数中添加以下代码,修改棋盘的背景色为米黄色。
//设置棋盘去区的背景颜色和大小
QPalette palette;
// 本来想绘制成模板线条颜色,但效果不理想,就设置成了米黄
QLinearGradient linearGradient(0, 0, 400, 400);
linearGradient.setColorAt(0.0, QColor(216, 180, 80));
linearGradient.setColorAt(0.2, QColor(216, 160, 72));
linearGradient.setColorAt(1.0, QColor(216, 156, 72));
palette.setBrush(QPalette::Background, QBrush(linearGradient));
setPalette(palette);
setAutoFillBackground(true);
setMinimumSize(600, 660);
2. 重写paintEvent重绘事件,在这里,我们添加象棋的棋盘线
void ChessArea::paintEvent(QPaintEvent *)
{
// 设置画笔为实线
QPen pen(Qt::SolidLine);
pen.setWidth(10);
pen.setColor(Qt::green);
QPainter p(this);
p.setPen(pen);
//反锯齿
p.setRenderHint(QPainter::Antialiasing);
//初始化描绘四个绿色点坐标
p.drawPoint(chessArea-5, chessArea-5);
p.drawPoint(chessArea*9+5, chessArea-5);
p.drawPoint(chessArea-5, chessArea*10+5);
p.drawPoint(chessArea*9+5, chessArea*10+5);
//设置画笔颜色和宽度
pen.setColor(Qt::black);
pen.setWidth(3);
p.setPen(pen);
// 1.画棋盘的轮廓线
p.drawLine(chessArea-5, chessArea-5, chessArea*9+5, chessArea-5);
p.drawLine(chessArea-5, chessArea-5, chessArea-5, chessArea*10+5);
p.drawLine(chessArea-5, chessArea*10+5, chessArea*9+5, chessArea*10+5);
p.drawLine(chessArea*9+5, chessArea-5, chessArea*9+5, chessArea*10+5);
// 2.画棋盘的18条垂直线
//pen = p.pen();
//background.setColor(Qt::black);
pen.setWidth(2);
p.setPen(pen);
for (int i=1; i<10; i++) {
p.drawLine(chessArea*i, chessArea, chessArea*i, chessArea*5);
p.drawLine(chessArea*i, chessArea*6,chessArea*i, chessArea*10);
}
// 3.楚河 汉界
p.drawLine(chessArea, chessArea*5, chessArea, chessArea*6);
p.drawLine(chessArea*9, chessArea*5 ,chessArea*9, chessArea*6);
// 4.画棋盘的10条水平线
for(int i=1;i<=10; i++)
p.drawLine(chessArea,chessArea*i, chessArea*9, chessArea*i);
// 5.画棋盘“士”行走的斜线
p.drawLine(chessArea*4, chessArea, chessArea*6, chessArea*3);
p.drawLine(chessArea*6, chessArea, chessArea*4, chessArea*3);
p.drawLine(chessArea*4, chessArea*8,chessArea*6, chessArea*10);
p.drawLine(chessArea*6, chessArea*8,chessArea*4, chessArea*10);
// 6. 写上楚河汉界
QPointF point(chessArea*2.6, chessArea*5.7);
p.setFont(QFont("Arial", 25));
p.drawText(point, "楚河 汉界");
}
这个时候基本的棋盘样子就出来了,样子大概是这样的:
这个时候,我们看到的棋盘比较简单,和现实生活中的棋盘相比还欠缺一点瑕疵,于是,可以在 paintEvent 函数里面继续添加以下代码,增加棋盘上面棋子,炮和兵的站位直角。(接着上面的第 6 步写)
// 7. 直角折线
pen.setWidth(4);
p.setPen(pen);
for(int j=2; j>0; j--)
{
for(int i=1; i<5; i++) /* 兵的井字格 */
{
QPoint points1[3] = {
QPoint(chessArea*(2*i-1)+5, chessArea*(10-j*3)-15),
QPoint(chessArea*(2*i-1)+5, chessArea*(10-j*3)-5),
QPoint(chessArea*(2*i-1)+15, chessArea*(10-j*3)-5),
};
p.drawPolyline(points1, 3);
QPoint points2[3] = {
QPoint(chessArea*(2*i+1)-15, chessArea*(10-j*3)-5),
QPoint(chessArea*(2*i+1)-5, chessArea*(10-j*3)-5),
QPoint(chessArea*(2*i+1)-5, chessArea*(10-j*3)-15),
};
p.drawPolyline(points2, 3);
QPoint points3[3] = {
QPoint(chessArea*(2*i-1)+5, chessArea*(10-j*3)+15),
QPoint(chessArea*(2*i-1)+5, chessArea*(10-j*3)+5),
QPoint(chessArea*(2*i-1)+15, chessArea*(10-j*3)+5),
};
p.drawPolyline(points3, 3);
QPoint points4[3] = {
QPoint(chessArea*(2*i+1)-15, chessArea*(10-j*3)+5),
QPoint(chessArea*(2*i+1)-5, chessArea*(10-j*3)+5),
QPoint(chessArea*(2*i+1)-5, chessArea*(10-j*3)+15),
};
p.drawPolyline(points4, 3);
if(i < 3) /* 炮的井字格 */
{
QPoint points5[3] = {
QPoint(chessArea*pow(2, 2*i-1)-15, chessArea*(pow(j+1,2)-1)-5),
QPoint(chessArea*pow(2, 2*i-1)-5, chessArea*(pow(j+1,2)-1)-5),
QPoint(chessArea*pow(2, 2*i-1)-5, chessArea*(pow(j+1,2)-1)-15),
};
p.drawPolyline(points5, 3);
QPoint points6[3] = {
QPoint(chessArea*pow(2, 2*i-1)+15, chessArea*(pow(j+1,2)-1)-5),
QPoint(chessArea*pow(2, 2*i-1)+5, chessArea*(pow(j+1,2)-1)-5),
QPoint(chessArea*pow(2, 2*i-1)+5, chessArea*(pow(j+1,2)-1)-15),
};
p.drawPolyline(points6, 3);
QPoint points7[3] = {
QPoint(chessArea*pow(2, 2*i-1)-15, chessArea*(pow(j+1,2)-1)+5),
QPoint(chessArea*pow(2, 2*i-1)-5, chessArea*(pow(j+1,2)-1)+5),
QPoint(chessArea*pow(2, 2*i-1)-5, chessArea*(pow(j+1,2)-1)+15),
};
p.drawPolyline(points7, 3);
QPoint points8[3] = {
QPoint(chessArea*pow(2, 2*i-1)+15, chessArea*(pow(j+1,2)-1)+5),
QPoint(chessArea*pow(2, 2*i-1)+5, chessArea*(pow(j+1,2)-1)+5),
QPoint(chessArea*pow(2, 2*i-1)+5, chessArea*(pow(j+1,2)-1)+15),
};
p.drawPolyline(points8, 3);
}
}
}
这个时候,棋盘绘制成这个样子了,和现实生活的棋盘就比较像,同时也美观了很多,到此,棋盘的绘制就成功了。