之前的文章请看:中国象棋游戏Chess(1) - 棋盘绘制以及棋子的绘制
现在实现走棋的功能。
首先需要获取点击到的棋子,用QWidget中的函数
mouseReleaseEvent
实现函数:
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(); } }
这里涉及到点击位置的有效性,写了一个函数,根据点击得到的位置判断是否属于所在矩形四个顶点中的某个圆内。
// 判断点击位置是否在某个顶点的圆内 // 返回值为bool类型是为了处理点击在棋盘外的情况 bool Board::getRowCol(QPoint pt, int &row, int &col) { row = pt.y() / (2 * _r) - 1; col = pt.x() / (2 * _r) - 1; 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; } row += 1; c = center(row, col); dx = c.x() - pt.x(); dy = c.y() - pt.y(); dist = dx * dx + dy * dy; // 和鼠标所处矩形左下顶点的距离 if (dist < _r * _r) { return true; } row -= 1; col += 1; c = center(row, col); dx = c.x() - pt.x(); dy = c.y() - pt.y(); dist = dx * dx + dy * dy; // 和鼠标所处矩形右上顶点的距离 if (dist < _r * _r) { return true; } row += 1; c = center(row, col); dx = c.x() - pt.x(); dy = c.y() - pt.y(); dist = dx * dx + dy * dy; // 和鼠标所处矩形右下顶点的距离 if (dist < _r * _r) { return true; } return false; }
注意更改drawStone函数中的绘制棋子部分。
if (id == _selectid) { painter.setBrush(QBrush(Qt::gray)); } else { painter.setBrush(QBrush(QColor(255, 228, 181))); // 将棋子底色设置为鹿皮色 }
如果是被选中的,把底色设置成灰色。
最终就实现了棋子的选中和走棋,效果为:
此时走棋可以随意走,可以随意吃,还没规则的限制,下一篇中再实现。
完整代码:Github