鸿蒙版(ArkTs) 贪吃蛇,包含无敌模式 最高分 暂停和继续功能

时间:2025-04-09 19:25:32
// 所有import语句必须放在文件开头 import router from '@ohos.router'; import promptAction from '@ohos.promptAction'; // Add this import at the top with other imports // Remove the problematic import // import { Gradient, GradientDirection } from '@ohos.arkui.graphics'; // 在文件开头添加Preferences导入 import preferences from '@ohos.data.preferences'; // 移除@Entry装饰器 @Entry @Component struct Tsc { @State snake: Array<[number, number]> = [[5, 5], [5, 6], [5, 7]]; @State food: [number, number] = [10, 10]; @State private _moveDirection: number = 3; @State score: number = 0; @State highScore: number = 0; private prefs?: preferences.Preferences; // Use optional type instead of undefined @State isInvincible: boolean = false; @State foodColor: Color = Color.Red; @State snakeHeadColor: Color = Color.Green; private gridSize: number = 20; private timer: number = 0; @State isPlaying: boolean = false; // 添加generateFood方法 generateFood() { const gridCells = 12; let newFood: [number, number] = [0, 0]; let validPositionFound = false; const allPositions: Array<[number, number]> = []; for (let x = 0; x < gridCells; x++) { for (let y = 0; y < gridCells; y++) { allPositions.push([x, y]); } } allPositions.sort(() => Math.random() - 0.5); for (const pos of allPositions) { const isOverlap = this.snake.some(segment => segment[0] === pos[0] && segment[1] === pos[1] ); if (!isOverlap) { newFood = pos; validPositionFound = true; break; } } this.food = newFood; this.foodColor = Color.Red; // 设置默认食物颜色 } // 重置游戏状态 resetGame() { this.snake = [[5, 5], [5, 6], [5, 7]]; this._moveDirection = 3; this.score = 0; this.generateFood(); } startGame() { // 先清除之前的定时器 if (this.timer) { clearInterval(this.timer); } this.resetGame(); this.isPlaying = true; this.timer = setInterval(() => { this.moveSnake(); }, 200); } // 添加生命周期方法 aboutToAppear() { this.loadHighScore(); } // 加载历史最高分 async loadHighScore() { try { this.prefs = await preferences.getPreferences(getContext(this), 'snakeGamePrefs'); const score = await this.prefs.get('highScore', 0); this.highScore = Number(score); } catch (err) { console.error('Failed to load high score:', err); } } // 保存历史最高分 async saveHighScore(score: number) { try { if (this.prefs) { // Add null check await this.prefs.put('highScore', score); await this.prefs.flush(); } } catch (err) { console.error('Failed to save high score:', err); } } endGame() { clearInterval(this.timer); this.isPlaying = false; // 更新历史最高分 if (this.score > this.highScore) { this.highScore = this.score; this.saveHighScore(this.highScore); } promptAction.showToast({ message: '游戏结束!', duration: 2000 }); } stopGame() { clearInterval(this.timer); this.isPlaying = false; if (this.score > this.highScore) { this.highScore = this.score; this.saveHighScore(this.highScore); } } moveSnake() { if (!this.isPlaying) return; let head: [number, number] = [this.snake[0][0], this.snake[0][1]]; switch (this._moveDirection) { case 0: head[1] -= 1; break; case 1: head[1] += 1; break; case 2: head[0] -= 1; break; case 3: head[0] += 1; break; } // 修正边界检测逻辑 const gridCells = 12; // 与显示区域保持一致 if (head[0] < 0 || head[0] >= gridCells || head[1] < 0 || head[1] >= gridCells) { if (!this.isInvincible) { this.endGame(); return; } head[0] = (head[0] + gridCells) % gridCells; head[1] = (head[1] + gridCells) % gridCells; } if (head[0] === this.food[0] && head[1] === this.food[1]) { this.score += 10; this.generateFood(); // 吃到食物时,只添加新头部,不删除尾部 this.snake = [head, ...this.snake]; } else { // 没吃到食物时,移动蛇身 this.snake.pop(); this.snake = [head, ...this.snake]; } } // 添加暂停游戏方法 @State isPaused: boolean = false; // 添加暂停状态 // 修改暂停游戏方法 pauseGame() { clearInterval(this.timer); this.isPlaying = false; this.isPaused = true; } // 修改恢复游戏方法 resumeGame() { this.isPlaying = true; this.isPaused = false; this.timer = setInterval(() => { this.moveSnake(); }, 200); } build() { Column() { Button('返回首页') .width(100) .height(40) .fontSize(16) .alignSelf(ItemAlign.Start) .margin(10) .onClick(() => { router.pushUrl({ url: 'pages/Index' }) }) // 添加历史最高分显示 Row() { Text(`当前得分: ${this.score}`) .fontSize(20) Text(`最高分: ${this.highScore}`) .fontSize(20) .margin({ left: 20 }) } .margin({ bottom: 10 }) // 修改按钮布局 Row() { if (!this.isPlaying && !this.isPaused) { Button('开始游戏') .width(100) .height(35) .fontSize(14) .margin(5) .onClick(() => { this.startGame(); }) } else if (this.isPlaying) { Button('暂停') .width(100) .height(35) .fontSize(14) .margin(5) .onClick(() => { this.pauseGame(); }) } else if (this.isPaused) { Button('继续') .width(100) .height(35) .fontSize(14) .margin(5) .onClick(() => { this.resumeGame(); }) } Button('重新开始') .width(100) .height(35) .fontSize(14) .margin(5) .onClick(() => { this.startGame(); }) Button('结束游戏') .width(100) .height(35) .fontSize(14) .margin(5) .onClick(() => { this.stopGame(); }) } .margin({ top: 10 }) Stack() { Circle({ width: this.gridSize, height: this.gridSize }) .fill(this.foodColor) // 使用固定颜色描边 .stroke(Color.Gray) .strokeWidth(2) // 添加阴影效果模拟渐变 .shadow({ radius: 3, color: Color.White, offsetX: 1, offsetY: 1 }) .position({ x: this.food[0] * this.gridSize, y: this.food[1] * this.gridSize }) ForEach(this.snake, (segment: [number, number], index: number) => { if (index === 0) { Rect({ width: this.gridSize, height: this.gridSize }) .fill(this.snakeHeadColor) .radius(5) .position({ x: segment[0] * this.gridSize, y: segment[1] * this.gridSize }) } else { // 每节蛇身使用食物颜色 Circle({ width: this.gridSize, height: this.gridSize }) .fill(this.foodColor) .position({ x: segment[0] * this.gridSize, y: segment[1] * this.gridSize }) } }) } .width(this.gridSize * 12) .height(this.gridSize * 12) .border({ width: 1, color: Color.Black }) .clip(true) // 添加裁剪确保内容不会超出边框 .margin({ bottom: 10 }) Column() { Button('上') .width(80) .height(50) .fontSize(18) .margin(5) .onClick(() => { this._moveDirection = 0; }) Row() { Button('左') .width(80) .height(50) .fontSize(18) .margin(