当前位置:   article > 正文

鸿蒙HarmonyOS项目实战开发:井字过三关小游戏_基于harmonyos的井字棋游戏开发

基于harmonyos的井字棋游戏开发

简介

Demo基于Open Harmony系统使用ETS语言进行编写,本Demo主要通过设备认证、分布式拉起、分布式数据管理等功能来实现。

应用效果
  1. 设备认证,开始游戏前,如果是陌生设备需要先通过认证

deviceAuthentication

  1. 开始游戏,如果设备之前认证过了,可以直接开始游戏

startGame

开发步骤

1.新建Openharmony ETS工程

在DevEco Studio中点击File -> New Project ->[Standard]Empty Ability->Next,Language 选择ETS语言,最后点击Finish即创建成功。

1

2.界面代码编写
1) 开始界面

2

在入口组件(@Entry修饰的组件)中绘制布局,该布局使用Stack容器,展示文字,图片的堆叠效果,在容器中依次填入Image,Text,Image,Butto,Text组件,具体代码如下

  1. build() {
  2. Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
  3. Stack() {
  4. Image($r("app.media.bg"))
  5. Column() {
  6. Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
  7. Text('井字游戏大作战').fontSize(30).textAlign(TextAlign.Center).fontColor(Color.White)
  8. }.height('10%')
  9. Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Start }) {
  10. Stack() {
  11. Image($r("app.media.bg_start_game"))
  12. Column() {
  13. Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
  14. Image($r("app.media.battles")).height(100).width(100)
  15. }.height('50%')
  16. Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
  17. Button('开始游戏').height(50).width(200).backgroundColor('#32CD99').fontSize(20).onClick(() => {
  18. this.startDialog.open()
  19. })
  20. Text("").height(20)
  21. Text('游戏规则').fontSize(20).fontColor('#FF00FF').height(60).decoration({ type: TextDecorationType.Underline, color: Color.Red }).onClick(() => {
  22. this.rulesDialog.open()
  23. })
  24. }.height('40%')
  25. }
  26. }
  27. }.height('50%').width('90%')
  28. Flex() {
  29. }.height('30%')
  30. }
  31. }
  32. }.width('100%').height('100%')
  33. }

自定义弹窗

1.点击开始按钮的弹窗如下图所示,窗口从上到下由TextListButton组成,List中的子元素由Text和Radio组成,以下代码的省略号表示非UI相关的逻辑代码,具体实现参考源代码

 

3

  1. @CustomDialog
  2. struct gameStart {
  3. build() {
  4. Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
  5. Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
  6. //顶部标题
  7. Text('发现以下在线设备').fontColor(Color.Black).fontSize(30)
  8. }.width('100%').height('20%')
  9. Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Start }) {
  10. //使用List容器动态加载在线设备
  11. List() {
  12. ForEach(this.deviceName, (item) => {
  13. ListItem() {
  14. Row() {
  15. //Text组件显示设备名
  16. Text(item.deviceName).width('80%').fontSize(30).fontColor(Color.Black)
  17. //Radio组件显示单选框
  18. Radio({ value: '' }).checked(this.check[item.id]).onChange(() => {
  19. //这里保证List里面点击了多个Radio组件时,只有当前点击的为选中状态
  20. for (let i = 0; i < this.check.length; i++) {
  21. this.check[i] = false
  22. }
  23. this.check[item.id] = true
  24. })
  25. }
  26. }
  27. }, item => item.id)
  28. }
  29. .height('80%')
  30. Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
  31. Button('确定').width(200).height(50).fontSize(30).onClick(() => {
  32. //......
  33. this.controller.close()
  34. })
  35. }.height('30%')
  36. }.width('100%').height('80%')
  37. }.height('100%').width('100%')
  38. }
  39. }

点击游戏规则的弹窗由Text,Text,button组成,具体实现可以参考弹窗1,和源代码

2) 棋盘界面

 

4

棋盘界面由状态栏(左上图标表示当前由X或者O执行,右上表示自己本局使用X或者O),九宫格棋盘(Grid组件绘制),button按钮组成。

  1. build() {
  2. Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
  3. Row({ useAlign: HorizontalAlign.Start }) {
  4. //左上图标
  5. if (this.selfChess === EMPTY) {
  6. Image(this.current_X).height(150).width('30%')
  7. } else if (this.curChess === CIRCLE) {
  8. Image(this.current_O).height(150).width('30%')
  9. } else {
  10. Image(this.current_X).height(150).width('30%')
  11. }
  12. //填充空格
  13. Text("").width('40%')
  14. //右上图标
  15. if (this.selfChess === EMPTY) {
  16. Image(this.whiteBg).height(150).width('30%')
  17. } else {
  18. Image(this.selfChess === FORK ? this.self_X : this.self_O).height(150).width('30%')
  19. }
  20. }.height('30%')
  21. Flex() {
  22. //堆叠容器
  23. Stack() {
  24. //绘制九宫格
  25. Grid() {
  26. ForEach(this.gridVis, (item) => {
  27. GridItem() {
  28. //每个子格子当前需要填充的图片
  29. if (item.value === FORK) {
  30. Image(this.fork).backgroundColor(Color.White)
  31. } else if (item.value === CIRCLE) {
  32. Image(this.circle).backgroundColor(Color.White)
  33. } else {
  34. Image(this.whiteBg)
  35. }
  36. }.onClick(() => {
  37. //点触格子触发事件
  38. this.dealPoint(item)
  39. })
  40. }, item => item.id)
  41. }.columnsTemplate('1fr 1fr 1fr').rowsTemplate('1fr 1fr 1fr').columnsGap(3).rowsGap(3).align(Alignment.Center).alignSelf(ItemAlign.Center).backgroundColor('#9F5F9F')
  42. //根据胜负状态显示图片
  43. if (result === YOU_WIN) {
  44. Image($r("app.media.game_win")).width(224).height(224)
  45. } else if (result === YOU_LOSE) {
  46. Image($r("app.media.game_fail")).width(224).height(224)
  47. } else if (result === TIE) {
  48. Image($r("app.media.game_tie")).width(224).height(224)
  49. }
  50. }
  51. }.height('50%')
  52. Row({ useAlign: HorizontalAlign.Center }) {
  53. Button('重新开始').width(200).height(50).fontSize(30).backgroundColor('#8E6B23').onClick(() => {
  54. this.initGame()
  55. })
  56. }.height('20%')
  57. }
  58. }
3.设备认证

设备认证是依赖DeviceManager组件来实现的,详细代码参考源码RemoteDeviceModel.ets

1.创建DeviceManager实例

  1. registerDeviceListCallback(callback) {
  2. if (typeof (this.#deviceManager) === 'undefined') {
  3. deviceManager.createDeviceManager('com.example.tictactoegame', (error, value) => {
  4. if (error) return
  5. this.#deviceManager = value;
  6. this.registerDeviceListCallback_(callback);
  7. });
  8. } else {
  9. this.registerDeviceListCallback_(callback);
  10. }
  11. }

2.查询可信设备列表

  1. var list = this.#deviceManager.getTrustedDeviceListSync();
  2. if (typeof (list) != 'undefined' && typeof (list.length) != 'undefined') {
  3. this.deviceList = list;
  4. }

3.注册设备上下线监听

  1. this.#deviceManager.on('deviceStateChange', (data) => {
  2. switch (data.action) {
  3. case 0:
  4. this.deviceList[this.deviceList.length] = data.device;
  5. this.callback();
  6. if (this.authCallback != null) {
  7. this.authCallback();
  8. this.authCallback = null;
  9. }
  10. break;
  11. case 2:
  12. if (this.deviceList.length > 0) {
  13. for (var i = 0; i < this.deviceList.length; i++) {
  14. if (this.deviceList[i].deviceId === data.device.deviceId) {
  15. this.deviceList[i] = data.device;
  16. break;
  17. }
  18. }
  19. }
  20. this.callback();
  21. break;
  22. case 1:
  23. if (this.deviceList.length > 0) {
  24. var list = [];
  25. for (var i = 0; i < this.deviceList.length; i++) {
  26. if (this.deviceList[i].deviceId != data.device.deviceId) {
  27. list[i] = data.device;
  28. }
  29. }
  30. this.deviceList = list;
  31. }
  32. this.callback();
  33. break;
  34. default:
  35. break;
  36. }
  37. });

4.设备发现

  1. this.#deviceManager.on('deviceFound', (data) => {
  2. for (let i = 0; i < this.discoverList.length; i++) {
  3. if (that.discoverList[i].deviceId === data.device.deviceId) {
  4. return;
  5. }
  6. }
  7. this.discoverList[this.discoverList.length] = data.device;
  8. this.callback();
  9. });

5.设备认证

  1. authDevice(deviceInfo, callback){
  2. let extraInfo = {
  3. "targetPkgName": 'com.example.tictactoegame',
  4. "appName": 'com.example.tictactoegame',
  5. "appDescription": 'com.example.tictactoegame',
  6. "business": '0'
  7. };
  8. let authParam = {
  9. "authType": 1,
  10. "appIcon": '',
  11. "appThumbnail": '',
  12. "extraInfo": extraInfo
  13. };
  14. this.#deviceManager.authenticateDevice(deviceInfo, authParam, (err, data) => {
  15. if (err) {
  16. this.authCallback = null;
  17. } else {
  18. this.authCallback = callback;
  19. }
  20. });
  21. }
4.数据管理

分布式数据管理依赖@ohos.data.distributedData模块实现,详细参考源码RemoteDataManager.ets

1.导入该模块

import factory from '@ohos.data.distributedData';

2.创建KVManager实例,用于管理数据库对象

  1. registerDataListCallback(callback) {
  2. let that = this
  3. if (this.kvManager == null) {
  4. try {
  5. const config = {
  6. userInfo: {
  7. userId: '0',
  8. userType: 0
  9. },
  10. bundleName: 'com.example.tictactoegame'
  11. }
  12. factory.createKVManager(config).then((manager) => {
  13. that.kvManager = manager
  14. that.registerDataListCallback_(callback)
  15. }).catch((err) => {
  16. })
  17. } catch (e) {
  18. }
  19. } else {
  20. this.registerDataListCallback_(callback)
  21. }
  22. }

3.创建并获取KVStore数据库

  1. registerDataListCallback_(callback) {
  2. let that = this
  3. if (that.kvManager == null) {
  4. callback()
  5. return
  6. }
  7. if (that.kvStore == null) {
  8. try {
  9. let options =
  10. {
  11. createIfMissing: true,
  12. encrypt: false,
  13. backup: false,
  14. autoSync: true,
  15. kvStoreType: 1,
  16. securityLevel: 3
  17. }
  18. this.kvManager.getKVStore(this.STORE_ID, options).then((store) => {
  19. that.kvStore = store
  20. that._registerDataListCallback_(callback)
  21. }).catch((err) => {
  22. })
  23. } catch (e) {
  24. }
  25. } else {
  26. this._registerDataListCallback_(callback)
  27. }
  28. }

4.订阅指定类型的数据变更通知

  1. _registerDataListCallback_(callback) {
  2. let that = this
  3. if (that.kvManager == null) {
  4. callback()
  5. return
  6. }
  7. this.kvStore.on('dataChange', 1, function(data) {
  8. if (data) {
  9. that.arr = data.updateEntries
  10. callback()
  11. }
  12. })
  13. }

5.添加指定类型键值对到数据库

  1. dataChange(key, value) {
  2. let that = this
  3. try {
  4. that.kvStore.put(JSON.stringify(key), JSON.stringify(value)).then((data) => {
  5. }).catch((err) => {
  6. prompt.showToast({message:'put err:'+JSON.stringify(value)})
  7. })
  8. } catch (e) {
  9. }
  10. }
5.远程拉起设备app

使用FeatureAbility模块的startAbility接口拉起远程设备app

  1. startAbilityContinuation(deviceId) {
  2. let wantValue = {
  3. bundleName: 'com.example.tictactoegame',
  4. abilityName: 'com.example.tictactoegame.MainAbility',
  5. deviceId: deviceId,
  6. parameters: {
  7. uri: 'pages/Fight'
  8. }
  9. };
  10. featureAbility.startAbility({ want: wantValue }).then(() => {
  11. router.replace({ uri: 'pages/Fight' })
  12. });
  13. }
6.棋局胜负判定

对于棋盘中的任一个格子只存在已落子和未落子两种状态,我们把这两种状态定义为1和0,则九宫格可以看成是一个只有9位的二进制数,胜利状态有八种情况如下,详细代码参考源码Chess.ets:

  1. 0b111000000
  2. 0b100100100
  3. 0b100010001
  4. 0b010010010
  5. 0b001001001
  6. 0b000111000
  7. 0b000000111
  8. 0b001010100

胜负判定实现如下

  1. isWin() {
  2. let x = this.result_X
  3. let o = this.result_O
  4. if (448 == (x & 448) || 292 == (x & 292) || 273 == (x & 273) || 146 == (x & 146) || 73 == (x & 73) || 56 == (x & 56) || 7 == (x & 7) || 84 == (x & 84)){
  5. this.allIsTrue()
  6. return FORK
  7. }
  8. if (448 == (o & 448) || 292 == (o & 292) || 273 == (o & 273) || 146 == (o & 146) || 73 == (o & 73) || 56 == (o & 56) || 7 == (o & 7) || 84 == (o & 84)) {
  9. this.allIsTrue()
  10. return CIRCLE
  11. }
  12. let res = 0;
  13. for (let i = 0; i < 9; i++) {
  14. if (this.used[i] == false) {
  15. res = 1
  16. break
  17. }
  18. }
  19. if (res === 1) {
  20. return CONTINUE
  21. }
  22. return EMPTY
  23. }

最后,有很多小伙伴不知道学习哪些鸿蒙开发技术?不知道需要重点掌握哪些鸿蒙应用开发知识点?而且学习时频繁踩坑,最终浪费大量时间。所以有一份实用的鸿蒙(Harmony NEXT)资料用来跟着学习是非常有必要的。 

为了能够帮助大家快速掌握鸿蒙(Harmony NEXT)应用开发技术知识。在此给大家分享一下我结合鸿蒙最新资料整理出来的鸿蒙南北向开发学习路线以及整理的最新版鸿蒙学习文档资料。

这份鸿蒙(Harmony NEXT)资料包含了鸿蒙开发必掌握的核心知识要点,内容包含了ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、Harmony南向开发、鸿蒙项目实战等等)鸿蒙(Harmony NEXT)技术知识点。

希望这一份鸿蒙学习资料能够给大家带来帮助,有需要的小伙伴自行领取,限时开源,先到先得~无套路领取!!

如果你是一名有经验的资深Android移动开发、Java开发、前端开发、对鸿蒙感兴趣以及转行人员,可以直接领取这份资料

 获取这份完整版高清学习路线,请点击→纯血版全套鸿蒙HarmonyOS学习资料

鸿蒙(Harmony NEXT)最新学习路线

  •  HarmonOS基础技能

  • HarmonOS就业必备技能 
  •  HarmonOS多媒体技术

  • 鸿蒙NaPi组件进阶

  • HarmonOS高级技能

  • 初识HarmonOS内核 
  • 实战就业级设备开发

 有了路线图,怎么能没有学习资料呢,小编也准备了一份联合鸿蒙官方发布笔记整理收纳的一套系统性的鸿蒙(OpenHarmony )学习手册(共计1236页)鸿蒙(OpenHarmony )开发入门教学视频,内容包含:ArkTS、ArkUI、Web开发、应用模型、资源分类…等知识点。

获取以上完整版高清学习路线,请点击→纯血版全套鸿蒙HarmonyOS学习资料

《鸿蒙 (OpenHarmony)开发入门教学视频》

《鸿蒙生态应用开发V2.0白皮书》

图片

《鸿蒙 (OpenHarmony)开发基础到实战手册》

OpenHarmony北向、南向开发环境搭建

图片

 《鸿蒙开发基础》

  • ArkTS语言
  • 安装DevEco Studio
  • 运用你的第一个ArkTS应用
  • ArkUI声明式UI开发
  • .……

图片

 《鸿蒙开发进阶》

  • Stage模型入门
  • 网络管理
  • 数据管理
  • 电话服务
  • 分布式应用开发
  • 通知与窗口管理
  • 多媒体技术
  • 安全技能
  • 任务管理
  • WebGL
  • 国际化开发
  • 应用测试
  • DFX面向未来设计
  • 鸿蒙系统移植和裁剪定制
  • ……

图片

《鸿蒙进阶实战》

  • ArkTS实践
  • UIAbility应用
  • 网络案例
  • ……

图片

 获取以上完整鸿蒙HarmonyOS学习资料,请点击→纯血版全套鸿蒙HarmonyOS学习资料

总结

总的来说,华为鸿蒙不再兼容安卓,对中年程序员来说是一个挑战,也是一个机会。只有积极应对变化,不断学习和提升自己,他们才能在这个变革的时代中立于不败之地。 

声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号