鸿蒙版(ArkTs) 贪吃蛇,包含无敌模式 最高分 暂停和继续功能
鸿蒙版(ArkTs) 贪吃蛇,包含无敌模式 最高分 暂停和继续功能;
效果图如下:
代码如下:
// 所有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 checkawait 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(5).onClick(() => { this._moveDirection = 2; })Button('右').width(80).height(50).fontSize(18).margin(5).onClick(() => { this._moveDirection = 3; })}Button('下').width(80).height(50).fontSize(18).margin(5).onClick(() => { this._moveDirection = 1; })}.margin({ top: 10 })Row() {Text('无敌模式:').fontSize(18).fontColor(this.isInvincible ? Color.Red : Color.Black).margin({ right: 10 })Toggle({ type: ToggleType.Switch, isOn: this.isInvincible }).width(40).height(24).onChange((isOn: boolean) => {this.isInvincible = isOn;})Text(this.isInvincible ? '开启' : '关闭').fontSize(18).fontColor(this.isInvincible ? Color.Red : Color.Black).margin({ left: 10 })}.margin({ top: 20 }).padding(10).borderRadius(10).backgroundColor('#f0f0f0').margin({ top: 10 })}.width('100%').height('100%').backgroundColor('#E0F7FA').onKeyEvent((event: KeyEvent) => {if (event.type === KeyType.Down) {switch (event.keyCode) {case 19: if (this._moveDirection !== 1) this._moveDirection = 0; break;case 20: if (this._moveDirection !== 0) this._moveDirection = 1; break;case 21: if (this._moveDirection !== 3) this._moveDirection = 2; break;case 22: if (this._moveDirection !== 2) this._moveDirection = 3; break;}}})}
}相关文章:
鸿蒙版(ArkTs) 贪吃蛇,包含无敌模式 最高分 暂停和继续功能
鸿蒙版(ArkTs) 贪吃蛇,包含无敌模式 最高分 暂停和继续功能; 效果图如下: 代码如下: // 所有import语句必须放在文件开头 import router from ohos.router; import promptAction from ohos.promptAction; // Add this import at the top wit…...
设计模式简述(十三)适配器模式
适配器模式 描述基本使用使用关于适配器关联不兼容类的方式如果原有抽象层是抽象类若原有抽象是接口使用 描述 适配器模式常用于系统已经上限稳定运行,但现有需求需要将两个不匹配的类放到一起工作时使用。 也就是说这是一个迭代阶段使用的模式。 这种模式&#x…...
4月6日随笔
一觉起来十点多 其实六点和九点分别醒过一次。 起来之后点了个侍卫草推荐的猪排饭,真的巨好吃,猪排很脆,溏心蛋也很香 但是因为酒店十二点半要退房,就匆匆吃完了猪排和一半米饭就走了 今天下午在科技楼写了一会作业,…...
Spring Boot 3.4.3 和 Spring Security 6.4.2 实现基于内存和 MySQL 的用户认证
在 Web 应用开发中,用户认证是保障系统安全的基础需求。Spring Boot 3.4.3 结合 Spring Security 6.4.2 提供了强大的安全框架支持,可以轻松实现基于内存或数据库的用户认证功能。本文将详细介绍如何在 Spring Boot 3.4.3 中集成 Spring Security 6.4.2&…...
多款CANFD芯片单粒子效应对比分析
一、引言 随着航天、工业自动化等领域的快速发展,通信芯片在各种复杂环境下的可靠性变得至关重要。单粒子效应(Single Event Effect,SEE)是空间辐射环境中影响半导体器件性能的重要因素之一。CANFD(Controller Area Network with…...
解决Win11耳机没有声音的问题
方法一:更新驱动程序(有效) 进入 “设置”(快捷键:WinX),点击 “Windows 更新” → “高级选项” 点击 “可选更新” ,然后点击 “驱动程序更新” 【注】:更新后可能会出…...
【spring02】Spring 管理 Bean-IOC,基于 XML 配置 bean
文章目录 🌍一. bean 创建顺序🌍二. bean 对象的单例和多例❄️1. 机制❄️2. 使用细节 🌍三. bean 的生命周期🌍四. 配置 bean 的后置处理器 【这个比较难】🌍五. 通过属性文件给 bean 注入值🌍六. 基于 X…...
内网渗透(杂项集合) --- 中的多协议与漏洞利用技术(杂项知识点 重点) 持续更新
目录 1. NetBIOS 名称的网络协议在局域网中内网渗透中起到什么作用 2. 使用 UDP 端口耗尽技术强制所有 DNS 查找失败,这个技术如何应用在局域网内网渗透测试中 3. 在本地创建一个 HTTP 服务来伪造 WPAD 服务器 什么是 WPAD 服务器?这个服务器是干嘛的…...
el-tabs添加按钮增加点击禁止样式
前置文章 一、vue使用element-ui自定义样式思路分享【实操】 二、vue3&ts&el-tabs多个tab表单校验 现状确认 点击添加按钮,没有点击样式,用户感知不明显没有限制最大的tab添加数量,可以无限添加 调整目标&代码编写 调整目标…...
LINUX 5 vim cat zip unzip
dd u撤销 ctrlr取消撤销 q!刚才的操作不做保存 刚才是编辑模式 现在是可视化模式 多行注释...
PDFBox渲染生成pdf文档
使用PDFBox可以渲染生成pdf文档,并且自定义程度高,只是比较麻烦,pdf的内容位置都需要手动设置x(横向)和y(纵向)绝对位置,但是每个企业的单据都是不一样的,一般来说都会设…...
Batch Normalization:深度学习训练的加速引擎
引言 在深度学习的发展历程中,训练深度神经网络一直是一项极具挑战性的任务。随着网络层数的增加,梯度消失、梯度爆炸以及训练过程中的内部协变量偏移(Internal Covariate Shift)问题愈发严重,极大地影响了模型的收敛…...
低空经济基础设施建设方向与展望
随着科技的不断进步,低空经济正逐渐成为推动国家经济发展的新引擎。低空经济,指的是在低空范围内进行的各种经济活动,包括但不限于无人机物流、空中交通管理、低空旅游、农业监测等。本文将探讨低空经济基础设施建设的方向与未来展望。 1. 低…...
如何保证RabbitMQ消息的可靠传输?
在这个图中,消息可能丢失的场景是1,2,3 1.在生产者将消息发送给RabbitMQ的时候,消息到底有没有正确的到达服务器呢,RabbitMQ提供了两种解决方案: a. 通过事务机制实现(比较消耗性能࿰…...
Kotlin语言进阶:协程、Flow、Channel详解(二)
Kotlin语言进阶:协程、Flow、Channel详解(二) 一、Flow基础 1.1 什么是Flow Flow是Kotlin提供的用于处理异步数据流的解决方案,它建立在协程之上,具有以下特点: 冷流特性:只有在收集时才会开始发射数据背压处理:自动处理生产者和消费者速度不匹配的问题组合操作:提…...
Sentinel核心源码分析(上)
文章目录 前言一、客户端与Spring Boot整合二、SphU.entry2.1、构建责任链2.2、调用责任链2.2.1、NodeSelectorSlot2.2.2、ClusterBuilderSlot2.2.3、LogSlot2.2.4、StatisticSlot2.2.5、AuthoritySlot2.2.6、SystemSlot2.2.7、FlowSlot2.2.7.1、selectNodeByRequesterAndStrat…...
Systemd安全加密备份系统与智能通知
实训背景 你是一家金融科技公司的系统架构师,需为敏感数据设计一套安全备份系统,满足以下需求: 加密存储:自动解密插入的LUKS加密USB设备,挂载到安全目录。备份验证:备份完成后校验文件完整性,…...
6.0 使用Qt+ OpenCV+Python加载图片
本例作为python图像处理的入门课程1,使用Qt+ OpenCV+Python加载图片。 主要有如下几个地方需要注意: 1. OpenCV 默认使用 BGR 格式,而 Qt 使用 RGB。显示前需要转换:cv2.cvtColor(img, cv2.COLOR_BGR2RGB),一般使用某个QLabel控件进行显示。 pic = cv2.cvtColor(pic, cv2.C…...
深度学习篇---网络分析(1)
文章目录 前言1. ImprovedResBlock(改进的残差块)结构组成卷积层1卷积层2跳跃连接(Downsample) 前向传播流程主路径跳跃路径残差连接 2. EnhancedCNN(主模型)2.1 初始特征提取层功能参数变化 2.2 残差块堆叠…...
【Mac 从 0 到 1 保姆级配置教程 11】- Mac 基础配置 Finder、触控板、常用快捷键等
文章目录 前言配置 Finder1. 把我们的家目录请出来2. 显示文件扩展名3. 展示隐藏文件4. 显示路径栏和状态栏5. 固定文件夹到工具栏 基础快捷键1. Finder 导航快捷键2. 文件操作快捷键3. 视图和显示快捷键4. 搜索和选择快捷键5. 实用技巧6. 关于文件创建 配置触控板1. 右键设置2…...
C++Primer - 动态内存管理
欢迎阅读我的 【CPrimer】专栏 专栏简介:本专栏主要面向C初学者,解释C的一些基本概念和基础语言特性,涉及C标准库的用法,面向对象特性,泛型特性高级用法。通过使用标准库中定义的抽象设施,使你更加适应高级…...
DeepSeek本地部署(Ollama)
1. Ollama 安装 Ollama 官网地址: https://ollama.com/安装包网盘地址: https://pan.baidu.com 2. Deepseek 部署 根据自己电脑配置和应用需求选择不同模型,配置不足会导致运行时候卡顿。 版本安装指令模型大小硬盘(存储)显卡…...
Amodal3R ,南洋理工推出的 3D 生成模型
Amodal3R 是一款先进的条件式 3D 生成模型,能够从部分可见的 2D 物体图像中推断并重建完整的 3D 结构与外观。该模型建立在基础的 3D 生成模型 TRELLIS 之上,通过引入掩码加权多头交叉注意力机制与遮挡感知注意力层,利用遮挡先验知识优化重建…...
第二期:深入理解 Spring Web MVC [特殊字符](核心注解 + 进阶开发)
前言: 欢迎来到 Spring Web MVC 深入学习 的第二期!在第一期中,我们介绍了 Spring Web MVC 的基础知识,学习了如何 搭建开发环境、配置 Spring MVC、编写第一个应用,并初步了解了 控制器、视图解析、请求处理流程 等核…...
论伺服电机在轨道式巡检机器人中的优势及应用实践
一、引言 1.1 研究背景与意义 在现代工业生产、电力系统、轨道交通等诸多领域,保障设施设备的安全稳定运行至关重要。轨道式巡检机器人作为一种高效、智能的巡检工具,正逐渐在这些领域崭露头角。它能够沿着预设轨道,对目标区域进行全方位…...
开源软件与自由软件:一场理念与实践的交锋
在科技的世界里,“开源软件”和“自由软件”这两个词几乎无人不知。很多人或许都听说过,它们的代码是公开的,可以供所有人查看、修改和使用。然而,若要细究它们之间的区别,恐怕不少朋友会觉得云里雾里。今天࿰…...
(51单片机)独立按键控制流水灯LED流向(独立按键教程)(LED使用教程)
源代码 如上图将7个文放在Keli5 中即可,然后烧录在单片机中就行了 烧录软件用的是STC-ISP,不知道怎么安装的可以去看江科大的视频: 【51单片机入门教程-2020版 程序全程纯手打 从零开始入门】https://www.bilibili.com/video/BV1Mb411e7re?…...
开发指南111-关闭所有打开的子窗口
门户系统是通过window.open通过单点登录的模式打开子系统的,这就要求门户系统退出时,关闭所有打开的子系统。 平台处理这一问题的核心原理如下: 主窗口定义: allChildWindows:[], //所有子窗口 pushChildWindow(childWindow){ …...
react-router children路由报错
项目场景: 写个路由页面,引发的问题 问题描述 报错: An absolute child route path must start with the combined path of all its parent routes. 代码: import { createBrowserRouter } from "react-router-dom";…...
双向链表示例
#include <stdio.h> #include <stdlib.h>// 定义双向链表节点结构体 typedef struct list {int data; // 数据部分struct list *next; // 指向下一个节点的指针struct list *prev; // 指向前一个节点的指针 } list_t;// 初始化链表,将链表的…...
