门后有诡钥匙在手:基于HarmonyOS ArkTS API 24的QQ密室迷城逃脱暗紫荧光青悬疑风与钥匙蜡烛骷髅粒子动画系统全记录
门后有诡钥匙在手:基于HarmonyOS ArkTS API 24的QQ密室迷城逃脱暗紫荧光青悬疑风与钥匙蜡烛骷髅粒子动画系统全记录
本文基于 HarmonyOS NEXT(API 24)ArkTS 声明式 UI 框架,完整拆解一个密室逃脱主题社交应用「QQ密室·迷城逃脱」的源码实现。应用以暗紫
#3D2352为主色、荧光青#3EE6C1为强调色,构建了底部 4 Tab(密室/拼场/战绩/我的)+ 顶部 7 Tab(全城/恐怖/机械/沉浸/剧情/双人/搞笑)的双层导航体系,配套 14 个钥匙蜡烛骷髅粒子的向下飘动动画、全城主题恐惧值柱状图、4 个模态弹窗(组队拼场新增/发布点评新增/退出拼场删除/密室详情查询),覆盖从密室发现、拼场组队、战绩记录到个人收藏的完整密室社交闭环。

一、引言:今晚,敢进哪个门?
密室逃脱正在从小众解谜游戏变成年轻人的周末社交首选。一扇门、一把锁、一群队友,在限定时间内破解谜题逃出生天,紧张刺激又充满合作乐趣。「QQ密室·迷城逃脱」正是为这一生活方式打造的移动端社区应用:用户可以按主题类型(全城/恐怖/机械/沉浸/剧情/双人/搞笑)发现密室、发起拼场找到同频搭子、记录战绩解锁荣誉徽章、在个人中心跟踪常去店铺与收藏。
应用的视觉语言高度统一:暗紫代表悬疑与神秘,荧光青代表线索与希望,米白 #F3EFF7 底色模拟密室墙壁的幽暗质感。粒子系统选用钥匙 🔑、蜡烛 🕯️、骷髅 💀、星光 ✨、齿轮 ⚙️、面具 🎭 六种图标循环,以不同速度向下飘动——这一设计巧妙模拟了密室中烛光摇曳、钥匙坠落、灰尘下落的悬疑氛围,与向上飘动的常规粒子形成鲜明反差。
本文将从架构概览、色彩系统、数据模型、工具函数与筛选函数、粒子动画系统、双层导航、7 大主题差异化布局、拼场/战绩/我的三大 Tab、4 个模态弹窗、特性对比、完整代码、开发环境搭建等维度,对源码 1092.ets 进行逐模块深度解析。
二、架构概览:单文件声明式组件 + 状态驱动
整个应用采用 ArkTS 声明式 UI 范式,全部逻辑收敛在一个 @Entry @Component struct EscapePage 主组件中,通过 @State 装饰器驱动视图刷新。架构上可分为以下几层:
- 常量层:
ROOM_COLORS配色对象、BOTTOM_TABS/TOP_TABS导航配置、ROOMS(15 个密室)/TEAMS(8 个拼场)/RECORDS(8 条战绩)/STORES(6 家店铺)/ROOM_REVIEWS(3 条点评)五大业务数据数组、FEAR_BARS/FEAR_LABELS恐惧值柱状图数据。 - 接口层:
ColorPalette/TabItem/ParticleItem/RoomItem/TeamItem/RecordItem/StoreItem/ReviewItem共 8 个 interface,强类型约束所有数据结构。 - 工具函数层:
fearColor(恐惧值 4 色映射)、fearLabel(恐惧值 4 档文案)、hotRoomLabel(热度 4 档文案)、fearBarHeight(柱状图高度换算)、teamLeftText(拼场剩余人数文案),共 5 个工具函数。 - 筛选函数层:
horrorRooms/machineRooms/immersiveRooms/storyRooms/duoRooms/funnyRooms/brainRankRooms/favRooms,共 8 个ROOMS.filter()筛选函数,为 7 大顶部 Tab 和我的收藏提供数据来源。 - 组件层:主组件
EscapePage内部通过@Builder装饰器定义了头部、顶部 Tab、底部 Tab、标签行、7 个主题内容构建器、拼场/战绩/我的内容构建器、4 个弹窗构建器,共 20 个@Builder方法。 - 状态层:17 个
@State变量 + 1 个private timerId,覆盖当前 Tab、弹窗显隐、表单数据、粒子数组、定时器 ID。 - 生命周期层:
aboutToAppear中构建粒子并启动setInterval150ms 定时器;aboutToDisappear中clearInterval释放资源。

主组件的 build() 方法以 Stack 为根容器,底层是 Column 布局的主界面(头部 + 顶部 Tab + 滚动内容区 + 底部 Tab),上层叠加 ForEach 渲染的粒子层,最上层是 4 个条件渲染的模态弹窗遮罩。这种 Stack 分层结构保证了粒子始终浮在内容之上、弹窗始终浮在最顶层。
三、色彩系统:暗紫主色 + 荧光青强调 + 悬疑幽暗底色
应用的配色通过 ColorPalette 接口约束,由 ROOM_COLORS 常量统一提供,共 11 个色值(比常规应用多 2 个,新增 primaryDeep 深暗紫和 dark 极暗紫):
| 色值名 | HEX | 用途 |
|---|---|---|
primary |
#3D2352 |
暗紫主色,头部渐变、激活态、按钮、文字强调 |
primaryDeep |
#241238 |
深暗紫,渐变终止色、安全须知卡底 |
accent |
#3EE6C1 |
荧光青强调色,CTA 按钮、标签、下划线、统计数字 |
accentSoft |
#DFF8F1 |
荧光青浅色,按钮背景、输入框背景 |
bg |
#F3EFF7 |
页面底色,幽暗米白 |
card |
#FFFFFF |
卡片背景 |
dark |
#1D1230 |
极暗紫,恐怖主题深底 |
textMain |
#241832 |
主文字,深紫黑 |
textSub |
#8B7F99 |
次级文字,灰紫 |
line |
#E5DEEC |
分割线与边框,浅紫灰 |
除了这 11 个基础色,应用还在多个场景中引入了辅助色以丰富视觉层次:
- 恐惧值映射:
fearColor函数为 4 档恐惧值分配专属色——>=85#C0392B红(超恐预警)、>=60#E07B39橙(重恐)、>=30#C9A227金(微恐)、其他#3EE6C1荧光青(不吓人)。这一函数在全城 Tab 的主题标签、恐怖 Tab 的恐惧值、沉浸 Tab 的恐惧值柱状图中广泛使用,用颜色直观表达恐怖程度。 - 双人主题:
#B03A6E玫红,用于双人房标签、默契指数文字、测默契按钮背景。 - 机械主题:
#4A6FA5钢蓝,用于机械系标签、通关率文字。 - 恐怖主题深底:
#2E1A42深紫,用于恐怖 Tab 的密室卡片背景;#C9BADF淡紫用于恐怖卡片描述文字。 - 危险/删除:
#C0392B红色,用于价格、退出拼场按钮、被吓哭统计、确认退出按钮。 - 成功/通关:
#5B8C5A草绿,用于通关结果、已满员标签、推荐新手按钮。 - 搞笑主题:
#E07B39橙 +#FFF0E3浅橙底,用于搞笑标签云。

渐变的运用是本应用色彩表达的重点:头部使用 linearGradient angle:160 colors:[[#3D2352,0],[#241238,1]] 暗紫渐变(angle 160 度比常规 135 度更倾斜,模拟密室门后的幽暗纵深);全城 Tab 的本周密室之王 banner 使用 angle:135 暗紫到玫红渐变 #3D2352→#6B2D5B;组队拼场弹窗头使用暗紫到玫红渐变 #3D2352→#6B2D5B;密室详情弹窗头使用暗紫到深紫渐变 #3D2352→#5A2A6E。发布点评弹窗头使用纯荧光青浅 #DFF8F1 底(深字,是所有弹窗中唯一用浅色头的),与其他暗紫渐变头形成鲜明对比。不同弹窗通过头色快速区分交互类型。
四、数据模型设计:8 个 interface 强类型约束
应用定义了 8 个 interface,覆盖配色、导航、粒子、密室、拼场、战绩、店铺、点评八大领域:
4.1 ColorPalette、TabItem 与 ParticleItem
interface ColorPalette {
primary: string
primaryDeep: string
accent: string
accentSoft: string
bg: string
card: string
dark: string
textMain: string
textSub: string
line: string
}
interface TabItem {
label: string
icon: string
}
interface ParticleItem {
id: number
icon: string
x: number
y: number
size: number
opacity: number
speed: number
}
ColorPalette 比常规应用多了 primaryDeep 和 dark 两个字段,适配密室主题的多层暗紫需求。ParticleItem 新增了 speed 字段,每个粒子拥有独立的飘动速度 0.25 + (i % 5) * 0.1,范围 0.25~0.65,形成快慢错落的自然感。x/y 采用百分比坐标(0~100),渲染时通过 p.x.toString() + '%' 转为百分比定位。
4.2 RoomItem 密室模型(核心)
interface RoomItem {
id: number
name: string
store: string
theme: string
level: string
players: string
duration: string
price: number
score: string
fear: number
hot: number
tags: string[]
desc: string
}
密室模型是应用最复杂的数据结构,13 个字段覆盖了密室的完整信息:id 唯一标识、name 密室名、store 所属店铺、theme 主题类型(恐怖/机械/沉浸/剧情/双人/搞笑)、level 难度等级(如「烧脑★★★★」「新手★★」)、players 建议人数(如「4-6人」)、duration 时长(如「70分钟」)、price 人均价格、score 评分(字符串如「4.9」)、fear 恐惧值(0~100)、hot 热度值(0~100)、tags 玩法标签数组、desc 详细描述。
ROOMS 常量预置了 15 个密室,从午夜病院、怨铃、贞子回魂夜(恐怖三巨头),到蒸汽齿轮城、时光钟塔(机械烧脑),到盗墓笔记·七星鲁王宫、长安十二时辰(沉浸实景),到雾都侦探社、人皮画师(剧情情感),到双生、囚徒困境(双人默契),到皇帝的新装、大话西游番外(搞笑欢乐),覆盖六大主题类型,每个密室的 fear/hot/tags/desc 都精心设计以匹配主题特色。
4.3 TeamItem 拼场模型、RecordItem 战绩模型、StoreItem 店铺模型与 ReviewItem 点评模型
interface TeamItem {
id: number
room: string
owner: string
need: number
total: number
time: string
note: string
gender: string
}
interface RecordItem {
id: number
room: string
date: string
result: string
used: string
mates: string
icon: string
}
interface StoreItem {
name: string
area: string
rooms: number
score: string
price: string
icon: string
}
interface ReviewItem {
user: string
starStr: string
text: string
time: string
}
TeamItem 8 字段记录拼场信息,TEAMS 预置 8 个拼场(午夜病院求大佬带飞、时光钟塔硬核解谜队、双生缺心有灵犀搭子等),note 字段充满密室圈黑话(「求不怕NPC的大佬带飞,全程躲最后」「怂的别来会哭」)。RecordItem 7 字段记录战绩,RECORDS 预置 8 条(结果包括通关/差一步/求助2次/指错凶手等)。StoreItem 6 字段记录店铺信息,STORES 预置 6 家(迷城旗舰店/机械大师/暗巷实景/实景大世界/双人事务所/欢乐剧场)。ReviewItem 4 字段记录点评,starStr 用 Emoji 星号字符串直接渲染,ROOM_REVIEWS 预置 3 条(评价用户名「吓到腿软的猫」「解谜机器人大王」「胆子最小的队长」充满密室圈梗文化)。
五、工具函数与筛选函数:5 工具 + 8 筛选驱动视觉映射与数据分发
应用定义了 5 个工具函数和 8 个筛选函数,工具函数负责将数据值映射为视觉属性,筛选函数负责为 7 大顶部 Tab 和我的收藏提供数据来源。
5.1 五个工具函数
function fearColor(fear: number): string {
if (fear >= 85) return '#C0392B'
if (fear >= 60) return '#E07B39'
if (fear >= 30) return '#C9A227'
return '#3EE6C1'
}
function fearLabel(fear: number): string {
if (fear >= 85) return '超恐预警'
if (fear >= 60) return '重恐'
if (fear >= 30) return '微恐'
return '不吓人'
}
function hotRoomLabel(hot: number): string {
if (hot >= 90) return '全城爆满'
if (hot >= 80) return '热门'
if (hot >= 75) return '口碑之选'
return '小众宝藏'
}
function fearBarHeight(fear: number): string {
return (fear * 1.1).toString() + 'vp'
}
function teamLeftText(need: number): string {
return '还差 ' + need.toString() + ' 人'
}
fearColor:将恐惧值映射为 4 色(红/橙/金/荧光青),是本应用最具特色的工具函数,用颜色直观表达恐怖程度。fearLabel:将恐惧值映射为 4 档文案(超恐预警/重恐/微恐/不吓人),在恐怖 Tab 的密室卡片中使用。hotRoomLabel:将热度值映射为 4 档文案(全城爆满/热门/口碑之选/小众宝藏),在全城 Tab 的密室卡片中以荧光青字渲染。fearBarHeight:将恐惧值换算为柱状图高度 vp(fear * 1.1),在沉浸 Tab 的恐惧值柱状图中使用。teamLeftText:将拼场剩余人数格式化为「还差 X 人」文案,在拼场 Tab 的卡片中以红字渲染。
5.2 八个筛选函数
function horrorRooms(): RoomItem[] { return ROOMS.filter(r => r.theme === '恐怖') }
function machineRooms(): RoomItem[] { return ROOMS.filter(r => r.theme === '机械') }
function immersiveRooms(): RoomItem[] { return ROOMS.filter(r => r.theme === '沉浸') }
function storyRooms(): RoomItem[] { return ROOMS.filter(r => r.theme === '剧情' || r.fear >= 60) }
function duoRooms(): RoomItem[] { return ROOMS.filter(r => r.theme === '双人') }
function funnyRooms(): RoomItem[] { return ROOMS.filter(r => r.theme === '搞笑' || r.fear <= 15) }
function brainRankRooms(): RoomItem[] { return ROOMS.filter(r => r.theme === '机械' || r.level === '烧脑★★★★★') }
function favRooms(): RoomItem[] { return ROOMS.filter(r => r.hot >= 85) }
8 个筛选函数均为 ROOMS.filter() 的纯函数,为不同 Tab 和模块提供数据:
horrorRooms/machineRooms/immersiveRooms/duoRooms:按theme精确筛选,对应恐怖/机械/沉浸/双人四个 Tab。storyRooms:剧情 Tab 筛选theme === '剧情' || fear >= 60,将高恐惧值的密室也纳入剧情追更清单(恐怖本往往剧情也出色)。funnyRooms:搞笑 Tab 筛选theme === '搞笑' || fear <= 15,将完全不吓人的密室也纳入搞笑欢乐清单。brainRankRooms:机械 Tab 的通关率排行榜筛选theme === '机械' || level === '烧脑★★★★★',将五星烧脑密室也纳入硬核解谜排行。favRooms:我的 Tab 的收藏筛选hot >= 85,将高热度密室作为默认收藏展示。
这种「工具函数 + 筛选函数」的分层设计,让数据映射与数据分发各司其职,模板中只需调用对应函数即可获得正确数据,保持模板简洁。
六、粒子动画系统:14 粒子独立速度向下飘动(钥匙蜡烛骷髅悬疑氛围)
粒子系统是本应用的动态灵魂,选用钥匙 🔑、蜡烛 🕯️、骷髅 💀、星光 ✨、齿轮 ⚙️、面具 🎭 六种图标循环,以独立速度向下飘动,模拟密室中烛光摇曳、钥匙坠落、灰尘下落的悬疑氛围。
6.1 粒子构建:14 粒子 6 图标循环
buildParticles(): ParticleItem[] {
const arr: ParticleItem[] = []
const icons: string[] = ['🔑', '🕯️', '💀', '✨', '⚙️', '🎭']
for (let i = 0; i < 14; i++) {
arr.push({
id: i,
icon: icons[i % icons.length],
x: (i * 47) % 100,
y: (i * 71) % 90,
size: 10 + (i * 9) % 16,
opacity: 0.2 + (i % 4) * 0.1,
speed: 0.25 + (i % 5) * 0.1
})
}
return arr
}
14 个粒子通过质数乘法 (i * 47) % 100 和 (i * 71) % 90 生成伪随机分布的 x/y 百分比坐标。图标在 🔑🕯️💀✨⚙️🎭 六种中循环(钥匙/蜡烛/骷髅/星光/齿轮/面具),size 范围 10~25,opacity 范围 0.2~0.5,speed 范围 0.25~0.65(每个粒子独立速度,是所有应用中最慢的粒子速度,模拟密室中缓慢下落的灰尘与烛光)。
6.2 粒子驱动:向下飘动 + 顶部循环
driftParticles(): void {
const next: ParticleItem[] = []
for (const p of this.particles) {
let ny: number = p.y + p.speed
if (ny > 96) {
ny = -6
}
next.push({
id: p.id, icon: p.icon, x: p.x, y: ny,
size: p.size, opacity: p.opacity, speed: p.speed
})
}
this.particles = next
}
关键点:每帧将每个粒子的 y 坐标加上自身 speed(向下飘动),当 y > 96(飘出底部)时重置为 -6(从顶部重新进入),实现无限循环。x 坐标保持不变(纯垂直下落)。这一方向设计模拟了密室中钥匙从锁孔坠落、蜡烛灰烬飘落、灰尘从天花板缓缓下落的悬疑场景意象,与常规上升粒子形成鲜明反差。
6.3 生命周期与渲染
aboutToAppear(): void {
this.particles = this.buildParticles()
this.timerId = setInterval(() => {
this.driftParticles()
}, 150)
}
aboutToDisappear(): void {
if (this.timerId >= 0) clearInterval(this.timerId)
}
aboutToAppear 中先构建粒子数组,再启动 setInterval 150ms 定时器(约 6.7fps,是所有应用中最慢的刷新频率,配合最慢的粒子速度,模拟密室中缓慢、压抑、悬疑的氛围),将定时器 ID 存入 private timerId。aboutToDisappear 中清除定时器。
渲染层在 Stack 中通过 ForEach 遍历粒子,position 使用百分比坐标 x% y%,ForEach 的 key 函数使用 'p' + p.id(仅 id,不含 y),避免每帧销毁重建所有粒子节点。
七、双层导航架构:底部 4 Tab + 顶部 7 Tab
应用采用双层 Tab 导航,底部 Tab 切换大模块、顶部 Tab 在「密室」模块内切换主题类型分类。注意本应用顶部 Tab 为 7 个(全城/恐怖/机械/沉浸/剧情/双人/搞笑),比常规应用的 6 个多 1 个,是本应用的一个特点。
7.1 头部 headerBuilder:暗紫渐变 + 今晚拼场卡片
头部使用 angle:160 暗紫渐变 #3D2352→#241238(160 度比常规 135 度更倾斜,模拟密室门后的幽暗纵深),左侧是应用名「迷城逃脱」24sp 粗体白字 + 副标题「今晚,敢进哪个门?」12sp #B9A9D6 淡紫字,右侧是一个拼场卡片(#3EE6C1 荧光青底圆角 12):「今晚 7 场」11sp 粗体深字 + 「全城拼场中」9sp 暗紫字。荧光青卡片在暗紫头部上形成强烈对比,是密室应用「在黑暗中寻找线索」视觉隐喻的体现。
7.2 顶部 Tab topTabsBuilder(仅密室 Tab 显示,7 Tab 横向滚动)
7 个 Tab 横向排列(全城🏙️/恐怖👻/机械⚙️/沉浸🎭/剧情📖/双人💞/搞笑🤡),由于 7 个 Tab 在窄屏可能溢出,外层包裹 Scroll horizontal 支持横向滚动。每个 Tab 显示图标 + 文字 13sp。激活态为白字粗体 + #3D2352 暗紫底圆角 14 + #3EE6C1 荧光青下划线(Divider width18 strokeWidth2),非激活态为 #8B7F99 灰紫字。点击切换 currentTopTab。
7.3 底部 Tab bottomTabsBuilder
4 个 Tab(密室🔐/拼场👥/战绩🏆/我的👤)等宽排列,激活态为 #3D2352 暗紫字粗体 + 图标 opacity:1,非激活态为 #9A8FA8 灰紫字 + 图标 opacity:0.45。底部 Tab 使用白底 + shadow radius:6 color:'14000000' offsetY:-2 顶部阴影。点击切换 currentBottomTab。
八、密室 Tab:7 大主题差异化布局
密室 Tab 是应用最核心的模块,7 个顶部 Tab 对应 7 种完全不同的布局风格,从全城的暗紫 banner+双列瀑布、恐怖的安全须知+深紫卡片、机械的横滑大卡+通关率排行、沉浸的恐惧值柱状图+实景大店、剧情的时间轴、双人的左右对决卡、到搞笑的标签云+紧凑列表,每种主题都有专属的视觉语言。
8.1 全城 cityContent:本周密室之王 banner + 双列瀑布卡片
全城 Tab 由两部分组成:
- 本周密室之王 banner:
angle:135暗紫到玫红渐变#3D2352→#6B2D5B,标题「🏮 本周密室之王」18sp 粗体白字,副标题「贞子回魂夜 · 通关率仅17% · 敢来挑战吗」12sp#B9E8DC淡青字,底部「预约本场」荧光青底深字粗体按钮,点击打开贞子回魂夜(id=3)的详情弹窗。 - 双列瀑布卡片:
Flex wrap justifyContent:SpaceBetween双列布局,15 个密室各渲染一个 width:48.5%卡片,包含:主题标签(fearColor映射色底白字,如恐怖本 fear=95 显示红底「恐怖」)+ ⭐评分(#C9862B金字粗体)、密室名 16sp 粗体、店铺名 11sp 次级文字、玩法标签行(roomTagRow构建器,#EFE8F8浅紫底#6B4FA0紫字)、建议人数·时长、底部「¥价格/人」#C0392B红字粗体 +hotRoomLabel热度标签(#3EE6C1荧光青字粗体)。
8.2 恐怖 horrorContent:安全须知 + 深紫密室卡片
恐怖 Tab 由两部分组成:
- 恐怖房安全须知卡:
#241238深暗紫底圆角 14,标题「⚠️ 恐怖房安全须知」14sp 粗体#FF6B6B红字,内容「心脏疾病 / 幽闭恐惧 / 孕妇请勿入场 · 全程可喊安全词」11sp#B9A9D6淡紫字。安全须知是恐怖密室应用的必备功能,体现对用户安全的关怀。 - 恐怖密室列表:
horrorRooms()筛选出 4 个恐怖主题密室(午夜病院/怨铃/贞子回魂夜/午夜出租车),每个渲染为#2E1A42深紫底圆角 16 卡片,包含:fearLabel恐惧档标签(#FF6B6B红字粗体)+ 恐惧值数字(#B9A9D6淡紫字)+ ¥价格(#3EE6C1荧光青粗体)、密室名 17sp 粗体白字、desc 12sp#C9BADF淡紫字 lineHeight:18、店铺·人数·时长 11sp#8B7F99灰紫字、底部「拼场」荧光青底深字粗体按钮(→拼场弹窗)+ 「详情」荧光青描边按钮(→详情弹窗)。
恐怖 Tab 通过深紫底色 + 红字安全须知 + 荧光青价格,完整营造了「恐怖但刺激」的氛围,是 7 个主题中视觉反差最大的一个。
8.3 机械 machineContent:横滑大卡 + 通关率排行榜
机械 Tab 由两部分组成:
- 横滑大卡:
Scroll horizontal横向滚动,machineRooms()筛选出 3 个机械主题密室(蒸汽齿轮城/时光钟塔/无名实验室),每个渲染为 width:170 的白底圆角 16 卡片,包含:「⚙️ 机械系」标签(#4A6FA5钢蓝底白字)、密室名 16sp 粗体、难度等级 11sp#4A6FA5钢蓝字、desc 11sp 次级文字(maxLines3)、¥价格·人数 13sp 粗体#C0392B红字。横滑大卡适合机械密室的「工业感」展示。 - 通关率排行榜:标题「🏆 全城通关率排行榜」,
brainRankRooms()筛选出机械+五星烧脑密室,每行左侧是序号(idx=0 红#C0392B/idx=1 橙#E07B39/其他金#C9A227,金银铜配色),中间是密室名+店铺+时长,右侧是「通关率 X%」#4A6FA5钢蓝粗体(通关率通过100 - r.hot + 8计算,热度越高通关率越低,符合烧脑密室的逻辑)。
8.4 沉浸 immersiveContent:恐惧值柱状图 + 沉浸实景大店
沉浸 Tab 是应用中唯一包含数据可视化的主题:
- 全城主题恐惧值一览柱状图:标题「📊 全城主题恐惧值一览」,下方是一个白底圆角 16 卡片(height:190,
alignItems:VerticalAlign.Bottom底部对齐),内含Row布局的 12 根柱子(FEAR_BARS = [95,88,97,20,15,45,30,70,40,25,86,10],对应病院/怨铃/贞子/齿轮/钟塔/盗墓/长安/画师/双生/囚徒/出租/新装)。每根柱子通过fearBarHeight(fv)计算高度(fear * 1.1),使用fearColor(fv)映射色(>=85 红/>=60 橙/>=30 金/其他荧光青),柱子顶部标注恐惧值数字(fearColor映射色),底部标注主题简称。12 根柱子等宽排列,底部对齐,形成完整的恐惧值对比可视化。 - 沉浸实景大店列表:
immersiveRooms()筛选出 2 个沉浸主题密室(盗墓笔记·七星鲁王宫/长安十二时辰),每个渲染为白底圆角 14 卡片,包含:密室名+⭐评分、desc、玩法标签行、店铺+¥价格/人·时长。

沉浸 Tab 通过恐惧值柱状图让用户一眼对比各主题的恐怖程度,通过沉浸实景大店展示大型实景密室的特色,是数据可视化与主题展示结合的典范。
8.5 剧情 storyContent:时间轴列表
剧情 Tab 使用时间轴布局,storyRooms() 筛选出剧情主题+高恐惧值密室(人皮画师/雾都侦探社/午夜病院/怨铃/贞子回魂夜/午夜出租车等),每行左侧是 30x30 圆形 #3D2352 暗紫底序号(白字粗体),右侧是密室名 14sp 粗体 + 难度·人数 10sp 次级文字 + desc 11sp 次级文字(maxLines2)+ ⭐评分 12sp 金字粗体。圆形序号纵向排列形成时间轴视觉,适合剧情党的「追更清单」主题。
8.6 双人 duoContent:左右对决卡 + 默契测试
双人 Tab 由两部分组成:
- 左右对决卡:
duoRooms()筛选出 2 个双人主题密室(双生/囚徒困境),每个渲染为白底圆角 16 卡片,左侧是「两人房」标签(#B03A6E玫红底白字)+ 密室名 16sp 粗体 + desc + ¥双人价格 14sp 粗体#C0392B红字,右侧是 90 宽的统计区:「默契指数 X%」20sp 粗体#B03A6E玫红字(通过r.hot - 5计算)+ 「通关率 X%」14sp 粗体#3D2352暗紫字(通过100 - r.hot + 15计算)。左右对决卡形式适合双人密室的「默契 vs 通关」对比主题。 - 测一测默契度按钮:「❤️ 测一测你们的默契度」13sp
#B03A6E玫红字粗体,#FBE8F0浅玫红底圆角 20,点击打开拼场弹窗。

8.7 搞笑 funnyContent:标签云 + 紧凑列表
搞笑 Tab 由两部分组成:
- 标签云:
Flex wrap justifyContent:Center7 个搞笑标签(#戏精附体/#笑到脸酸/#NPC太会整活/#社死现场/#团建神器/#梗浓度超标/#笑点低勿入),#FFF0E3浅橙底#E07B39橙字,居中排列形成标签云,营造欢乐氛围。 - 紧凑列表:
funnyRooms()筛选出搞笑主题+完全不吓人密室(皇帝的新装/大话西游番外/蒸汽齿轮城/时光钟塔),每行左侧 🤡 图标 24sp,中间密室名·店铺 + 时长·人数·¥价格,右侧 ⭐评分 12sp 金字粗体。紧凑列表适合搞笑密室的「轻松欢乐」展示。

九、拼场 Tab:进行中拼场 + 我发起的拼场
拼场 Tab teamContent 由标题栏 + 进行中拼场列表 + 我发起的拼场组成:
- 标题栏:左侧「进行中的拼场」16sp 粗体,右侧「发起拼场 +」12sp 荧光青字粗体(
#DFF8F1浅青底圆角 14),点击打开拼场弹窗。 - 进行中拼场列表:8 个拼场卡片,每个包含:🔐 密室名 15sp 粗体 + 「还差 X 人」
teamLeftText11sp#C0392B红字粗体、队长·时间·总人数 11sp 次级文字、斜体宣言(#6B4FA0紫字FontStyle.Italic,如「“求不怕NPC的大佬带飞,全程躲最后”」)、右侧「加入」暗紫底白字粗体按钮(→拼场弹窗)。 - 我发起的拼场:标题「我发起的拼场」,下方
#F8F5FB浅紫底卡片,包含:🔐 怨铃·今晚22:00 + 「已满员」#5B8C5A草绿字(#E8F4E7浅绿底标签)、队员列表(我 + 胆小鬼阿伟 + 齿轮控小美 + 2位待确认)、「取消拼场」#C0392B红描边按钮(→退出拼场弹窗)。
拼场 Tab 通过「还差 X 人」红字突出拼场紧迫感,通过斜体宣言增加拼场的人情味,通过我发起的拼场提供取消入口,是密室社交的核心功能区。
十、战绩 Tab:四列统计 + 荣誉徽章 + 最近战绩 + 写点评
战绩 Tab recordContent 由四部分组成:
- 四列统计卡:白底圆角 16,等宽四列——「38 总场次」
#3D2352暗紫字、「29 通关数」#3EE6C1荧光青字、「76% 通关率」#E07B39橙字、「9 被吓哭」#C0392B红字。「被吓哭」是密室圈特色统计项,充满幽默感。 - 荣誉徽章:标题「🏆 荣誉徽章」,
Flex wrap6 个徽章(👑首通达成/💀恐怖大师/⚙️解谜之光/💞默契满分/🤡快乐源泉/🔥十连打卡),#EFE8F8浅紫底#6B4FA0紫字。 - 最近战绩:标题「📜 最近战绩」,8 条战绩记录,每行左侧 icon(🏥🕰️💞🎬🔔⚙️🕵️👑对应不同密室),中间密室名 + 日期·人数·用时,右侧结果(「通关」
#5B8C5A草绿字/「差一步」「求助2次」「指错凶手」#C0392B红字)。 - 写下今天的点评按钮:「✍️ 写下今天的点评」13sp
#3D2352暗紫字粗体,#EFE8F8浅紫底圆角 20,点击打开点评弹窗。

战绩 Tab 通过四列统计(含「被吓哭」特色项)+ 荣誉徽章 + 最近战绩(含多种结果状态)+ 写点评入口,完整记录用户的密室生涯,是密室社交的成就系统。
十一、我的 Tab:个人信息 + 常去店铺 + 我的收藏
我的 Tab mineContent 由三部分组成:
- 个人信息卡:白底圆角 18,左侧 🕵️ 侦探图标 46sp,右侧「解谜爱好者No.7」18sp 粗体 + 「ID: 88521 · 密室年龄3年 · 恐怖绝缘体」11sp 次级文字。「恐怖绝缘体」是密室圈黑话,形容完全不怕恐怖本的玩家。
- 常去的密室店:标题「🏪 常去的密室店」,6 家店铺列表,每行左侧 icon(🏰⚙️🚪🌏💞🎭),中间店铺名 + 地区·主题数,右侧 ⭐评分 + 价格。
- 我的收藏:标题「🔑 我的收藏」,
Flex wrap展示favRooms()筛选出的高热度密室(hot>=85,共约 8 个),每个为「🔐 密室名」11sp#3D2352暗紫字,#FFFFFF白底圆角 12。

十二、4 个模态弹窗:新增/新增/删除/详情四态闭环
应用实现了 4 个模态弹窗,覆盖组队拼场(新增)、发布点评(新增)、退出拼场(删除)、密室详情(查询)四种交互形态,每个弹窗都有专属的头色与表单结构。
12.1 组队拼场 teamModal:暗紫到玫红渐变头 + 密室/时间/人数/宣言
拼场弹窗 width:90% height:74% 圆角 20,顶部是 angle:120 暗紫到玫红渐变头 #3D2352→#6B2D5B,标题「👥 发起拼场」17sp 粗体白字 + 「找到你的逃亡搭子」11sp #B9E8DC 淡青字。
滚动内容区包含:
- 选择密室:
Flex wrap15 个密室选项,选中态暗紫底白字,非选中#EFE8F8浅紫底暗紫字。 - 场次时间:
Flex wrap6 个选项(今晚19:30/今晚21:00/今晚22:30/明天14:00/周六19:00/周日15:30),选中态#6B4FA0紫底白字。 - 期望人数:
Row5 个选项(3人/4人/5人/6人/7人),选中态荧光青底深字,非选中#DFF8F1浅青底荧光青字。 - 拼场宣言:
Flex wrap5 个选项(求大佬带飞/我不怕!真的/安静解谜型/戏精求收留/第一次玩轻点吓),#EFE8F8浅紫底紫字。 - 操作按钮:「取消」
#EDE7F3灰底灰字 + 「发布拼场」荧光青底深字粗体,均点击关闭弹窗。
12.2 发布点评 reviewModal:荧光青浅头 + 评分/标签/剧透/推荐
点评弹窗 width:90% height:70% 圆角 20,顶部是纯荧光青浅 #DFF8F1 底(深字,是所有弹窗中唯一用浅色头的),标题「✍️ 发布密室点评」17sp 粗体深字 + 「你的攻略是别人的勇气」11sp 次级文字。
滚动内容区包含:
- 本场评分:
Row5 颗星(⭐/☆),点击切换reviewScoreIndex(默认 4 星即 idx=4),选中显示实心 ⭐,未选中显示空心 ☆。 - 印象标签:
Flex wrap7 个选项(机关惊艳/NPC演技炸裂/吓得半死/剧情封神/谜题偏难/性价比高/适合新手),选中态#E07B39橙底白字,非选中#FFF0E3浅橙底橙字。 - 剧透程度:
Row3 个选项(绝不剧透/轻微提示/深度复盘),#EFE8F8浅紫底紫字。 - 是否推荐给新手:
Row两个选项——「😊 推荐」#E8F4E7浅绿底草绿字 + 「😱 劝退」#FBE9E7浅红底红字。 - 操作按钮:「取消」灰底灰字 + 「发布」暗紫底白字粗体。
12.3 退出拼场 quitModal:💀 警告小卡
退出弹窗是 4 个弹窗中最小的一个,width:78% 白底圆角 20,居中显示:
- 💀 骷髅图标 40sp
- 「确认退出拼场?」16sp 粗体主文字
- 「退出后队友将收到通知,本场次数不计入战绩,已付定金将在24小时内退回。」12sp 次级文字(lineHeight:18,居中)
- 操作按钮:「再想想」
#EDE7F3灰底灰字 + 「确认退出」#C0392B红底白字粗体,均点击关闭弹窗。
退出弹窗通过 💀 骷髅图标 + 红色确认按钮 + 详细后果说明(不计战绩/定金退回),提醒用户操作不可逆,符合删除类操作的交互规范。
12.4 密室详情 roomDetailModal:暗紫到深紫渐变头 + 标签/统计/点评/拼场+写点评
详情弹窗 width:90% height:76% 圆角 20,是 4 个弹窗中最高的一个,内容最丰富。顶部是 angle:135 暗紫到深紫渐变头 #3D2352→#5A2A6E:
- 顶部行:左侧 🔐 图标 34sp,右侧「✕」关闭按钮(
#5A3C78深紫底圆角 14),点击关闭弹窗。 - 密室名 20sp 粗体白字(通过
detailRoomName()查找)。 - 店铺 · ⭐评分 12sp
#B9E8DC淡青字。
滚动内容区包含:
- 密室描述:
detailRoomDesc()返回的 desc 文本,13sp 主文字 lineHeight:20。 - 玩法标签:标题 +
Flex wrap渲染detailRoomTags()返回的标签数组,每个标签为#EFE8F8浅紫底#6B4FA0紫字粗体。 - 三列统计卡:
#F5F1F9浅紫底圆角 14,等宽三列——「¥价格 每人」#C0392B红字粗体、「⭐评分 玩家评分」#C9862B金字粗体、「价格水平(偏贵/实惠,通过 price>=150 判断)」#E07B39橙字粗体。 - 玩家点评:标题 +
ForEach(ROOM_REVIEWS)渲染 3 条点评,每条为#F5F1F9浅紫底圆角 12 卡片,包含用户名 + 时间(右对齐)、星号 Emoji、点评文字 12sp 次级文字 lineHeight:18。评价用户名「吓到腿软的猫」「解谜机器人大王」「胆子最小的队长」充满密室圈梗文化。 - 操作按钮:「发起拼场」暗紫底白字粗体(点击关闭详情 + 打开拼场弹窗,实现详情→拼场的流畅跳转)+ 「写点评」荧光青底深字粗体(点击关闭详情 + 打开点评弹窗)。
12.5 detailRoom 系列方法:6 个查找方法
详情弹窗通过 selectedRoomId 从 ROOMS 数组中查找对应密室,定义了 6 个方法:detailRoomName()、detailRoomStore()、detailRoomDesc()、detailRoomScore()、detailRoomPrice()、detailRoomTags()。每个方法都通过 for...of 遍历 ROOMS 查找匹配 id 的密室,再返回对应字段,若未找到则返回默认值(空字符串/0/空数组)。
十三、特性对比表
| 特性维度 | QQ密室·迷城逃脱实现 |
|---|---|
| 主题风格 | 暗紫 #3D2352 + 荧光青 #3EE6C1 + 幽暗米白 #F3EFF7 悬疑密室风 |
| 导航架构 | 底部 4 Tab(密室/拼场/战绩/我的)+ 顶部 7 Tab(全城/恐怖/机械/沉浸/剧情/双人/搞笑),顶部 Tab 仅密室模块显示,7 Tab 外层 Scroll horizontal 支持横向滚动 |
| 数据模型 | 8 个 interface(ColorPalette/TabItem/ParticleItem/RoomItem/TeamItem/RecordItem/StoreItem/ReviewItem) |
| 业务数据量 | 15 密室 + 8 拼场 + 8 战绩 + 6 店铺 + 3 点评 + 12 恐惧值柱状图 |
| 工具函数 | 5 个(fearColor/fearLabel/hotRoomLabel/fearBarHeight/teamLeftText) |
| 筛选函数 | 8 个(horrorRooms/machineRooms/immersiveRooms/storyRooms/duoRooms/funnyRooms/brainRankRooms/favRooms) |
| 粒子系统 | 14 粒子,🔑🕯️💀✨⚙️🎭 六图标循环,独立 speed 0.25~0.65,setInterval 150ms(最慢刷新),向下飘动(y+speed,模拟密室钥匙坠落/灰尘下落/烛光摇曳)+ 顶部循环,百分比坐标 |
| 数据可视化 | 沉浸 Tab 全城主题恐惧值柱状图(12 主题,fearBarHeight fear*1.1,fearColor 4 色映射,底部对齐 height190) |
| 场景差异化 | 7 大顶部 Tab 完全不同布局:全城(暗紫banner+双列瀑布)/恐怖(安全须知+深紫卡片)/机械(横滑大卡+通关率排行金银铜)/沉浸(恐惧值柱状图+实景大店)/剧情(时间轴圆形序号)/双人(左右对决卡+默契测试)/搞笑(标签云+紧凑列表) |
| 模态弹窗 | 4 个:组队拼场(暗紫到玫红渐变头,密室/时间/人数/宣言表单)/发布点评(荧光青浅头,唯一浅色头,5星评分/印象标签/剧透程度/推荐新手)/退出拼场(💀红警告小卡,不计战绩/定金退回)/密室详情(暗紫到深紫渐变头,标签/三列统计/点评,可跳转拼场+写点评) |
| 状态变量 | 17 个 @State + 1 个 private timerId |
| 生命周期 | aboutToAppear 构建粒子+启动定时器,aboutToDisappear clearInterval |
| 头部特色 | 暗紫渐变 angle:160 + 今晚7场全城拼场中荧光青卡片 |
| 顶部 Tab 特色 | 7 Tab(比常规多1个),外层 Scroll horizontal,激活态暗紫底圆角+荧光青下划线 |
| 分类色系统 | fearColor 4 色(恐惧值映射,红/橙/金/荧光青)+ 双人玫红#B03A6E + 机械钢蓝#4A6FA5 + 搞笑橙#E07B39 |
| 密室圈文化梗 | 恐怖绝缘体/被吓哭统计/超恐预警/全城爆满/求大佬带飞/怂的别来会哭/吓到腿软的猫/解谜机器人大王/胆子最小的队长/安全词 |
| 安全提醒 | 恐怖房安全须知卡(心脏疾病/幽闭恐惧/孕妇请勿入场/全程可喊安全词) |
| 弹窗跳转 | 密室详情「发起拼场」→关闭详情+打开拼场;「写点评」→关闭详情+打开点评 |
十四、完整代码
应用完整源码位于 1092.ets,总计约 1500 行,包含 8 个 interface、10 个常量数组/对象、5 个工具函数、8 个筛选函数、1 个 @Entry @Component struct EscapePage 主组件(17 个 @State + 2 个生命周期方法 + 20 个 @Builder 方法 + 6 个 detailRoom 查找方法 + build 方法)。
核心代码结构如下:
// 8 个 interface 定义
interface ColorPalette { ... }
interface TabItem { ... }
interface ParticleItem { ... }
interface RoomItem { ... }
interface TeamItem { ... }
interface RecordItem { ... }
interface StoreItem { ... }
interface ReviewItem { ... }
// 常量定义
const ROOM_COLORS: ColorPalette = { ... }
const BOTTOM_TABS: TabItem[] = [ ... ]
const TOP_TABS: TabItem[] = [ ... ] // 7 个 Tab
const ROOMS: RoomItem[] = [ ... ] // 15 个密室
const TEAMS: TeamItem[] = [ ... ] // 8 个拼场
const RECORDS: RecordItem[] = [ ... ] // 8 条战绩
const STORES: StoreItem[] = [ ... ] // 6 家店铺
const ROOM_REVIEWS: ReviewItem[] = [ ... ] // 3 条点评
const FEAR_BARS: number[] = [95, 88, 97, 20, 15, 45, 30, 70, 40, 25, 86, 10]
const FEAR_LABELS: string[] = ['病院', '怨铃', '贞子', '齿轮', '钟塔', '盗墓', '长安', '画师', '双生', '囚徒', '出租', '新装']
// 5 个工具函数
function fearColor(fear: number): string { ... }
function fearLabel(fear: number): string { ... }
function hotRoomLabel(hot: number): string { ... }
function fearBarHeight(fear: number): string { ... }
function teamLeftText(need: number): string { ... }
// 8 个筛选函数
function horrorRooms(): RoomItem[] { ... }
function machineRooms(): RoomItem[] { ... }
function immersiveRooms(): RoomItem[] { ... }
function storyRooms(): RoomItem[] { ... }
function duoRooms(): RoomItem[] { ... }
function funnyRooms(): RoomItem[] { ... }
function brainRankRooms(): RoomItem[] { ... }
function favRooms(): RoomItem[] { ... }
// 主组件
@Entry
@Component
struct EscapePage {
// 17 个 @State + timerId
@State currentBottomTab: number = 0
@State currentTopTab: number = 0
@State showTeamModal: boolean = false
@State showReviewModal: boolean = false
@State showQuitModal: boolean = false
@State showDetailModal: boolean = false
@State selectedRoomId: number = 0
@State quitTeamId: number = 0
@State teamRoomIndex: number = 0
@State teamSizeIndex: number = 0
@State teamTimeIndex: number = 0
@State reviewScoreIndex: number = 4
@State reviewTagIndex: number = 0
@State particles: ParticleItem[] = []
private timerId: number = -1
// 生命周期
aboutToAppear(): void { ... }
aboutToDisappear(): void { ... }
// 粒子方法
buildParticles(): ParticleItem[] { ... }
driftParticles(): void { ... }
// 6 个 detailRoom 查找方法
detailRoomName(): string { ... }
detailRoomStore(): string { ... }
detailRoomDesc(): string { ... }
detailRoomScore(): string { ... }
detailRoomPrice(): number { ... }
detailRoomTags(): string[] { ... }
// 20 个 @Builder 方法
@Builder headerBuilder() { ... }
@Builder topTabsBuilder() { ... } // 7 Tab Scroll horizontal
@Builder bottomTabsBuilder() { ... }
@Builder roomTagRow(tags: string[]) { ... }
@Builder cityContent() { ... }
@Builder horrorContent() { ... }
@Builder machineContent() { ... }
@Builder immersiveContent() { ... } // 恐惧值柱状图
@Builder storyContent() { ... } // 时间轴
@Builder duoContent() { ... } // 左右对决卡
@Builder funnyContent() { ... } // 标签云
@Builder teamContent() { ... }
@Builder recordContent() { ... }
@Builder mineContent() { ... }
@Builder teamModal() { ... }
@Builder reviewModal() { ... }
@Builder quitModal() { ... }
@Builder roomDetailModal() { ... }
// 根布局
build() {
Stack() {
Column() { // 主界面
this.headerBuilder()
if (this.currentBottomTab === 0) this.topTabsBuilder()
Scroll() { Column() { ... 内容分发 ... } }
this.bottomTabsBuilder()
}
ForEach(this.particles, ...) // 粒子层(向下飘动)
if (this.showTeamModal) { ... } // 4 个弹窗层
if (this.showReviewModal) { ... }
if (this.showQuitModal) { ... }
if (this.showDetailModal) { ... }
}
}
}
将 1092.ets 放入 HarmonyOS 项目的 entry/src/main/ets/pages/ 目录下,在 main_pages.json 中注册路由,即可在 DevEco Studio 中预览运行。
十五、开发环境搭建:DevEco Studio + API 24
本应用基于 HarmonyOS NEXT(API 24)开发,使用 ArkTS 声明式 UI 框架。以下是完整的开发环境搭建步骤。
15.1 安装 DevEco Studio
从华为开发者联盟官网下载 DevEco Studio 安装包,双击运行安装程序。安装欢迎界面如下,点击「Next」继续。

15.2 选择安装位置
在安装路径选择界面,建议选择空间充足的磁盘(建议剩余空间 20GB 以上),避免使用中文路径或含空格的路径。点击「Next」继续。

15.3 配置安装选项
在安装选项配置界面,勾选「Create Desktop Shortcut」(创建桌面快捷方式)、「Add to PATH」(添加到环境变量)等选项,方便后续命令行调用。点击「Next」继续。

15.4 新建项目:选择 Empty Ability 模板
安装完成后启动 DevEco Studio,点击「Create Project」新建项目。在模板选择界面,选择「Empty Ability」(空 Ability)模板,这是最基础的 ArkTS 应用模板,适合从零构建自定义 UI。点击「Next」继续。

15.5 配置项目信息:API 24
在项目配置界面,填写项目名称(如 QQEscape)、包名(如 com.example.qqescape),Compatible SDK 选择 6.1.1(24)(即 API 24),Save location 选择项目保存路径。确认信息无误后点击「Finish」创建项目。

15.6 导入源码与运行
项目创建完成后,将 1092.ets 文件复制到 entry/src/main/ets/pages/ 目录下,打开 entry/src/main/resources/base/profile/main_pages.json,在 src 数组中添加 "pages/1092" 路由注册。
在 DevEco Studio 顶部工具栏选择 Previewer(预览器)或连接真机/模拟器,点击运行按钮即可看到「QQ密室·迷城逃脱」应用的完整运行效果。可以切换底部 4 Tab、顶部 7 Tab,点击密室卡片查看详情、发起拼场填写表单、在战绩 Tab 写点评、在拼场 Tab 退出拼场,体验完整的密室社交闭环。
十六、总结
「QQ密室·迷城逃脱」是一个以密室逃脱为主题的完整移动端社区应用,基于 HarmonyOS NEXT(API 24)ArkTS 声明式 UI 框架构建,单文件 1092.ets 约 1500 行代码实现了全部功能。
应用的核心亮点包括:
- 暗紫 + 荧光青悬疑密室风视觉体系:11 色基础调色板(含 primaryDeep 深暗紫和 dark 极暗紫,比常规多 2 色)+ fearColor 4 色恐惧值映射(红/橙/金/荧光青)+ 双人玫红 + 机械钢蓝 + 搞笑橙,通过色彩快速区分主题与恐怖程度。头部使用 angle:160 暗紫渐变(比常规 135 度更倾斜,模拟密室门后幽暗纵深)+ 荧光青今晚拼场卡片,是「在黑暗中寻找线索」视觉隐喻的体现。
- 双层导航 + 7 大主题差异化布局:底部 4 Tab(密室/拼场/战绩/我的)+ 顶部 7 Tab(全城/恐怖/机械/沉浸/剧情/双人/搞笑,比常规多 1 个,外层 Scroll horizontal 支持横向滚动),7 个主题采用完全不同的布局风格(暗紫 banner+双列瀑布/安全须知+深紫卡片/横滑大卡+通关率排行金银铜/恐惧值柱状图+实景大店/时间轴圆形序号/左右对决卡+默契测试/标签云+紧凑列表),是主题差异化设计的典范。
- 14 粒子独立速度向下飘动动画:🔑🕯️💀✨⚙️🎭 六图标循环,每个粒子拥有独立 speed 0.25~0.65(所有应用中最慢),向下飘动(y+speed,模拟密室中钥匙从锁孔坠落、蜡烛灰烬飘落、灰尘从天花板缓缓下落的悬疑氛围,与常规上升粒子形成鲜明反差)+ 顶部循环,百分比坐标适配多屏幕,setInterval 150ms 驱动(所有应用中最慢刷新频率,配合最慢速度模拟压抑悬疑氛围),aboutToAppear/aboutToDisappear 生命周期管理。向下飘动是本应用粒子系统最具特色的设计决策。
- 全城主题恐惧值柱状图数据可视化:沉浸 Tab 内嵌 12 主题恐惧值柱状图,fearBarHeight 函数换算高度(fear*1.1),fearColor 4 色映射(>=85 红超恐预警/>=60 橙重恐/>=30 金微恐/其他荧光青不吓人),底部对齐渲染 height190,让用户一眼对比各主题恐怖程度。
- 4 个模态弹窗闭环:组队拼场(暗紫到玫红渐变头,密室/时间/人数/宣言完整表单)、发布点评(荧光青浅头,是所有弹窗中唯一用浅色头的,5 星评分⭐☆点击切换/印象标签/剧透程度/推荐新手😊😱)、退出拼场(💀骷髅红警告小卡,强调不计战绩/定金 24 小时退回)、密室详情(暗紫到深紫渐变头,描述/玩法标签/三列统计含价格水平偏贵实惠判断/玩家点评充满密室圈梗文化,可跳转拼场+写点评),覆盖新增/新增/删除/查询四态。
- 强类型数据模型 + 工具函数 + 筛选函数三层架构:8 个 interface 约束所有数据结构,15 密室 + 8 拼场 + 8 战绩 + 6 店铺 + 3 点评的丰富预置数据,5 个工具函数(fearColor/fearLabel/hotRoomLabel/fearBarHeight/teamLeftText)负责视觉映射,8 个筛选函数(horrorRooms/machineRooms/immersiveRooms/storyRooms/duoRooms/funnyRooms/brainRankRooms/favRooms)负责数据分发,detailRoom 系列 6 个查找方法实现详情弹窗的数据驱动。三层架构让模板简洁、逻辑清晰。
- 密室圈文化梗贯穿全应用:恐怖绝缘体/被吓哭统计/超恐预警/全城爆满/求大佬带飞/怂的别来会哭/吓到腿软的猫/解谜机器人大王/胆子最小的队长/安全词/默契测试/通关率排行,让应用充满密室社区的文化认同感。恐怖房安全须知卡(心脏疾病/幽闭恐惧/孕妇请勿入场/全程可喊安全词)体现对用户安全的关怀。

对于希望学习 HarmonyOS ArkTS 声明式 UI 开发的读者,本应用提供了一个完整的参考范本:如何通过 @State 驱动状态更新、如何用 @Builder 拆分复杂布局、如何用 Stack 分层实现粒子与弹窗、如何用 setInterval + 生命周期实现动画(特别是如何通过方向反转与速度变慢模拟不同场景的氛围)、如何用 interface + 常量数组 + 工具函数 + 筛选函数构建分层数据层、如何通过 7 Tab 差异化布局展示不同主题。将源码导入 DevEco Studio(API 24)即可直接运行预览,在此基础上可以扩展更多密室数据、接入真实后端 API、增加地图定位与导航功能、接入实时拼场匹配与聊天功能,打造一个真正可用的密室社交平台。
门后有诡,钥匙在手。愿每一个热爱密室的人,都能在谜题与线索之间找到属于自己的那把钥匙,也能在代码与逃亡之间找到属于自己的那份刺激。
标签: HarmonyOS · ArkTS · API 24
更多推荐

所有评论(0)