TestMgr.ts 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614
  1. import {
  2. _decorator,
  3. assetManager,
  4. Button,
  5. Component,
  6. director,
  7. instantiate,
  8. Label,
  9. log,
  10. Node,
  11. Prefab,
  12. ScrollView,
  13. Size,
  14. size,
  15. Sprite,
  16. SpriteFrame,
  17. tween,
  18. UIOpacity,
  19. UITransform,
  20. v2,
  21. v3,
  22. Vec3
  23. } from 'cc';
  24. import {NodeUtils} from '../../script/utils/NodeUtils';
  25. import {LoadUtils} from '../../script/utils/LoadUtils';
  26. import {ArrUtils} from '../../script/utils/ArrUtils';
  27. import {UserInfo} from '../../script/UserInfo';
  28. import {BlindsTransitionNodes} from '../../script/utils/BlindsTransitionNodes';
  29. import {IntroMgr} from './IntroMgr';
  30. import {TimeProgress} from './TimeProgress';
  31. import {AudioManage} from './AudioManage';
  32. import {formatDate} from '../../script/utils/TimeUtils';
  33. const {ccclass, property} = _decorator;
  34. @ccclass('TestMgr')
  35. export class TestMgr extends Component {
  36. private stageLevel: number = 1
  37. private maxLevel: number = 5
  38. private turnLevel: number = 0
  39. private timeLimit: number = 5
  40. private timeLimitMax: number = 20
  41. private timeStep: number = 0
  42. private timeInterval: number = 1
  43. private timeStart: boolean = false
  44. private score: number = 0
  45. private scoreMax: number = 4
  46. private timeArr: number[] = new Array()//答题时间数组,用于计算平均答题时间
  47. private waitOpTime: number = 8//主画面出现后,等待选项出现的时间
  48. private totalRight: number = 0
  49. private totalWrong: number = 0
  50. private totalTimeout: number = 0
  51. private totalQustion: number = 0
  52. @property([SpriteFrame])
  53. private btnSprite: SpriteFrame[] = new Array()
  54. @property(Prefab)
  55. private btnPre: Prefab = null
  56. @property(Prefab)
  57. private btnPre2: Prefab = null
  58. @property(Prefab)
  59. private scrollTip: Prefab = null
  60. private isShowIntro: boolean = false
  61. private detail: any = {}
  62. private details: any[] = new Array()
  63. // private timuTotal:number = 0
  64. // private rightCnt:number = 0//z
  65. /**
  66. * 图片有错误的
  67. * 1-5
  68. * 2-0
  69. * 2-2
  70. * 3-5
  71. */
  72. private optionArr: any[][] = [
  73. [],
  74. [//5
  75. {//1
  76. txt: "哪张图片上的物体位置与刚才不同?",
  77. itmes: [{index: 4, isRight: false}, {index: 5, isRight: false}, {index: 6, isRight: true}, {
  78. index: 7,
  79. isRight: false
  80. }, {index: 7, isRight: false}],
  81. rightCnt: 1
  82. },
  83. {//2
  84. txt: "哪张图片上的物体位置与刚才不同?",
  85. itmes: [{index: 4, isRight: false}, {index: 5, isRight: false}, {index: 6, isRight: true}, {
  86. index: 7,
  87. isRight: false
  88. }, {index: 7, isRight: false}],
  89. rightCnt: 1
  90. },
  91. {//3
  92. txt: "哪张图片上的物体位置与刚才不同?",
  93. itmes: [{index: 4, isRight: false}, {index: 5, isRight: false}, {index: 6, isRight: true}, {
  94. index: 7,
  95. isRight: false
  96. }, {index: 7, isRight: false}],
  97. rightCnt: 1
  98. },
  99. {//4
  100. txt: "哪张图片上的物体位置与刚才不同?",
  101. itmes: [{index: 4, isRight: false}, {index: 5, isRight: false}, {index: 6, isRight: true}, {
  102. index: 7,
  103. isRight: false
  104. }, {index: 7, isRight: false}],
  105. rightCnt: 1
  106. },
  107. {//5
  108. txt: "哪张图片上的物体位置与刚才不同?",
  109. itmes: [{index: 4, isRight: false}, {index: 5, isRight: false}, {index: 6, isRight: true}, {
  110. index: 7,
  111. isRight: false
  112. }, {index: 7, isRight: false}],
  113. rightCnt: 1
  114. },
  115. {//6
  116. txt: "哪张图片上的物体位置与刚才不同?",
  117. itmes: [{index: 4, isRight: false}, {index: 5, isRight: false}, {index: 6, isRight: true}, {
  118. index: 7,
  119. isRight: false
  120. }, {index: 7, isRight: false}],
  121. rightCnt: 1
  122. },
  123. {//7
  124. txt: "哪张图片上的物体位置与刚才不同?",
  125. itmes: [{index: 4, isRight: false}, {index: 5, isRight: false}, {index: 6, isRight: true}, {
  126. index: 7,
  127. isRight: false
  128. }, {index: 7, isRight: false}],
  129. rightCnt: 1
  130. },
  131. {//8
  132. txt: "哪张图片上的物体位置与刚才不同?",
  133. itmes: [{index: 4, isRight: false}, {index: 5, isRight: false}, {index: 6, isRight: true}, {
  134. index: 7,
  135. isRight: false
  136. }, {index: 7, isRight: false}],
  137. rightCnt: 1
  138. },
  139. {//9
  140. txt: "哪张图片上的物体位置与刚才不同?",
  141. itmes: [{index: 4, isRight: false}, {index: 5, isRight: false}, {index: 6, isRight: true}, {
  142. index: 7,
  143. isRight: false
  144. }, {index: 7, isRight: false}],
  145. rightCnt: 1
  146. },
  147. {//10
  148. txt: "哪张图片上的物体位置与刚才不同?",
  149. itmes: [{index: 4, isRight: false}, {index: 5, isRight: false}, {index: 6, isRight: true}, {
  150. index: 7,
  151. isRight: false
  152. }, {index: 7, isRight: false}],
  153. rightCnt: 1
  154. },
  155. {//11
  156. txt: "哪张图片上的物体位置与刚才不同?",
  157. itmes: [{index: 4, isRight: false}, {index: 5, isRight: false}, {index: 6, isRight: true}, {
  158. index: 7,
  159. isRight: false
  160. }, {index: 7, isRight: false}],
  161. rightCnt: 1
  162. },
  163. {//12
  164. txt: "哪张图片上的物体位置与刚才不同?",
  165. itmes: [{index: 4, isRight: false}, {index: 5, isRight: false}, {index: 6, isRight: true}, {
  166. index: 7,
  167. isRight: false
  168. }, {index: 7, isRight: false}],
  169. rightCnt: 1
  170. },
  171. {//13
  172. txt: "哪张图片上的物体位置与刚才不同?",
  173. itmes: [{index: 4, isRight: false}, {index: 5, isRight: false}, {index: 6, isRight: true}, {
  174. index: 7,
  175. isRight: false
  176. }, {index: 7, isRight: false}],
  177. rightCnt: 1
  178. },
  179. {//14
  180. txt: "哪张图片上的物体位置与刚才不同?",
  181. itmes: [{index: 4, isRight: false}, {index: 5, isRight: false}, {index: 6, isRight: true}, {
  182. index: 7,
  183. isRight: false
  184. }, {index: 7, isRight: false}],
  185. rightCnt: 1
  186. },
  187. {//15
  188. txt: "哪张图片上的物体位置与刚才不同?",
  189. itmes: [{index: 4, isRight: false}, {index: 5, isRight: false}, {index: 6, isRight: true}, {
  190. index: 7,
  191. isRight: false
  192. }, {index: 7, isRight: false}],
  193. rightCnt: 1
  194. },
  195. ]
  196. ]
  197. protected onLoad(): void {
  198. this.timeStart = false
  199. this.timeStep = 0
  200. this.timeArr = []
  201. this.node.getChildByName("titleBg").getChildByName("startBtn").off("click")
  202. this.node.getChildByName("titleBg").getChildByName("startBtn").on("click", () => {
  203. this.begin()
  204. }, this)
  205. this.isShowIntro = true
  206. }
  207. start() {
  208. this.score = 0
  209. this.initGame()
  210. }
  211. update(deltaTime: number) {
  212. if (this.timeStart) {
  213. this.timeStep += deltaTime
  214. }
  215. }
  216. private cleanTime() {
  217. this.timeStart = false
  218. this.timeStep = 0
  219. }
  220. private canClick: boolean = true
  221. private isGameing: boolean = true
  222. private rightCnt: number = 0
  223. private rightNodeArr: Node[] = new Array()
  224. //初始化游戏
  225. private initGame() {
  226. this.cleanTime()
  227. // this.score = 0
  228. this.isGameing = true
  229. this.canClick = true
  230. this.rightCnt = 0
  231. this.rightNodeArr = []
  232. this.node.getChildByName("Label").active = false
  233. this.node.getChildByName("noclick").active = true
  234. this.node.getChildByName("noclick2").active = true
  235. this.node.getChildByName("loadSpine").active = true
  236. this.node.getChildByName("content").getChildByName("Layout").removeAllChildren()
  237. this.node.getChildByName("content").active = false
  238. this.node.getChildByName("icon").getComponent(Sprite).spriteFrame = null
  239. this.node.getChildByName("icon").active = false
  240. this.node.getChildByName("icon").getChildByName("Label").active = false
  241. this.node.getChildByName("progress").active = false
  242. this.node.getChildByName("progress").getComponent(TimeProgress).prepair(this.timeLimitMax)
  243. // this.closeTitle()
  244. this.node.getChildByName("Label2").getComponent(Label).string = this.stageLevel + "-" + this.turnLevel + "--" + this.score
  245. this.node.getChildByName("titleBg").active = false
  246. this.node.getChildByName("titleBg").getChildByName("Label2").getComponent(Label).string = ""
  247. this.node.getChildByName("titleBg").getChildByName("Label3").getComponent(Label).string = ""
  248. this.scheduleOnce(function () {
  249. if (this.isShowIntro) {
  250. this.showIntro()
  251. // this.showTitle()
  252. } else {
  253. this.node.getChildByName("intro").active = false
  254. this.showTitle()
  255. }
  256. }, 0.5);
  257. }
  258. private showIntro() {
  259. this.isShowIntro = false
  260. const content = this.node.getChildByName("intro").getChildByName("ScrollView").getChildByName("view").getChildByName("content")
  261. const len = content.children.length
  262. this.node.getChildByName("intro").getChildByName("Layout").removeAllChildren()
  263. for (let i = 0; i < len; i++) {
  264. const n_st = instantiate(this.scrollTip)
  265. if (i == 0) {
  266. n_st.getChildByName("icon").active = true
  267. }
  268. this.node.getChildByName("intro").getChildByName("Layout").addChild(n_st)
  269. }
  270. this.node.getChildByName("intro").active = true
  271. NodeUtils.maoPaoShow(this.node.getChildByName("intro"), () => {
  272. // this.goIntro(len)
  273. this.node.getChildByName("intro").getComponent(IntroMgr).startIntro()
  274. })
  275. }
  276. public showTitle() {
  277. AudioManage.instance.pauseMusic()
  278. this.scheduleOnce(function () {
  279. AudioManage.instance.playSoundCallback("sound/intro4")
  280. }, 0.5);
  281. // if (this.turnLevel == 0) {
  282. this.node.getChildByName("titleBg").getChildByName("Label2").getComponent(Label).string = "第" + (this.turnLevel + 1) + "题"
  283. this.node.getChildByName("titleBg").getChildByName("Label3").getComponent(Label).string = "您有" + this.waitOpTime + "秒时间观察图片,之后在" + this.timeLimitMax + "秒时间内从4个选项中选出正确答案。"
  284. // this.node.getChildByName("titleBg").getChildByName("startBtn").active = true
  285. NodeUtils.maoPaoShow(this.node.getChildByName("titleBg"), () => {
  286. })
  287. // } else {
  288. // this.begin()
  289. // }
  290. }
  291. private closeTitle() {
  292. AudioManage.instance.pauseMusic()
  293. this.node.getChildByName("titleBg").active = false
  294. // this.node.getChildByName("titleBg").getChildByName("bg").active = false
  295. // this.node.getChildByName("titleBg").getChildByName("startBtn").active = false
  296. }
  297. private begin() {
  298. this.detail.topicStartTime = new Date()//记录题目开始时间
  299. this.closeTitle()
  300. // this.node.getChildByName("content").getChildByName("Label").getComponent(Label).string = this.optionArr[this.stageLevel][this.turnLevel].txt
  301. this.node.getChildByName("content").getChildByName("Label").getComponent(Label).string = ""
  302. this.node.getChildByName("noclick2").active = true
  303. this.node.getChildByName("loadSpine").active = true
  304. const index = this.genCenterPic("图例", true)
  305. }
  306. /**
  307. * 生成题目的主图片
  308. * @param name 图片名字(URL路径名称)
  309. * @param isGen 默认false。如果设置成true则生成主图片后会继续生成按钮图片
  310. * @returns
  311. */
  312. private genCenterPic(name: string, isGen: boolean = false, callback: Function = null) {
  313. LoadUtils.loadBundleRes("distance", "resources/texture/question/a (" + (this.turnLevel + 1) + ")/" + name + "/spriteFrame", (asset) => {
  314. this.node.getChildByName("icon").getComponent(Sprite).spriteFrame = asset
  315. // this.node.getChildByName("noclick2").active = false
  316. // this.scheduleOnce(function () {
  317. // tween(this.node.getChildByName("icon")).to(0.5, { position: v3(0, 0) }).start()
  318. // }, 0.5);
  319. if (isGen) {
  320. // this.genBtn(index)
  321. let tarr: Node[] = new Array()
  322. this.genBtn2(0, tarr)
  323. }
  324. if (null != callback) {
  325. callback()
  326. }
  327. }, null, SpriteFrame)
  328. // return index
  329. }
  330. /**
  331. * 从第5关开始,生成侧面的按钮
  332. * @param index
  333. * @param tarr
  334. * @param folderIndex
  335. */
  336. private genBtn2(index: number = 0, tarr: Node[]) {
  337. index++
  338. if (index <= 4) {
  339. LoadUtils.loadBundleRes("distance", "resources/texture/question/a (" + (this.turnLevel + 1) + ")/" + index + "/spriteFrame", (asset) => {
  340. // this.node.getChildByName("icon").getComponent(Sprite).spriteFrame = asset
  341. const tnode: Node = instantiate(this.btnPre2)
  342. tnode.getChildByName("Mask").getChildByName("icon").getComponent(Sprite).spriteFrame = asset
  343. const ii = index
  344. tnode.off("click")
  345. tnode.on("click", (event) => {
  346. this.clicked(event, (index == 1), ii)
  347. }, this)
  348. tarr.push(tnode)
  349. if (index == 1) {
  350. this.rightNodeArr.push(tnode)
  351. }
  352. this.genBtn2(index, tarr)
  353. }, null, SpriteFrame)
  354. } else {
  355. //测试的时候暂时注释,让所有的第一个选项都是正确答案2025-10-09
  356. tarr = ArrUtils.shuffleArray(tarr)
  357. tarr.forEach((tnode) => {
  358. this.node.getChildByName("content").getChildByName("Layout").addChild(tnode)
  359. })
  360. this.waitOption()
  361. // this.beginTime()
  362. }
  363. }
  364. /**
  365. * 等待waitOptime秒,再开始出现答题选项
  366. */
  367. private waitOption() {
  368. this.node.getChildByName("noclick2").active = false
  369. this.node.getChildByName("loadSpine").active = false
  370. //主图片入场
  371. // this.node.getChildByName("icon").getComponent(BlindsTransitionNodes).setHide(false)
  372. this.node.getChildByName("icon").getComponent(BlindsTransitionNodes).setHide(true)
  373. this.node.getChildByName("icon").active = true
  374. // this.node.getChildByName("icon").getComponent(BlindsTransitionNodes).playReverse(() => {
  375. // // this.setCountdown(5)
  376. // })
  377. this.scheduleOnce(function () {//选项图入场
  378. // this.node.getChildByName("noclick2").active = true
  379. this.opShow()
  380. }, this.waitOpTime);
  381. }
  382. private opShow() {
  383. this.node.getChildByName("icon").getComponent(BlindsTransitionNodes).playByStep(() => {
  384. // console.log("cccccc");
  385. this.node.getChildByName("content").getComponent(BlindsTransitionNodes).setHide(false)
  386. this.node.getChildByName("content").active = true
  387. this.node.getChildByName("content").getComponent(BlindsTransitionNodes).playReverse(() => {
  388. this.beginTime()
  389. })
  390. })
  391. }
  392. /**
  393. * 开始答题
  394. */
  395. private beginTime() {
  396. this.cancelTime()
  397. this.timeStart = true
  398. this.node.getChildByName("noclick").active = false
  399. this.node.getChildByName("noclick2").active = false
  400. this.node.getChildByName("loadSpine").active = false
  401. // this.schedule(this.timeAlert, this.timeLimit, 0, this.timeLimit);
  402. this.detail.userTime1 = new Date().getTime()//记录用户答题开始时间
  403. this.schedule(this.timeOver, this.timeLimitMax, 0, this.timeLimitMax)
  404. this.node.getChildByName("progress").active = true
  405. this.node.getChildByName("progress").getComponent(TimeProgress).startProgress()
  406. }
  407. /**
  408. * 取消计时
  409. */
  410. private cancelTime() {
  411. // this.unschedule(this.timeAlert);
  412. this.unschedule(this.timeOver)
  413. }
  414. /**
  415. * 开始计时
  416. */
  417. private timeAlert() {
  418. this.node.getChildByName("Label").getComponent(Label).string = "请尽快作答"
  419. this.node.getChildByName("Label").active = true
  420. this.scheduleOnce(function () {
  421. this.node.getChildByName("Label").active = false
  422. }, 3);
  423. }
  424. /**
  425. * 超时,显示正确答案
  426. * 2025-09-29-不显示正确答案,直接进入下一题
  427. */
  428. private timeOver() {
  429. this.node.getChildByName("noclick").active = true
  430. this.detail.userTime2 = new Date().getTime()//记录用户答题结束时间
  431. this.detail.results = 2//记录用户答题是否正确
  432. this.detail.topicEndTime = new Date()//记录题目结束时间
  433. this.detail.userTime2 = new Date().getTime()//记录用户答题结束时间
  434. this.detail.topicMainPic = "图例"
  435. this.detail.topicRightPic = "1"
  436. this.detail.userChosePic = "-1"
  437. // this.rightNodeArr.forEach((tnode) => {
  438. // tnode.getChildByName("duigou").active = true
  439. // })
  440. // this.scheduleOnce(function () {
  441. this.node.getChildByName("progress").getComponent(TimeProgress).stopProgress()
  442. this.totalTimeout++
  443. this.totalQustion++
  444. this.next()
  445. // }, 0.5);
  446. }
  447. //点击答案
  448. private clicked(event, isRight: boolean, ii: number) {
  449. if (!this.isGameing) return
  450. if (!this.canClick) return
  451. this.canClick = false
  452. // this.detail.topicEndTime = formatDate(new Date(), "yyyy-MM-dd HH:mm:ss")//记录题目结束时间
  453. this.detail.topicEndTime = new Date()//记录题目结束时间
  454. this.detail.userTime2 = new Date().getTime()//记录用户答题结束时间
  455. this.detail.topicMainPic = "图例"
  456. this.detail.topicRightPic = "1"
  457. this.detail.userChosePic = ii + ""
  458. this.node.getChildByName("Label").active = false
  459. this.node.getChildByName("progress").getComponent(TimeProgress).stopProgress()
  460. this.totalQustion++
  461. if (isRight) {
  462. this.totalRight++
  463. this.rightCnt++
  464. this.detail.results = 0//记录用户答题是否正确
  465. event.target.getChildByName("duigou").active = true
  466. if (this.rightCnt >= this.optionArr[this.stageLevel][this.turnLevel].rightCnt) {
  467. this.cancelTime()
  468. this.node.getChildByName("noclick").active = true
  469. this.score += this.scoreMax
  470. this.next()
  471. } else {
  472. this.unschedule(this.timeAlert);
  473. }
  474. } else {
  475. this.totalWrong++
  476. this.detail.results = 1//记录用户答题是否正确
  477. this.cancelTime()
  478. // if (this.stageLevel < 5) {
  479. // this.genCenterPic("top")
  480. // } else {
  481. // this.genCenterPic("top")
  482. // }
  483. event.target.getChildByName("chacha").active = true
  484. this.node.getChildByName("noclick").active = true
  485. this.rightNodeArr.forEach((tnode) => {
  486. tnode.getChildByName("duigou").active = true
  487. })
  488. this.scheduleOnce(function () {
  489. this.next()
  490. }, 0.5);
  491. }
  492. this.scheduleOnce(function () {
  493. this.canClick = true
  494. // this.next()
  495. }, 0.5);
  496. }
  497. //回答正确后,进入下一轮
  498. private next() {
  499. const tdata: any = {
  500. "topicStartTime": this.detail.topicStartTime,
  501. "topicEndTime": this.detail.topicEndTime,
  502. "userTime": (this.detail.userTime2 - this.detail.userTime1) / 1000,
  503. "results": this.detail.results,
  504. "topicMainPic": this.detail.topicMainPic,
  505. "topicRightPic": this.detail.topicRightPic,
  506. "userChosePic": this.detail.userChosePic,
  507. "stageLevel": this.turnLevel + 1
  508. }
  509. // const aa =
  510. // console.log("00000000000= " + JSON.stringify(tdata));
  511. this.details.push(tdata)//记录答题数据
  512. // console.log(tdata);
  513. this.isGameing = false
  514. this.timeStart = false
  515. const t = this.timeStep > 15 ? 15 : this.timeStep
  516. this.timeArr.push(t)
  517. this.timeStep = 0
  518. this.node.getChildByName("noclick").active = true
  519. // this.setScore()
  520. this.turnLevel++
  521. if (this.turnLevel >= this.optionArr[this.stageLevel].length) {
  522. this.turnLevel = 0
  523. this.stageLevel++
  524. if ((this.stageLevel >= this.optionArr.length) || (this.stageLevel > this.maxLevel)) {//题目全部做完了
  525. console.log("题目全部做完了");
  526. this.setScore()
  527. } else {
  528. this.showSuccTip()
  529. }
  530. } else {
  531. this.showSuccTip()
  532. }
  533. }
  534. private showSuccTip() {
  535. this.scheduleOnce(function () {
  536. this.initGame()
  537. }, 1);
  538. }
  539. //设置分数显示
  540. private setScore() {
  541. let tTime: number = 0
  542. this.timeArr.forEach((val) => {
  543. tTime += val
  544. })
  545. const aveTime = tTime / this.timeArr.length
  546. const tScore = this.score
  547. UserInfo.score = tScore
  548. UserInfo.aveTime = aveTime
  549. UserInfo.totalRight = this.totalRight
  550. UserInfo.totalWrong = this.totalWrong
  551. UserInfo.totalTimeout = this.totalTimeout
  552. UserInfo.totalQuestion = this.totalQustion
  553. UserInfo.details = this.details
  554. // console.log("000000000= " + JSON.stringify(this.details));
  555. // console.log(JSON.stringify(this.timeArr));
  556. // console.log("00000000000= "+this.score+" "+aveTime);
  557. director.loadScene("sc_result")
  558. }
  559. public noclick() {
  560. }
  561. }