本文只展示部分代码,仅仅介绍思路
文章目录
- 0.效果
- 1.绘制背景
- 载入棋子(使用工厂模式)
- 写好绘画的框架
- 载入(调用工厂函数)
- 2.绘画棋子
象棋蛮好玩的,但是某些象棋推行健康系统是真的…,有些网站容易崩,所以我想自己搞一个来玩。
0.效果 1.绘制背景void GameMainWindow::drawBackground(QPainter& painter)
{
{
// draw line ——
for (int i = 0; i < 10; ++i) {
painter.drawLine(left_distance,
top_distance + i * gird_height,
left_distance + 8 * gird_width,
top_distance + i * gird_height);
}
}
{
// draw line |
painter.drawLine(left_distance,
top_distance,
left_distance,
top_distance + 9 * gird_height);
painter.drawLine(default_width - left_distance,
top_distance,
default_width - left_distance,
top_distance + 9 * gird_height);
for (int i = 1; i < 8; ++i) {
painter.drawLine(left_distance + i * gird_width,
top_distance,
left_distance + i * gird_width,
top_distance + 4 * gird_height);
painter.drawLine(left_distance + i * gird_width,
top_distance + 5 * gird_height,
left_distance + i * gird_width,
top_distance + 9 * gird_height);
}
}
{
// draw text
auto pen = painter.pen();
auto font = painter.font();
QFont f;
f.setPointSize(28);
f.setFamily(tr("华文新魏"));
painter.setPen(Qt::black);
painter.setFont(f);
painter.drawText(left_distance + gird_width / 4,
top_distance + (9 * gird_height) / 2 + gird_height / 8,
tr("楚"));
painter.drawText(left_distance + 3 * gird_width - 3 * gird_width / 4,
top_distance + (9 * gird_height) / 2 + gird_height / 8,
tr("河"));
painter.setPen(Qt::red);
painter.drawText(left_distance + 6 * gird_width - 3 * gird_width / 4,
top_distance + (9 * gird_height) / 2 + gird_height / 8,
tr("汉"));
painter.drawText(left_distance + 8 * gird_width - 3 * gird_width / 4,
top_distance + (9 * gird_height) / 2 + gird_height / 8,
tr("界"));
painter.setPen(pen);
painter.setFont(font);
}
{
// draw line
painter.drawLine(left_distance + 3 * gird_width,
top_distance,
left_distance + 5 * gird_width,
top_distance + 2 * gird_height);
painter.drawLine(left_distance + 5 * gird_width,
top_distance,
left_distance + 3 * gird_width,
top_distance + 2 * gird_height);
painter.drawLine(left_distance + 3 * gird_width,
top_distance + 7 * gird_height,
left_distance + 5 * gird_width,
top_distance + 9 * gird_height);
painter.drawLine(left_distance + 5 * gird_width,
top_distance + 7 * gird_height,
left_distance + 3 * gird_width,
top_distance + 9 * gird_height);
}
}
代码仅供参考
在一个主窗口上绘制了一个棋盘,但是上下左右都有间距,左右大小是left_distance,上下大小是top_distance,一行有9个棋子的位置,一个阵营有5个位置。
先划线,把大概轮廓勾出来,注意,中间有楚河和汉界是不需要划线的,所以需要分情况处理。
我做了很多棋子类,都继承于Chess类,Chess类提供了一个绘画框架,子类只需要提供需要显示的文字即可绘画出来了
void Chess::draw(QPainter& painter, int left_distance, int top_distance, int gird_width, int gird_height)
{
auto pen = painter.pen();
auto font = painter.font();
int curr_x = x();
int curr_y = y();
int default_point_x = left_distance + curr_x * gird_width;
int default_point_y = top_distance + curr_y * gird_height;
int start_point_x = default_point_x - 0.5 * gird_width;
int start_point_y = default_point_y - 0.5 * gird_height;
int& arc_width = gird_width;
painter.setPen(Qt::gray);
painter.drawArc(start_point_x, start_point_y, arc_width, arc_width, 0, 360 * 16);
// text
{
QFont f;
f.setFamily(tr("华文新魏"));
f.setPointSize(26);
painter.setFont(f);
painter.setPen(bloc_ == Chess::Bloc::Red ? Qt::red : Qt::black);
}
painter.drawText(
default_point_x - gird_width / M_PI,
default_point_y - gird_width / M_PI, arc_width, arc_width, 0,
show_text_);
painter.setPen(pen);
painter.setFont(font);
}
载入(调用工厂函数)
void ChessBoard::loadChesses()
{
int&& board_height = chesses_.size();
{
// Red
for (int i = 0; i < 5; ++i) {
chesses_.last()[i] = ChessFactory(4 - i, i, board_height - 1, Chess::Bloc::Red, this);
}
for (int i = 5; i < chesses_[0].size(); ++i) {
chesses_.last()[i] = ChessFactory(i - 4, i , board_height - 1, Chess::Bloc::Red, this);
}
chesses_[board_height - 3][1] = ChessFactory(5, 1, board_height - 3, Chess::Bloc::Red, this);
chesses_[board_height - 3][7] = ChessFactory(5, 7, board_height - 3, Chess::Bloc::Red, this);
for (int i = 0; i < 5; ++i) {
chesses_[board_height - 4][i * 2] = ChessFactory(6, i * 2, board_height - 4, Chess::Bloc::Red, this);
}
}
{
// Black
for (int i = 0; i < 5; ++i) {
chesses_.front()[i] = ChessFactory(4 - i, i, 0, Chess::Bloc::Black, this);
}
for (int i = 5; i < chesses_[0].size(); ++i) {
chesses_.front()[i] = ChessFactory(i - 4, i, 0, Chess::Bloc::Black, this);
}
chesses_[2][1] = ChessFactory(5, 1, 2, Chess::Bloc::Black, this);
chesses_[2][7] = ChessFactory(5, 7, 2, Chess::Bloc::Black, this);
for (int i = 0; i < 5; ++i) {
chesses_[3][i * 2] = ChessFactory(6, i * 2, 3, Chess::Bloc::Black, this);
}
}
}
为了不一次性引入太多头文件,我将需要的棋子的头文件都引入到includer这个头文件里面,这样真的方便很多,同时在里面写了一个棋子的工厂函数,根据id,位置,阵营生成对应棋子,加上Qt的内存管理机制是真的起飞。
2.绘画棋子趁热打铁,绘画方法有了,直接在主窗口上画!
void GameMainWindow::drawChessBoard(QPainter& painter)
{
for (int i = 0; i < 10; ++i) {
for (int j = 0; j < 9; ++j) {
if (Chess* chess = chessboard_[i][j]; chess != nullptr) {
chess->draw(painter, left_distance, top_distance, gird_width, gird_height);
}
}
}
}



