#HarmonyOS NEXT体验官# 使用HarmonyOS NEXT写一个刮一刮应用 原创

第一小趴菜
发布于 2024-8-16 13:15
浏览
0收藏

前言

突发奇想,写一个刮一刮应用,会不会可以在聚会的场合为我们的生活增添一些乐趣呢
#HarmonyOS NEXT体验官#  使用HarmonyOS NEXT写一个刮一刮应用-鸿蒙开发者社区
说干就干

开发

初始页

刮刮乐,我们肯定要写一个初始化的页面,我们可以在这里设置我们想设置的内容,以及长和宽的规格

import { router } from '@kit.ArkUI';

@Entry
@Component
struct Index {
  // 长有多少格
  @State long: number = 0;
  // 宽有多少格
  @State wide: number = 0;
  @State Input: string = ""
  // 奖项数组
  @State prize: string[] = []

  build() {
    Column() {
      // 选择规格
      Row() {
        Text("生成刮刮乐的大小:")
        TextInput()
          .width("50vp")
          .height("40vp")
          .textAlign(TextAlign.Center)
          .maxLength(2)
          .onChange((val) => {
            this.long = parseInt(val);
          })
        Text("X")
        TextInput()
          .width("50vp")
          .height("40vp")
          .textAlign(TextAlign.Center)
          .maxLength(2)
          .onChange((val) => {
            this.wide = parseInt(val);
          })
      }

      Text(`当前的尺寸共有${this.long * this.wide}个空格`)
        .height("40vp")
      // 输入奖项
      Row() {
        Text("请输入奖项:")
        TextInput({ text: this.Input })
          .width("200vp")
          .height("40vp")
          .textAlign(TextAlign.Center)
          .onChange((val) => {
            this.Input = val;
          })
        Button("添加")
          .onClick(() => {
            this.prize.push(this.Input)
            this.Input = ""
          })
      }

      Text(`当前已添加${this.prize.length}个奖项`)
      // 奖项
      List() {
        ForEach(this.prize, (item: string, index: number) => {
          ListItem() {
            Column() {
              prize_item({
                prize: item,
                // 删除奖励的函数
                delete: () => {
                  this.prize.splice(index, 1)
                }
              })
            }
            .size({ width: "100%", height: "100vp" })
            .justifyContent(FlexAlign.Center)
            .alignItems(HorizontalAlign.Center)

          }
        })
      }
      .width('100%')
      .height("1700px")

      Button("生成")
        .margin("20px")
        .onClick(()=>{
          router.pushUrl({
            url:"pages/scrape",
            params:{
              long:this.long,
              wide:this.wide,
              prize:this.prize
            }
          })
        })

    }
    .size({ height: "100%", width: "100%" })
  }
}
// 奖项组件
@Component
struct prize_item {
  @Prop prize: string
  delete = () => {
  }

  build() {
    Row() {
      Text(this.prize)
        .fontSize("100px")
      Text("x")
        .fontSize("100px")
        .fontColor("#ff0000")
        .onClick(() => {
          this.delete()
        })
    }
    .margin("10px")
    .borderRadius("20px")
    .backgroundColor("#F0FFF0")
    .justifyContent(FlexAlign.SpaceAround)
    .size({ width: "70%", height: "70%" })

  }
}

(ps:陈桑的主页:https://ost.51cto.com/user/posts/16146021
虽然代码有点长这样我们就能得到一个比较合适的页面了,就像这个样子
#HarmonyOS NEXT体验官#  使用HarmonyOS NEXT写一个刮一刮应用-鸿蒙开发者社区
我们点击奖项右方的叉号便可以把这个奖项从列表中删除

设置背景

设置完最基本的初始化设置之后,我们就要开始着手刮一刮内容的生成了
思路:生成我们规定的规格的二位数组,再将我们需要添加的奖项随机埋在我们的格子中,这样就可以解决奖被塞到哪这个问题了。

function Generate_body(long: number, wide: number, prize: Array<string>, fail: string): Array<Array<string>> {
  // 初始化一个二维数组,所有元素都是0
  let array: Array<Array<string>> = Generate_arrays(long, wide, fail)
  let len = prize.length
  // 在二位数组中埋雷
  for (let i = 0; i < len; ) {
    // 生成随机行和列索引
    let row = Math.floor(Math.random() * wide);
    let col = Math.floor(Math.random() * long);
    if (array[row][col] == fail) {
      array[row][col] = prize[i];
      i++;
    }
  }
  return array;
}

function Generate_arrays(long: number, wide: number, value: string) {
  // 初始化一个二维数组,所有元素都是value
  const array: Array<Array<string>> = [];
  for (let index = 0; index < wide; index++) {
    let result: Array<string> = [];
    for (let i = 0; i < long; i++) {
      result.push(value);
    }
    array.push(result)
  }
  return array;
}

我们经过两层ForEach将内容渲染到我们的屏幕上

      // 竖放向
      Flex({ wrap: FlexWrap.NoWrap, direction: FlexDirection.Row }) {
        ForEach(this.List, (item_y: Array<string>, index_y: number) => {
          // 横放向
          Flex({ wrap: FlexWrap.NoWrap, direction: FlexDirection.Column }) {
            ForEach(item_y, (item_x: string, index_x: number) => {
              scrape_item({
                prize: item_x,
                h:this.long,
                w:this.wide
              })
            })
          }
        })

      }
      .size({ width: 350, height: 350 })

显示的效果如下所示

#HarmonyOS NEXT体验官#  使用HarmonyOS NEXT写一个刮一刮应用-鸿蒙开发者社区
完美
下面也就是我们的最后的一个步骤了

添加蒙版

当我们准备好内容后,就只剩下最后一件事情,那就是添加蒙版,让我们可以体验纯天然刮刮乐的乐趣了
当然,首先还是需要写一个奖项组件,当然对于屏幕前的各位大佬来说毫无难度

@Component
struct scrape_item {
  @Prop prize: string
  @Prop h: number
  @Prop w: number
  @State is_show: boolean = false

  build() {
    Column() {
      Column() {
        if (this.is_show) {
          Text(this.prize)
        }

      }
      .size({ width: "100%", height: "100%" })
      .backgroundColor(this.is_show ? "#F5F5F5" : "#DCDCDC")
      .alignItems(HorizontalAlign.Center)
      .justifyContent(FlexAlign.Center)
      .onClick(() => {
        this.is_show = true
      })
    }
    .padding("20px")
    .size({ width: 350 / this.w, height: 350 / this.h })
    .alignItems(HorizontalAlign.Center)
    .justifyContent(FlexAlign.Center)

  }
}

最后再把代码全部拼接起来,就可以愉快的刮刮乐了,效果如下方显示
#HarmonyOS NEXT体验官#  使用HarmonyOS NEXT写一个刮一刮应用-鸿蒙开发者社区

刮一刮页的完整代码

import { router } from '@kit.ArkUI';

@Entry
@Component
struct scrap {
  // 接收到的数据
  @State long: number = (router.getParams() as object)?.["long"];
  @State wide: number = (router.getParams() as object)?.["wide"];
  @State prize: string[] = (router.getParams() as object)?.["prize"];
  @State fail: string = "空"
  // 主体数组列表
  @State List: Array<Array<string>> = Generate_body(this.long, this.wide, this.prize, this.fail)

  build() {
    Column() {

      // 竖放向
      Flex({ wrap: FlexWrap.NoWrap, direction: FlexDirection.Row }) {
        ForEach(this.List, (item_y: Array<string>, index_y: number) => {
          // 横放向
          Flex({ wrap: FlexWrap.NoWrap, direction: FlexDirection.Column }) {
            ForEach(item_y, (item_x: string, index_x: number) => {
              scrape_item({
                prize: item_x,
                h: this.long,
                w: this.wide,
              })
            })
          }
        })

      }
      .size({ width: 350, height: 350 })

      Button("重开")
        .margin("10px")
        .onClick(() => {
          this.List = Generate_body(this.long, this.wide, this.prize, this.fail)
        })

    }
    .justifyContent(FlexAlign.SpaceEvenly)
    .alignItems(HorizontalAlign.Center)
    .size({ width: "100%", height: "100%" })
  }
}

function Generate_body(long: number, wide: number, prize: Array<string>, fail: string): Array<Array<string>> {
  // 初始化一个二维数组,所有元素都是0
  let array: Array<Array<string>> = Generate_arrays(long, wide, fail)
  let len = prize.length
  // 在二位数组中埋雷
  for (let i = 0; i < len; ) {
    // 生成随机行和列索引
    let row = Math.floor(Math.random() * wide);
    let col = Math.floor(Math.random() * long);
    if (array[row][col] == fail) {
      array[row][col] = prize[i];
      i++;
    }
  }
  return array;
}

function Generate_arrays(long: number, wide: number, value: string) {
  // 初始化一个二维数组,所有元素都是value
  const array: Array<Array<string>> = [];
  for (let index = 0; index < wide; index++) {
    let result: Array<string> = [];
    for (let i = 0; i < long; i++) {
      result.push(value);
    }
    array.push(result)
  }
  return array;
}


@Component
struct scrape_item {
  @Prop prize: string
  @Prop h: number
  @Prop w: number
  @State is_show: boolean = false

  build() {
    Column() {
      Column() {
        if (this.is_show) {
          Text(this.prize)
        }

      }
      .size({ width: "100%", height: "100%" })
      .backgroundColor(this.is_show ? "#F5F5F5" : "#DCDCDC")
      .alignItems(HorizontalAlign.Center)
      .justifyContent(FlexAlign.Center)
      .onClick(() => {
        this.is_show = true
      })
    }
    .padding("20px")
    .size({ width: 350 / this.w, height: 350 / this.h })
    .alignItems(HorizontalAlign.Center)
    .justifyContent(FlexAlign.Center)

  }
}

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
标签
已于2024-8-16 13:15:54修改
收藏
回复
举报
回复
    相关推荐