鸿蒙ArkTS+ArkUI实现五子棋游戏

鸿蒙ArkTS+ArkUI实现五子棋游戏

前言

  近期,鸿蒙系统热度飙升,引发了周围众多朋友的热烈探讨。出于这份浓厚的好奇心,我初步浏览了其官方文档,发现信息量庞大,全面消化需耗时良久并考验人的毅力。自踏入编程领域以来,我一直秉持着“实践出真知”的原则,倾向于在动手操作中领悟文字背后的深意。恰逢我之前已利用Java和Python成功开发过五子棋游戏,一个念头油然而生:何不借助鸿蒙系统,再次挑战这一经典游戏的项目实践呢?正是这份灵感与决心,催生了本篇文章的诞生。

  让我们一同利用鸿蒙系统,将五子棋游戏从Java和Python的实践迁移到鸿蒙平台,通过亲身实践深入理解鸿蒙的开发魅力。这不仅是一次技术尝试,更是一场充满乐趣与成长的学习之旅。

效果图

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

技术栈

  1. 版本:HarmonyOS 5.0.3(15)
  2. 编程语言:ArkTS
  3. UI框架:ArkUI

源码

  这里只展示pages文件下的代码,如要获取整个项目,可以访问我的GitHub仓库,不知道仓库地址的朋友可以私聊我获取。
在这里插入图片描述

Index.ets —— 开始界面
import { font, router } from '@kit.ArkUI';@Entry
@Component
struct Index {// 注册字体aboutToAppear() {font.registerFont({familyName: $r('app.string.index_title_font_name'),familySrc: $r('app.string.index_title_font_src'),})}build() {Column() {Row() {Text($r("app.string.index_title")).fontSize($r('app.float.title_text_font_size')).fontWeight(FontWeight.Bold).fontFamily('SThuawenxingkai')}Row() {Button() {Text($r("app.string.start_button_text")).fontSize(20).fontWeight(FontWeight.Bold).fontColor('#000').fontFamily('SThuawenxingkai')}.onClick(() => {router.pushUrl({ url: "pages/Second" })}).type(ButtonType.Capsule).startButtonStyle()}}.height('100%').width('100%').justifyContent(FlexAlign.Center).backgroundImage($r("app.media.background_img")).backgroundImageSize(ImageSize.Cover)}@StylesstartButtonStyle() {.margin({top: 20}).backgroundColor($r('sys.color.button_background_color_transparent')).width('40%').height('6%').borderRadius(20).shadow({radius: 10,color: '#000',offsetX: 0,offsetY: 5})}
}
Second.ets —— 游戏界面
// 坐标类型
interface Coord {x: number;y: number;color: boolean;
}@Entry
@Component
struct Index {private settings: RenderingContextSettings = new RenderingContextSettings(true)private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)// 棋盘起始坐标board_x: number = 0board_y: number = 0// 棋盘宽度board_width: number = 0// 棋盘线的间距line_spacing: number = 0// true黑 false白chess_color: boolean = true// 棋子坐标chess_coord: Coord[] = []build() {Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {Canvas(this.context).width('100%').height('100%').backgroundColor($r("sys.color.ohos_id_color_background")).onReady(() => {this.init()}).onClick((e) => {this.drawChess(e.x, e.y)}).backgroundImage($r("app.media.background_img")).backgroundImageSize(ImageSize.Cover)}.width('100%').height('100%')}// 初始化棋盘方法init() {// 计算宽度,适配横屏if (this.context.width < this.context.height) {this.board_width = this.context.width - 40} else {this.board_width = this.context.height - 40}this.board_x = (this.context.width - this.board_width) / 2this.board_y = (this.context.height - this.board_width) / 2// 绘制正方形this.context.lineWidth = 4this.context.fillStyle = '#DBC26F'; // 设置填充颜色this.context.strokeStyle = '#000'this.context.fillRect(this.board_x, this.board_y, this.board_width, this.board_width); // 填充圆形this.context.strokeRect(this.board_x, this.board_y, this.board_width, this.board_width)// 计算棋盘线间距this.line_spacing = this.board_width / 14this.context.beginPath(); // 开始新路径this.context.lineWidth = 2for (let i = 0; i < 14; i++) {this.context.moveTo(this.board_x, this.board_y + i * this.line_spacing)this.context.lineTo(this.board_x + this.board_width, this.board_y + i * this.line_spacing)}for (let i = 0; i < 14; i++) {this.context.moveTo(this.board_x + i * this.line_spacing, this.board_y)this.context.lineTo(this.board_x + i * this.line_spacing, this.board_y + this.board_width)}this.context.stroke() // 绘制// 绘制棋盘上的五个点const points: Coord[] = [{ x: 3, y: 3, color: true },{ x: 11, y: 3, color: true },{ x: 3, y: 11, color: true },{ x: 11, y: 11, color: true },{ x: 7, y: 7, color: true }];this.context.fillStyle = '#000'; // 设置填充颜色this.context.lineWidth = 1; // 设置描边宽度for (const point of points) {this.context.beginPath(); // 新路径const x = this.board_x + this.line_spacing * point.x;const y = this.board_y + this.line_spacing * point.y;this.context.arc(x, y, 4, 0, 2 * Math.PI); // 绘制圆形路径this.context.fill(); // 填充圆形}}// 绘制棋子drawChess(x: number, y: number) {// 判断点击区域是否在棋盘内if (x >= this.board_x && x <= this.board_x + this.board_width && y >= this.board_y &&y <= this.board_y + this.board_width) {// 判断并设置棋子颜色if (this.chess_color) {this.context.fillStyle = '#000';} else {this.context.fillStyle = '#FFF';}// 修正坐标x = Math.round((x - this.board_x) / this.line_spacing);y = Math.round((y - this.board_y) / this.line_spacing);// 判断是否已经有棋子for (const coord of this.chess_coord) {if (coord.x === x && coord.y === y) {return}}// 绘制棋子this.context.strokeStyle = '#000'; // 设置描边颜色this.context.beginPath(); // 新路径this.context.arc(x * this.line_spacing + this.board_x, y * this.line_spacing + this.board_y,this.line_spacing / 2 - 1, 0, 2 * Math.PI); // 绘制圆形路径this.context.fill(); // 填充圆形this.context.stroke(); // 描边圆形// 加入棋子坐标this.chess_coord.push({ x, y, color: this.chess_color })// 判断是否五子连珠this.checkLink()// 切换棋子颜色this.chess_color = !this.chess_color}}// 判断是否五子连珠checkLink() {if (!this.chess_coord || this.chess_coord.length === 0) {return;}const lastCoord = this.chess_coord[this.chess_coord.length - 1];const directions: [number, number][] = [[1, 0], // 垂直方向[0, 1], // 水平方向[1, 1], // 右对角线[-1, 1]// 左对角线];for (const direction of directions) {for (let method = 0; method < 5; method++) {const linkingCoords: Coord[] = [];for (let i = 0; i < 5; i++) {const newCoord: Coord = {x: lastCoord.x + direction[0] * (i - method),y: lastCoord.y + direction[1] * (i - method),color: lastCoord.color};const found = this.chess_coord.find(coord =>coord.x === newCoord.x && coord.y === newCoord.y && coord.color === newCoord.color);if (found) {linkingCoords.push(found)}}if (linkingCoords.length >= 5) {linkingCoords.forEach(item => {console.log(item.x.toString(), item.y.toString(), item.color)this.context.strokeStyle = '#FEFE00'; // 设置描边颜色this.context.beginPath(); // 新路径this.context.arc(item.x * this.line_spacing + this.board_x, item.y * this.line_spacing + this.board_y,this.line_spacing / 2 - 1, 0, 2 * Math.PI); // 绘制圆形路径this.context.stroke(); // 描边圆形})AlertDialog.show({message: `恭喜${this.chess_color ? '黑棋' : '白棋'},你赢了!`,cancel: () => {// 初始化棋盘this.chess_coord = []this.chess_color = true// 初始化棋盘this.context.clearRect(0, 0, this.context.width, this.context.height);this.init()}});}}}}
}

结束语

  经过这一系列的探索与实践,我们不仅成功地将五子棋游戏实现到了鸿蒙系统之上,更在这一过程中深刻体会到了鸿蒙平台的强大功能与无限潜力。从初步接触鸿蒙的迷茫,到逐步熟悉并掌握其开发技巧,每一次挑战都见证了我们的成长与进步。如今,回顾这段旅程,我们收获的不仅仅是技术上的提升,更有对编程热爱的加深,以及对未来无限可能的憧憬。愿这份经历能够激励更多开发者,勇敢地在鸿蒙的世界里探索、实践、创新,共同书写属于我们的精彩篇章。

  由于我也是初学者,目前实现的功能非常简单,如果后续有功能的更新,将实时更新到GitHub仓库。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/37926.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

单元测试mock

一、背景 现在有A类,B类,C类&#xff0c;A类依赖B类,依赖C类&#xff0c;如果想要测试A类中的某个方法的业务逻辑。A类依赖其他类&#xff0c;则把其他类给mock&#xff0c;然后A类需要真实对象。这样就可以测试A类中的方法。 举例&#xff1a;Ticket类需要调用Flight类和Pas…

深度学习篇---深度学习中的范数

文章目录 前言一、向量范数1.L0范数1.1定义1.2计算式1.3特点1.4应用场景1.4.1特征选择1.4.2压缩感知 2.L1范数&#xff08;曼哈顿范数&#xff09;2.1定义2.2计算式2.3特点2.4应用场景2.4.1L1正则化2.4.2鲁棒回归 3.L2范数&#xff08;欧几里得范数&#xff09;3.1定义3.2特点3…

JVM常见概念之条件移动

问题 当我们有分支频率数据时&#xff0c;有什么有趣的技巧可以做吗&#xff1f;什么是条件移动&#xff1f; 基础知识 如果您需要在来自一个分支的两个结果之间进行选择&#xff0c;那么您可以在 ISA 级别做两件不同的事情。 首先&#xff0c;你可以创建一个分支&#xff…

Debug-037-table列表勾选回显方案

效果展示&#xff1a; 图1 图2 最近实现一个支持勾选的el-table可以回显之前勾选项的功能。实现了一个“编辑”的功能&#xff1a; 在图1中的列表中有三行数据&#xff0c;当点击“更换设备”按钮时&#xff0c;打开抽屉显示el-table组件如图2所示&#xff0c;可以直接回显勾选…

Python散点图(Scatter Plot):数据探索的“第一张图表”

在数据可视化领域,散点图是一种强大而灵活的工具,它能够帮助我们直观地理解和探索数据集中变量之间的关系。本文将深入探讨散点图的核心原理、应用场景以及如何使用Python进行高效绘制。 后续几篇将介绍高级技巧、复杂应用场景。 Python散点图(Scatter Plot):高阶分析、散点…

docker利用ollama +Open WebGUI在本地搭建部署一套Deepseek-r1模型

系统&#xff1a;没有限制&#xff0c;可以运行docker就行 磁盘空间&#xff1a;至少预留50GB; 内存&#xff1a;8GB docker版本&#xff1a;4.38.0 桌面版 下载ollama镜像 由于docker镜像地址&#xff0c;网络不太稳定&#xff0c;建议科学上网的一台服务器拉取ollama镜像&am…

JavaScript |(六)DOM事件 | 尚硅谷JavaScript基础实战

学习来源&#xff1a;尚硅谷JavaScript基础&实战丨JS入门到精通全套完整版 笔记来源&#xff1a;在这位大佬的基础上添加了一些东西&#xff0c;欢迎大家支持原创&#xff0c;大佬太棒了&#xff1a;JavaScript |&#xff08;六&#xff09;DOM事件 | 尚硅谷JavaScript基础…

卷积神经网络 - 梯度和反向传播算法

在卷积网络中&#xff0c;参数为卷积核中权重以及偏置。和全连接前馈网络类似&#xff0c;卷积网络也可以通过误差反向传播算法来进行参数学习。本文我们从数学角度&#xff0c;来学习卷积神经网络梯度的推导和其反向传播算法的原理。 一、梯度&#xff1a;损失函数 L 关于第 …

鸿蒙NEXT项目实战-百得知识库03

代码仓地址&#xff0c;大家记得点个star IbestKnowTeach: 百得知识库基于鸿蒙NEXT稳定版实现的一款企业级开发项目案例。 本案例涉及到多个鸿蒙相关技术知识点&#xff1a; 1、布局 2、配置文件 3、组件的封装和使用 4、路由的使用 5、请求响应拦截器的封装 6、位置服务 7、三…

【测试篇】关于allpairs实现正交测试用例保姆级讲解,以及常见的错误问题

前言 &#x1f31f;&#x1f31f;本期讲解关于测试工具相关知识介绍~~~ &#x1f308;感兴趣的小伙伴看一看小编主页&#xff1a;GGBondlctrl-CSDN博客 &#x1f525; 你的点赞就是小编不断更新的最大动力 &#x1f386;那么废话不多说…

OpenCV图像拼接(4)图像拼接模块的一个匹配器类cv::detail::BestOf2NearestRangeMatcher

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 cv::detail::BestOf2NearestRangeMatcher 是 OpenCV 库中用于图像拼接模块的一个匹配器类&#xff0c;专门用于寻找两幅图像之间的最佳特征点匹配…

C++: AVL树(实现旋转操作)

前言 map/set容器有个共同点是&#xff1a;其底层都是按照二叉搜索树来实现的&#xff0c;但是二叉搜索树有其自身的缺陷&#xff0c;假如往树中插入的元素有序或者接近有序&#xff0c;二叉搜索树就会退化成单支树&#xff0c;时间复杂度会退化成O(N)&#xff0c;因此map、set…

OpenCV中距离公式

一、各类距离公式总结 常见距离公式 欧氏距离&#xff1a; 曼哈顿距离&#xff08;L1&#xff09;‌&#xff1a; 切比雪夫距离&#xff08;Chessboard&#xff09;‌&#xff1a; 1、点与点距离(欧氏距离) ‌二维空间‌ 设两点坐标为 P1(x1,y1)、P2(x2,y2)&#xff0c;其距离…

六十天前端强化训练之第二十四天之Vue 模板语法与 v-for 指令大师级详解

欢迎来到编程星辰海的博客讲解 看完可以给一个免费的三连吗&#xff0c;谢谢大佬&#xff01; 目录 一、模板语法与指令知识精讲 1.1 模板语法三大核心 1.2 常见指令全家福 1.3 v-for 深度解析 二、商品列表示例完整实现 2.1 完整可运行代码 2.2 代码解析 2.3 运行效果…

XSS跨站脚本攻击漏洞(Cross Site Scripting)

前提概要 本文章主要用于分享XSS跨站脚本攻击漏洞基础学习&#xff0c;以下是对XSS跨站脚本攻击漏洞的一些个人解析&#xff0c;请大家结合参考其他文章中的相关信息进行归纳和补充。 XSS跨站脚本攻击漏洞描述 跨站脚本攻击&#xff08;XSS&#xff09;漏洞是一种常见且危害较…

用ArcGIS做一张符合环评要求的植被类型图

植被类型图是环境影响评价&#xff08;环评&#xff09;中的重要图件&#xff0c;需满足数据准确性、制图规范性和信息完整性等要求。本教程将基于ArcMap平台&#xff0c;从数据准备到成果输出&#xff0c;详细讲解如何制作符合环评技术规范的植被类型图。 ArcGIS遥感解译土地…

详解string类+迭代器

迭代器 概念&#xff1a;在 C 中&#xff0c;迭代器是访问容器&#xff08;如数组、列表、向量、字符串等&#xff09;元素的一种方式。迭代器提供了一种统一的接口&#xff0c;使得你可以使用相同的代码来遍历不同类型的容器。迭代器本质上是一个指针或者指针的封装&#xff0…

Sqoop安装部署

Apache Sqoop 简介 Sqoop&#xff08;SQL-to-Hadoop&#xff09;是 Apache 开源项目&#xff0c;主要用于&#xff1a; 将关系型数据库中的数据导入 Hadoop 分布式文件系统&#xff08;HDFS&#xff09;或相关组件&#xff08;如 Hive、HBase&#xff09;。 将 Hadoop 处理后…

软件工程之软件验证计划Software Verification Plan

个人主页&#xff1a;云纳星辰怀自在 座右铭&#xff1a;“所谓坚持&#xff0c;就是觉得还有希望&#xff01;” 本文为基于ISO26262软件验证计划模板&#xff0c;仅供参考。 软件验证计划&#xff0c;包括&#xff1a; 1. 软件需求验证计划 2. 软件架构设计验证计划 3. 软件单…

Windows系统本地部署OpenManus对接Ollama调用本地AI大模型

文章目录 前言1. 环境准备1.1 安装Python1.2. 安装conda 2. 本地部署OpenManus2.1 创建一个新conda环境2.2 克隆存储库2.3 安装依赖环境 3. 安装Ollama4. 安装QwQ 32B模型5. 修改OpenManus配置文件6. 运行OpenManus7.通过网页使用OpenManus8. 安装内网穿透8.1 配置随机公网地址…