index.html 54 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770
  1. <!doctype html>
  2. <html class="no-js" lang="">
  3. <head>
  4. <meta charset="utf-8">
  5. <meta http-equiv="x-ua-compatible" content="ie=edge">
  6. <title>心灵照相机</title>
  7. <meta name="description"
  8. content="A website that learns to predict where you are looking at. Written in TensorFlow.js">
  9. <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  10. <link rel="stylesheet" href="normalize.css">
  11. <link rel="stylesheet" href="style.css">
  12. <style>
  13. .buttonArr button {
  14. position: fixed;
  15. width: 10px;
  16. height: 1px;
  17. /* opacity: 0.0; */
  18. z-index: 2000;
  19. color: #000000;
  20. border-radius: 10px;
  21. border: 0px;
  22. }
  23. .buttonArr {
  24. position: unset !important;
  25. width: 1px;
  26. height: 0px;
  27. opacity: 0.0;
  28. z-index: 2000;
  29. border-radius: 10px;
  30. border: 0px;
  31. }
  32. #num1 {
  33. position: absolute;
  34. left: 20px;
  35. top: 20px;
  36. }
  37. #num2 {
  38. position: absolute;
  39. left: 33%;
  40. top: 20px;
  41. }
  42. #num3 {
  43. position: absolute;
  44. left: 66%;
  45. top: 20px;
  46. }
  47. #num4 {
  48. position: absolute;
  49. right: 80px;
  50. top: 20px;
  51. }
  52. #num5 {
  53. position: absolute;
  54. left: 20px;
  55. top: 33%;
  56. }
  57. #num6 {
  58. position: absolute;
  59. left: 33%;
  60. top: 33%;
  61. }
  62. #num7 {
  63. position: absolute;
  64. left: 66%;
  65. top: 33%;
  66. }
  67. #num8 {
  68. position: absolute;
  69. right: 80px;
  70. top: 33%;
  71. }
  72. #num9 {
  73. position: absolute;
  74. left: 20px;
  75. top: 66%;
  76. }
  77. #num10 {
  78. position: absolute;
  79. left: 33%;
  80. top: 66%;
  81. }
  82. #num11 {
  83. position: absolute;
  84. left: 66%;
  85. top: 66%;
  86. }
  87. #num12 {
  88. position: absolute;
  89. right: 80px;
  90. top: 66%;
  91. }
  92. #num13 {
  93. position: absolute;
  94. left: 20px;
  95. bottom: 0px;
  96. }
  97. #num14 {
  98. position: absolute;
  99. left: 33%;
  100. bottom: 0px;
  101. }
  102. #num15 {
  103. position: absolute;
  104. left: 66%;
  105. bottom: 0px;
  106. }
  107. #num16 {
  108. position: absolute;
  109. right: 80px;
  110. bottom: 0px;
  111. }
  112. #targetMini {
  113. background-color: #00FF00;
  114. position: absolute;
  115. border-radius: 50%;
  116. height: 55px;
  117. width: 55px;
  118. /* z-index: 0; */
  119. opacity: 0.5;
  120. left: 0;
  121. bottom: 0;
  122. top: 0;
  123. right: 0;
  124. margin: auto;
  125. z-index: 999;
  126. transition: 1s;
  127. transition-timing-function: steps(1000, start);
  128. border: 2.5px solid #000000;
  129. }
  130. #target {
  131. /* text-align: center; */
  132. justify-content: center;
  133. background-image: url('calibrate.png');
  134. background-size: 120px 120px;
  135. /* background-color: lightgreen; */
  136. position: fixed;
  137. /* position: absolute; */
  138. border-radius: 50%;
  139. height: 120px;
  140. width: 120px;
  141. left: 0px;
  142. top: 0px;
  143. transition: left 0.01s, top 0.01s;
  144. box-shadow: 0 0 10px 5px white;
  145. opacity: 0.5;
  146. display: inline-block;
  147. z-index: 999;
  148. }
  149. #targetMini1 {
  150. background-color: #00FF00;
  151. /* position: absolute; */
  152. position: absolute;
  153. border-radius: 50%;
  154. height: 54px;
  155. width: 54px;
  156. /* z-index: 0; */
  157. opacity: 0.6;
  158. left: 0;
  159. bottom: 0;
  160. top: 0;
  161. right: 0;
  162. margin: auto;
  163. z-index: 999;
  164. transition: 1s;
  165. transition-timing-function: steps(1000, start);
  166. border: 3px solid #000000;
  167. }
  168. #target1 {
  169. /* text-align: center; */
  170. justify-content: center;
  171. background-image: url('calibrate.png');
  172. background-size: 60px 60px;
  173. /* background-color: lightgreen; */
  174. position: relative;
  175. /* position: absolute; */
  176. border-radius: 50%;
  177. height: 60px;
  178. width: 60px;
  179. left: 0px;
  180. top: 0px;
  181. transition: left 1s, top 1s;
  182. box-shadow: 0 0 10px 5px white;
  183. opacity: 0.9;
  184. display: inline-block;
  185. z-index: 999;
  186. }
  187. #refresh {
  188. width: 60px;
  189. font-size: 10px;
  190. position: fixed;
  191. top: 0px;
  192. left: 90%;
  193. display: inline-block;
  194. z-index: 999;
  195. margin-left: -40px;
  196. top: 2%;
  197. background-color: rgb(127, 178, 255);
  198. line-height: 30px;
  199. color: aliceblue;
  200. /* border: 1px solid; */
  201. text-align: center;
  202. border-radius: 5px;
  203. cursor: pointer;
  204. }
  205. #exit {
  206. width: 60px;
  207. font-size: 10px;
  208. position: fixed;
  209. top: 0px;
  210. left: 98%;
  211. display: inline-block;
  212. z-index: 999;
  213. margin-left: -40px;
  214. top: 2%;
  215. background-color: rgb(127, 178, 255);
  216. line-height: 30px;
  217. color: aliceblue;
  218. /* border: 1px solid; */
  219. text-align: center;
  220. border-radius: 5px;
  221. cursor: pointer;
  222. /* padding: 5px; */
  223. }
  224. #startCalibration {
  225. position: fixed;
  226. top: 0px;
  227. left: 50%;
  228. display: inline-block;
  229. margin-left: -40px;
  230. top: 30%;
  231. color: aliceblue;
  232. background-color: rgb(127, 178, 255);
  233. width: 80px;
  234. line-height: 40px;
  235. /* border: 1px solid; */
  236. text-align: center;
  237. border-radius: 5px;
  238. cursor: pointer;
  239. padding: 5px;
  240. }
  241. #came {
  242. position: fixed;
  243. top: 5%;
  244. left: 50%;
  245. margin-left: -100px;
  246. color: #ffffff;
  247. /* font-size: 16px;
  248. right:0px;
  249. bottom:0; */
  250. background-color: #666666;
  251. padding-top: 5px;
  252. padding-left: 5px;
  253. padding-right: 5px;
  254. padding-bottom: 5px;
  255. border-radius: 5px;
  256. ;
  257. z-index: 9999
  258. }
  259. </style>
  260. </head>
  261. <body>
  262. <div id="content">
  263. <div class="buttonArr">
  264. <button id='num1'>&nbsp;</button><button id="num2">&nbsp;</button><button id="num3">&nbsp;</button><button
  265. id='num4'>&nbsp;</button><br>
  266. <button id='num5'>&nbsp;</button><button id='num6'>&nbsp;</button><button id='num7'>&nbsp;</button><button
  267. id='num8'>&nbsp;</button><br>
  268. <button id='num9'>&nbsp;</button> <button id='num10'>&nbsp;</button> <button id='num11'>&nbsp;</button> <button
  269. id='num12'>&nbsp;</button><br>
  270. <button id='num13'>&nbsp;</button> <button id='num14'>&nbsp;</button> <button id='num15'>&nbsp;</button> <button
  271. id='num16'>&nbsp;</button>
  272. </div>
  273. <div id="target">
  274. <div id="targetMini"></div>
  275. </div>
  276. <div id="target1">
  277. <div id="targetMini1"></div>
  278. </div>
  279. <canvas id="solar" width="900" height="auto" style="background:#000000;position: fixed; z-index:998"></canvas>
  280. <div id="came">摄像头初始化中稍后再试...</div>
  281. <!-- <div id="finishcalibration" margin-left:300px;position: fixed;top:60px
  282. style="position: fixed;top:20px;left:20px;display: inline-block;width: 80px;height: 17px;border:1px solid;text-align: center;border-radius: 5px;cursor: pointer;padding: 5px;">
  283. 关闭校正</div> onclick="startCal()" -->
  284. <!-- <div id="startCalibration">
  285. 开始校准</div> -->
  286. <div id="exit">
  287. 切换游戏</div>
  288. <div id="refresh">
  289. 重新校验</div>
  290. <canvas id="tracker-canvas"
  291. style="position: fixed;top:0px;left:50%;width:250px;height:200px;margin-left:-125px;"></canvas>
  292. </div>
  293. <!-- <script src="js/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
  294. crossorigin="anonymous"></script> -->
  295. <script src="js/jquery-3.3.1.min.js"></script>
  296. <script src="js/gazefilter.js"></script>
  297. <script src="js/aes.js" type="text/javascript" charset="utf-8"></script>
  298. <!--script src="js/calibration.js"></script-->
  299. <script>
  300. $('#came').hide()
  301. var soundSrc = 'sound/worm1.mp3'
  302. var mp3Url = soundSrc;
  303. var soundFlag = true;
  304. var cameraFlag = true
  305. var player = new Audio(mp3Url);
  306. //点击按钮声音
  307. var soundButtonSrc = 'sound/button.mp3'
  308. var mp3Button = soundButtonSrc
  309. var playerButton = new Audio(mp3Button);
  310. //打虫子音效
  311. var soundHitSrc = 'sound/wormHit.mp3'
  312. var mp3Hit = soundHitSrc
  313. var playerHit = new Audio(mp3Hit)
  314. //背景音乐
  315. var soundBgSrc = 'sound/wormMusicBg.mp3'
  316. var mp3Bg = soundBgSrc
  317. var playerBg = new Audio(mp3Bg)
  318. //总分
  319. var totalScore = 0;
  320. var key = CryptoJS.enc.Utf8.parse("Sp5biS+gX+#CqAFF");//密钥
  321. var iv = CryptoJS.enc.Utf8.parse('ud2E8l6wchltwIDA');
  322. //传输参数为字符串
  323. function Encrypt(word) {
  324. let srcs = CryptoJS.enc.Utf8.parse(word);
  325. let encrypted = CryptoJS.AES.encrypt(srcs, key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 });
  326. return encrypted.ciphertext.toString().toUpperCase();
  327. }
  328. function Decrypt(word) {
  329. let encryptedHexStr = CryptoJS.enc.Hex.parse(word);
  330. let srcs = CryptoJS.enc.Base64.stringify(encryptedHexStr);
  331. let decrypt = CryptoJS.AES.decrypt(srcs, key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 });
  332. let decryptedStr = decrypt.toString(CryptoJS.enc.Utf8);
  333. return decryptedStr.toString();
  334. }
  335. // levelFun(2, 20)
  336. //
  337. //传输关卡和得分的字符串
  338. function levelFun(level, score) {
  339. //1----获取userId
  340. // let userMi = sessionStorage.getItem('B922C64EC97B4FF08485886B2AAEF40C')
  341. // //解密userMi
  342. // let user = Decrypt(userMi)
  343. // //需要传输的参数
  344. // let userId = JSON.parse(user).id
  345. // //2----获取唯一标识
  346. // let associatedFlag = new Date().getTime() + '';
  347. // var params = {
  348. // userId: userId,
  349. // associatedFlag: associatedFlag,
  350. // gameFlag: 'g_ydrzxlzcz',
  351. // checkPoint: level,
  352. // level: level,
  353. // score: score,
  354. // performance: {},
  355. // data: {}
  356. // }
  357. // // Encrypt(JSON.stringify(params))
  358. // // console.log(Encrypt(JSON.stringify(params)))
  359. // //给参数加密
  360. // let paramsMi = Encrypt(JSON.stringify(params))
  361. // // console.log(Decrypt(paramsMi))
  362. // let tokenLin = Decrypt(sessionStorage.getItem(Encrypt('token'))) || '';
  363. // $.ajax({
  364. // url: "https://child.jue-ming.com:8060/gameLevelRecord/saveResult", //请求接口的地址
  365. // type: "POST",
  366. // contentType: "json/application",
  367. // dataType: 'json', //请求的方法GET/POST
  368. // data: JSON.stringify({ data: paramsMi }),
  369. // headers: {
  370. // 'Authorization': "Bearer " + tokenLin,
  371. // }, //需要传递的参数
  372. // success: function (res) {
  373. // res = Decrypt(res)
  374. // //调用解密方法 //请求成功后的操作
  375. // //在控制台输出返回结果
  376. // },
  377. // error: function (err) { //请求失败后的操作
  378. // //请求失败在控制台输出22
  379. // }
  380. // })
  381. }
  382. function saveResult(score) {
  383. //1----获取userId
  384. let userMi = sessionStorage.getItem('B922C64EC97B4FF08485886B2AAEF40C')
  385. //解密userMi
  386. let user = Decrypt(userMi)
  387. //需要传输的参数
  388. let userId = JSON.parse(user).id
  389. //2----获取唯一标识
  390. let associatedFlag = new Date().getTime() + '';
  391. var params = {
  392. userId: userId,
  393. associatedFlag: associatedFlag,
  394. gameFlag: 'g_ydrzxlzcz',
  395. totalScore: score,
  396. gameName: '眼动认知训练捉虫子'
  397. }
  398. let paramsMi = Encrypt(JSON.stringify(params))
  399. let tokenLin = Decrypt(sessionStorage.getItem(Encrypt('token'))) || '';
  400. $.ajax({
  401. url: "https://child.jue-ming.com:8060/gameRecord/saveResult", //请求接口的地址
  402. type: "POST",
  403. contentType: "json/application",
  404. dataType: 'json', //请求的方法GET/POST
  405. data: JSON.stringify({ data: paramsMi }),
  406. headers: {
  407. 'Authorization': "Bearer " + tokenLin,
  408. }, //需要传递的参数
  409. success: function (res) {
  410. res = Decrypt(res)
  411. //调用解密方法 //请求成功后的操作
  412. //在控制台输出返回结果
  413. },
  414. error: function (err) { //请求失败后的操作
  415. //请求失败在控制台输出22
  416. }
  417. })
  418. }
  419. //
  420. //切水果游戏变量
  421. let apple;
  422. let appleLeft;
  423. let appleRight;
  424. let banana;
  425. let bananaLeft;
  426. let bananaRight;
  427. let sandia;
  428. let sandiaLeft;
  429. let sandiaRight;
  430. let basaha;
  431. let basahaLeft;
  432. let basahaRight;
  433. let bg;
  434. let ctx;
  435. let widthLeft;
  436. //退出按钮
  437. let button1;
  438. let button2;
  439. //等于1时代表在水果游戏页面
  440. //等于2时代表在抓虫子页面
  441. let fruitFlag = 2;
  442. //水果下降的速度
  443. let y = [20, 20, 20, 20];
  444. let speed = [1, 1.5, 1.3, 1.4];
  445. let x = [100, 300, 500, 700]
  446. let rondom;
  447. let timer;
  448. //设置水果的起点
  449. let fruitStart = 10
  450. //设置说过的结尾
  451. let fruitEnd = 900;
  452. //是否隐藏
  453. let flag = [true, true, true, true]
  454. //苹果左右碎片
  455. let apple_x_left = x[0];
  456. let apple_x_right = x[0];
  457. let banana_x_left = x[1];
  458. let banana_x_right = x[1]
  459. let sandia_x_left = x[2];
  460. let sandia_x_right = x[2]
  461. let basaha_x_left = x[3];
  462. let basaha_x_right = x[3];
  463. let targ = [0, 0]
  464. let tempCanvasFruit;
  465. let tempCtxFruit;
  466. let patternFruit;
  467. //水果倒计时初始时间
  468. let startTimeFruit;
  469. //设置倒计时结束时间
  470. let endTimeFruit;
  471. let canvas = document.getElementById('solar');
  472. ctx = canvas.getContext("2d");
  473. window.addEventListener("resize", resizeCanvas, false);
  474. let countdownFlag = false;
  475. let diff = 1;
  476. let count = 0
  477. //第几关进行提示
  478. let diffFlag = false;
  479. //通关提示
  480. //当passFlag默认为1为正常状态
  481. //当passFlag为2时为超时未通过状态
  482. //当passFlag为3时为已通关状态
  483. let passFlag = 1;
  484. //训练提示页flag
  485. let trainingFlag = 1
  486. //第一张训练图片
  487. let trainOne;
  488. let trainTwo;
  489. let trainThree;
  490. let trainFour;
  491. let onStep;
  492. let underStep;
  493. let startGame;
  494. let backMa;
  495. //canvas监听事件
  496. canvas.addEventListener("mouseup", clickButton);
  497. function resizeCanvas() {
  498. canvas.width = window.innerWidth;
  499. x = [canvas.width / 5, canvas.width / 5 * 2, canvas.width / 5 * 3, canvas.width / 5 * 4]
  500. xWorm = [canvas.width / 5, canvas.width / 5 * 2, canvas.width / 5 * 3, canvas.width / 5 * 4]
  501. // canvas.height = window.innerHeight;
  502. canvas.height = window.innerHeight;
  503. fruitEnd = canvas.height
  504. wormStart = canvas.height
  505. //canvas.height = '100vh';
  506. apple_x_left = x[0];
  507. apple_x_right = x[0];
  508. banana_x_left = x[1];
  509. banana_x_right = x[1]
  510. sandia_x_left = x[2];
  511. sandia_x_right = x[2]
  512. basaha_x_left = x[3];
  513. basaha_x_right = x[3];
  514. }
  515. //获取
  516. // initWorm()
  517. //初始化切水果的图
  518. //第几关2秒显示
  519. function middleFont() {
  520. diffFlag = true;
  521. setTimeout(() => {
  522. diffFlag = false;
  523. }, 2000);
  524. }
  525. function soundChange() {
  526. if (soundFlag) {
  527. soundOpen()
  528. } else {
  529. soundClose()
  530. }
  531. }
  532. function clickButton(event) {
  533. //鼠标在当前画布的位置
  534. // let x1 = event.clientX;
  535. // let y1 = event.clientY;
  536. let x = event.clientX - canvas.getBoundingClientRect().left;
  537. let y = event.clientY - canvas.getBoundingClientRect().top;
  538. //判断点是否在长方形内
  539. //当在第一步训练时 只有一个按钮下一步的按钮
  540. if (trainingFlag == 1) {
  541. if (x > (canvas.width / 2 - 80) && x < (canvas.width / 2 + 80) && y > (canvas.height / 2 + 100) && y < (canvas.height / 2 + +100 + 80)) {
  542. // ctx.drawImage(underStep, canvas.width / 2 - 80, canvas.height / 2 + 100, 160, 80);
  543. soundButtonOpen()
  544. soundSrc = 'sound/worm1.mp3'
  545. soundClose()
  546. if (soundFlag) {
  547. soundOpen()
  548. }
  549. trainingFlag = 2
  550. }
  551. } else if (trainingFlag == 2) { //当在第二步训练时 有上一步下一步按钮
  552. //当是在点击声音播放声音时
  553. if (x > (canvas.width - widthLeft - 90) && x < (canvas.width - widthLeft - 58) && y > (30) && y < (76)) {
  554. // ctx.drawImage(underStep, canvas.width / 2 - 80, canvas.height / 2 + 100, 160, 80);
  555. soundButtonOpen()
  556. soundFlag = !soundFlag
  557. soundChange()
  558. }
  559. // 上一步按钮
  560. if (x > (canvas.width / 2 - 200) && x < (canvas.width / 2 + 40) && y > (canvas.height / 2 + 220) && y < (canvas.height / 2 + 220 + 80)) {
  561. // ctx.drawImage(underStep, canvas.width / 2 - 80, canvas.height / 2 + 100, 160, 80);
  562. soundButtonOpen()
  563. trainingFlag = 1
  564. soundClose()
  565. }
  566. // ctx.drawImage(onStep, canvas.width / 2 - 200, canvas.height / 2 + 100, 160, 80);
  567. // 下一步按钮
  568. if (x > (canvas.width / 2 + 40) && x < (canvas.width / 2 + 200) && y > (canvas.height / 2 + 220) && y < (canvas.height / 2 + 220 + 80)) {
  569. // ctx.drawImage(underStep, canvas.width / 2 - 80, canvas.height / 2 + 100, 160, 80);
  570. soundButtonOpen()
  571. trainingFlag = 3
  572. soundClose()
  573. soundSrc = 'sound/worm2.mp3'
  574. if (soundFlag) {
  575. soundOpen()
  576. }
  577. }
  578. // ctx.drawImage(underStep, canvas.width / 2 + 40, canvas.height / 2 + 100, 160, 80);
  579. } else if (trainingFlag == 3) {
  580. //当是在点击声音播放声音时
  581. if (x > (canvas.width - widthLeft - 90) && x < (canvas.width - widthLeft - 58) && y > (30) && y < (76)) {
  582. soundButtonOpen()
  583. soundFlag = !soundFlag
  584. soundChange()
  585. // ctx.drawImage(underStep, canvas.width / 2 - 80, canvas.height / 2 + 100, 160, 80);
  586. // soundOpen()
  587. }
  588. // 上一步按钮
  589. if (x > (canvas.width / 2 - 200) && x < (canvas.width / 2 + 40) && y > (canvas.height / 2 + 220) && y < (canvas.height / 2 + 220 + 80)) {
  590. // ctx.drawImage(underStep, canvas.width / 2 - 80, canvas.height / 2 + 100, 160, 80);
  591. soundButtonOpen()
  592. soundSrc = 'sound/worm1.mp3'
  593. soundClose()
  594. if (soundFlag) {
  595. soundOpen()
  596. }
  597. trainingFlag = 2
  598. }
  599. // ctx.drawImage(onStep, canvas.width / 2 - 200, canvas.height / 2 + 100, 160, 80);
  600. // 下一步按钮
  601. if (x > (canvas.width / 2 + 40) && x < (canvas.width / 2 + 200) && y > (canvas.height / 2 + 220) && y < (canvas.height / 2 + 220 + 80)) {
  602. // ctx.drawImage(underStep, canvas.width / 2 - 80, canvas.height / 2 + 100, 160, 80);
  603. // soundClose()
  604. // calibrationAccuracy()
  605. soundBgOpen()
  606. soundButtonOpen()
  607. if (cameraFlag) {
  608. soundClose()
  609. calibrationAccuracy()
  610. } else {
  611. $('#came').show()
  612. setTimeout(() => {
  613. $('#came').hide()
  614. }, 2000);
  615. }
  616. }
  617. } else if (trainingFlag == 4) {
  618. if (x > (canvas.width / 2 - 80) && x < (canvas.width / 2 + 80) && y > (canvas.height / 2 + 220) && y < (canvas.height / 2 + 220 + 80)) {
  619. // ctx.drawImage(underStep, canvas.width / 2 - 80, canvas.height / 2 + 100, 160, 80);
  620. soundButtonOpen()
  621. soundBgClose()
  622. trainingFlag = 1
  623. $('#target').hide()
  624. // init()
  625. }
  626. }
  627. //ctx.drawImage(backMa, 20, 20, 40, 30);
  628. if (x > widthLeft + 40 && x < widthLeft + 98 && y > 30 && y < 76) {
  629. soundButtonOpen()
  630. //点击退出按钮就返回到感统综合页面即可
  631. // window.location.href = 'http://49.232.79.112:8088/home'
  632. //http://localhost:8084/gameRecord/saveResult
  633. // window.location.href = 'http://child.jue-ming.com/home'
  634. window.location.href = 'https://org.jue-ming.com/welcome/mainTable'
  635. }
  636. }
  637. function init() {
  638. middleFont()
  639. //第一张训练图片
  640. trainOne = new Image();
  641. trainTwo = new Image();
  642. trainThree = new Image();
  643. trainFour = new Image();
  644. onStep = new Image();
  645. underStep = new Image()
  646. startGame = new Image();
  647. backMa = new Image();
  648. button1 = new Image;
  649. //苹果
  650. apple = new Image();
  651. //苹果碎片
  652. appleLeft = new Image();
  653. appleRight = new Image();
  654. //香蕉
  655. banana = new Image();
  656. bananaLeft = new Image();
  657. bananaRight = new Image();
  658. //西瓜
  659. sandia = new Image();
  660. sandiaLeft = new Image();
  661. sandiaRight = new Image();
  662. //草莓
  663. basaha = new Image();
  664. basahaLeft = new Image();
  665. basahaRight = new Image();
  666. bg = new Image();
  667. trainOne.src = './image/fruit1.png'
  668. trainTwo.src = './image/fruit2.png'
  669. trainThree.src = './image/fruit3.png'
  670. trainFour.src = './image/fruit4.png'
  671. onStep.src = './image/onStep.png'
  672. underStep.src = './image/underStep.png'
  673. startGame.src = './image/startGame.png'
  674. backMa.src = './image/backMa.png'
  675. button1.src = './image/button1.png'
  676. apple.src = "./image/apple.png";
  677. appleLeft.src = './image/apple-1.png';
  678. appleRight.src = './image/apple-2.png';
  679. banana.src = './image/banana.png';
  680. bananaLeft.src = './image/banana-1.png';
  681. bananaRight.src = './image/banana-2.png';
  682. sandia.src = './image/sandia.png'
  683. sandiaLeft.src = './image/sandia-2.png'
  684. sandiaRight.src = './image/sandia-1.png'
  685. basaha.src = './image/basaha.png'
  686. basahaLeft.src = './image/basaha-2.png'
  687. basahaRight.src = './image/basaha-1.png'
  688. bg.src = './image/background.png'
  689. //canvas =
  690. //let canvas = document.querySelector("#solar");
  691. apple.onload = function () {
  692. //设置初始时间
  693. countdown()
  694. draw()
  695. }
  696. // bg.onload = imgFn;
  697. }
  698. //初始化虫子的变量
  699. //虫子1
  700. let wormOne;
  701. //虫子二
  702. let wormTwo;
  703. //虫子3
  704. let wormThree;
  705. //虫子4
  706. let wormFour;
  707. let bgtree;
  708. let timerWorm;
  709. //水果下降的速度
  710. let yWorm = [600, 600, 600, 600];
  711. let speedWorm = [1, 1.5, 1.3, 1.4];
  712. let xWorm = [100, 300, 500, 700]
  713. //设置虫子的起点
  714. let wormStart = 600
  715. //设置说过的结尾
  716. let wormEnd = 20;
  717. let tempCanvas;
  718. let tempCtx;
  719. let pattern
  720. //初始化抓虫子的图
  721. //声音的图片
  722. let soundImgClose;
  723. let soundImgOpen;
  724. //成功图片
  725. let success;
  726. function initWorm() {
  727. //第一张训练图片
  728. trainOne = new Image();
  729. trainTwo = new Image();
  730. trainThree = new Image();
  731. trainFour = new Image();
  732. onStep = new Image();
  733. underStep = new Image()
  734. startGame = new Image();
  735. backMa = new Image();
  736. soundImgClose = new Image();
  737. soundImgOpen = new Image();
  738. success = new Image()
  739. wormOne = new Image();
  740. wormTwo = new Image();
  741. wormThree = new Image();
  742. wormFour = new Image();
  743. bgtree = new Image();
  744. wormOne.src = './image/bug1.png';
  745. wormTwo.src = './image/bug2.png';
  746. wormThree.src = './image/bug3.png';
  747. wormFour.src = './image/bug4.png';
  748. bgtree.src = './image/tree.png'
  749. wormFlag = [true, true, true, true]
  750. trainOne.src = './image/worm1.png'
  751. trainTwo.src = './image/worm2.png'
  752. trainThree.src = './image/worm3.png'
  753. trainFour.src = './image/worm4.png'
  754. success.src = './image/success.png'
  755. onStep.src = './image/onStep.png'
  756. underStep.src = './image/underStep.png'
  757. startGame.src = './image/startGame.png'
  758. backMa.src = './image/backMa.png'
  759. soundImgClose.src = './image/close.png'
  760. soundImgOpen.src = './image/open.png'
  761. bgtree.onload = function () {
  762. countdown()
  763. //先把加载好的图片绘制在一个临时的画布上
  764. drawWorm()
  765. }
  766. }
  767. //画虫子
  768. function drawWorm() {
  769. widthLeft = (canvas.width - (1270 / 714 * canvas.height)) / 2
  770. if (trainingFlag == 1) {
  771. tempCanvasFruit = document.createElement('canvas');
  772. tempCanvasFruit.width = canvas.width;
  773. tempCanvasFruit.height = canvas.height;
  774. tempCtxFruit = tempCanvasFruit.getContext('2d');
  775. tempCtxFruit.drawImage(trainOne, widthLeft, 0, 1270 / 714 * canvas.height, canvas.height);
  776. patternFruit = ctx.createPattern(tempCanvasFruit, 'repeat');
  777. ctx.fillStyle = patternFruit;
  778. ctx.fillRect(0, 0, canvas.width, canvas.height);
  779. //增加下一步的按钮。点击后将trainningFlag设置2
  780. ctx.drawImage(underStep, canvas.width / 2 - 80, canvas.height / 2 + 100, 160, 80);
  781. //返回按钮
  782. //ctx.drawImage(backMa, 20, 20, 40, 30);
  783. ctx.drawImage(backMa, widthLeft + 40, 30, 58, 46);
  784. }
  785. if (trainingFlag == 2) {
  786. tempCanvasFruit = document.createElement('canvas');
  787. tempCanvasFruit.width = canvas.width;
  788. tempCanvasFruit.height = canvas.height;
  789. tempCtxFruit = tempCanvasFruit.getContext('2d');
  790. tempCtxFruit.drawImage(trainTwo, widthLeft, 0, 1270 / 714 * canvas.height, canvas.height);
  791. patternFruit = ctx.createPattern(tempCanvasFruit, 'repeat');
  792. ctx.fillStyle = patternFruit;
  793. ctx.fillRect(0, 0, canvas.width, canvas.height);
  794. ctx.drawImage(trainThree, (canvas.width - (canvas.width / 2 + 200)) / 2, 80, canvas.width / 2 + 200, canvas.height / 2 + 130);
  795. // ctx.drawImage(trainThree, (canvas.width - canvas.width / 2) / 2, 100, canvas.width / 2, canvas.height / 2 + 100);
  796. //上一步按钮
  797. ctx.drawImage(onStep, canvas.width / 2 - 200, canvas.height / 2 + 220, 160, 80);
  798. //下一步按钮
  799. ctx.drawImage(underStep, canvas.width / 2 + 40, canvas.height / 2 + 220, 160, 80);
  800. //返回按钮
  801. ctx.drawImage(backMa, widthLeft + 40, 30, 58, 46);
  802. if (soundFlag) {
  803. ctx.drawImage(soundImgOpen, canvas.width - widthLeft - 90, 30, 58, 46);
  804. // ctx.drawImage(soundImgOpen, canvas.width - 60, 20, 40, 30);
  805. } else {
  806. //ctx.drawImage(soundImgClose, canvas.width - 60, 20, 40, 30);
  807. ctx.drawImage(soundImgClose, canvas.width - widthLeft - 90, 30, 58, 46);
  808. }
  809. }
  810. if (trainingFlag == 3) {
  811. tempCanvasFruit = document.createElement('canvas');
  812. tempCanvasFruit.width = canvas.width;
  813. tempCanvasFruit.height = canvas.height;
  814. tempCtxFruit = tempCanvasFruit.getContext('2d');
  815. tempCtxFruit.drawImage(trainTwo, widthLeft, 0, 1270 / 714 * canvas.height, canvas.height);
  816. patternFruit = ctx.createPattern(tempCanvasFruit, 'repeat');
  817. ctx.fillStyle = patternFruit;
  818. ctx.fillRect(0, 0, canvas.width, canvas.height);
  819. ctx.drawImage(trainFour, (canvas.width - (canvas.width / 2 + 200)) / 2, 80, canvas.width / 2 + 200, canvas.height / 2 + 130);
  820. //ctx.drawImage(trainFour, (canvas.width - canvas.width / 2) / 2, 100, canvas.width / 2, canvas.height / 2 + 100);
  821. //上一步按钮
  822. ctx.drawImage(onStep, canvas.width / 2 - 200, canvas.height / 2 + 220, 160, 80);
  823. //下一步按钮countdownFlag
  824. ctx.drawImage(underStep, canvas.width / 2 + 40, canvas.height / 2 + 220, 160, 80);
  825. //返回按钮
  826. ctx.drawImage(backMa, widthLeft + 40, 30, 58, 46);
  827. // ctx.drawImage(soundImgOpen, canvas.width - 60, 20, 40, 30)
  828. if (soundFlag) {
  829. ctx.drawImage(soundImgOpen, canvas.width - widthLeft - 90, 30, 58, 46);
  830. // ctx.drawImage(soundImgOpen, canvas.width - 60, 20, 40, 30);
  831. } else {
  832. //ctx.drawImage(soundImgClose, canvas.width - 60, 20, 40, 30);
  833. ctx.drawImage(soundImgClose, canvas.width - widthLeft - 90, 30, 58, 46);
  834. }
  835. }
  836. if (trainingFlag == 4) {
  837. ctx.fillRect(0, 0, canvas.width, canvas.height)
  838. tempCanvas = document.createElement('canvas');
  839. tempCanvas.width = canvas.width;
  840. tempCanvas.height = canvas.height;
  841. tempCtx = tempCanvas.getContext('2d');
  842. tempCtx.drawImage(bgtree, 0, 0, canvas.width, canvas.height);
  843. pattern = ctx.createPattern(tempCanvas, 'repeat');
  844. ctx.fillStyle = pattern;
  845. ctx.fillRect(0, 0, canvas.width, canvas.height);
  846. ctx.drawImage(backMa, widthLeft + 40, 30, 58, 46);
  847. var gradient = ctx.createLinearGradient(0, 0, 100, 0);
  848. if (countdownFlag) {
  849. gradient.addColorStop("1.0", "#D1BBFF");
  850. // Fill with gradient
  851. ctx.strokeStyle = gradient;
  852. ctx.font = "30px Arial";
  853. ctx.strokeText("倒计时:" + countdown(), canvas.width - 240, 100);
  854. gradient.addColorStop("1.0", "#D1BBFF");
  855. // Fill with gradient
  856. ctx.strokeStyle = gradient;
  857. ctx.font = "30px Arial";
  858. ctx.strokeText("第" + diff + '关', 100, 100);
  859. ctx.font = "30px Arial";
  860. ctx.strokeText("得分:" + count, canvas.width - 240, 150);
  861. ctx.drawImage(backMa, widthLeft + 40, 30, 58, 46);
  862. // ctx.fillText("Hello World", 10, 50);
  863. //切水果倒计时三分钟
  864. //初始化
  865. }
  866. if (diffFlag) {
  867. gradient.addColorStop("1.0", "#D1BBFF");
  868. // Fill with gradient
  869. ctx.strokeStyle = gradient;
  870. ctx.font = "80px Arial";
  871. ctx.strokeText("第 " + diff + ' 关', canvas.width / 2 - 120, canvas.height / 2 - 100);
  872. }
  873. if (passFlag == 2) {
  874. gradient.addColorStop("1.0", "red");
  875. // Fill with gradient
  876. ctx.strokeStyle = gradient;
  877. ctx.font = "20px Arial";
  878. ctx.strokeText("很遗憾您已超时,继续加油!", canvas.width / 2 - 100, canvas.height / 2 - 100);
  879. countdownFlag = false;
  880. diffFlag = false;
  881. //ctx.drawImage(startGame, canvas.width / 2 - 80, canvas.height / 2 + 100, 160, 80);
  882. ctx.drawImage(startGame, canvas.width / 2 - 80, canvas.height / 2 + 220, 160, 80);
  883. //重新开始按钮 //或返回主页
  884. // ctx.drawImage(button1, canvas.width / 2 - 200, canvas.height / 2 + 100, 60, 30);
  885. }
  886. if (passFlag == 3) {
  887. gradient.addColorStop("1.0", "#D1BBFF");
  888. // Fill with gradient
  889. ctx.strokeStyle = gradient;
  890. // ctx.font = "50px Arial";
  891. // ctx.strokeText("您已通关!!!", canvas.width / 2 - 120, canvas.height / 2 - 100);success
  892. ctx.drawImage(success, canvas.width / 2 - 325, 10);
  893. ctx.drawImage(startGame, canvas.width / 2 - 80, canvas.height / 2 + 220, 160, 80);
  894. // ctx.drawImage(success, canvas.width / 2 - 120, canvas.height / 2 - 100);
  895. // ctx.drawImage(startGame, canvas.width / 2 - 80, canvas.height / 2 + 100, 160, 80);
  896. countdownFlag = false;
  897. diffFlag = false;
  898. //重新开始按钮 //或返回主页
  899. // ctx.drawImage(button1, canvas.width / 2 - 200, canvas.height / 2 + 100, 60, 30);
  900. }
  901. // ctx.font = "40px Arial";
  902. // ctx.strokeText("Hello World", 10, 50);
  903. // ctx.fillText("Hello World", 10, 50);
  904. //虫子1
  905. ctx.drawImage(wormOne, xWorm[0], yWorm[0], 60, 60);
  906. ctx.drawImage(wormTwo, xWorm[1], yWorm[1], 60, 60);
  907. //虫子三
  908. ctx.drawImage(wormThree, xWorm[2], yWorm[2], 60, 60);
  909. //虫子4
  910. ctx.drawImage(wormFour, xWorm[3], yWorm[3], 60, 60);
  911. let random = Math.random() + 1
  912. if (wormFlag[0]) {
  913. yWorm[0] = yWorm[0] - speedWorm[0] * random
  914. } else {
  915. yWorm[0] = yWorm[0] + speedWorm[0] * random * 1.5
  916. }
  917. if (yWorm[0] < wormEnd || yWorm[0] > wormStart) {
  918. yWorm[0] = wormStart
  919. wormFlag[0] = true
  920. random = Math.random() + 1
  921. }
  922. if (wormFlag[1]) {
  923. yWorm[1] = yWorm[1] - speedWorm[1] * random
  924. } else {
  925. yWorm[1] = yWorm[1] + speedWorm[1] * random * 1.5
  926. }
  927. //yWorm[1] = yWorm[1] - speedWorm[1] * random
  928. if (yWorm[1] < wormEnd || yWorm[1] > wormStart) {
  929. yWorm[1] = wormStart
  930. wormFlag[1] = true;
  931. random = Math.random() + 1
  932. }
  933. if (wormFlag[2]) {
  934. yWorm[2] = yWorm[2] - speedWorm[2] * random
  935. } else {
  936. yWorm[2] = yWorm[2] + speedWorm[2] * random * 1.5
  937. }
  938. //yWorm[2] = yWorm[2] - speedWorm[2] * random
  939. if (yWorm[2] < wormEnd || yWorm[2] > wormStart) {
  940. yWorm[2] = wormStart
  941. wormFlag[2] = true;
  942. random = Math.random() + 1
  943. }
  944. if (wormFlag[3]) {
  945. yWorm[3] = yWorm[3] - speedWorm[3] * random
  946. } else {
  947. yWorm[3] = yWorm[3] + speedWorm[3] * random * 1.5
  948. }
  949. if (yWorm[3] < wormEnd || yWorm[3] > wormStart) {
  950. yWorm[3] = wormStart
  951. wormFlag[3] = true;
  952. random = Math.random() + 1
  953. }
  954. let first = [xWorm[0] + 30, yWorm[0] + 30]
  955. //第二列中心点坐标
  956. let second = [xWorm[1] + 30, yWorm[1] + 30]
  957. let third = [xWorm[2] + 30, yWorm[2] + 30]
  958. let four = [xWorm[3] + 30, yWorm[3] + 30]
  959. collision(first, second, third, four)
  960. }
  961. timerWorm = requestAnimationFrame(drawWorm);
  962. if (fruitFlag !== 2) {
  963. window.cancelAnimationFrame(timerWorm)
  964. ctx.clearRect(0, 0, canvas.width, canvas.height); //清空所有的内容
  965. }
  966. }
  967. function soundClose() {
  968. player.pause()
  969. }
  970. function soundOpen() {
  971. mp3Url = soundSrc;
  972. player = new Audio(mp3Url);
  973. player.play()
  974. }
  975. //按钮点击音效
  976. function soundButtonOpen() {
  977. playerButton.play()
  978. }
  979. //捉虫子音效
  980. function soundHitOpen() {
  981. playerHit.play()
  982. }
  983. //背景音乐音效
  984. function soundBgOpen() {
  985. playerBg.play()
  986. playerBg.loop = true;
  987. }
  988. function soundBgClose() {
  989. playerBg.pause()
  990. }
  991. function draw() {
  992. ctx.clearRect(0, 0, canvas.width, canvas.height); //清空所有的内容
  993. // let a = ctx.createPattern(bg, 'repeat')
  994. // ctx.fillStyle = a;
  995. // ctx.fillRect(0, 0, canvas.width, canvas.height)
  996. /*绘制 太阳*/
  997. tempCanvasFruit = document.createElement('canvas');
  998. tempCanvasFruit.width = canvas.width;
  999. tempCanvasFruit.height = canvas.height;
  1000. tempCtxFruit = tempCanvasFruit.getContext('2d');
  1001. tempCtxFruit.drawImage(bg, 0, 0, canvas.width, canvas.height);
  1002. patternFruit = ctx.createPattern(tempCanvasFruit, 'repeat');
  1003. ctx.fillStyle = patternFruit;
  1004. ctx.fillRect(0, 0, canvas.width, canvas.height);
  1005. if (trainingFlag == 1) {
  1006. tempCanvasFruit = document.createElement('canvas');
  1007. tempCanvasFruit.width = canvas.width;
  1008. tempCanvasFruit.height = canvas.height;
  1009. tempCtxFruit = tempCanvasFruit.getContext('2d');
  1010. tempCtxFruit.drawImage(trainOne, 0, 0, canvas.width, canvas.height);
  1011. patternFruit = ctx.createPattern(tempCanvasFruit, 'repeat');
  1012. ctx.fillStyle = patternFruit;
  1013. ctx.fillRect(0, 0, canvas.width, canvas.height);
  1014. //增加下一步的按钮。点击后将trainningFlag设置2
  1015. ctx.drawImage(underStep, canvas.width / 2 - 80, canvas.height / 2 + 100, 160, 80);
  1016. //返回按钮
  1017. ctx.drawImage(backMa, 20, 20, 40, 30);
  1018. }
  1019. if (trainingFlag == 2) {
  1020. tempCanvasFruit = document.createElement('canvas');
  1021. tempCanvasFruit.width = canvas.width;
  1022. tempCanvasFruit.height = canvas.height;
  1023. tempCtxFruit = tempCanvasFruit.getContext('2d');
  1024. tempCtxFruit.drawImage(trainTwo, 0, 0, canvas.width, canvas.height);
  1025. patternFruit = ctx.createPattern(tempCanvasFruit, 'repeat');
  1026. ctx.fillStyle = patternFruit;
  1027. ctx.fillRect(0, 0, canvas.width, canvas.height);
  1028. ctx.drawImage(trainThree, (canvas.width - canvas.width / 2) / 2, 100, canvas.width / 2, canvas.height / 2 + 100);
  1029. //上一步按钮
  1030. ctx.drawImage(onStep, canvas.width / 2 - 200, canvas.height / 2 + 100, 160, 80);
  1031. //下一步按钮
  1032. ctx.drawImage(underStep, canvas.width / 2 + 40, canvas.height / 2 + 100, 160, 80);
  1033. //返回按钮
  1034. ctx.drawImage(backMa, 20, 20, 40, 30);
  1035. }
  1036. if (trainingFlag == 3) {
  1037. tempCanvasFruit = document.createElement('canvas');
  1038. tempCanvasFruit.width = canvas.width;
  1039. tempCanvasFruit.height = canvas.height;
  1040. tempCtxFruit = tempCanvasFruit.getContext('2d');
  1041. tempCtxFruit.drawImage(trainTwo, 0, 0, canvas.width, canvas.height);
  1042. patternFruit = ctx.createPattern(tempCanvasFruit, 'repeat');
  1043. ctx.fillStyle = patternFruit;
  1044. ctx.fillRect(0, 0, canvas.width, canvas.height);
  1045. ctx.drawImage(trainFour, (canvas.width - canvas.width / 2) / 2, 100, canvas.width / 2, canvas.height / 2 + 100);
  1046. //上一步按钮
  1047. ctx.drawImage(onStep, canvas.width / 2 - 200, canvas.height / 2 + 100, 160, 80);
  1048. //下一步按钮
  1049. ctx.drawImage(underStep, canvas.width / 2 + 40, canvas.height / 2 + 100, 160, 80);
  1050. //返回按钮
  1051. ctx.drawImage(backMa, 20, 20, 40, 30);
  1052. }
  1053. if (trainingFlag == 4) {
  1054. var gradient = ctx.createLinearGradient(0, 0, 100, 0);
  1055. //返回按钮
  1056. ctx.drawImage(backMa, 20, 20, 40, 30);
  1057. if (countdownFlag) {
  1058. gradient.addColorStop("1.0", "#D1BBFF");
  1059. // Fill with gradient
  1060. ctx.strokeStyle = gradient;
  1061. ctx.font = "30px Arial";
  1062. ctx.strokeText("倒计时:" + countdown(), canvas.width - 240, 100);
  1063. gradient.addColorStop("1.0", "#D1BBFF");
  1064. // Fill with gradient
  1065. ctx.strokeStyle = gradient;
  1066. ctx.font = "30px Arial";
  1067. ctx.strokeText("第" + diff + '关', 100, 100);
  1068. ctx.font = "30px Arial";
  1069. ctx.strokeText("得分:" + count, canvas.width - 240, 150);
  1070. // ctx.fillText("Hello World", 10, 50);
  1071. //切水果倒计时三分钟
  1072. //初始化
  1073. }
  1074. if (diffFlag) {
  1075. gradient.addColorStop("1.0", "yellow");
  1076. // Fill with gradient
  1077. ctx.strokeStyle = gradient;
  1078. ctx.font = "80px Arial";
  1079. ctx.strokeText("第 " + diff + ' 关', canvas.width / 2 - 120, canvas.height / 2 - 100);
  1080. }
  1081. if (passFlag == 2) {
  1082. gradient.addColorStop("1.0", "red");
  1083. // Fill with gradient
  1084. ctx.strokeStyle = gradient;
  1085. ctx.font = "20px Arial";
  1086. ctx.strokeText("很遗憾您已超时,继续加油!", canvas.width / 2 - 100, canvas.height / 2 - 100);
  1087. ctx.drawImage(startGame, canvas.width / 2 - 80, canvas.height / 2 + 100, 160, 80);
  1088. countdownFlag = false;
  1089. diffFlag = false;
  1090. //重新开始按钮 //或返回主页
  1091. //ctx.drawImage(button1, canvas.width / 2 - 200, canvas.height / 2 + 100, 60, 30);
  1092. }
  1093. if (passFlag == 3) {
  1094. gradient.addColorStop("1.0", "yellow");
  1095. // Fill with gradient
  1096. ctx.strokeStyle = gradient;
  1097. ctx.font = "20px Arial";
  1098. ctx.strokeText("您已通关!!!", canvas.width / 2 - 100, canvas.height / 2 - 100);
  1099. ctx.drawImage(startGame, canvas.width / 2 - 80, canvas.height / 2 + 100, 160, 80);
  1100. countdownFlag = false;
  1101. diffFlag = false;
  1102. //重新开始按钮 //或返回主页
  1103. // ctx.drawImage(button1, canvas.width / 2 - 200, canvas.height / 2 + 100, 60, 30);
  1104. }
  1105. // ctx.drawImage(button1, canvas.width / 2 - 100, canvas.height / 2 + 100, 100, 40);
  1106. // ctx.drawImage(button1, canvas.width / 2 + 100, canvas.height / 2 + 100, 100, 40);
  1107. if (flag[0]) {
  1108. ctx.drawImage(apple, x[0], y[0], 60, 60);
  1109. getColl()
  1110. } else {
  1111. apple_x_left += 0.5
  1112. apple_x_right -= 0.5
  1113. ctx.drawImage(appleLeft, apple_x_right, y[0], 60, 60);
  1114. ctx.drawImage(appleRight, apple_x_left, y[0], 60, 60);
  1115. }
  1116. if (flag[1]) {
  1117. ctx.drawImage(banana, x[1], y[1], 60, 30);
  1118. getColl()
  1119. } else {
  1120. banana_x_left += 0.5
  1121. banana_x_right -= 0.5
  1122. ctx.drawImage(bananaLeft, banana_x_left, y[1], 60, 30);
  1123. ctx.drawImage(bananaRight, banana_x_right, y[1], 60, 30);
  1124. }
  1125. if (flag[2]) {
  1126. ctx.drawImage(sandia, x[2], y[2], 60, 60);
  1127. getColl()
  1128. } else {
  1129. sandia_x_left += 0.5
  1130. sandia_x_right -= 0.5
  1131. ctx.drawImage(sandiaLeft, sandia_x_left, y[2], 60, 60);
  1132. ctx.drawImage(sandiaRight, sandia_x_right, y[2], 60, 60);
  1133. }
  1134. if (flag[3]) {
  1135. ctx.drawImage(basaha, x[3], y[3], 60, 60);
  1136. getColl()
  1137. } else {
  1138. basaha_x_left += 0.5
  1139. basaha_x_right -= 0.5
  1140. ctx.drawImage(basahaLeft, basaha_x_left, y[3], 60, 60);
  1141. ctx.drawImage(basahaRight, basaha_x_right, y[3], 60, 60);
  1142. }
  1143. random = Math.random() + 1
  1144. y[0] = y[0] + speed[0] * random
  1145. if (y[0] > fruitEnd) {
  1146. y[0] = fruitStart
  1147. flag[0] = true
  1148. apple_x_left = x[0]
  1149. apple_x_right = x[0]
  1150. }
  1151. random = Math.random() + 1
  1152. y[1] = y[1] + speed[1] * random
  1153. if (y[1] > fruitEnd) {
  1154. y[1] = fruitStart
  1155. flag[1] = true;
  1156. banana_x_left = x[1];
  1157. banana_x_right = x[1]
  1158. }
  1159. random = Math.random() + 1
  1160. y[2] = y[2] + speed[2] * random
  1161. if (y[2] > fruitEnd) {
  1162. y[2] = fruitStart;
  1163. flag[2] = true;
  1164. sandia_x_left = x[2];
  1165. sandia_x_right = x[2]
  1166. }
  1167. random = Math.random() + 1
  1168. y[3] = y[3] + speed[3] * random
  1169. if (y[3] > fruitEnd) {
  1170. y[3] = fruitStart
  1171. flag[3] = true;
  1172. basaha_x_left = x[3]
  1173. basaha_x_right = x[3]
  1174. }
  1175. }
  1176. timer = requestAnimationFrame(draw);
  1177. if (fruitFlag !== 1) {
  1178. //取消循环
  1179. window.cancelAnimationFrame(timer)
  1180. ctx.clearRect(0, 0, 900, 900); //清空所有的内容
  1181. }
  1182. //
  1183. }
  1184. //在合适的时机调用碰撞检测方法
  1185. function getColl() {
  1186. let first = [x[0] + 30, y[0] + 30]
  1187. //第二列中心点坐标
  1188. let second = [x[1] + 30, y[1] + 15]
  1189. let third = [x[2] + 30, y[2] + 30]
  1190. let four = [x[3] + 30, y[3] + 30]
  1191. //碰撞检测方法
  1192. collision(first, second, third, four)
  1193. }
  1194. //分数判断方法
  1195. function countComputer() {
  1196. if (diff == 1) {
  1197. if (passFlag == 1) {
  1198. count += 5
  1199. }
  1200. }
  1201. if (diff == 2) {
  1202. // resetTime()
  1203. if (passFlag == 1) {
  1204. count += 5
  1205. }
  1206. }
  1207. if (diff == 3) {
  1208. // resetTime()
  1209. if (passFlag == 1) {
  1210. count += 5
  1211. }
  1212. }
  1213. }
  1214. //水果的相交方法
  1215. function collision(first, second, third, four) {
  1216. //判断是否与第一个相交
  1217. if (wormFlag[0]) {
  1218. if ((Math.abs(targ[0] - (first[0])) <= (60 / 2 + 60 / 2)) && (Math.abs(targ[1] - (first[1])) <= (60 / 2 + 60 / 2))) {
  1219. //两个面积相交了\
  1220. soundHitOpen()
  1221. wormFlag[0] = false
  1222. countComputer()
  1223. }
  1224. }
  1225. //第二条线相交
  1226. if (wormFlag[1]) {
  1227. if ((Math.abs(targ[0] - (second[0])) <= (60 / 2 + 60 / 2)) && (Math.abs(targ[1] - (second[1])) <= (60 / 2 + 60 / 2))) {
  1228. //两个面积相交了
  1229. soundHitOpen()
  1230. wormFlag[1] = false
  1231. countComputer()
  1232. }
  1233. }
  1234. //第三条线相交
  1235. if (wormFlag[2]) {
  1236. if ((Math.abs(targ[0] - (third[0])) <= (60 / 2 + 60 / 2)) && (Math.abs(targ[1] - (third[1])) <= (60 / 2 + 60 / 2))) {
  1237. //两个面积相交了
  1238. soundHitOpen()
  1239. wormFlag[2] = false
  1240. countComputer()
  1241. }
  1242. }
  1243. //第四条线相交
  1244. //第三条线相交
  1245. if (wormFlag[3]) {
  1246. if ((Math.abs(targ[0] - (four[0])) <= (60 / 2 + 60 / 2)) && (Math.abs(targ[1] - (four[1])) <= (60 / 2 + 60 / 2))) {
  1247. //两个面积相交了
  1248. soundHitOpen()
  1249. wormFlag[3] = false
  1250. countComputer()
  1251. }
  1252. }
  1253. }
  1254. //虫子的相交方法
  1255. function wormCollision(first, second, third, four) {
  1256. //判断是否与第一个相交console
  1257. if ((Math.abs(targ[0] - (first[0])) <= (60 / 2 + 60 / 2)) && (Math.abs(targ[1] - (first[1])) <= (60 / 2 + 60 / 2))) {
  1258. //两个面积相交了
  1259. wormFlag[0] = false
  1260. }
  1261. //第二条线相交
  1262. if ((Math.abs(targ[0] - (second[0])) <= (60 / 2 + 60 / 2)) && (Math.abs(targ[1] - (second[1])) <= (60 / 2 + 60 / 2))) {
  1263. //两个面积相交了
  1264. wormFlag[1] = false
  1265. }
  1266. //第三条线相交
  1267. if ((Math.abs(targ[0] - (third[0])) <= (60 / 2 + 60 / 2)) && (Math.abs(targ[1] - (third[1])) <= (60 / 2 + 60 / 2))) {
  1268. //两个面积相交了
  1269. wormFlag[2] = false
  1270. }
  1271. //第四条线相交
  1272. //第三条线相交
  1273. if ((Math.abs(targ[0] - (four[0])) <= (60 / 2 + 60 / 2)) && (Math.abs(targ[1] - (four[1])) <= (60 / 2 + 60 / 2))) {
  1274. //两个面积相交了
  1275. wormFlag[3] = false
  1276. }
  1277. }
  1278. //倒计时方法
  1279. function countdown() {
  1280. startTimeFruit = new Date().getTime();
  1281. let surplusTime = endTimeFruit - startTimeFruit;
  1282. let th = Math.floor(surplusTime / (1000 * 60 * 60) % 24);
  1283. let tm = Math.floor(surplusTime / (1000 * 60) % 60);
  1284. let ts = Math.floor(surplusTime / 1000 % 60);
  1285. if (ts < 10) {
  1286. ts = '0' + ts
  1287. }
  1288. if (surplusTime >= 0) {
  1289. if (!(passFlag == 2 || passFlag == 3)) {
  1290. countdownFlag = true
  1291. }
  1292. return '0' + th + ':' + '0' + tm + ':' + ts
  1293. } else {
  1294. if (diff == 1) {
  1295. if (count >= 90) {
  1296. //执行保存结果
  1297. levelFun(diff, count)
  1298. totalScore += count;
  1299. middleFont()
  1300. speedWorm = [1.5, 2.0, 2.3, 2.4];
  1301. //且进行将关卡设置为2
  1302. diff = 2;
  1303. count = 0
  1304. //将时间重置为3分钟
  1305. resetTime()
  1306. } else {
  1307. if (passFlag != 2) {
  1308. levelFun(diff, count)
  1309. }
  1310. passFlag = 2
  1311. //很遗憾失败了
  1312. }
  1313. } else if (diff == 2) {
  1314. if (count >= 60) {
  1315. middleFont()
  1316. levelFun(diff, count)
  1317. totalScore += count;
  1318. speedWorm = [2.0, 2.5, 2.8, 3.1];
  1319. diff = 3;
  1320. count = 0
  1321. //将时间重置为3分钟
  1322. resetTime()
  1323. } else {
  1324. if (passFlag != 2) {
  1325. levelFun(diff, count)
  1326. }
  1327. passFlag = 2
  1328. }
  1329. } else if (diff == 3) {
  1330. if (count >= 45) {
  1331. if (passFlag != 3) {
  1332. totalScore += count;
  1333. levelFun(diff, count)
  1334. saveResult(totalScore)
  1335. }
  1336. passFlag = 3
  1337. } else {
  1338. if (passFlag != 2) {
  1339. levelFun(diff, count)
  1340. }
  1341. passFlag = 2
  1342. }
  1343. }
  1344. return '00' + ':' + '00' + ':' + '00'
  1345. }
  1346. }
  1347. //捉虫子游戏变量
  1348. $('#solar').hide();
  1349. $('#exit').hide();
  1350. $('#refresh').hide();
  1351. let WASM_URL = "js/gazefilter.wasm";
  1352. var buttonList = []
  1353. $('#target').hide();
  1354. $('#target1').hide();
  1355. var record = {
  1356. beforePoint: -1,
  1357. currentPoint: 0,
  1358. }
  1359. //校准方法
  1360. function calibrationAccuracy() {
  1361. $('#solar').hide();
  1362. handleFullScreen();
  1363. getFun()
  1364. $('#target1').show();
  1365. $('#startCalibration').hide();
  1366. switchTime()
  1367. //初始化游戏
  1368. $('#target1').hide()
  1369. // $('#target').show()
  1370. //clearInterval(time)
  1371. //$('#solar').show();
  1372. //$('#exit').show();
  1373. //$('#refresh').show();
  1374. }
  1375. $("#startCalibration").click(function () {
  1376. // handleFullScreen(); //全屏
  1377. handleFullScreen();
  1378. getFun()
  1379. $('#target1').show();
  1380. $('#startCalibration').hide();
  1381. //switchTime()
  1382. //初始化游戏
  1383. //
  1384. $('#target1').hide()
  1385. $('#target').show()
  1386. clearInterval(time)
  1387. $('#solar').show();
  1388. //$('#exit').show();
  1389. // $('#refresh').show();
  1390. //init();
  1391. // $('.enterClass').css('display','none');
  1392. // $('.returnClass').css('display','block');
  1393. });
  1394. //切换游戏
  1395. $('#exit').click(function () {
  1396. //隐藏画布一
  1397. // $('#exit').innerHtml()
  1398. if (fruitFlag == 1) {
  1399. setTimeout(() => {
  1400. initWorm()
  1401. fruitFlag = 2
  1402. }, 30);
  1403. } else {
  1404. setTimeout(() => {
  1405. // init()
  1406. fruitFlag = 1
  1407. }, 30);
  1408. }
  1409. })
  1410. $('#refresh').click(function () {
  1411. location.reload()
  1412. })
  1413. function handleFullScreen() {
  1414. var de = document.documentElement;
  1415. if (de.requestFullscreen) {
  1416. de.requestFullscreen();
  1417. } else if (de.msRequestFullscreen) {
  1418. de.msRequestFullscreen();
  1419. } else if (de.webkitRequestFullScreen) {
  1420. de.webkitRequestFullScreen();
  1421. } else if (de.mozRequestFullScreen) {
  1422. de.mozRequestFullScreen();
  1423. } else {
  1424. wtx.info("当前浏览器不支持全屏!");
  1425. }
  1426. }
  1427. //重置通过状态
  1428. function resetStatus() {
  1429. //重置是否通过的状态
  1430. passFlag = 1;
  1431. //重置速度
  1432. speedWorm = [1, 1.5, 1.3, 1.4];
  1433. }
  1434. //重置计时函数
  1435. function resetTime() {
  1436. startTimeFruit = new Date().getTime();
  1437. endTimeFruit = startTimeFruit + 180000;
  1438. countdownFlag = true
  1439. }
  1440. //重置难度重置关数
  1441. function resetCount(val, value) {
  1442. //设置难度为多少
  1443. diff = val;
  1444. //设置分数为多少
  1445. count = value;
  1446. }
  1447. //轮询当前的图表
  1448. var time = null;
  1449. function switchTime() {
  1450. let a = 0
  1451. time = setInterval(() => {
  1452. $('#target1').show()
  1453. $('#targetMini').show()
  1454. if (a == 16) {
  1455. $('#target1').hide()
  1456. $('#target').show()
  1457. clearInterval(time)
  1458. $('#solar').show();
  1459. //$('#exit').show();
  1460. // $('#refresh').show();
  1461. trainingFlag = 4
  1462. //重置计时函数
  1463. resetTime()
  1464. //重置分数和参数
  1465. resetCount(1, 0)
  1466. //都重置到初始状态
  1467. resetStatus();
  1468. } else {
  1469. $('#targetMini1').css('transition', '0s');
  1470. $('#targetMini1').css('width', 54 + 'px');
  1471. $('#targetMini1').css('height', 54 + 'px');
  1472. let x = buttonList[a].x1;
  1473. x = Math.floor(x)
  1474. let y = buttonList[a].y1;
  1475. y = Math.floor(y)
  1476. $('#target1').css('left', x + 'px');
  1477. $('#target1').css('top', y + 'px');
  1478. // init();
  1479. setTimeout(() => {
  1480. $('#targetMini1').css('transition', '1s');
  1481. $('#targetMini1').css('width', 20 + 'px');
  1482. $('#targetMini1').css('height', 20 + 'px');
  1483. }, 1000);
  1484. setTimeout(() => {
  1485. coordinates(x + 30, y + 30)
  1486. }, 1500);
  1487. setTimeout(() => {
  1488. coordinates(x + 30, y + 30)
  1489. }, 1840);
  1490. setTimeout(() => {
  1491. coordinates(x + 30, y + 30)
  1492. }, 1940);
  1493. a = a + 1
  1494. }
  1495. }, 2000)
  1496. }
  1497. function coordinates(x, y) {
  1498. gazefilter.tracker.calibrate( //校正,发送当前点击位置进行校正
  1499. //event.timeStamp,
  1500. window.performance.now(),
  1501. //window.performance.now(),
  1502. //mill,
  1503. //1000, // relative to performance.timeOrigin
  1504. x, // in pixels
  1505. y, // in pixels
  1506. 1.0 // see note below
  1507. );
  1508. }
  1509. //获取各个按钮的left和top
  1510. /**
  1511. * 在屏幕上画出注视点
  1512. * 是否画点,以及画点方式均可自定义
  1513. **/
  1514. function drawTargetOnScreen(position) {
  1515. if (position != null && position.length == 2) {
  1516. //判断是否是NAN如果是NAN则不执行
  1517. //如果不是则需要判断当前点是否在第一个点中,如果在则执行settimeout函数1秒后改变改块状态
  1518. //如果在第一个点中但第二次坐标出来的时候还在第一个坐标里那就没问题
  1519. // $('#target').css('display', 'block');
  1520. targ[0] = position[0] + 60;
  1521. targ[1] = position[1] + 60;
  1522. $('#target').css('left', position[0] + 'px');
  1523. $('#target').css('top', position[1] + 'px');
  1524. // $('#target').css('z-index', 100);
  1525. //judge(position[0], position[1])
  1526. // judge(position[0], position[1])
  1527. }
  1528. }
  1529. //判断是否在第一个点中
  1530. //获取全部的校验点
  1531. function getFun() {
  1532. for (let i = 0; i < 16; i++) {
  1533. let a = document.getElementById('num' + (i + 1));
  1534. buttonList.push({
  1535. x1: a.getBoundingClientRect().left,
  1536. y1: a.getBoundingClientRect().top
  1537. })
  1538. }
  1539. }
  1540. async function initGazefilter() {
  1541. cameraFlag = false
  1542. await gazefilter.init(WASM_URL); //初始化
  1543. await gazefilter.tracker.connect(); //连接摄像头
  1544. let canvas = document.getElementById("tracker-canvas");
  1545. await gazefilter.visualizer.setCanvas(canvas); //绘制图像
  1546. cameraFlag = true
  1547. await gazefilter.tracker.addListener("calib", response => {
  1548. //console.log(response.errorCode, event.errorValue); //校验结果 errorCode 0: calibration is successfull;1: screen dimentions should be set;2: calibration sample cannot be created;3: not enough data to fit calibration model.
  1549. });
  1550. }
  1551. function startTrace() {
  1552. gazefilter.tracker.addListener("filter", event => { //注视点
  1553. drawTargetOnScreen(event.bestGazePoint()); //Best gaze point of left or right eye. 其他取点可参考https://beehiveor.gitlab.io/gazefilter/data.html,有不同类型的点 fixationPoint
  1554. });
  1555. }
  1556. function hideSence() {
  1557. //隐藏目标物
  1558. $('#target').hide()
  1559. $('#target1').hide()
  1560. $('#targetMini').hide()
  1561. //隐藏摄像头
  1562. $('#solar').show()
  1563. }
  1564. $("#finishcalibration").click(function () {
  1565. window.removeEventListener("click", onmouseclick); //九点校正完成,取消鼠标事件,并开始绘制轨迹点
  1566. $("#finishcalibration").hide();
  1567. })
  1568. $(document).ready(function () {
  1569. //将canvas自适应屏幕
  1570. resizeCanvas()
  1571. //init()
  1572. initWorm()
  1573. hideSence()
  1574. //将该隐藏的隐藏然后初始化游戏场景
  1575. //初始华摄像头
  1576. initGazefilter();
  1577. startTrace();
  1578. });
  1579. </script>
  1580. </body>
  1581. </html>