棋盘,棋子画好了,现在应该开始走棋了,走棋,用鼠标点击一个棋子,再点击一个位置,就可以走了。
首先就是鼠标事件函数,这里有两个,一个是鼠标释放和鼠标点下去的函数,选择释放的函数。因为在下棋的时候,习惯点击后松开,在要走的位置点击。
//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。
上面是选中棋子,下面就要移动棋子。定义一个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;
到这就完成,但是这个棋子就没有规则,随便下。如果自觉遵守规则,这个棋盘已经可以下棋了。
计算距离代码:
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();
}
}