您的位置:首页 > 其它

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

2015-07-21 21:06 525 查看
本项目都使用QT来实现绘图,没有任何第三方的资源。

工程详情:Github

首先将棋盘设计为一个类Board

// Board.h
// Board类实现了棋盘的绘制以及显示
//

#ifndef BOARD_H
#define BOARD_H

#include <QWidget>
#include "Stone.h"

class Board : public QWidget
{
Q_OBJECT
public:
explicit Board(QWidget *parent = 0);

Stone _s[32]; // 定义32个棋子
int _r; // 棋子的半径

// 返回棋盘行列对应的像素坐标
QPoint center(int row, int col);
QPoint center(int id);

void drawStone(QPainter &painter, int id); // 绘制棋子

virtual void paintEvent(QPaintEvent *);

void DrawBackground(); // 设置背景颜色

signals:

public slots:
};

#endif // BOARD_H


// Board.cpp

#include "Board.h"
#include <QPainter> // 绘制棋盘需要

Board::Board(QWidget *parent) : QWidget(parent)
{
for (int i = 0; i < 32; ++i) {
_s[i].init(i);
}
}

// 绘制棋盘
void Board::paintEvent(QPaintEvent *)
{
DrawBackground();

QPainter painter(this);

int d = 40; // d表示棋盘格子的直径,也就是棋子的直径
_r = d / 2;

// 绘制10条横线
for (int i = 1; i <= 10; ++i) {
painter.drawLine(QPoint(d, i * d), QPoint(9 * d, i * d));
}

// 绘制9条竖线
for (int i = 1; i <= 9; ++i) {
if (1 == i || 9 == i) { // 中间有楚河汉界,不能全部都画通
painter.drawLine(QPoint(i * d, d), QPoint(i * d, 10 * d));
}
else {
painter.drawLine(QPoint(i * d, d), QPoint(i * d, 5 * d));
painter.drawLine(QPoint(i * d, 6 * d), QPoint(i * d, 10 * d));
}
}

// 绘制九宫格
painter.drawLine(QPoint(4 * d, d), QPoint(6 * d, 3 * d));
painter.drawLine(QPoint(4 * d, 3 * d), QPoint(6 * d, d));
painter.drawLine(QPoint(4 * d, 8 * d), QPoint(6 * d, 10 * d));
painter.drawLine(QPoint(4 * d, 10 * d), QPoint(6 * d, 8 * d));

// 绘制32个棋子
for (int i = 0; i < 32; ++i) {
drawStone(painter, i);
}
}

// 设置背景颜色
void Board::DrawBackground()
{
QPalette p = this->palette();
<pre style="margin-top: 0px; margin-bottom: 0px;">    p.setColor(<span style=" color:#800080;">QPalette</span>::<span style=" color:#800080;">Window</span>,<span style=" color:#c0c0c0;"> </span><span style=" color:#800080;">QColor</span>(<span style=" color:#000080;">224</span>,<span style=" color:#c0c0c0;"> </span><span style=" color:#000080;">255</span>,<span style=" color:#c0c0c0;"> </span><span style=" color:#000080;">255</span>));
this->setPalette(p);}QPoint Board::center(int row, int col){ QPoint ret; ret.rx() = (col + 1) * _r * 2; ret.ry() = (row + 1) * _r * 2; return ret;}// 重载center函数,方便调用QPoint Board::center(int id){ return center(_s[id]._row, _s[id]._col);}void
Board::drawStone(QPainter &painter, int id){ QPoint c = center(id); QRect rect = QRect(c.x() - _r, c.y() - _r, _r * 2, _r * 2); painter.setBrush(QBrush(QColor(255, 228, 181))); // 将棋子底色设置为鹿皮色 painter.setPen(Qt::black); // 先将画笔设置成黑色绘制圆形 painter.drawEllipse(center(id),
_r, _r); // 绘制圆形 if (_s[id]._red) { // 将上方的棋子字体颜色设置为红色 painter.setPen(Qt::red); } painter.setFont(QFont("system", _r, 700)); // 设置字体大小和类型 painter.drawText(rect, _s[id].getText(), QTextOption(Qt::AlignCenter));}



然后将其中的棋子也设计为一个类Stone

// Stone.h
// 棋子类,存储了棋子的基础信息

#ifndef STONE_H
#define STONE_H

#include <QString>

class Stone
{
public:
Stone();

enum TYPE{JIANG, CHE, PAO, MA, BING, SHI, XIANG};
int _row; // 棋子所处的行
int _col; // 棋子所处的列
int _id; // 棋子的id
bool _dead;
bool _red;
TYPE _type;

// 棋子的初始化
void init(int id);

// 判断_type返回相应字符串
QString getText();

};

#endif // STONE_H


// Stone.cpp

#include "Stone.h"

Stone::Stone()
{

}

void Stone::init(int id)
{
struct {
int row, col;
Stone::TYPE type;
} pos[16] = {
{0, 0, Stone::CHE},
{0, 1, Stone::MA},
{0, 2, Stone::XIANG},
{0, 3, Stone::SHI},
{0, 4, Stone::JIANG},
{0, 5, Stone::SHI},
{0, 6, Stone::XIANG},
{0, 7, Stone::MA},
{0, 8, Stone::CHE},

{2, 1, Stone::PAO},
{2, 7, Stone::PAO},
{3, 0, Stone::BING},
{3, 2, Stone::BING},
{3, 4, Stone::BING},
{3, 6, Stone::BING},
{3, 8, Stone::BING},
};

_id = id;
_dead = false;
_red = id < 16;

if (_red) { // 上方的棋子
_row = pos[id].row;
_col = pos[id].col;
_type = pos[id].type;
}
else { // 下方的棋子
_row = 9 - pos[id - 16].row;
_col = 8 - pos[id - 16].col;
_type = pos[id - 16].type;
}
}

QString Stone::getText()
{
switch (this->_type)
{
case CHE:
return "车";
case MA:
return "马";
case PAO:
return "炮";
case BING:
return "兵";
case JIANG:
return "将";
case SHI:
return "士";
case XIANG:
return "相";
}
return "错误";
}


最后实现的棋盘效果为:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: