之前的文章请看:中国象棋游戏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. linux中probe函数传递参数的寻找(下)

    点击打开链接 linux中probe函数传递参数的寻找(下) 通过追寻driver的脚步,我们有了努力的方向:只有找到spi_bus_type的填充device即可,下面该从device去打通,当两个 ...

  2. list标准函数的模拟

    ;反序 ( ) -> ( ) (define (rvs x) (let recur ((x x)(res '())) (if (null? x) res (recur (cdr x) (cons ...

  3. [ExtJS5学习笔记]第三十六节 报表组件mzPivotGrid

    mzPivotGrid 是一个报表组件,采用这个组件之后,可以令你的应用体现更多的价值. 什么是pivot grid 什么是mzPivotGrid 学习资源 与图表组件的融合 什么是pivot gri ...

  4. acm入门搜索-水池数目

    水池数目 时间限制:3000 ms  |  内存限制:65535 KB 难度:4 描述 校园里有一些小河和一些湖泊,现在,我们把它们通一看成水池,假设有一张我们学校的某处的地图,这个地图上仅标识了此处 ...

  5. C语言获取文件大小

    C语言是一种比较底层的语言,有时在其他语言中很容易操作的事情,在C语言中就比较麻烦,例如获取一个文件的大小.Java中File类有个length函数,Python中os.path包中有个getsize ...

  6. Linux下使用两个线程协作完成一个任务的简易实现

    刚解决了之前的那个Linux下Pthread库的问题,这次就来使用两个线程来协作,共同完成一个求和的任务. 打一下基础吧 本次需要使用到的知识点有: lpthread,编译的时候用到,相当于一个声明的 ...

  7. LaTex计数器

    记数器 绝大多数都与可以改变他们的命令有相同的名称 part chapter section subsection paragraph subparagraph page equation figur ...

  8. Java进阶(一)Java内存解析

    栈.堆.常量池等虽同属Java内存分配时操作的区域,但其适用范围和功用却大不相同.本文将深入Java核心,简单讲解Java内存分配方面的知识. 首先我们先来讲解一下内存中的各个区域. stack(栈) ...

  9. TCP/IP入门(2) --网络层

    /** 本篇博客由 126(127不可用) 2^24 -2 B 2^14 -1 128.1 191.255 2^16 -2 C 2^21 -1 192.0.1 223.255.255 2^8 -2 D ...

  10. Accounting Flexfield Setup and Usage (Doc ID 124333.1)

    APPLIES TO:Oracle General Ledger - Version 11.5.10.2 to 12.1.3 [Release 11.5.10 to 12.1] Information ...