栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C++ 使用Qt绘画象棋的思路

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++ 使用Qt绘画象棋的思路

本文只展示部分代码,仅仅介绍思路

文章目录
  • 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);
			}
		}
	}
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/989780.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号