QT象棋练习(5)-走棋

棋盘,棋子画好了,现在应该开始走棋了,走棋,用鼠标点击一个棋子,再点击一个位置,就可以走了。

首先就是鼠标事件函数,这里有两个,一个是鼠标释放和鼠标点下去的函数,选择释放的函数。因为在下棋的时候,习惯点击后松开,在要走的位置点击。

//void mousePressEvent(QMouseEvent*);  //鼠标点下去的
void mouseReleaseEvent(QMouseEvent*);  //鼠标释放的

获取释放后的坐标值,这个坐标值时窗口左边,我们需要的是棋盘坐标,所以在这还要进行坐标转换,上次时窗口的坐标值转化为棋盘坐标值,这次是要把其棋盘的坐标值转化为窗口的坐标值。

bool getRowCol(QPoint pt,int &row,int &col);

枚举每个棋子,看他们距离点击的距离是否小于半径,是的话点击的位于其坐标下。这个是一个效率低下的方式,但是最好理解。

bool Board::getRowCol(QPoint pt, int &row, int &col)
{
    for(row=0; row<=9; row++)
    {
        for(col=0; col<=8; col++)
        {
            QPoint c = center(row, col);
            int dx = c.x() - pt.x();
            int dy = c.y() - pt.y();
            int dist = dx*dx+dy*dy;
            if(dist < _r*_r)
                return true;
        }
    }
    return false;
}

如果返回false,则代表点到棋盘外了。

    if(bRet == false)   //点到棋盘外了
        return;

枚举32颗棋子,如果其行列坐标相对应,且没死的话,则代表该棋子被选中。定义一个_selectid用来记录被选中的棋子。

    for(int i=0;i<32;i++)
    {
        if(_s[i]._row==row&&_s[i]._col==col&&_s[i]._dead == false)
            break;
    }
    if(i<32)  //棋子被选中
        _slectid=i;
    
int _selectid;

 

选中的棋子,应该和其他的棋子有一点区别,要让人知道这个棋子是被选中的棋子,我们可以将棋子的背景绘成不一样的颜色。在这个就需要在上一个函数void drawStone(QPainter &painter,int id);中去改。我们记录了被选中棋子的id,也就是_selectid。选中棋子背景颜色是灰色,其他的是黄色。

if(id==_selectid)
        painter.setBrush(QBrush(Qt::gray));
    else
        painter.setBrush(QBrush(Qt::yellow));   //背景颜色

然后在点要用函数update(),该函数会重新调用paintEvent。

QT象棋练习(5)-走棋_第1张图片

 

上面是选中棋子,下面就要移动棋子。定义一个clickid被点击的地方,

    int i;
    int clickid=-1;   //被点击的地方
    for(i=0;i<32;i++)
    {
        if(_s[i]._row==row&&_s[i]._col==col&&_s[i]._dead == false)
        {
            break;
        }
    }
    if(i<32)  //棋子被选中
    {
        clickid=i;
    }

被点击的地方有没有棋子,如果没有的话,直接移过去。


    if(_selectid==-1)
    {
        if(clickid!=-1)
        {
            _selectid=clickid;
            update();
        }
     }

如果有棋子,就吃掉棋子

    else
    {
        _s[_selectid]._row=row;
        _s[_selectid]._col=col;
        if(clickid!=-1)  //被点的地方如果有棋子就把他吃掉
            _s[clickid]._dead=true;
        _selectid=-1;
        update();
    }

且该棋子在drawStone函数中不再显示。

    if(_s[id]._dead)
        return;

到这就完成,但是这个棋子就没有规则,随便下。如果自觉遵守规则,这个棋盘已经可以下棋了。

QT象棋练习(5)-走棋_第2张图片

计算距离代码:

bool Board::getRowCol(QPoint pt, int &row, int &col)
{
    for(row=0; row<=9; row++)
    {
        for(col=0; col<=8; col++)
        {
            QPoint c = center(row, col);
            int dx = c.x() - pt.x();
            int dy = c.y() - pt.y();
            int dist = dx*dx+dy*dy;
            if(dist < _r*_r)
                return true;
        }
    }
    return false;
}

 走棋代码:

void Board::mouseReleaseEvent(QMouseEvent *ev)
{
    QPoint pt=ev->pos();
    //将pt转化为棋子的行列值
    //然后再判断行列值上面有没有棋子
    int row,col;
    bool bRet = getRowCol(pt,row,col);
    if(bRet == false)   //点到棋盘外了
        return;
    int i;
    int clickid=-1;   //被点击的棋子
    for(i=0;i<32;i++)
    {
        if(_s[i]._row==row&&_s[i]._col==col&&_s[i]._dead == false)
        {
            break;
        }
    }
    if(i<32)  //棋子被选中
    {
        clickid=i;
    }

    if(_selectid==-1)
    {
        if(clickid!=-1)
        {
            _selectid=clickid;
            update();
        }
     }
    else
    {
        _s[_selectid]._row=row;
        _s[_selectid]._col=col;
        if(clickid!=-1)  //被点的地方如果有棋子就把他吃掉
            _s[clickid]._dead=true;
        _selectid=-1;
        update();
    }

}

 

你可能感兴趣的:(QT)