1. 程式人生 > >Qt開發之中國象棋篇(二):棋盤的繪製

Qt開發之中國象棋篇(二):棋盤的繪製

        中國象棋遊戲的棋盤繪製主要是在 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);
            }

        }

    }

         這個時候,棋盤繪製成這個樣子了,和現實生活的棋盤就比較像,同時也美觀了很多,到此,棋盤的繪製就成功了。