QT象棋练习(4)-棋子初始化

初始化棋子,首先,得有棋子,先定义一个棋子类。Stone.h。棋子需要有坐标,也就是行列,序号,是否被吃,颜色等属性。

#ifndef STONE_H
#define STONE_H


class Stone
{
public:
    Stone();
    ~Stone();
    
    enum TYPE {jiang, bing, pao, shi, che, ma, xiang};
    
    int _row;
    int _col;
    int _id;
    bool _dead;
    bool _red;
    TYPE type;
    
};

#endif // STONE_H

然后需要在棋盘中声明32个棋子。

Stone _s[32];

定义好棋子后,画在棋盘上。但是画棋子很复杂,需要定义一个函数来画。用drawStone(int id);思考?画棋子,需要画些什么,看以前 的图片知道,棋子是有一个圆圈组成,上面写着字。所以,我们需要的画的就是一个圆,还有一个字。画32个棋子就行。

//绘制棋子
    for(int i=0;i<32;i++)
    {
        drawStone(painter,i);
    }

先声明函数void drawStone(QPainter &painter,int id);画棋子画在哪?肯定是画在棋盘上,所以还需要有一个以前定义的painter。这里用的是引用,因为绘制的棋子需要和窗口关联。

void drawStone(QPainter &painter,int id);

现在来写drawStone函数,

函数的第一步就是画圆圈。画圆圈需要知道半径以及圆心坐标。但是,棋盘的坐标和窗口的坐标是不一样的。需要就行转换。这里用一个center函数来将窗口的坐标转化为棋盘坐标。半径就根据前面的画棋盘,半径是整个代码中都需要的属性,就直接加在棋盘的成员变量中。还要声明center函数。

    int _r;//棋子半径
    
    //返回棋盘对应的窗口坐标
    QPoint center(int row,int col); 

然后实现center函数。根据窗口和棋盘坐标关系很容易实现函数。

QPoint Board::center(int row,int col)
{
    QPoint ret;
    ret.rx()=(col+1)*_r*2;
    ret.ry()=(row+1)*_r*2;
    return ret;
}

 写完,发现center函数的参数比较多,麻烦,所以再写一个函数center函数,也就是函数重载。这样的话,在花圈的时候直接传入id就行了。

QPoint Board::center(int id)
{
    return center(_s[id].row,_s[id].col);
}
painter.drawEllipse(center(id),_r,_r);

 

花完圈后,还需要在上面写字。写字的话需要根据象棋的类型来写,在棋子类中加个函数,根据棋子的类型写字。

QString getText()()
    {
        switch(this->_type)
        {
        case CHE:
            return "车";
        case MA:
            return "马";
        case PAO:
            return "炮";
        case BING:
            return "兵";
        case JIANG:
            return "将";
        case SHI:
            return "士";
        case XIANG:
            return "相";
        }
        return "错误";
    }

写字也需要面临一个问题,就是写在哪。也就是需要坐标,根据函数drawText()知道,可以指定一个矩形,然后指定一个字符串,以及对齐方式。首先,要有一个矩形,然后就是字符串也就是函数getText()上面的函数,再就是对齐方式。

矩形怎么弄?用QRect()函数,这个函数,需要知道左上角的点的坐标还有就是边长。

    QPoint c=center(id);
    QRect rect=QRect(c.rx()-_r,c.ry(-_r),_r*2,_r*2);

目前,画好了,运行以下试试,看一下情况。发现,棋子好像没有初始化。也就是在棋盘中只定义了一个数组,但是没有出初始化。

Stone _s[32];

     

现在需要对32个棋子初始化。用一个init函数,在构造函数中初始化。


    void init(int id)
    {
        struct {
            int row, col;
            Stone::TYPE type;
        } pos[16] = {
        {0, 0, Stone::CHE},
        {0, 1, Stone::MA},
        {0, 2, Stone::XIANG},
        {0, 3, Stone::SHI},
        {0, 4, Stone::JIANG},
        {0, 5, Stone::SHI},
        {0, 6, Stone::XIANG},
        {0, 7, Stone::MA},
        {0, 8, Stone::CHE},

        {2, 1, Stone::PAO},
        {2, 7, Stone::PAO},
        {3, 0, Stone::BING},
        {3, 2, Stone::BING},
        {3, 4, Stone::BING},
        {3, 6, Stone::BING},
        {3, 8, Stone::BING},
        };

        if(id<16)
        {
            _row=pos[id].row;
            _col=pos[id].col;
            _type=pos[id].type;
        }
        else
        {
            _row=9-pos[id-16].row;
            _col=8-pos[id-16].col;
            _type=pos[id-16].type;
        }

        _id=id;
        _dead=false;
        _red=id<16;


    }

运行:

现字棋子初始化,但是不够美观,还有颜色美分。

在绘制的时候注意下一,首先绘制圆形,加入黄色的背景。再就是区别棋子是红的还是黑的。还有就是字体。

    painter.setBrush(QBrush(QColor(255,255,0)));   //背景颜色
    painter.setPen(Qt::black);  //画黑色矩形框

    if(_s[id]._red)
        painter.setPen(Qt::red);  //红色棋子,默认的黑色棋子,也就是上面黑色矩形框

    painter.setFont(QFont("system", _r, 700));  //字体

 

今日代码:

Board.cpp

#include "Board.h"
#include<QPainter>

Board::Board(QWidget *parent) : QWidget(parent)
{
    for(int i=0;i<32;i++)
    {
        _s[i].init(i);
    }
}
void Board::paintEvent(QPaintEvent*)
{
    QPainter painter(this);

    int d=40;  //棋子直径
    _r=d/2;
    //十条横线
    for(int i=1;i<=10;i++)
    {
        painter.drawLine(QPoint(d,i*d),QPoint(9*d,i*d));
    }

    //九条竖线
    for(int i=1;i<=9;i++)
    {
        if(i==1||i==9)
            painter.drawLine(QPoint(d*i,d),QPoint(i*d,10*d));
        else
        {
            painter.drawLine(QPoint(d*i,d),QPoint(i*d,5*d));
            painter.drawLine(QPoint(d*i,6*d),QPoint(i*d,10*d));
        }
    }
    //九宫格
    painter.drawLine(QPoint(d*4,d),QPoint(6*d,3*d));
    painter.drawLine(QPoint(d*6,d),QPoint(4*d,3*d));

    painter.drawLine(QPoint(d*4,10*d),QPoint(6*d,8*d));
    painter.drawLine(QPoint(d*6,10*d),QPoint(4*d,8*d));

    //绘制棋子
    for(int i=0;i<32;i++)
    {
        drawStone(painter,i);
    }
}

QPoint Board::center(int row,int col)
{
    QPoint ret;
    ret.rx()=(col+1)*_r*2;
    ret.ry()=(row+1)*_r*2;
    return ret;
}
QPoint Board::center(int id)
{
    return center(_s[id]._row,_s[id]._col);
}

void Board::drawStone(QPainter &painter,int id)
{
    QPoint c=center(id);
    QRect rect=QRect(c.rx()-_r,c.ry()-_r,_r*2,_r*2);

    painter.setBrush(QBrush(QColor(255,255,0)));   //背景颜色
    painter.setPen(Qt::black);  //画黑色矩形框

    if(_s[id]._red)
        painter.setPen(Qt::red);  //红色棋子,默认的黑色棋子,也就是上面黑色矩形框

    painter.setFont(QFont("system", _r, 700));  //字体

    painter.drawEllipse(center(id),_r,_r);
    painter.drawText(rect,_s[id].getText(),QTextOption(Qt::AlignCenter));
}

Board.h

#ifndef BOARD_H
#define BOARD_H

#include <QWidget>
#include"Stone.h"

class Board : public QWidget
{
    Q_OBJECT
public:
    explicit Board(QWidget *parent = 0);

    Stone _s[32];
    int _r;//棋子半径

    //返回棋盘对应的窗口坐标
    QPoint center(int row,int col);
    QPoint center(int id);

    void drawStone(QPainter &painter,int id);
    void paintEvent(QPaintEvent *);

signals:

public slots:
};

#endif // BOARD_H

 

Stone.h

#ifndef STONE_H
#define STONE_H
#include<QString>

class Stone
{
public:
    Stone();
    ~Stone();

    enum TYPE {JIANG,CHE,MA,PAO,SHI,BING,XIANG};

    int _row;
    int _col;
    int _id;
    bool _dead;
    bool _red;
    TYPE _type;

    void init(int id)
    {
        struct {
            int row, col;
            Stone::TYPE type;
        } pos[16] = {
        {0, 0, Stone::CHE},
        {0, 1, Stone::MA},
        {0, 2, Stone::XIANG},
        {0, 3, Stone::SHI},
        {0, 4, Stone::JIANG},
        {0, 5, Stone::SHI},
        {0, 6, Stone::XIANG},
        {0, 7, Stone::MA},
        {0, 8, Stone::CHE},

        {2, 1, Stone::PAO},
        {2, 7, Stone::PAO},
        {3, 0, Stone::BING},
        {3, 2, Stone::BING},
        {3, 4, Stone::BING},
        {3, 6, Stone::BING},
        {3, 8, Stone::BING},
        };

        if(id<16)
        {
            _row=pos[id].row;
            _col=pos[id].col;
            _type=pos[id].type;
        }
        else
        {
            _row=9-pos[id-16].row;
            _col=8-pos[id-16].col;
            _type=pos[id-16].type;
        }

        _id=id;
        _dead=false;
        _red=id<16;


    }

    QString getText()
    {
        switch(this->_type)
        {
        case CHE:
            return "车";
        case MA:
            return "马";
        case PAO:
            return "炮";
        case BING:
            return "兵";
        case JIANG:
            return "将";
        case SHI:
            return "士";
        case XIANG:
            return "相";
        }
        return "错误";
    }

};

#endif // STONE_H

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值