HarmonyOS鸿蒙Next学习例程3:数字华容道 v0.1.20241228

HarmonyOS鸿蒙Next学习例程3:数字华容道 v0.1.20241228 老白有点儿老啦。

折腾了2天,搞了个初版的【数字华容道】。

给孩子试了下,还行。

后续再完善吧。上图!

![图像]

上代码:

class RowCol {
  Row: number = 0
  Col: number = 0
}

class HuaRongdao {
  rowCol: RowCol = { Row: 3, Col: 3 }
  EmptyRowCol: RowCol = { Row: 2, Col: 2 }
  cells: HRDCell[][] = []
  YouWin:boolean=false

  constructor(rows: number, cols: number) {
    this.init(rows, cols)
  }

  init(rows: number, cols: number) {
    this.YouWin=false
    console.log("init 华容道", `[${rows},${cols}]`)
    this.rowCol.Row = rows
    this.rowCol.Col = cols
    this.cells.length = 0
    this.EmptyRowCol.Row = rows - 1
    this.EmptyRowCol.Col = cols - 1
    for (let _row = 0; _row < rows; _row++) {
      this.cells[_row] = [];
      for (let _col = 0; _col < cols; _col++) {
        this.cells[_row][_col] = new HRDCell()
        this.cells[_row][_col].rowCol = { Row: _row, Col: _col }
        this.cells[_row][_col].num = _row * cols + _col+1
        console.log('单元格:', this.cells[_row][_col])
      }
    }
    this.cells[rows-1][cols-1].num = -1
    this.oderRandom()
  }

  oderRandom(): void {
    for (let i = 0; i < this.rowCol.Row*this.rowCol.Col*40; i++) {
//      for (let i = 0; i < 5; i++) {

      let isGood: Boolean = false
      let trc: RowCol = { Row: 0, Col: 0 }
      let tx=0
      let ty=0
      do {
        tx = this.GetRandomNum(-1, 1)
        ty = this.GetRandomNum(-1, 1)

        trc = { Row: this.EmptyRowCol.Row + ty, Col: this.EmptyRowCol.Col + tx }
        isGood = (trc.Row >= 0) && (trc.Row < this.rowCol.Row) && (trc.Col >= 0) && (trc.Col < this.rowCol.Col)
        console.log('新坐标',`[${trc.Row},${trc.Col}]`)
      } while((!isGood)||(Math.abs(tx)+Math.abs(ty)!=1))

      let oldNum = this.getCell(trc).num
      this.getCell(trc).num = this.getCell(this.EmptyRowCol).num
      this.getCell(this.EmptyRowCol).num = oldNum
      this.EmptyRowCol=trc
    }
  }
  win():boolean
  {
    let oldNum:number=0
    for (let _row = 0; _row < this.rowCol.Row; _row++) {
      //this.cells[_row] = [];
      for (let _col = 0; _col < this.rowCol.Col; _col++) {
        if(_row==this.rowCol.Row-1 && _col==this.rowCol.Col-1)
          break
        if(this.cells[_row][_col].num != oldNum+1)
          return false
        oldNum++
        //console.log('wining',oldNum)
      }
    }
    console.log('wining','赢了')
    return true
  }
  GetRandomNum(Min: number, Max: number): number {
    return (Min + Math.round(Math.random() * (Max - Min)));
  }

  getCell(rowCol: RowCol): HRDCell {
    return this.cells[rowCol.Row][rowCol.Col]
  }
}

class HRDCell {
  rowCol: RowCol = { Row: 0, Col: 0 }
  huaRongDao?: HuaRongdao
  num: number = 0

  constructor() {
  }

  static adjoin(a: RowCol, b: RowCol): boolean {
    if (Math.abs(a.Row - b.Row) + Math.abs(a.Col - b.Col) == 1) {
      return true
    }
    return false
  }

  show(): string {
    return this.num == -1 ? '' : this.num.toString()
    // if (this.num == -1) {
    //   return `[${this.rowCol.Col},${this.rowCol.Row}]`
    // }
    // return `${this.num}\n[${this.rowCol.Col},${this.rowCol.Row}]`
  }

  toString(): string {
    return "【华容道】单元格"+"["+this.rowCol.Col.toString()+","+this.rowCol.Row.toString()+"]:"+this.num.toString()
  }
}

@Entry
@Component
struct Index {
  [@State](/user/State) message: string = '鸿蒙开发初探 → 数字华容道'
  [@State](/user/State) version:string="v0.1.20241228"
  [@State](/user/State) huaRongdao: HuaRongdao = new HuaRongdao(3, 3)
  [@State](/user/State) RowTempString: string = ""
  [@State](/user/State) ColTempString: string = ""

  aboutToAppear(): void {
    this.huaRongdao.init(this.huaRongdao.rowCol.Row,this.huaRongdao.rowCol.Col)
    this.RowTempString = ""
    for (let i = 0; i < this.huaRongdao.rowCol.Row; i++) {
      this.RowTempString += "1fr "
    }
    console.log('RowTempString', this.RowTempString)
    this.ColTempString = ""
    for (let i = 0; i < this.huaRongdao.rowCol.Col; i++) {
      this.ColTempString += "1fr "
    }

  }

  build() {
    Column() {
      Text(this.message)
        .fontSize(20)
        .fontWeight(FontWeight.Bold)
        .fontColor('#080888')
        .width('100%')
        .textAlign(TextAlign.Start)
        .padding({ top: 5, left: 15 })
      Text(this.version)
        .fontSize(10)
        .fontColor('#222222')
        .width('100%')
        .textAlign(TextAlign.End)
        .padding({ top: 5, left: 15 })

      Grid() {
        ForEach(this.huaRongdao.cells, (line: HRDCell[], idxLine: number) => {
          ForEach(line, (_cell: HRDCell, idxCell: number) => {
            GridItem() {
              GridButton({ parentHRD: this.huaRongdao, cellRowCol: _cell.rowCol })
                .borderRadius(15)
                .align(Alignment.Center)
            }

          },)
        },)
      }
      .columnsTemplate(this.ColTempString)
      .rowsTemplate(this.ColTempString)
      .columnsGap(10)
      .rowsGap(10)
      .height(300)
      .margin({ top: 10, left: 10, right: 10 })

      Text('新局')

      .width('50%')
      .height('50')
      .backgroundColor(0x444444)
      .fontColor(0xffffff)
      .margin({ top: 30 })
      .padding(5)
      .borderRadius(5)
      .textAlign(TextAlign.Center)
      .onClick((event: ClickEvent) => {
        this.aboutToAppear()
      })
    }
    .height('100%')
    .width('100%')
    .backgroundColor('#F1F3F5')
  }
}

@Component
struct GridButton {
  [@Link](/user/Link) parentHRD: HuaRongdao
  [@State](/user/State) cellRowCol: RowCol = { Row: 0, Col: 0 }
  [@State](/user/State) cell:HRDCell=new HRDCell()
  aboutToAppear(): void {
    this.cell=this.parentHRD.getCell(this.cellRowCol)
    console.log('GridButton',this.cell)
  }
  build() {
    Text(this.parentHRD.YouWin && this.parentHRD.getCell(this.cellRowCol).num==-1?'赢了': this.parentHRD.getCell(this.cellRowCol).show())
      .fontColor(0xffffff)
      .backgroundColor(this.cell.num == -1 ? (this.parentHRD.YouWin?0xff0000:0x0) : 0x4444ff)
      .borderRadius(15)
      .fontSize(20)
      .fontWeight(FontWeight.Bolder)
      .textAlign(TextAlign.Center)
      .width('100%')
      .height('100%')
      .onClick((event: ClickEvent) => {
        if(this.parentHRD.YouWin) return
        console.log("点击", this.parentHRD.getCell(this.cellRowCol))
        console.log('空格子', `[${this.parentHRD.EmptyRowCol.Row},${this.parentHRD.EmptyRowCol.Col}]`)
        if (HRDCell.adjoin(this.cellRowCol, this.parentHRD.EmptyRowCol)) {
          console.log('与空格子相邻!','即将交换')
          let oldNum = this.parentHRD.getCell(this.cellRowCol).num
          this.parentHRD.getCell(this.cellRowCol).num = this.parentHRD.getCell(this.parentHRD.EmptyRowCol).num
          this.parentHRD.getCell(this.parentHRD.EmptyRowCol).num = oldNum
          this.parentHRD.EmptyRowCol = this.cellRowCol
          if(this.parentHRD.win()) {
            console.log("大胜!")
            this.parentHRD.YouWin=true
          }
        }
      })
  }
}

今后一小段时间,借着完善这个小东东来学习鸿蒙开发吧。

学习痛点:

痛点1:interface,对象字面量。这玩意儿还是有些不习惯,跟想象的不一样。有些规则还是得弄清楚。

痛点2:多维数组的动态初始化。稍微折腾了下。感谢万能的互联网提供支持。

痛点3:状态管理,@State @Link @ObjectLink @Observed 还需要仔细琢磨。


更多关于HarmonyOS鸿蒙Next学习例程3:数字华容道 v0.1.20241228的实战教程也可以访问 https://www.itying.com/category-93-b0.html

5 回复

大大一个赞  学习了

更多关于HarmonyOS鸿蒙Next学习例程3:数字华容道 v0.1.20241228的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


666好厉害,

姓名: 张三 职位: 软件工程师 简介: 拥有超过10年的软件开发经验,擅长Java和Python。

HarmonyOS鸿蒙Next的数字华容道例程v0.1.20241228是一个基于鸿蒙系统的应用程序示例,展示了如何在鸿蒙平台上开发简单的游戏应用。该例程主要涉及鸿蒙的UI框架、事件处理机制以及数据管理等功能。

在鸿蒙系统中,UI框架使用ArkUI进行开发,ArkUI提供了丰富的组件和布局方式,开发者可以通过XML或JavaScript来定义界面。数字华容道例程中,UI部分通过ArkUI的网格布局(Grid)来实现华容道的棋盘,使用按钮(Button)组件表示每个数字块。

事件处理方面,鸿蒙系统提供了统一的事件分发机制,开发者可以通过监听器(Listener)来处理用户的交互操作。在数字华容道例程中,用户点击数字块时,系统会触发相应的事件,开发者通过事件处理函数来判断是否可以移动数字块,并更新UI。

数据管理部分,鸿蒙系统提供了轻量级的数据存储方案,如Preferences,用于保存应用的配置和状态。数字华容道例程中,可以使用Preferences来保存游戏的进度和分数等信息。

该例程的代码结构清晰,适合初学者通过实践来理解鸿蒙应用开发的基本流程和核心概念。开发者可以通过该例程学习如何在鸿蒙系统中构建UI、处理事件以及管理数据,为开发更复杂的应用打下基础。

HarmonyOS鸿蒙Next的数字华容道例程v0.1.20241228是一个基于鸿蒙系统的经典益智游戏实现。通过该例程,开发者可以学习如何在鸿蒙系统中使用布局、事件处理、动画等技术构建交互式应用。主要功能包括:

  1. 使用GridLayout实现棋盘布局;
  2. 通过触摸事件处理滑块移动;
  3. 实现滑块滑动动画效果;
  4. 包含游戏逻辑判断及胜利条件检测。

该例程展示了鸿蒙系统在UI开发、事件处理等方面的能力,适合初学者快速上手鸿蒙应用开发。

回到顶部