Qt Creator开发安卓五子棋游戏全流程
1. Qt Creator创建安卓项目全流程解析作为一款跨平台的集成开发环境Qt Creator在移动端开发领域有着独特的优势。我使用Qt开发移动应用已有五年时间今天就来详细讲解如何从零开始创建一个安卓平台的五子棋游戏APP。1.1 环境准备与工具链配置在开始之前我们需要确保开发环境完整配置。不同于普通的桌面应用开发安卓开发需要额外的组件支持Qt安装建议使用官方在线安装器勾选Android组件。目前最新稳定版是Qt 6.5它提供了更好的安卓兼容性。JDK必须安装Java Development Kit 11或更高版本。Oracle JDK和OpenJDK都可以我个人推荐使用Amazon Corretto JDK。Android SDK通过Android Studio安装或独立下载命令行工具。关键要安装Platform SDKAPI级别建议选31Build Tools版本30.0.3以上NDK版本23以上CMake环境变量配置export ANDROID_HOME/path/to/android-sdk export ANDROID_NDK_HOME$ANDROID_HOME/ndk/25.1.8937393 export JAVA_HOME/path/to/jdk注意在麒麟系统V10 aarch64架构上安装时需要下载对应架构的Qt离线安装包。配置步骤与x86平台类似但NDK必须使用aarch64版本。1.2 新建安卓项目步骤详解打开Qt Creator后按照以下步骤操作点击文件→新建文件或项目选择Application→Qt Quick Application - Empty在Details步骤中设置项目名称如Gobang选择项目位置勾选Create for Android选项在Kits选择界面确保已检测到安卓工具链选择目标API级别建议≥26完成创建后项目结构如下Gobang/ ├── android/ │ ├── AndroidManifest.xml │ ├── build.gradle │ └── res/ ├── qml/ │ └── main.qml └── Gobang.pro1.3 安卓平台特殊配置在项目根目录的Gobang.pro文件中需要添加android { ANDROID_PACKAGE_SOURCE_DIR $$PWD/android ANDROID_EXTRA_LIBS $$PWD/android/libs/ # 最低API级别 ANDROID_MIN_SDK_VERSION 23 # 目标API级别 ANDROID_TARGET_SDK_VERSION 31 }在AndroidManifest.xml中需要配置关键权限和活动uses-permission android:nameandroid.permission.INTERNET/ application android:nameorg.qtproject.qt5.android.bindings.QtApplication android:labelstring/app_name activity android:nameorg.qtproject.qt5.android.bindings.QtActivity android:screenOrientationportrait intent-filter action android:nameandroid.intent.action.MAIN/ category android:nameandroid.intent.category.LAUNCHER/ /intent-filter /activity /application2. 五子棋游戏核心逻辑实现2.1 游戏数据结构设计我们先在C端实现游戏核心逻辑。创建gameengine.h头文件#include QObject #include QVector class GameEngine : public QObject { Q_OBJECT public: explicit GameEngine(QObject *parent nullptr); enum Player { Empty, Black, White }; Q_ENUM(Player) Q_INVOKABLE bool playMove(int x, int y); Q_INVOKABLE Player checkWinner() const; Q_INVOKABLE void resetGame(); signals: void boardChanged(); private: static const int BOARD_SIZE 15; QVectorQVectorPlayer m_board; Player m_currentPlayer Black; bool checkLine(int x, int y, int dx, int dy) const; };对应的gameengine.cpp实现GameEngine::GameEngine(QObject *parent) : QObject(parent) { m_board.resize(BOARD_SIZE); for (auto row : m_board) { row.resize(BOARD_SIZE); row.fill(Empty); } } bool GameEngine::playMove(int x, int y) { if (x 0 || x BOARD_SIZE || y 0 || y BOARD_SIZE || m_board[x][y] ! Empty) { return false; } m_board[x][y] m_currentPlayer; emit boardChanged(); if (checkWinner() ! Empty) { return true; } m_currentPlayer (m_currentPlayer Black) ? White : Black; return true; } GameEngine::Player GameEngine::checkWinner() const { // 检查四个方向水平、垂直、对角线 const int directions[4][2] {{1,0}, {0,1}, {1,1}, {1,-1}}; for (int x 0; x BOARD_SIZE; x) { for (int y 0; y BOARD_SIZE; y) { if (m_board[x][y] Empty) continue; for (const auto dir : directions) { if (checkLine(x, y, dir[0], dir[1])) { return m_board[x][y]; } } } } return Empty; } bool GameEngine::checkLine(int x, int y, int dx, int dy) const { Player player m_board[x][y]; int count 1; for (int i 1; i 5; i) { int nx x dx * i; int ny y dy * i; if (nx 0 || nx BOARD_SIZE || ny 0 || ny BOARD_SIZE || m_board[nx][ny] ! player) { break; } count; } for (int i 1; i 5; i) { int nx x - dx * i; int ny y - dy * i; if (nx 0 || nx BOARD_SIZE || ny 0 || ny BOARD_SIZE || m_board[nx][ny] ! player) { break; } count; } return count 5; } void GameEngine::resetGame() { for (auto row : m_board) { row.fill(Empty); } m_currentPlayer Black; emit boardChanged(); }2.2 QML界面设计与交互修改main.qml实现游戏界面import QtQuick 2.15 import QtQuick.Controls 2.15 ApplicationWindow { id: window visible: true width: 360 height: 480 title: qsTr(五子棋) GameEngine { id: gameEngine } Rectangle { anchors.fill: parent color: #f0d9b5 GridView { id: board anchors.centerIn: parent width: Math.min(parent.width, parent.height) - 40 height: width cellWidth: width / 15 cellHeight: cellWidth interactive: false model: 225 // 15x15 delegate: Rectangle { width: board.cellWidth height: board.cellHeight color: transparent border.color: #8b4513 border.width: 1 property int row: Math.floor(index / 15) property int col: index % 15 Rectangle { anchors.centerIn: parent width: parent.width * 0.8 height: width radius: width / 2 color: { var state gameEngine.m_board[row][col] if (state GameEngine.Black) return black if (state GameEngine.White) return white return transparent } } MouseArea { anchors.fill: parent onClicked: gameEngine.playMove(row, col) } } } Button { anchors { bottom: parent.bottom horizontalCenter: parent.horizontalCenter margins: 10 } text: 重新开始 onClicked: gameEngine.resetGame() } Label { anchors { top: parent.top horizontalCenter: parent.horizontalCenter margins: 10 } text: gameEngine.currentPlayer GameEngine.Black ? 黑方回合 : 白方回合 font.pixelSize: 20 } } }2.3 C与QML的交互绑定在main.cpp中注册C类型#include QGuiApplication #include QQmlApplicationEngine #include QQmlContext #include gameengine.h int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); qmlRegisterTypeGameEngine(com.gobang, 1, 0, GameEngine); QQmlApplicationEngine engine; engine.load(QUrl(QStringLiteral(qrc:/main.qml))); return app.exec(); }3. 安卓平台适配与优化3.1 触摸操作优化为提升移动端体验我们需要优化触摸交互。修改main.qml中的MouseAreaMouseArea { anchors.fill: parent onClicked: gameEngine.playMove(row, col) onPressed: { // 添加按下效果 parent.border.color #ff0000 parent.border.width 2 } onReleased: { parent.border.color #8b4513 parent.border.width 1 } }3.2 屏幕适配策略在main.qml的ApplicationWindow中添加property real scaling: Math.min(width/360, height/480) transform: Scale { origin.x: 0 origin.y: 0 xScale: scaling yScale: scaling }3.3 安卓权限与特性配置在AndroidManifest.xml中添加必要的权限uses-feature android:nameandroid.hardware.touchscreen android:requiredtrue/ uses-permission android:nameandroid.permission.VIBRATE/添加触觉反馈效果修改main.qmlimport QtAndroid 1.0 // ... MouseArea { onClicked: { QtAndroid.vibrate(50) // 50ms震动 gameEngine.playMove(row, col) } }4. 构建与部署实战4.1 构建配置要点在Qt Creator的项目设置中选择Android for arm64-v8a构建套件在Build Android APK部分设置应用图标至少512x512配置应用名称和版本选择Release模式并配置签名4.2 常见构建问题解决NDK版本不兼容错误信息NDK not configured解决方案在android/local.properties中添加ndk.dir/path/to/ndk/25.1.8937393Java版本冲突错误信息Unsupported class file major version解决方案确保使用JDK 11在Qt Creator的工具→选项→Kits中设置正确的JDK路径资源文件缺失错误信息AAPT: error: resource android:attr/lStar not found解决方案将compileSdkVersion和targetSdkVersion升级到314.3 性能优化技巧QML性能优化GridView { // ... cacheBuffer: 1000 // 预缓存更多项 boundsBehavior: Flickable.StopAtBounds }C代码优化// 使用QVector的reserve预分配内存 m_board.reserve(BOARD_SIZE); for (auto row : m_board) { row.reserve(BOARD_SIZE); }安卓特定优化 在android/AndroidManifest.xml中添加application android:hardwareAcceleratedtrue meta-data android:nameandroid.app.lib_name android:valuegobang/ /application5. 高级功能扩展5.1 网络对战功能使用Qt的Network模块实现网络对战#include QTcpServer #include QTcpSocket class NetworkManager : public QObject { Q_OBJECT public: explicit NetworkManager(QObject *parent nullptr); Q_INVOKABLE void createGame(); Q_INVOKABLE void joinGame(const QString address); signals: void moveReceived(int x, int y); void connectionStatusChanged(bool connected); private slots: void onNewConnection(); void onDataReceived(); private: QTcpServer *m_server nullptr; QTcpSocket *m_socket nullptr; };5.2 AI对手实现简单的AI算法实现QPairint, int GameEngine::findBestMove() const { // 简单实现寻找能形成最长连线的位置 int maxScore -1; QPairint, int bestMove(-1, -1); for (int x 0; x BOARD_SIZE; x) { for (int y 0; y BOARD_SIZE; y) { if (m_board[x][y] ! Empty) continue; int score evaluatePosition(x, y); if (score maxScore) { maxScore score; bestMove {x, y}; } } } return bestMove; }5.3 接入Qt Creator的AI辅助功能最新版Qt Creator支持AI代码补全安装Qt Creator AI Plugin在代码编辑器中右键点击选择AI Assist可以生成代码片段或优化现有代码例如输入提示生成一个五子棋的评分函数AI可能会生成int GameEngine::evaluatePosition(int x, int y) const { // 评估四个方向的潜在连线 const int directions[4][2] {{1,0}, {0,1}, {1,1}, {1,-1}}; int totalScore 0; for (const auto dir : directions) { int ourCount 1; // 当前位置 int emptyCount 0; bool blocked false; // 正向检查 for (int i 1; i 5; i) { int nx x dir[0] * i; int ny y dir[1] * i; if (nx 0 || nx BOARD_SIZE || ny 0 || ny BOARD_SIZE) { blocked true; break; } if (m_board[nx][ny] m_currentPlayer) { ourCount; } else if (m_board[nx][ny] Empty) { emptyCount; break; } else { blocked true; break; } } // 反向检查 for (int i 1; i 5; i) { int nx x - dir[0] * i; int ny y - dir[1] * i; if (nx 0 || nx BOARD_SIZE || ny 0 || ny BOARD_SIZE) { blocked true; break; } if (m_board[nx][ny] m_currentPlayer) { ourCount; } else if (m_board[nx][ny] Empty) { emptyCount; break; } else { blocked true; break; } } // 根据连子数评分 if (ourCount 5) { totalScore 100000; // 必胜 } else if (!blocked) { totalScore ourCount * ourCount; } } return totalScore; }在开发过程中我发现合理使用Qt Creator的调试工具能极大提高效率。特别是对于安卓开发可以使用Qt Creator的安卓调试器来实时查看日志输出和性能指标。当遇到界面渲染问题时QML Profiler工具能帮助分析渲染性能瓶颈。

相关新闻

LIN总线从入门到精通:低成本汽车通信协议原理与实战

LIN总线从入门到精通:低成本汽车通信协议原理与实战

1. 项目概述:为什么我们需要关注LIN总线?如果你在汽车电子、车身控制或者一些对成本敏感的嵌入式领域工作,那么“LIN总线”这个词你一定不陌生。它不像它的老大哥CAN总线那样名声在外,但在很多你看不见的地方,比如车窗…

2026/10/18 9:43:04 阅读更多 →
Mind+图形化编程集成AS608指纹模块:从串口协议到扩展库开发实战

Mind+图形化编程集成AS608指纹模块:从串口协议到扩展库开发实战

1. 项目概述:当Mind遇上指纹识别 最近在折腾一个需要身份验证的小项目,手头正好有一块常见的AS608或FPM10A光学指纹模块。这类模块价格亲民、性能稳定,在门禁、考勤或者一些DIY的智能锁项目里很常见。但当我打算用Mind(一款面向青…

2026/10/17 16:15:15 阅读更多 →
企业HR必备:如何用评选星发起万人员工评选投票活动

企业HR必备:如何用评选星发起万人员工评选投票活动

又到一年评优季。年度优秀员工评选、季度最佳团队投票、十佳店长评比……这些看似常规的企业活动,实际操作起来却往往让HR头疼不已:有的平台做到一半突然弹窗收费,有的活动上线后被刷票搞到崩溃,还有的活动结束了才发现数据根本导…

2026/10/16 2:57:08 阅读更多 →

最新新闻

一帧画面八道关:rebucca视频行为分析平台源码拆解

一帧画面八道关:rebucca视频行为分析平台源码拆解

最近在做工业场景的 AI 监控方案选型时,我注意到一个很有意思的开源项目:rebucca 视频行为分析平台。它主打工业环境下的实时行为识别,而且最吸引人的一点是“一行命令就能跑起来”,不需要折腾一堆依赖。真正开始读源码之后&#…

2026/10/18 9:42:33 阅读更多 →
Markdown流式渲染:构建AI生成式UI的结构信标

Markdown流式渲染:构建AI生成式UI的结构信标

1. 项目概述:这不是一次简单的格式转换,而是一场交互范式的迁移“从 Markdown 到生成式 UI:AI 应用中的流式渲染实践”——这个标题里藏着三个关键动作:“从…到…”是路径,“生成式 UI”是目标形态,“流式…

2026/10/18 9:42:33 阅读更多 →
虚拟演唱会视频制作全解析:从PJSK渲染到中日双语字幕压制

虚拟演唱会视频制作全解析:从PJSK渲染到中日双语字幕压制

很多读者看到“【中日双字/PJSK】初音未来生日2026 虚拟演唱会”这样的视频标题时,第一反应是“去哪个平台找资源”,第二反应是“这个字幕组剪辑得真快”。但如果从技术角度去看,这一类内容并不是简单“录屏 打轴”就能完成的:它…

2026/10/18 9:42:33 阅读更多 →
SpringBoot+Vue+MySQL办公用品直售系统:从下单闭环到部署答辩

SpringBoot+Vue+MySQL办公用品直售系统:从下单闭环到部署答辩

简介:面向高校毕业设计、课程设计及需要完整前后端项目参考的开发者,这是一套基于JAVASpringBootVueMySQL的日常办公用品直售系统,用于满足线上采购、商品管理与订单处理等真实场景的实战需求。项目涵盖商品展示、购物车、订单处理、用户管理…

2026/10/18 9:42:33 阅读更多 →
键盘记录器3.0:Windows低层钩子与日志落盘全解析

键盘记录器3.0:Windows低层钩子与日志落盘全解析

简介:全能键盘记录器3.0是一款面向企业管理者、家长及安全审计人员的键盘监控工具,能够完整捕获字母、数字、特殊字符以及回车、空格等按键动作,并支持后台隐蔽运行、定期生成带时间戳的日志报告、关键词过滤与远程访问功能,适用于…

2026/10/18 9:42:33 阅读更多 →
计算机网络面试高频考点:三次握手、DNS解析与HTTP缓存全梳理

计算机网络面试高频考点:三次握手、DNS解析与HTTP缓存全梳理

简介:面向技术面试准备的计算机基础知识点 PDF 文档,重点覆盖计算机网络中的高频考点,与“代码随想录知识星球”最强八股文系列的计算机基础篇对应,适合后端、前端开发者跳槽或校招前集中复习。内容系统梳理了TCP三次握手与四次挥…

2026/10/18 9:41:33 阅读更多 →

日新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 0:55:02 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 14:23:36 阅读更多 →