Qt開發之中國象棋篇(二):棋盤的繪製
阿新 • • 發佈:2018-12-12
中國象棋遊戲的棋盤繪製主要是在 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);
}
}
}
這個時候,棋盤繪製成這個樣子了,和現實生活的棋盤就比較像,同時也美觀了很多,到此,棋盤的繪製就成功了。