之前的文章请看:中国象棋游戏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

中国象棋游戏Chess(2) - 走棋的更多相关文章

  1. 中国象棋游戏Chess(3) - 实现走棋规则

    棋盘的绘制和走棋参看博文:中国象棋游戏Chess(1) - 棋盘绘制以及棋子的绘制,中国象棋游戏Chess(2) - 走棋 现在重新整理之前写的代码,并且对于每个棋子的走棋规则都进行了限制,不像之前那 ...

  2. 中国象棋游戏Chess(1) - 棋盘绘制以及棋子的绘制

    本项目都使用QT来实现绘图,没有任何第三方的资源. 工程详情:Github 首先将棋盘设计为一个类Board // Board.h // Board类实现了棋盘的绘制以及显示 // #ifndef B ...

  3. 基于HTML5实现的中国象棋游戏

    棋类游戏在桌面游戏中已经非常成熟,中国象棋的版本也非常多.今天这款基于HTML5技术的中国象棋游戏非常有特色,我们不仅可以选择中国象棋的游戏难度,而且可以切换棋盘的样式.程序写累了,喝上一杯咖啡,和电 ...

  4. C/C++编程笔记:C语言打造中国象棋游戏,项目源代码分享!

    中国象棋是起源于中国的一种棋,属于二人对抗性游戏的一种,在中国有着悠久的历史.由于用具简单,趣味性强,成为流行极为广泛的棋艺活动. 它是中国棋文化,也是中华民族的文化瑰宝,它源远流长,趣味浓厚,基本规 ...

  5. C#中国象棋+游戏大厅 服务器 + 客户端源码

    来源:www.ajerp.com/bbs C#中国象棋+游戏大厅 服务器 + 客户端源码 源码开源 C#版中国象棋(附游戏大厅) 基于前人大虾的修改版 主要用委托实现 服务器支持在线人数,大厅桌数的设 ...

  6. 【原创】使用HTML5+canvas+JavaScript开发的原生中国象棋游戏及源码分享

    目前已经实现的功能: V1.0 : 实现棋子的布局,画布及游戏场景的初始化V2.0 : 实现棋子的颜色改变V3.0 :实现所有象棋的走棋规则V4.0 : 实现所有棋子的吃子功能 GItHub源码下载地 ...

  7. Cocos2d-X开发中国象棋《八》走棋

    在上一节中实现了新局,至此中国象棋的准备工作差点儿相同都完毕了,在接下来的博客中将介绍玩家的走棋和一些游戏属性的设置,今天先介绍走棋和走棋规则 老规则,先看走棋的效果图,然后依据效果图一步一步分析游戏 ...

  8. Cocos2d-X开发中国象棋《九》走棋规则

    在上一节中实现了走棋,这篇博客将介绍中国象棋中的走棋规则 在写博客前先可能一下象棋的走棋规则: 1)将 将的坐标关系:横坐标相等,纵坐标相减绝对值等于1,或者纵坐标相等,横坐标相减绝对值等于1 将的特 ...

  9. GMchess Linux下的中国象棋游戏

    gmchess,一款Linux下的中国象棋程序

随机推荐

  1. 动手试试Android Studio插件开发

    由于业务关系,经常需要写一些表单页面,基本也就是简单的增删改查然后上传,做过几个页面之后就有点想偷懒了,这么低水平重复性的体力劳动,能不能用什么办法自动生成呢,查阅相关资料,发现android stu ...

  2. springMVC源码分析--HttpRequestHandlerAdapter(四)

    上一篇博客springMVC源码分析--HandlerAdapter(一)中我们主要介绍了一下HandlerAdapter接口相关的内容,实现类及其在DispatcherServlet中执行的顺序,接 ...

  3. Effective Python 中文版

    如题,博主正在翻译一本Python相关的书. 图为Python作者. [美]Brett Slatkin的名作. Effective Python: 59 Specific Ways to Write ...

  4. 让sublime总是在新选项卡打开新文件

    sublime的一个默认设置让人很不爽,比如现在选项卡里面已经打开了一个文件A,当你从左边side bar里面点击一个新文件B时,如果你不是快速的双击,且A没有处于编辑未保存状态,那么B就会覆盖A的选 ...

  5. 【安卓开发】Android为什么选择binder

    Binder (Android技术内幕): 在上面这些可供选择的方式中,Android使用得最多也最被认可的还是Binder机制. 为什么会选择Binder来作为进程之间的通信机制呢?因为Binder ...

  6. PHP学习(3)—在HTML中嵌入PHP

    我们以一个提交订单和显示订单信息的例子为学习PHP的开始.这个例子包含两个文件.一个提交订单的html文件:orderform.html,一个显示订单信息的php文件:processorder.php ...

  7. ActiveMQ入门示例

    1.ActiveMQ下载地址 http://activemq.apache.org/download.html 2.ActiveMQ安装,下载解压之后如下目录

  8. Asp.net 在刷新或提交页面后保持滚动条的位置

    网页内容在较长时,每次回传刷新页面或提交网页时都会定位到最顶端,非常不利于用户交互. 将Page.MaintainScrollPositionOnPostBack属性值设置为true即可实现刷新后保持 ...

  9. [ExtJS5学习笔记]第八节 Extjs5的Ext.toolbar.Toolbar工具条组件及其应用

    本文地址:http://blog.csdn.net/sushengmiyan/article/details/38515499 本文作者:sushengmiyan ------------------ ...

  10. 【编程练习】poj1111

    Image Perimeters Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 8632   Accepted: 5168 ...