鸿蒙HarmonyOS NEXT开发:简易2048小游戏的实现

效果图:

鸿蒙HarmonyOS NEXT开发:简易2048小游戏的实现_第1张图片鸿蒙HarmonyOS NEXT开发:简易2048小游戏的实现_第2张图片

为何使用全局变量而不直接在状态变量中使用二维数组:

在ArkTS中,使用@State修饰器,二维数组中的某个数字发生改变时,UI是无法监听到的,导致不能实时渲染,因此定义一个二维的全局变量arr[][]作为"中介",操作时是对arr[][]进行操作,操作后对每一行进行赋值,即可让UI监听到。若要UI监听到二维数组的变化,则需使用@Observed和@ObjectLink配合使用,可参考简易五子棋小游戏的实现icon-default.png?t=N7T8https://blog.csdn.net/weixin_63484971/article/details/141223205?spm=1001.2014.3001.5502

1.定义个全局变量表示16宫格的数字 0 不显示

let arr:number[][]=[]

2.状态变量定义模块

@State row1 到 @State row4 这四个状态变量分别代表了游戏棋盘的四行数字状态。初始时,每行都被初始化为包含四个 0 的数组,表示棋盘上的初始位置均为空。

@State text 用于存储游戏过程中的提示信息,例如“游戏结束”等。

@State colors 定义了不同数字所对应的背景颜色。这样,在游戏界面中,根据数字的大小可以为其显示相应的背景颜色,增强视觉效果。

@State maxScore 用于记录游戏过程中出现的最高分数。

@State totalScore 则用于累计游戏中的总得分。

  //  每一行 共四行
  @State row1:number[] = [0, 0, 0, 0]
  @State row2:number[] = [0, 0, 0, 0]
  @State row3:number[] = [0, 0, 0, 0]
  @State row4:number[] = [0, 0, 0, 0]

  @State text:string = ''
  // 背景颜色 不同的数字不同的背景颜色
  @State colors:ResourceColor[]=[Color.Transparent,'#fcc307','#e2c027','#806332', '#edc3ae',
    '#f43e06', '#12aa9c','#428675','#d2d97a','#8fb2c9',
    '#b0d5df','#2e317c','#983680']
  // 最大分
  @State maxScore:number = 0
  // 总分
  @State totalScore:number = 0

3.函数定义模块

updateArr 函数的作用是将四个表示行的状态变量组合成一个二维数组 arr 。这样在后续的游戏逻辑处理中,可以更方便地对整个棋盘进行统一的操作和判断。

  // 更新全局的arr 用二维数组表示4乘4
  updateArr(){
    arr=[]
    arr.push(this.row1)
    arr.push(this.row2)
    arr.push(this.row3)
    arr.push(this.row4)
  }

updateRows 函数的功能与 updateArr 相反,它将全局的二维数组 arr 的内容更新到四个行状态变量中,以实现游戏界面的同步渲染。

  // 更新每一行的渲染
  updateRows(){
    this.row1 = arr[0]
    this.row2 = arr[1]
    this.row3 = arr[2]
    this.row4 = arr[3]
  }

haveZeros 函数用于检查 arr 数组中是否还存在值为 0 的元素。通过两层循环遍历整个数组,如果找到任何一个 0 元素,立即返回 true ,表示还有可操作的空间;如果循环结束都没有找到 0 元素,则返回 false ,意味着游戏可能已经无法继续。

  // 是否还有0
  haveZeros(){
    for(let i:number = 0;i<4;i++){
      for(let j:number = 0;j<4;j++){
        if(arr[i][j]==0) return true
      }
    }
    // 循环完还为发现0 则游戏结束
    return false
  }

gameOver 函数用于判断游戏是否结束。首先检查是否存在 0 元素,如果有则游戏未结束,返回 false 。然后通过两层循环检查每个位置的数字是否与其相邻位置(上、下、左、右)的数字相同。如果存在相同的情况,游戏也未结束,返回 false 。如果整个循环结束都没有满足上述未结束的条件,则表示游戏结束,返回 true 。

  gameOver(){
    //还有0或者存相邻的数是一样的 说明游戏未结束
    if(this.haveZeros()) return false
    for(let i:number = 0;i<4;i++){
      for(let j:number = 0;j<4;j++){
        // 利用 逻辑中断做判断
        if(arr[i][j]==( ((i-1)>=0?1:0) && arr[i-1][j] ) ||
        arr[i][j]==( ((i+1)<=3?1:0) && arr[i+1][j] ) ||
        arr[i][j]==( ((j-1)>=0?1:0) && arr[i][j-1] ) ||
        arr[i][j]==( ((j+1)<=3?1:0) && arr[i][j+1] )
        ) return false
      }
    }
    // 循环完还为发现0 则游戏结束
    return true
  }

firstNonZero 函数根据给定的坐标 (x, y) 和移动方向 direction ,查找该方向上的下一个非零数字的坐标和值。例如,当 direction 为 1 表示向上移动时,从给定坐标开始向下查找,直到找到第一个非零数字,并返回其值、横坐标和纵坐标。如果在指定方向上没有找到非零数字,则返回 [-1, 0, 0] 作为标识。

  // 坐标x,y的下一个非零的坐标以及值  direction 1、2、3、4 分别为上、下、左、右
  firstNonZero(x:number, y:number, direction:number){
    // 向上移动则要向下寻找 (反向) 下面同理
    if(direction==1){
      y++
      while(y<=3){
        if(arr[y][x]!=0) {
          return [arr[y][x],x,y]
        }
        y++
      }
      // 没有非零的 返回一个标识
      return [-1,0,0]
    }
    else if(direction==2){
      y--
      while(y>=0){
        if(arr[y][x]!=0) {
          return [arr[y][x],x,y]
        }
        y--
      }
      return [-1,0,0]
    }
    else if(direction==3){
      x++
      while(x<=3){
        if(arr[y][x]!=0) {
          return [arr[y][x],x,y]
        }
        x++
      }
      return [-1,0,0]
    }
    else if(direction==4){
      x--
      while(x>=0){
        if(arr[y][x]!=0) {
          return [arr[y][x],x,y]
        }
        x--
      }
      return [-1,0,0]
    }
    return [-1,0,0]
  }

f 函数用于根据指定的方向对某一列或某一行进行处理。以向上移动为例,如果当前位置为 0 ,则与找到的下一个非零数字交换位置,并递归处理当前位置;如果当前位置数字不为 0 且与找到的下一个非零数字相同,则将当前数字乘以 2 ,并将找到的位置置为 0 ,然后继续处理下一个位置。其他方向(下、左、右)的处理逻辑类似。

  // 处理每一列或每一行
  f(x:number, y:number, direction:number){
    // 向上移 以此为例 (下、左、右) 同理
    if(direction==1){
      // 若找不到坐标x,y的下一个非零的坐标 则说明这一列已处理完成
      if(this.firstNonZero(x,y, direction)[0]==-1) return;
      // 若找到坐标x,y的下一个非零的坐标 则需要进行处理
      //  如果本身为0 则和找到的坐标交换 再在原来的坐标再继续执行 此方法this.f向下处理即可
      if(arr[y][x]==0) {
        arr[y][x] = 

你可能感兴趣的:(ArkTS,交互,华为,harmonyos)