LieDetectorManager.ts 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. import { _decorator, Component, Node, Button, Sprite, SpriteFrame, resources, Animation, Tween, tween, Vec3, UITransform } from 'cc';
  2. const { ccclass, property } = _decorator;
  3. /**
  4. * 测谎仪管理器,负责测谎仪UI的显示和功能实现
  5. */
  6. @ccclass('LieDetectorManager')
  7. export class LieDetectorManager extends Component {
  8. @property({
  9. type: Node,
  10. tooltip: '测谎仪UI面板'
  11. })
  12. lieDetectorPanel: Node = null;
  13. @property({
  14. type: Button,
  15. tooltip: '关闭按钮'
  16. })
  17. closeButton: Button = null;
  18. @property({
  19. type: Button,
  20. tooltip: '测谎按钮'
  21. })
  22. detectButton: Button = null;
  23. @property({
  24. type: Sprite,
  25. tooltip: '结果显示'
  26. })
  27. resultDisplay: Sprite = null;
  28. @property({
  29. type: SpriteFrame,
  30. tooltip: '真实结果图片'
  31. })
  32. trueResultFrame: SpriteFrame = null;
  33. @property({
  34. type: SpriteFrame,
  35. tooltip: '虚假结果图片'
  36. })
  37. falseResultFrame: SpriteFrame = null;
  38. @property({
  39. type: Node,
  40. tooltip: '提示信息Label节点'
  41. })
  42. hintLabel: Node = null;
  43. @property({
  44. type: Node,
  45. tooltip: '扫描框节点'
  46. })
  47. scanFrame: Node = null;
  48. @property({
  49. type: Node,
  50. tooltip: '扫描线节点'
  51. })
  52. scanLine: Node = null;
  53. // 当前角色是否为伪装者
  54. private isCharacterFake: boolean = false;
  55. // 是否正在扫描中
  56. private isScanning: boolean = false;
  57. start() {
  58. // 初始化隐藏面板
  59. if (this.lieDetectorPanel) {
  60. this.lieDetectorPanel.active = false;
  61. }
  62. // 隐藏结果
  63. this.hideResult();
  64. // 隐藏扫描元素
  65. this.hideScanElements();
  66. // 注册按钮事件
  67. this.setupButtons();
  68. }
  69. private setupButtons() {
  70. // 关闭按钮
  71. if (this.closeButton) {
  72. this.closeButton.node.on(Button.EventType.CLICK, this.hideLieDetectorPanel, this);
  73. } else {
  74. console.error('测谎仪关闭按钮未设置');
  75. }
  76. // 测谎按钮
  77. if (this.detectButton) {
  78. this.detectButton.node.on(Button.EventType.CLICK, this.startScanProcess, this);
  79. } else {
  80. console.error('测谎按钮未设置');
  81. }
  82. }
  83. /**
  84. * 设置当前角色的真实性
  85. * @param isFake 当前角色是否是伪装者
  86. */
  87. public setCharacterStatus(isFake: boolean) {
  88. this.isCharacterFake = isFake;
  89. // 重置结果显示
  90. this.hideResult();
  91. // 显示提示信息
  92. this.showHint();
  93. }
  94. /**
  95. * 显示测谎仪面板
  96. */
  97. public showLieDetectorPanel() {
  98. if (this.lieDetectorPanel) {
  99. this.lieDetectorPanel.active = true;
  100. this.lieDetectorPanel.setSiblingIndex(999); // 确保显示在最前面
  101. // 初始隐藏结果
  102. this.hideResult();
  103. // 隐藏扫描元素
  104. this.hideScanElements();
  105. // 显示提示信息
  106. this.showHint();
  107. } else {
  108. console.error('测谎仪面板未设置');
  109. }
  110. }
  111. /**
  112. * 隐藏测谎仪面板
  113. */
  114. public hideLieDetectorPanel() {
  115. if (this.lieDetectorPanel) {
  116. this.lieDetectorPanel.active = false;
  117. // 如果正在扫描,停止扫描
  118. this.isScanning = false;
  119. }
  120. }
  121. /**
  122. * 开始扫描流程
  123. */
  124. private startScanProcess() {
  125. // 如果正在扫描中,不做处理
  126. if (this.isScanning) {
  127. return;
  128. }
  129. // 开始扫描
  130. this.isScanning = true;
  131. // 确保结果隐藏
  132. this.hideResult();
  133. // 隐藏提示信息
  134. this.hideHint();
  135. // 显示扫描元素
  136. this.showScanElements();
  137. // 执行扫描动画
  138. this.playScanAnimation();
  139. }
  140. /**
  141. * 显示扫描元素
  142. */
  143. private showScanElements() {
  144. if (this.scanFrame) {
  145. this.scanFrame.active = true;
  146. }
  147. if (this.scanLine && this.scanFrame) {
  148. this.scanLine.active = true;
  149. // 获取扫描框的UITransform组件
  150. const scanFrameTransform = this.scanFrame.getComponent(UITransform);
  151. if (scanFrameTransform) {
  152. // 重置扫描线位置到顶部
  153. this.scanLine.setPosition(this.scanLine.position.x, this.scanFrame.position.y + scanFrameTransform.height / 2, 0);
  154. }
  155. }
  156. }
  157. /**
  158. * 隐藏扫描元素
  159. */
  160. private hideScanElements() {
  161. if (this.scanFrame) {
  162. this.scanFrame.active = false;
  163. }
  164. if (this.scanLine) {
  165. this.scanLine.active = false;
  166. }
  167. }
  168. /**
  169. * 播放扫描动画
  170. */
  171. private playScanAnimation() {
  172. if (!this.scanLine || !this.scanFrame) {
  173. console.error('扫描线或扫描框未设置');
  174. this.detectLie(); // 直接显示结果
  175. return;
  176. }
  177. // 获取扫描框的UITransform组件
  178. const scanFrameTransform = this.scanFrame.getComponent(UITransform);
  179. if (!scanFrameTransform) {
  180. console.error('扫描框缺少UITransform组件');
  181. this.detectLie(); // 直接显示结果
  182. return;
  183. }
  184. // 禁用测谎按钮,避免重复点击
  185. if (this.detectButton) {
  186. this.detectButton.interactable = false;
  187. }
  188. // 设置初始位置(顶部)
  189. const startY = this.scanFrame.position.y + scanFrameTransform.height / 2;
  190. const endY = this.scanFrame.position.y - scanFrameTransform.height / 2;
  191. this.scanLine.setPosition(this.scanLine.position.x, startY, 0);
  192. // 创建扫描动画(从上到下移动)
  193. tween(this.scanLine)
  194. .to(1.5, { position: new Vec3(this.scanLine.position.x, endY, 0) }, {
  195. easing: 'sineInOut',
  196. })
  197. .call(() => {
  198. // 扫描完成后显示结果
  199. this.hideScanElements();
  200. this.detectLie();
  201. // 重新启用测谎按钮
  202. if (this.detectButton) {
  203. this.detectButton.interactable = true;
  204. }
  205. this.isScanning = false;
  206. })
  207. .start();
  208. }
  209. /**
  210. * 执行测谎操作
  211. */
  212. private detectLie() {
  213. // 显示测谎结果
  214. if (this.resultDisplay) {
  215. if (this.isCharacterFake) {
  216. // 显示"假"结果
  217. this.resultDisplay.spriteFrame = this.falseResultFrame;
  218. } else {
  219. // 显示"真"结果
  220. this.resultDisplay.spriteFrame = this.trueResultFrame;
  221. }
  222. this.resultDisplay.node.active = true;
  223. }
  224. }
  225. /**
  226. * 隐藏测谎结果
  227. */
  228. private hideResult() {
  229. if (this.resultDisplay) {
  230. this.resultDisplay.node.active = false;
  231. }
  232. }
  233. /**
  234. * 显示提示信息
  235. */
  236. private showHint() {
  237. if (this.hintLabel) {
  238. this.hintLabel.active = true;
  239. }
  240. }
  241. /**
  242. * 隐藏提示信息
  243. */
  244. private hideHint() {
  245. if (this.hintLabel) {
  246. this.hintLabel.active = false;
  247. }
  248. }
  249. onDestroy() {
  250. // 清理按钮事件
  251. if (this.closeButton) {
  252. this.closeButton.node.off(Button.EventType.CLICK, this.hideLieDetectorPanel, this);
  253. }
  254. if (this.detectButton) {
  255. this.detectButton.node.off(Button.EventType.CLICK, this.startScanProcess, this);
  256. }
  257. }
  258. }