基于HarmonyOS ArkUI 3.0 框架的木棉花扫雷(上)

前言

HarmonyOS ArkUI 3.0 框架试玩初体验二来了||ヽ( ̄▽ ̄)ノミ|Ю,这一次相比上一次的 合成1024开发实战,多了部分内容:显示动画、页面跳转与数据传递、网格容器Grid、自定义窗口等内容。本来想做成分布式HarmonyOS ArkUI 3.0木棉花扫雷的,但是苦于没有相应API版本的分布式模拟器或多台真机用于调试和运行,只能落得个单机的尴尬实战了 ̄□ ̄||

效果图

::: hljs-center

:::

代码文件结构

::: hljs-center

:::

正文

一、创建一个空白的工程

1. 安装和配置DevEco Studio 3.0

 DevEco Studio 3.0下载
 DevEco Studio 3.0安装

2. 创建一个Empty eTS Ability应用

DevEco Studio下载安装成功后,打开DevEco Studio,点击左上角的File,点击New,再选择New Project,选择Empty Ability选项,点击Next按钮。

将文件命名为SaoLei(文件名不能出现中文或者特殊字符,否则将无法成功创建项目文件),Project Type勾选Application,选择保存路径,Language勾选eTS,选择API7,设备勾选Phone,最后点击Finish按钮。

3. 准备工作

entry>src>main>config.json文件中最下方"launchType": "standard"的后面添加以下代码,这样就可以实现去掉应用上方的标签栏了。
config.json最下方部分代码:

"metaData": {
      "customizeData": [
        {
          "name": "hwc-theme",
          "value": "androidhwext:style/Theme.Emui.Light.NoTitleBar",
          "extra": ""
        }
      ]
    }
4. 保存图片

将图片保存到entry>src>main>resources>rawfile文件中。

二、欢迎页面

1. 更改文件名

entry>src>ets>default>pages>index.ets文件右键,在弹出的菜单栏中选择Refactor,再在弹出的子菜单栏中选择Rename,或者按Shift+F6,将文件命名为logo.ets。
image.png

entry>src>main>config.json文件中"js"项中的"pages"项中的"pages/index"更改为"pages/logo"。
config.json最下方部分代码:

    "js": [
      {
        "mode": {
          "syntax": "ets",
          "type": "pageAbility"
        },
        "pages": [
          "pages/logo"
        ],
        "name": "default",
        "window": {
          "designWidth": 720,
          "autoDesignWidth": false
        }
      }
    ]
2. 添加背景

logo.ets文件中,通过Image($rawfile(‘LOGO.png’))可放置Logo图片,通过Text(‘木棉花扫雷’)可放置文字内容。
属性linearGradient为设置渐变颜色,linearGradient中的angle为渐变角度,设置为180,即为从上往下渐变,colors则为渐变的颜色。
logo.ets:

@Entry
@Component
struct Logo {
  build() {
    Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center, direction: FlexDirection.Column }) {
      Image($rawfile('LOGO.png'))
        .objectFit(ImageFit.Contain)
        .height(300)
      Text('木棉花扫雷')
        .fontSize(30)
        .fontColor(Color.White)
        .margin({ top: 200 })
    }
    .width('100%')
    .height('100%')
    .linearGradient(
      {
        angle: 180,
        colors: [['#D3D7DC', 0.1], ["#B4BED2", 0.6],  ["#A0AAC8", 1]]
      })
  }
}
3. 添加动画效果

这里使用的动画效果是通过animateTo显式动画实现的。animateTo显式动画可以设置组件从状态A到状态B的变化动画效果,包括样式、位置信息和节点的增加删除等,开发者无需关注变化过程,只需指定起点和终点的状态。animateTo还提供播放状态的回调接口,是对属性动画的增强与封装。
添加状态变量opacityValue和scaleValue并初始化为0,分别用于表示透明度和放缩的倍数,动画效果中实现这两个数值从0到1,即可实现Logo的渐出和放大效果。
定义一个贝塞尔曲线cubicBezier,Curves.cubicBezier(0.1, 0.2, 1, 1)。由于需要使用到动画能力接口中的插值计算,故需要导入curves模块。@ohos.curves模块提供了线性Curve. Linear、阶梯step、三阶贝塞尔(cubicBezier)和弹簧(spring)插值曲线的初始化函数,可以根据入参创建一个插值曲线对象。
在animateTo显式动画中,设置动画时长(duration)为2s,延时(delay)0.1s开始播放,设置显示动效event的闭包函数(curve),即起点状态到终点状态为透明度opacityValue和大小scaleValue从0到1。
logo.ets:

// @ts-nocheck
import Curves from '@ohos.curves'

@Entry
@Component
struct Logo {
  @State private opacityValue: number = 0
  @State private scaleValue: number = 0
  private curve1 = Curves.cubicBezier(0.1, 0.2, 1, 1)

  build() {
    Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center, direction: FlexDirection.Column }) {
      Image($rawfile('LOGO.png'))
        .objectFit(ImageFit.Contain)
        .height(300)
        .scale({ x: this.scaleValue, y: this.scaleValue })
        .opacity(this.opacityValue)
        .onAppear(() => {
          animateTo({
            duration: 2000,
            curve: this.curve1,
            delay: 100,
          }, () => {
            this.opacityValue = 1
            this.scaleValue = 1
          })
        })
      Text('木棉花扫雷')
        .fontSize(30)
        .fontColor(Color.White)
        .margin({ top: 200 })
    }
    .width('100%')
    .height('100%')
    .linearGradient(
      {
        angle: 180,
        colors: [['#D3D7DC', 0.1], ["#B4BED2", 0.6],  ["#A0AAC8", 1]]
      })
  }
}
4. 添加跳转效果

先创建一个mainpage.ets文件。
在animateTo显示动画播放结束的onFinish回调接口中,调用定时器Timer的setTimeout接口延时1s后,调用router.replace,显示mainpage.ets页面。其中同样需要导入router模块。
logo.ets:

// @ts-nocheck
import router from '@system.router'
import Curves from '@ohos.curves'

@Entry
@Component
struct Logo {
  @State private opacityValue: number = 0
  @State private scaleValue: number = 0
  private curve1 = Curves.cubicBezier(0.1, 0.2, 1, 1)

  build() {
    Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center, direction: FlexDirection.Column }) {
      Image($rawfile('LOGO.png'))
        .objectFit(ImageFit.Contain)
        .height(300)
        .scale({ x: this.scaleValue, y: this.scaleValue })
        .opacity(this.opacityValue)
        .onAppear(() => {
          animateTo({
            duration: 2000,
            curve: this.curve1,
            delay: 100,
            onFinish: () => {
              setTimeout(() => {
                router.replace({ uri: "pages/mainpage" })
              }, 1000);
            }
          }, () => {
            this.opacityValue = 1
            this.scaleValue = 1
          })
        })
      Text('木棉花扫雷')
        .fontSize(30)
        .fontColor(Color.White)
        .margin({ top: 200 })
    }
    .width('100%')
    .height('100%')
    .linearGradient(
      {
        angle: 180,
        colors: [['#D3D7DC', 0.1], ["#B4BED2", 0.6],  ["#A0AAC8", 1]]
      })
  }
}

三、主页页面

1. 添加背景

游戏页面的背景和欢迎页面的背景几乎一样,这里就不重复啰嗦了。
mainpage.ets:

@Entry
@Component
struct Mainpage {
  build() {
    Column() {
      Image($rawfile('mine.png'))
        .objectFit(ImageFit.Contain)
        .height(300)
        .scale({ x: 0.5, y: 0.5 })
        .opacity(0.8)
    }
    .width('100%')
    .height('100%')
    .linearGradient(
      {
        angle: 180,
        colors: [['#D3D7DC', 0.1], ["#B4BED2", 0.6],  ["#A0AAC8", 1]]
      })
  }
}
2. 添加按钮

从效果图可以看出按钮的样式是一致的,因此我们可以使用装饰器@Component自定义按钮。添加四个变量String、difficulty、Number_row和Number_column,分别用于记录难度文本、地雷数量、网格的行数和网格的列数。在Button组件中设置图片和文本的样式。 br/>在装饰器@Entry装饰的组件中,通过调用自定义组件的形式绘制三个按钮。
mainpage.ets:

@Entry
@Component
struct Mainpage {
  build() {
    Column() {
      Image($rawfile('mine.png'))
        .objectFit(ImageFit.Contain)
        .height(300)
        .scale({ x: 0.5, y: 0.5 })
        .opacity(0.8)

      setButton({ String: '初级', difficulty: 10, Number_row: 9, Number_column: 9 });
      setButton({ String: '中级', difficulty: 30, Number_row: 12, Number_column: 12 });
      setButton({ String: '高级', difficulty: 50, Number_row: 16, Number_column: 16 });
    }
    .width('100%')
    .height('100%')
    .linearGradient(
      {
        angle: 180,
        colors: [['#D3D7DC', 0.1], ["#B4BED2", 0.6],  ["#A0AAC8", 1]]
      })
  }
}

@Component
struct setButton {
  private String: string
  private difficulty: number
  private Number_row: number
  private Number_column: number

  build() {
    Button({ type: ButtonType.Capsule, stateEffect: true }){
      Column(){
        Text(this.String)
          .textAlign(TextAlign.Center)
          .fontSize(30)
          .fontWeight(600)
          .fontColor('#0000FF')
          .margin({ top: -5 })
        Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center, direction: FlexDirection.Row }) {
          Text('( ' + this.difficulty.toString() + '个')
            .textAlign(TextAlign.Center)
            .fontSize(22)
            .fontWeight(600)
            .fontColor('#416EBE')
            .margin({ top: -2, right: 5 })
          Image($rawfile('mine.png'))
            .height(26)
            .width(26)
          Text(this.Number_row.toString() + '*' + this.Number_column.toString() + ' )')
            .textAlign(TextAlign.Center)
            .fontSize(22)
            .fontWeight(600)
            .fontColor('#416EBE')
            .margin({ left: 5, top: -2})
        }.margin({ top: 5 })
      }
    }
    .width(220)
    .height(90)
    .backgroundColor('#F3F7FF')
    .margin({ top: 10 })
  }
}
3. 响应点击跳转事件

先创建一个game.ets文件。
在自定义按钮组件中添加点击事件onClick(),调用router.push接口,其中uri为跳转的页面,params为携带的数据,形式为params: { key: values },在新页面调用router.getParams().key来获取到页面跳转来时携带的key对应的数据,其中同样需要导入router模块。
mainpage.ets:

import router from '@system.router'

@Entry
@Component
struct Mainpage {
  build() {
    Column() {
      Image($rawfile('mine.png'))
        .objectFit(ImageFit.Contain)
        .height(300)
        .scale({ x: 0.5, y: 0.5 })
        .opacity(0.8)

      setButton({ String: '初级', difficulty: 10, Number_row: 9, Number_column: 9 });
      setButton({ String: '中级', difficulty: 30, Number_row: 12, Number_column: 12 });
      setButton({ String: '高级', difficulty: 50, Number_row: 16, Number_column: 16 });
    }
    .width('100%')
    .height('100%')
    .linearGradient(
      {
        angle: 180,
        colors: [['#D3D7DC', 0.1], ["#B4BED2", 0.6],  ["#A0AAC8", 1]]
      })
  }
}

@Component
struct setButton {
  private String: string
  private difficulty: number
  private Number_row: number
  private Number_column: number

  build() {
    Button({ type: ButtonType.Capsule, stateEffect: true }){
      Column(){
        Text(this.String)
          .textAlign(TextAlign.Center)
          .fontSize(30)
          .fontWeight(600)
          .fontColor('#0000FF')
          .margin({ top: -5 })
        Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center, direction: FlexDirection.Row }) {
          Text('( ' + this.difficulty.toString() + '个')
            .textAlign(TextAlign.Center)
            .fontSize(22)
            .fontWeight(600)
            .fontColor('#416EBE')
            .margin({ top: -2, right: 5 })
          Image($rawfile('mine.png'))
            .height(26)
            .width(26)
          Text(this.Number_row.toString() + '*' + this.Number_column.toString() + ' )')
            .textAlign(TextAlign.Center)
            .fontSize(22)
            .fontWeight(600)
            .fontColor('#416EBE')
            .margin({ left: 5, top: -2})
        }.margin({ top: 5 })
      }
    }
    .width(220)
    .height(90)
    .backgroundColor('#F3F7FF')
    .margin({ top: 10 })
    .onClick(() => {
      router.push({
        uri: 'pages/game',
        params: { difficulty: this.difficulty, Number_row: this.Number_row ,Number_column: this.Number_column }
      })
    })
  }
}

 至此,欢迎页面和主页面都已经全部完成了,在 基于HarmonyOS ArkUI 3.0 框架的木棉花扫雷(下)将会继续分享游戏页面的实现(~ ̄▽ ̄)~

关注我,每天分享知识干货~

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
被子植物是指种子由子房保护的植物,其种子通常有两个种子叶。根据种子叶数目,被子植物分为双子叶植物和单子叶植物。双子叶植物的种子通常有两个种子叶,而单子叶植物的种子只有一个种子叶。 下面是根据各科特征编写的分科检索表: | 科名 | 特征 | | --- | --- | | 木兰科 | 落叶乔木或灌木,花大而美丽,有香气 | | 葫芦科 | 藤本或者草本,果实为葫芦状 | | 锦葵科 | 草本或灌木,花大而美丽,常栽培为观赏植物 | | 十字花科 | 多为草本或亚灌木,花为四瓣十字形,包括蔬菜作物如油菜、芜菁等 | | 蝶形花科 | 多为草本,花形各异,包括豆类作物如大豆、芸豆等 | | 伞形科 | 多为草本,花序为伞形,包括调味品作物如茴香、芹菜等 | | 旋花科 | 多为草本或灌木,花序为螺旋状,包括观赏植物如玫瑰、草莓等 | | 唇形科 | 多为草本,花为唇形,包括观赏植物如唇形兰、鬼针草等 | | 菊科 | 多为草本,花形各异,包括观赏植物如菊花、向日葵等 | | 禾本科 | 多为草本,种子为谷粒,包括粮食作物如小麦、稻米等 | | 石竹科 | 多为草本或亚灌木,花多为五瓣,包括观赏植物如石竹、满天星等 | | 兰科 | 多为草本或兰花,花为唇形,包括观赏植物如蝴蝶兰、兰花等 | | 百合科 | 多为草本,花为六瓣,包括观赏植物如百合、鸢尾等 | 常见代表植物举例: - 木兰科:白玉兰、紫玉兰、木兰等。 - 葫芦科:葫芦、苦瓜、南瓜等。 - 锦葵科:木槿、芙蓉、木棉等。 - 十字花科:油菜、芜菁、芥菜等。 - 蝶形花科:豆类作物如大豆、芸豆等。 - 伞形科:茴香、芹菜、香菜等。 - 旋花科:玫瑰、草莓、蔷薇等。 - 唇形科:唇形兰、鬼针草、金鱼草等。 - 菊科:菊花、向日葵、蒲公英等。 - 禾本科:小麦、稻米、玉米等。 - 石竹科:石竹、满天星、铁线莲等。 - 兰科:蝴蝶兰、兰花、文心兰等。 - 百合科:百合、鸢尾、郁金香等。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值