• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16import mediaQuery from '@ohos.mediaquery'
17import mediaLibrary from '@ohos.multimedia.mediaLibrary'
18import GameRules from "../model/GameRules"
19import ImageModel from "../model/ImageModel"
20import ImagePicker from '../common/ImagePicker'
21import Logger from '../model/Logger'
22import PictureItem from '../model/PictureItem'
23
24enum gameStatus {
25  running = 1,
26  over = 0
27}
28
29const PERMISSIONS: Array<string> = ['ohos.permission.READ_MEDIA', 'ohos.permission.WRITE_MEDIA','ohos.permission.MEDIA_LOCATION']
30const IMAGE_SIZE: number = px2vp(640)
31const GAME_TIME: number = 300 // 游戏时长
32const TAG: string = 'Index'
33
34@Entry
35@Component
36struct Index {
37  private listener = mediaQuery.matchMediaSync('screen and (min-aspect-ratio: 1.5) or (orientation: landscape)')
38  private ImageModel: ImageModel = new ImageModel(getContext(this))
39  private game: GameRules = new GameRules()
40  private timer: number = -1
41  private isRefresh: boolean = false
42  @State numArray: PictureItem[] = []
43  @State imgDatas: Array<mediaLibrary.FileAsset> = []
44  @State @Watch("onTimeOver") gameTime: number = GAME_TIME
45  @State @Watch("onImageChange") index: number = 0
46  @State isLand: boolean = false
47  onLand = (mediaQueryResult) => {
48    console.info(`[eTSMediaQuery.Index]onLand: mediaQueryResult.matches=${mediaQueryResult.matches}`)
49    this.isLand = mediaQueryResult.matches
50  }
51
52  async aboutToAppear() {
53    this.listener.on('change', this.onLand)
54    let context = getContext(this) as any
55    await context.requestPermissionsFromUser(PERMISSIONS)
56    this.imgDatas = await this.ImageModel.getAllImg()
57    Logger.info(TAG, `images = ${this.imgDatas.length}`)
58    this.numArray = await this.ImageModel.splitPic(this.index)
59  }
60
61  onTimeOver() {
62    if (this.gameTime == 0) {
63      this.game.gameStatus = 0
64      AlertDialog.show({ message: 'TimeOver' })
65      clearInterval(this.timer)
66    }
67  }
68
69  async onImageChange() {
70    this.isRefresh = true
71    this.dialogController.close()
72    this.numArray = await this.ImageModel.splitPic(this.index)
73    this.init()
74    this.isRefresh = false
75  }
76
77  init() {
78    this.gameTime = GAME_TIME
79    this.game.gameStatus = 0
80    clearInterval(this.timer)
81  }
82
83  gameOver() {
84    let count = 0
85    for (let i = 0;i < 7; i++) {
86      if (this.numArray[i].index == i) {
87        count++
88      } else {
89        count = 0
90        break
91      }
92      if (count == 7) {
93        AlertDialog.show({ message: $r('app.string.congratulations') })
94        this.game.gameStatus = gameStatus.over
95        clearInterval(this.timer)
96        this.gameTime = GAME_TIME
97      }
98    }
99  }
100
101  start() {
102    this.init()
103    this.timer = setInterval(() => {
104      this.gameTime--
105    }, 1000)
106  }
107
108  dialogController: CustomDialogController = new CustomDialogController({
109    builder: ImagePicker({
110      imageDatas: this.imgDatas,
111      index: $index
112    }),
113    autoCancel: true,
114    gridCount: 12
115  })
116
117  @Builder
118  ImageShow() {
119    Image(this.imgDatas[this.index].uri)
120      .width(IMAGE_SIZE)
121      .height(290)
122      .objectFit(ImageFit.Fill)
123      .onClick(async () => {
124        if (this.isRefresh) {
125          return
126        }
127        this.imgDatas = await this.ImageModel.getAllImg()
128        setTimeout(() => {
129          this.dialogController.open()
130        }, 200)
131      })
132  }
133
134  @Builder
135  ImageGrid(leftMargin: number, topMargin: number) {
136    Grid() {
137      ForEach(this.numArray, (item, index) => {
138        GridItem() {
139          Image(item.pixelMap)
140            .width('99%')
141            .objectFit(ImageFit.Fill)
142            .height(vp2px(65))
143        }
144        .backgroundColor(item.pixelMap === undefined ? "#f5f5f5" : "#ffdead")
145        .onClick(() => {
146          if (this.isRefresh) {
147            return
148          }
149          if (this.game.gameStatus === gameStatus.running) {
150            this.isRefresh = true
151            this.numArray = this.game.gameInit(index, this.numArray)
152            this.gameOver()
153            this.isRefresh = false
154          }
155        })
156      })
157    }
158    .columnsTemplate('1fr 1fr 1fr')
159    .columnsGap(2)
160    .rowsGap(2)
161    .width(IMAGE_SIZE)
162    .height(290)
163    .margin({ left: leftMargin, top: topMargin })
164  }
165
166  build() {
167    Column() {
168      Row() {
169        Text(`Time:0${Math.floor(this.gameTime / 60)}:${this.gameTime % 60 < 10 ? '0' + this.gameTime % 60 : this.gameTime % 60}`)
170          .margin({ top: 5, bottom: 5 })
171      }
172
173      if (this.imgDatas.length > 0) {
174        if (this.isLand) {
175          Row() {
176            this.ImageShow()
177            this.ImageGrid(10, 0)
178          }
179          .margin({ top: 5 })
180        } else {
181          Column() {
182            this.ImageShow()
183            this.ImageGrid(0, 5)
184          }
185          .margin({ top: 5 })
186        }
187      }
188      Button($r('app.string.start'), { type: ButtonType.Capsule, stateEffect: true })
189        .height(50)
190        .width('100%')
191        .fontSize(18)
192        .margin({ top: 5 })
193        .backgroundColor(this.game.gameStatus === gameStatus.over ? '#0D9FFB' : '#E5E5E5')
194        .enabled(this.game.gameStatus === gameStatus.over)
195        .onClick(() => {
196          this.start()
197          this.numArray = this.game.gameBegin(this.numArray)
198        })
199
200      Button($r('app.string.restart'), { type: ButtonType.Capsule, stateEffect: true })
201        .height(50)
202        .width('100%')
203        .fontSize(18)
204        .margin({ top: 5 })
205        .backgroundColor(this.game.gameStatus === gameStatus.running ? '#0D9FFB' : '#E5E5E5')
206        .enabled(this.game.gameStatus === gameStatus.running)
207        .onClick(() => {
208          this.start()
209          this.numArray = this.game.gameBegin(this.numArray)
210        })
211    }
212    .width('100%')
213    .height('100%')
214    .padding({ left: '1%', right: '1%' })
215  }
216}