{"id":365574,"date":"2024-05-21T02:41:08","date_gmt":"2024-05-21T02:41:08","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=365574"},"modified":"-0001-11-30T00:00:00","modified_gmt":"2024-05-21T02:41:08","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=365574","title":{"rendered":"<span>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0441\u0435\u0442\u0435\u0432\u043e\u0439 \u0438\u0433\u0440\u044b \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e Collagen_2, Node.js \u0438 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 socket.js<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/a03\/ae6\/b09\/a03ae6b0924494ecaa59761225b4a477.png\" width=\"1033\" height=\"721\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/a03\/ae6\/b09\/a03ae6b0924494ecaa59761225b4a477.png\"\/><\/figure>\n<p>\u0412 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u0431\u0443\u0434\u0435\u0442 \u043e\u043f\u0438\u0441\u0430\u043d \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0441\u0435\u0442\u0435\u0432\u043e\u0439 \u043e\u043d\u043b\u0430\u0439\u043d \u043c\u0438\u043d\u0438 \u0438\u0433\u0440\u044b \u043d\u0430\u043f\u043e\u0434\u043e\u0431\u0438\u0435 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0447\u0430\u0442 \u043a\u043e\u043c\u043d\u0430\u0442\u044b.  \u0418\u0433\u0440\u043e\u043a\u0438 \u043c\u043e\u0433\u0443\u0442 \u043f\u0435\u0440\u0435\u0434\u0432\u0438\u0433\u0430\u0442\u044c\u0441\u044f \u043f\u043e \u043f\u043e\u043b\u044e \u0438\u0433\u0440\u044b, \u043f\u0440\u044f\u0442\u0430\u0442\u044c\u0441\u044f \u0437\u0430 \u0434\u0435\u0440\u0435\u0432\u044c\u044f\u043c\u0438, \u0442\u0430\u043a\u0436\u0435 \u0435\u0441\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u043a\u0430\u043c\u0435\u0440\u043e\u0439 \u0432\u0438\u0434\u0430. \u0414\u043b\u044f \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438\u0433\u0440\u044b \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u043a\u0430\u0447\u0430\u0442\u044c <a href=\"https:\/\/github.com\/Sergey1234Ovechkin\/collagen_2\" rel=\"noopener noreferrer nofollow\">\u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440<\/a>, \u0437\u0430\u0439\u0442\u0438 \u0432 \u043f\u0430\u043f\u043a\u0443 collagen_2\/games\/game_3, \u0432\u0432\u0435\u0441\u0442\u0438 \u0432 \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0435 <code>forever start app.js. <\/code>\u0414\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0438\u0433\u0440\u044b \u0442\u0440\u0435\u0431\u0443\u044e\u0442\u0441\u044f \u043c\u043e\u0434\u0443\u043b\u0438 socket.js \u0438 forever(\u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u0430\u044f \u0438\u043d\u0441\u0442\u0430\u043b\u044f\u0446\u0438\u044f).<code> <\/code><\/p>\n<h2>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0441\u0446\u0435\u043d\u044b \u0438\u0433\u0440\u044b<\/h2>\n<p>\u0414\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0441\u0446\u0435\u043d\u044b \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u0442\u044c \u0432\u0441\u0435 \u0441\u043f\u0440\u0430\u0439\u0442\u044b: \u0444\u043e\u043d\u043e\u0432\u043e\u0439 \u043f\u043e\u0434\u043b\u043e\u0436\u043a\u0438, \u0434\u0435\u0440\u0435\u0432\u044c\u0435\u0432, \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430 \u0441 \u043f\u043e\u043a\u0430\u0434\u0440\u043e\u0432\u043e\u0439 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0435\u0439, \u0437\u0430\u0442\u0435\u043c \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0438\u0445. \u0414\u0430\u043b\u0435\u0435 \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u0432 \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440 \u0441\u0446\u0435\u043d\u044b, \u0434\u043b\u044f \u044d\u0442\u043e \u043d\u0430\u0436\u0430\u0442\u044c \u043a\u043d\u043e\u043f\u043a\u0443 code \u0441\u0438\u043d\u0435\u0433\u043e \u0446\u0432\u0435\u0442\u0430, \u0437\u0430\u0442\u0435\u043c \u043a\u043d\u043e\u043f\u043a\u0443 test. \u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0444\u043e\u043d\u043e\u0432\u043e\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0442\u043e\u0433\u043e \u0436\u0435 \u0440\u0430\u0437\u043c\u0435\u0440\u0430, \u0447\u0442\u043e \u0438 \u0441\u0446\u0435\u043d\u0430, \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0432\u0441\u0435 \u0441\u043f\u0440\u0430\u0439\u0442\u044b. \u0420\u0430\u0437\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u0441\u043f\u0440\u0430\u0439\u0442\u044b \u0431\u0435\u043a\u0433\u0440\u043e\u0443\u043d\u0434\u0430, \u0434\u0435\u0440\u0435\u0432\u044c\u0435\u0432 \u0438 \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430 \u043d\u0430 \u0441\u0446\u0435\u043d\u0435. \u0414\u043b\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u044f \u043a\u0430\u043c\u0435\u0440\u044b \u0432\u0438\u0434\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u043d\u043e\u043f\u043a\u0438 &#8212; a, w, s, d. \u0414\u0430\u043b\u0435\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0441\u043f\u0440\u0430\u0439\u0442\u044b \u0431\u0435\u043a\u0433\u0440\u043e\u0443\u043d\u0434\u0430 \u043a\u043d\u043e\u043f\u043a\u043e\u0439 add tile bg &#8212; \u0441\u0438\u043d\u0435\u0433\u043e \u0446\u0432\u0435\u0442\u0430, \u0441\u043f\u0440\u0430\u0439\u0442\u044b \u0441\u0446\u0435\u043d\u044b \u0438 \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430 \u043a\u043d\u043e\u043f\u043a\u043e\u0439 add tile.<\/p>\n<p>\u041e\u0434\u0438\u043d \u0438 \u0442\u043e\u0442 \u0436\u0435 \u0441\u043f\u0440\u0430\u0439\u0442 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0441\u0446\u0435\u043d\u044b, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0434\u0435\u0440\u0435\u0432\u044c\u0435\u0432, \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u0441\u043f\u0440\u0430\u0439\u0442 \u0432 \u043d\u043e\u0432\u043e\u0435 \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0438 \u0441\u043d\u043e\u0432\u0430 \u043d\u0430\u0436\u0430\u0442\u044c \u043a\u043d\u043e\u043f\u043a\u0443 add tile \u0438\u043b\u0438 add tile bg.  Id \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0441\u0446\u0435\u043d\u044b \u043c\u043e\u0436\u043d\u043e \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c, \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u043d\u0435\u043d\u0443\u0436\u043d\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 \u0438\u0437 \u043c\u0430\u0441\u0441\u0438\u0432\u043e\u0432 tile_common \u0438 tilt_bg,  \u043f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u043d\u0430\u0436\u0430\u0442\u044c \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0443 update \u0437\u0435\u043b\u0435\u043d\u043e\u0433\u043e \u0446\u0432\u0435\u0442\u0430. \u0412 \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u043c \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u0435 \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u0438\u0441\u0430\u0442\u044c \u043a\u043e\u0434 \u0434\u043b\u044f <a href=\"https:\/\/habr.com\/ru\/articles\/762652\/\" rel=\"noopener noreferrer nofollow\">\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438<\/a> \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0432 \u0431\u0440\u043e\u0443\u0437\u0435\u0440\u0435.  \u041f\u043e\u0441\u043b\u0435 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0438 \u0441\u0446\u0435\u043d\u044b &#8212; \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0435\u0435 \u0432 \u043f\u0430\u043f\u043a\u0435 \u0434\u043b\u044f \u0438\u0433\u0440 collagen_2\/games\/game_name \u0432 json \u0444\u0430\u0439\u043b ,\u043d\u0430\u0436\u0430\u0432 \u043a\u043d\u043e\u043f\u043a\u0443 save project &#8212; \u0432 \u043d\u0438\u0437\u0443 \u043f\u0430\u043d\u0435\u043b\u0435\u0439 \u0441 \u043a\u043d\u043e\u043f\u043a\u0430\u043c\u0438.<\/p>\n<h2>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u043b\u043e\u0433\u0438\u043a\u0438 \u0438\u0433\u0440\u044b \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u043e\u0439 \u0447\u0430\u0441\u0442\u0438<\/h2>\n<p>\u0412 \u0444\u0430\u0439\u043b\u0435 index.html \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043f\u0443\u0442\u044c \u043a \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c\u0443 \u0441\u043a\u0440\u0438\u043f\u0442\u0443 \u0438\u0433\u0440\u044b &#8212; ..\/..\/..\/collagen_2\/games\/game_name\/game_name.js, \u0432  \u0444\u0430\u0439\u043b\u0435 game_name.js \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043f\u0443\u0442\u044c \u043a json \u0444\u0430\u0439\u043b\u0443 \u0441\u0446\u0435\u043d\u044b \u0432 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 gameUrl, \u0442\u0430\u043a\u0436\u0435 \u043c\u0435\u043d\u044f\u0435\u043c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043f\u0430\u043f\u043a\u0438 \u0438\u0433\u0440\u044b \u0432 \u0444\u0430\u0439\u043b\u0435 app.js.<\/p>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043b\u043e\u0433\u0438\u043a\u0443 \u0438\u0433\u0440\u044b \u0432  \u0444\u0430\u0439\u043b\u0435 game_name.js: <\/p>\n<pre><code class=\"javascript\">\/\/\/\/\/\/\/\/\/\/\/\/\/\/\u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u0440\u0430\u0437\u043c\u0435\u0440 \u043a\u0430\u0440\u0442\u044b \u0441\u043c\u0435\u0449\u0435\u043d\u0438\u044f \u043a\u0430\u043c\u0435\u0440\u044b \u0432\u0438\u0434\u0430  var maxTranslate = [-1000, -0]; \/\/\u0430\u0434\u0440\u0435\u0441 json \u0444\u0430\u0439\u043b\u0430 \u0441\u043f\u0440\u0430\u0439\u0442\u043e\u0432 var gameUrl = \"http:\/\/localhost:3000\/collagen_2\/games\/game_1\/game_1.json\"; var personageId = \"personage\";   \/\/\u0430\u043d\u0438\u043c\u0430\u0446\u0438\u044f \u0441\u0446\u0435\u043d\u044b function apply_code(){         \/\/\u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u0432\u043a\u043e\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438   mode = \"animation\"; if (modules.animation)modules.animation.isOff = true; updateCommonTiles(HM.$props().sprites); updateBgTiles(HM.$props().sprites); \/\/\u0440\u0435\u0436\u0438\u043c code \u0447\u0442\u043e\u0431\u044b \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e Tiles HM.$$(\"emiter-operation-with\").set(\"code\");   \/\/\/\u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u044e \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430 modules.personage = null;  \/\/\u043d\u0430\u0445\u043e\u0434\u0438\u043c \u043e\u0431\u044a\u0435\u043a\u0442 \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430 \u0432 \u043c\u0430\u0441\u0441\u0438\u0432\u0435 tiles_common \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u043e\u043c \u0432 test  for(var i=0; i&lt;tiles_common.length; i++){ if(tiles_common[i].id == personageId){ modules.personage = tiles_common[i]; } }  \/\/\/\u0444\u043b\u0430\u0433 \u043b\u0438\u043a\u0430 \u043f\u043e \u043a\u043d\u043e\u043f\u043a\u0430\u043c \u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u044b var click  = false; \/\/\/\u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430 var interval  = 100;  \/\/\/id \u0442\u0430\u0439\u043c\u0435\u0440\u0430 \u0434\u043b\u044f \u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b\u0430 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438 var timerId  = 0;  \/\/\/\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u043d\u0430\u0436\u0430\u0442\u0438\u044f \u0441\u0442\u0440\u0435\u043b\u043e\u043a modules.keydown = function(key){ if(key == \"ArrowUp\"){  if (click == true)return; click = true; clearInterval(timerId);     timerId = setInterval(move, interval, 11, 15, 12, 0, -10); }else if(key == \"ArrowDown\"){ if (click == true)return; click = true; clearInterval(timerId);     timerId = setInterval(move, interval, -1, 3, 0, 0, 10); }else if(key == \"ArrowRight\"){  if (click == true)return; click = true; clearInterval(timerId);     timerId = setInterval(move, interval, 7, 11, 8, 10, 0);  }else if(key == \"ArrowLeft\"){ if (click == true)return; click = true; clearInterval(timerId);     timerId = setInterval(move, interval, 3, 7, 4, -10, 0); } } \/\/\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u043e\u0442\u0436\u0430\u0442\u0438\u044f \u043a\u043d\u043e\u043f\u043e\u043a-\u0441\u0442\u0440\u0435\u043b\u043e\u043a modules.keyup = function(key){ clearInterval(timerId); click = false; }  \/\/\/\u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430 \u0438 \u0441\u043c\u0435\u043d\u044b \u043a\u0430\u0434\u0440\u043e\u0432 function move(arg1,arg2,arg3, arg4, arg5) {      if(modules.personage.frame_index > arg1 &amp;&amp;  modules.personage.frame_index &lt; arg2){              modules.personage.nextFrame();}else{             modules.personage.nextFrame(arg3); } modules.personage.move(arg4, arg5); }  \/\/\u0437\u0430\u043f\u0443\u0441\u043a \u0446\u0438\u043a\u043b\u0430 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0444\u043e\u043d\u043e\u0432\u044b\u0445 \u0438 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u0441\u043f\u0440\u0430\u0439\u0442\u043e\u0432, \u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435 \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430 modules.animation=animationLopLayer(tiles_bg,tiles_common, 40);  }   \/\/\/\u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 json \u0444\u0430\u0439\u043b\u0430, \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0441\u043f\u0440\u0430\u0439\u0442\u043e\u0432 \u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0441\u0446\u0435\u043d\u044b - Tile fetch(gameUrl)   .then((response) => {     if (!response.ok) {       throw new Error(`HTTP error: ${response.status}`);     }     return response.json();   })   .then((json) => {     \/\/console.log(json)     var dataURL = 'data:image\/png;base64,' + json.backImg;     var context  = HM; \/\/\u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043a\u043e\u0440\u0435\u043d\u044c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f                        \/\/\/ tiles_bg_save, tiles_common_save - \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043c\u0430\u0441\u0441\u0438\u0432\u044b                        \/\/\/\u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 - \u0444\u0430\u0439\u043b js\/games\/main_games.js                     tiles_common_save = JSON.parse(json.tiles_common_save);         tiles_bg_save = JSON.parse(json.tiles_bg_save);  mainImgScale_x = 1; mainImgScale_y = 1;  img.src = dataURL;                         \/\/\/\u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u0444\u043e\u043d\u043e\u0432\u0443\u044e \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0443 img.onload = function(){  startImg(); }                         \/\/\/\u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0441\u043f\u0440\u0430\u0439\u0442\u043e\u0432 \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u0441\u044b\u043b\u0430\u044e\u0442\u0441\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0441\u0446\u0435\u043d\u044b \u0438                          \/\/\/\u0431\u0435\u043a\u0433\u0440\u043e\u0443\u043d\u0434\u0430 \u043f\u0440\u0438 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0438 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438 for(var key in  json.sprites){    var sprite = createFromPC(key, context, false, json.sprites[key]);    if(sprite)context.$$(\"emiter-create-sprite\").set(key); }                 \/\/\u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0431\u0435\u043a\u0433\u0440\u043e\u0443\u043d\u0434\u0430                tiles_bg = []; for(var i=0; i&lt;tiles_bg_save.length; i++){ if(context.$props().sprites[tiles_bg_save[i].parent])tiles_bg.push(new Tile(tiles_bg_save[i].id, context.$props().sprites[tiles_bg_save[i].parent], tiles_bg_save[i].point)); }                 \/\/\/\u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0441\u0446\u0435\u043d\u044b \u0438 \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430 tiles_common = []; for(var i=0; i&lt;tiles_common_save.length; i++){ if(context.$props().sprites[tiles_common_save[i].parent])tiles_common.push(new Tile(tiles_common_save[i].id, context.$props().sprites[tiles_common_save[i].parent], tiles_common_save[i].point)); } \/\/\/\u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438 apply_code();   })   .catch((err) => console.error(`Fetch problem: ${err.message}`));<\/code><\/pre>\n<p> \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u043b\u043e\u0433\u0438\u043a\u0438 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438 \u0441\u0446\u0435\u043d\u044b \u0438 \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430 \u0437\u0430\u043a\u043e\u043d\u0447\u0435\u043d\u0430, \u043f\u0440\u043e\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043c\u043e\u0436\u043d\u043e \u0432 \u043f\u0430\u043f\u043a\u0435  collagen_2\/games\/game_1.<\/p>\n<h2>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u043e\u0439 \u0441\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0435\u0439 \u0438\u0433\u0440\u044b<\/h2>\n<p>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0441\u0435\u0440\u0432\u0435\u0440\u0430.<\/p>\n<p>\u0414\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u043e\u0439 \u0447\u0430\u0441\u0442\u0438  \u0431\u044b\u043b\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 socket.js \u0438 \u043c\u043e\u0434\u0443\u043b\u044c forever \u0434\u043b\u044f  \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0430.<\/p>\n<pre><code class=\"javascript\">\/\/\u043f\u0440\u0438 \u0432\u044b\u0445\u043e\u0434\u0435 \u0438\u0433\u0440\u043e\u043a\u0430 \u0441\u0435\u0440\u0432\u0435\u0440 \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442\u0441\u044f  \/\/\/ \u0434\u043b\u044f \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043c\u043e\u0434\u0443\u043b\u044c forever.  \u0417\u0430\u043f\u0443\u0441\u043a \u0441\u0435\u0440\u0432\u0435\u0440\u0430:   forever start app.js  var users = {}; \/\/\/\u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0438 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u043a\u0430\u0434\u0440 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 var socketjs = require('socket.js');   \/\/\/\/\/\/\/\u0441\u0432\u044f\u0437\u044c \u0441 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u0430\u043c\u0438 \/\/\/\/\u0434\u0430\u043d\u043d\u044b\u0435 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438 \u0432\u0441\u0435\u0445 \u0438\u0433\u0440\u043e\u043a\u043e\u0432 socketjs(server, function(socket, reconnectData) {     console.log(reconnectData);       \/\/\u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043d\u043e\u0432\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f   if (reconnectData === null) {     console.log('A user connected.');   } else {     console.log('A user reconnected with: ', reconnectData);   }     \/\/\/\u043d\u043e\u0432\u044b\u0439 \u0438\u0433\u0440\u043e\u043a \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c users    socket.receive('newuser', function(message) { users[message.id] = message;   });         \/\/ \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0441 \u043a\u043b\u0438\u0435\u043d\u0442\u0430   socket.receive('coord', function(message) { users[message.id] = message;     });    \/\/\u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0438\u0433\u0440\u043e\u043a\u0430\u043c \u043a\u0430\u0436\u0434\u044b\u0435 100ms   var interval = setInterval(function() { socket.send('coord', users);   }, 100);     socket.close(function(data) {     console.log('A user disconnected.');     clearInterval(interval); return data;   }); });<\/code><\/pre>\n<p>\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u043e\u043a\u0435\u0442-\u0441\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0435\u0439 \u0432 \u0444\u0430\u0439\u043b \u043a\u043b\u0438\u0435\u043d\u0442\u0430.<\/p>\n<pre><code class=\"javascript\">\/\/\u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \/\/\u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0435 id \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440 (\u0442.\u043a. \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0438 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0435 \u0434\u043b\u044f \u0432\u0441\u0435\u0445) var userId = \"user_\" + Math.floor(Math.random() * 1000); \/\/\/\u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0441\u0446\u0435\u043d\u044b var numTiles = 0; \/\/\/\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0438\u0433\u0440\u043e\u043a\u043e\u0432 var numUsers = 1;  \/\/\/\u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0437\u0430\u043f\u0443\u0441\u043a \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0432 fetch \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 json \u0441\u0446\u0435\u043d\u044b                 \/\/\/\u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0441\u0446\u0435\u043d\u044b numTiles = tiles_common.length; \/\/\/\u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438 apply_code();  createSocket();  \/\/\/\u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043b\u043e\u0433\u0438\u043a\u0443 \u0441\u043e\u043a\u0435\u0442 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f function createSocket(){ \/\/\/\u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0441 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u0438\u0433\u0440\u043e\u043a\u0430\u043c\u0438   if (socketjs.isSupported()) {   \/\/ connect to the server   var socket = socketjs.connect();      \/\/\/\u043f\u0435\u0440\u0432\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435   \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440 \u0441 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430\u043c\u0438 \u043f\u0440\u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0435    socket.send('newuser', {id: userId, point: modules.personage.point, frame_index: modules.personage.frame_index});    \/\/ log a message if we get disconnected   socket.disconnect(function(data) {     console.log('Temporarily disconnected.');   });    \/\/ log a message when we reconnect   socket.reconnect(function() {     console.log('Reconnected.');      \/\/ whatever we return here is sent back to the server     return 'reconnected';   });     \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/      \/\/ \u043a\u043e\u0440\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0438\u0433\u0440\u043e\u043a\u043e\u0432 \u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u0430    socket.receive('coord', function(data) {  \/\/\u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0441\u0446\u0435\u043d\u044b \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0438\u043b\u0438 \u0432\u044b\u0445\u043e\u0434\u0430 \u0438\u0433\u0440\u043e\u043a\u0430   if(Object.keys(data).length != numUsers){ \/\/\u0443\u0434\u0430\u043b\u044f\u0435\u043c \u0432\u0441\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0441\u0446\u0435\u043d\u044b tiles_common.splice(0, tiles_common.length); \/\/\u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0435 \u043e\u0431\u0435\u043a\u0442\u044b  for(var i=0; i&lt;tiles_common_save.length; i++){               \/\/HM - \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043a\u043e\u0440\u0435\u043d\u044c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f  if(HM.$props().sprites[tiles_common_save[i].parent]){                      tiles_common.push(new Tile(tiles_common_save[i].id, HM.$props().sprites[tiles_common_save[i].parent], tiles_common_save[i].point));  }          }                    \/\/\/\u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u043e\u0432\u044b\u0445 \u0438\u0433\u0440\u043e\u043a\u043e\u0432  for(var key in data){   if(data[key].id != userId){ var tile = new Tile(data[key].id, HM.$props().sprites[modules.personage.parent], data[key].point);  tiles_common.push(tile);   }   }  \/\/\u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430  for(var i=0; i&lt;tiles_common.length; i++){                if(tiles_common[i].id == personageId){            tiles_common[i] = modules.personage;             }          }     \/\/ console.log(tiles_common);  numUsers  = Object.keys(data).length;\/\/\u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0438\u0433\u0440\u043e\u043a\u043e\u0432  }; \/\/\/\u0432\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u044e \u0438\u0433\u0440\u043e\u043a\u043e\u0432  updateUsers(data);     });    \/\/\u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0438 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u043a\u0430\u0434\u0440 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440 \u043a\u0430\u0436\u0434\u044b\u0435  100ms   var interval = setInterval(function() {     socket.send('coord', {id: userId, point: modules.personage.point, frame_index: modules.personage.frame_index});   }, 100);    socket.close(function() {     console.log('Connection closed.');     clearInterval(interval);   }); } else {   console.log('Your browser does not support WebSockets.'); } \/\/\/ } \/\/\/\u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442 \u0438 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u043a\u0430\u0434\u0440\u0430 \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430  function updateUsers(users){   for(var i=0; i&lt; tiles_common.length; i++ ){  if(users[tiles_common[i].id] &amp;&amp; tiles_common[i].id != userId ){ tiles_common[i].point[0] = users[tiles_common[i].id].point[0]; tiles_common[i].point[1] = users[tiles_common[i].id].point[1]; tiles_common[i].nextFrame(users[tiles_common[i].id].frame_index);  }   } }   <\/code><\/pre>\n<p>\u0421\u0435\u0440\u0432\u0435\u0440\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u0433\u043e\u0442\u043e\u0432\u0430, \u0440\u0430\u0431\u043e\u0447\u0438\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432 \u043f\u0430\u043f\u043a\u0435 collagen_2\/games\/game_2. <\/p>\n<h2>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0447\u0430\u0442\u0430<\/h2>\n<p>\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043d\u043e\u0432\u044b\u0439 \u0441\u043f\u0440\u0430\u0439\u0442-\u0434\u0438\u0430\u043b\u043e\u0433 \u0434\u043b\u044f \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/313\/2ea\/62b\/3132ea62bc4bff0e754e4baf5e82532e.png\" width=\"646\" height=\"780\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/313\/2ea\/62b\/3132ea62bc4bff0e754e4baf5e82532e.png\"\/><\/figure>\n<p>\u041d\u0430\u0437\u043e\u0432\u0435\u043c \u0435\u0433\u043e message, \u0434\u0430\u043b\u0435\u0435 \u043e\u0442\u043a\u0440\u043e\u0435\u043c \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440 \u0432 \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u043c \u0440\u0435\u0436\u0438\u043c\u0435 \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0441\u043f\u0440\u0430\u0439\u0442 \u0432 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0439 \u043f\u0440\u043e\u0435\u043a\u0442 \u043a\u043d\u043e\u043f\u043a\u043e\u0439 add tile, \u0438\u0437\u043c\u0435\u043d\u0438\u043c id \u043d\u0430 msg, \u043d\u0430\u0436\u043c\u0435\u043c update, \u0437\u0430\u0442\u0435\u043c \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u043c \u043f\u0440\u043e\u0435\u043a\u0442 \u0432 \u043f\u0430\u043f\u043a\u0435 \u0438\u0440\u044b game_3.<\/p>\n<p>\u041e\u0442\u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u0443\u0435\u043c \u043f\u0443\u0442\u0438 \u043a \u0440\u0435\u0441\u0443\u0440\u0441\u0430\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0432 \u0444\u0430\u0439\u043b\u0430\u0445 index.htm, app.js, game_3.js. \u0414\u0430\u043b\u0435\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u043c html \u0440\u0430\u0437\u043c\u0435\u0442\u043a\u0443 \u0434\u043b\u044f \u0444\u043e\u0440\u043c\u044b \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0432 \u0444\u0430\u0439\u043b index.html.<\/p>\n<pre><code class=\"xml\">&lt;!--\u0444\u043e\u0440\u043c\u0430 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 --> &lt;div data-user_message=\"container\" class=\"form-group \" style=\"position: fixed;  top: 2px; right: 2px; z-index:5\"> &lt;input name=\"user_msg\" type=\"text\"  style=\"width: 270px; padding: 0px; font-size: 14px; margin-top: 2px;\"  placeholder=\"\" title=\"\u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435\"> &lt;button data-hide_panel=\"container\" type=\"button\"  name=\"user_msg_btn\" class=\"btn btn-info btn-sm\"  title=\"\u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435\">message&lt;\/button> &lt;\/div><\/code><\/pre>\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u043c javascript \u043a\u043e\u0434 \u0432 \u0444\u0430\u0439\u043b game_3.js<\/p>\n<pre><code class=\"javascript\">  \/\/\u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0438 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u043a\u0430\u0434\u0440 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440 \u043a\u0430\u0436\u0434\u044b\u0435  100ms   \/\/\/\u043e\u0442\u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u0443\u0435\u043c \u043c\u0435\u0442\u043e\u0434:   var interval = setInterval(function() {                                                                                                                        socket.send('coord', {id: userId, point: modules.personage.point,                            frame_index: modules.personage.frame_index,                           \/\/\/\u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0438\u0433\u0440\u043e\u043a\u0430\u043c                           msg: modules.personage.message});   }, 100);      \/\/\/\u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442 \u0438 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u043a\u0430\u0434\u0440\u0430 \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430  function updateUsers(users){   for(var i=0; i&lt; tiles_common.length; i++ ){  if(users[tiles_common[i].id] &amp;&amp; tiles_common[i].id != userId ){ tiles_common[i].point[0] = users[tiles_common[i].id].point[0]; tiles_common[i].point[1] = users[tiles_common[i].id].point[1]; tiles_common[i].nextFrame(users[tiles_common[i].id].frame_index);  \/\/\/\u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e\u0442 \u0438\u0433\u0440\u043e\u043a\u043e\u0432 tiles_common[i].message = users[tiles_common[i].id].msg;  }   } }      \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\u0421\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0438\u0433\u043e\u0440\u043e\u043a\u043e\u0432 \/\/\/\u041f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u043c\u0435\u0442\u043e\u0434 pender \u0438\u0437 \u0444\u0430\u0439\u043b\u0430 \/test\/tiles.js Tile.prototype.render_ = function(){ if(!this.show)return;     ctx.drawImage(this.frame, this.point[0], this.point[1], this.width, this.height);  \/\/\u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u043c \u0441\u043f\u0440\u0430\u0439\u0442 \u0441 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435\u043c     if(this.message){  var spiteMsg = HM.$props().sprites[\"message\"]; spiteMsg.show = true; \/\/\/\u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0441\u043f\u0440\u0430\u0432\u0430 \u0432\u0432\u0435\u0440\u0445\u0443 \u043e\u0442 \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430 spiteMsg.point[0] = this.point[0]+50;  spiteMsg.point[1] = this.point[1]-70; \/\/\/\u043d\u0438\u0436\u043d\u044f\u044f \u043f\u0440\u0430\u0432\u0430\u044f \u0442\u043e\u0447\u043a\u0430 \u0441\u043f\u0440\u0430\u0439\u0442\u0430 spiteMsg.point2[0] = spiteMsg.point[0]+spiteMsg.width; spiteMsg.point2[1] = spiteMsg.point[1]+spiteMsg.height;      \/\/\u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u043e\u0433\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f - \u043e\u0442\u0441\u0442\u0443\u043f\u044b, \u0448\u0440\u0438\u0444\u0442, \u0440\u0430\u0437\u043c\u0435\u0440 spiteMsg.textParam = { text: this.message,  lineHeight: 15,  font: \"15px Balsamiq Sans\", fillStyle: \"black\", padding_x_l: 5,  padding_x_r: 5, padding_x: false,  padding_y: 5,  max_width: false,  textArr: false, }     spiteMsg.render_(); } } \/\/\/\u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u043c\u0435\u0442\u043e\u0434 render_ \u0441\u043f\u0440\u0430\u0439\u0442\u0430 \u0434\u043b\u044f \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \/js\/sprites \/\/\/\u0443\u0431\u0438\u0440\u0430\u0435\u043c \u0432\u0441\u0435 \u043b\u0438\u0448\u043d\u0435\u0435 \u0434\u043b\u044f \u0431\u043e\u043b\u0435\u0435 \u0431\u044b\u0441\u0442\u0440\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u044b, \u0434\u043e\u0431\u0430\u043b\u044f\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0434\u043b\u044f \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0442\u0435\u043a\u0441\u0442\u0430.  CollageSprite.prototype.render_ = function(){ if(!this.show)return; ctx.drawImage(this.frame, this.point[0], this.point[1], this.width, this.height); if(this.textParam)this.fillText(this.point[0], this.point[1]); }  \/\/\/\u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0441 \u0444\u043e\u0440\u043c\u043e\u0439 \u0432 \u0434\u043b\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439 \u0432 \u043e\u0431\u044a\u0435\u043a\u0442 StateMap  \/js\/games\/inteface_games.js  StateMap.user_message = { \/\/\u043a\u0430\u043d\u0432\u0430\u0441 container: \"user_message\", props: [[\"user_msg_btn\", \"mousedown\", \"[name='user_msg_btn']\"],                  [\"user_msg\", \"inputvalue\", \"[name='user_msg']\"],         ], methods: { user_msg_btn: function(){     var text  = this.props(\"user_msg\").getProp();  \/\/\/\/\u0442\u0435\u0441\u0442\u043e\u0432\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435                 modules.personage.message = text;             } }   } <\/code><\/pre>\n<p>\u041c\u0438\u043d\u0438-\u0447\u0430\u0442 \u0433\u043e\u0442\u043e\u0432, \u0440\u0430\u0431\u043e\u0447\u0438\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432 \u043f\u0430\u043f\u043a\u0435 collagen_2\/games\/game_3. \u0427\u0430\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 \u0442\u0440\u0430\u043d\u0441\u043b\u0438\u0442\u0435, \u0442.\u043a. socket.js \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u043a\u0438\u0440\u0438\u043b\u0438\u0446\u0443. <\/p>\n<h2>\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0432\u044b\u0431\u043e\u0440\u0430 \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430<\/h2>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/2d0\/1d7\/d34\/2d01d7d34a1d876b6acd2b602ef7ef4c.png\" width=\"968\" height=\"729\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/2d0\/1d7\/d34\/2d01d7d34a1d876b6acd2b602ef7ef4c.png\"\/><\/figure>\n<p>\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0441\u043f\u0440\u0430\u0439\u0442 \u0432\u0442\u043e\u0440\u043e\u0433\u043e \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430, \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0435\u0433\u043e \u0432 \u043f\u0440\u043e\u0435\u043a\u0442, \u0443\u0434\u0430\u043b\u0438\u043c \u0438\u0437 \u043c\u0430\u0441\u0441\u0438\u0432\u0430 tiles_common &#8212; \u043e\u0431\u044a\u0435\u043a\u0442 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0433\u043e \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430 (personage), \u0430 \u0442\u0430\u043a\u0436\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f &#8212; msg, \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0438 \u0431\u0443\u0434\u0443\u0442 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u0432 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u0430\u0441\u0441\u0438\u0432 \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0438\u0433\u0440\u044b, \u043f\u043e\u0441\u043b\u0435 \u0432\u044b\u0431\u043e\u0440\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f, \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0441\u043e\u0437\u0434\u0430\u044e\u0442\u0441\u044f \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0440\u0435\u043d\u0434\u0435\u0440. \u0422\u0430\u043a\u0436\u0435 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0441\u043f\u0440\u0430\u0439\u0442 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438 \u043a\u043e\u0441\u0442\u0440\u0430. \u0421\u043e\u0445\u0440\u0430\u043d\u0438\u043c json \u0432 \u043f\u0430\u043f\u043a\u0435 glitch_forest_2.<\/p>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043f\u0430\u043f\u043a\u0443 glitch_forest_2\/public \u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u0441\u0442\u0438\u043c \u0432 \u043d\u0435\u0435 \u0432\u0441\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0444\u0430\u0439\u043b\u044b, \u0432\u043a\u043b\u044e\u0447\u0430\u044f \u0441\u0442\u0438\u043b\u0438.<\/p>\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u043c html \u0440\u0430\u0437\u043c\u0435\u0442\u043a\u0443 \u0434\u043b\u044f \u0432\u044b\u0431\u043e\u0440\u0430 \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430, \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0441\u043a\u0440\u044b\u0442, \u0434\u043e \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0432\u0441\u0435\u0445 \u0444\u0430\u0439\u043b\u043e\u0432 &#8212; display: none.<\/p>\n<pre><code class=\"xml\">&lt;div data-chose_personage=\"container\" class=\"form-group \" style=\"display: none; padding: 10px; background-color: white; position: fixed;  top: 5px; left: 5px; z-index:5\"> &lt;p>\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430:&lt;\/p> &lt;div class=\"form-check\"> &lt;input  class=\"form-check-input\" type=\"radio\" name=\"personage_1\" id=\"\"> &lt;label class=\"form-check-label\" for=\"flexRadioDefault1\"> personage_1 &lt;\/label> &lt;\/div> &lt;div class=\"form-check\">     &lt;input class=\"form-check-input\" type=\"radio\" name=\"personage_2\" id=\"\"> &lt;label class=\"form-check-label\" for=\"flexRadioDefault2\"> personage_2 &lt;\/label> &lt;\/div> &lt;\/div><\/code><\/pre>\n<p>\u0412 \u0444\u0430\u0439\u043b \u0441\u0435\u0440\u0432\u0435\u0440\u0430 server.js \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043a\u043e\u0434, \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u043a\u0430\u0436\u0434\u044b\u0435 20 \u0441\u0435\u043a\u0443\u043d\u0434, \u0447\u0442\u043e\u0431\u044b \u0438\u0445 \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0438 \u043d\u0435 \u043e\u0441\u0442\u0430\u0432\u0430\u043b\u0438\u0441\u044c \u043f\u043e\u0441\u043b\u0435 \u0437\u0430\u043a\u0440\u044b\u0442\u0438\u044f \u0431\u0440\u043e\u0443\u0437\u0435\u0440\u0430.<\/p>\n<pre><code class=\"javascript\">\/\/\/\u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u043a\u0430\u0436\u0434\u044b\u0435 20\u0441\u0435\u043a \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0437\u0430\u043a\u0440\u044b\u0442\u0438\u044f \u043e\u043a\u043d\u0430 setInterval(function(){users={};}, 20000);<\/code><\/pre>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043b\u043e\u0433\u0438\u043a\u0443 \u0432\u044b\u0431\u043e\u0440\u0430 \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430, \u0432 \u0444\u0430\u0439\u043b game_script.js.<\/p>\n<pre><code class=\"javascript\">\/\/\/\u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u0434\u043b\u044f \u0432\u044b\u0431\u043e\u0440\u0430 \u0442\u0438\u043f\u0430 \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430 var pesonageType = null;  \/\/\/\u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 json \u0444\u0430\u0439\u043b\u0430 fetch(gameUrl).then((response) => {                  \/*                                         \u043a\u043e\u0434 \u0431\u0435\u0437 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439.....                                    *\/                     apply_code();  \/\/\/\u0430\u043d\u0438\u043c\u0430\u0446\u0438\u044f \u043a\u043e\u0441\u0442\u0440\u0430  setInterval(function(){modules.fire_1.nextFrame();}, 350);                                   \/\/\/\u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u043c \u0441\u043a\u0440\u044b\u0442\u043e\u0435 \u0432 html \u0440\u0430\u0437\u043c\u0435\u0442\u043a\u0435 \u043e\u043a\u043d\u043e \u043f\u043e\u0441\u043b\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432  HM.state.chose_personage.htmlLink.style.display = \"block\";                    maxTranslate = [-1000, -1000];    })   .catch((err) => console.error(`Fetch problem: ${err.message}`));   \/\/\/\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0442\u0438\u043f \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430 \u0432 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440 - pType function createSocket(){ \/\/\/\u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0441 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u0438\u0433\u0440\u043e\u043a\u0430\u043c\u0438   if (socketjs.isSupported()) {   \/\/ connect to the server   var socket = socketjs.connect();      \/\/\/\u043f\u0435\u0440\u0432\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435   \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440 \u0441 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430\u043c\u0438 \u043f\u0440\u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0435    socket.send('newuser', {id: userId, point: modules.personage.point,                            frame_index: modules.personage.frame_index,                            \/\/\u0442\u0438\u043f \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430                           pType: pesonageType});           \/* ....\u043a\u043e\u0434 \u0431\u0435\u0437 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439... *\/           \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/          \/\/ \u043a\u043e\u0440\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0438\u0433\u0440\u043e\u043a\u043e\u0432 \u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u0430          \/\/\/ socket.receive('coord', function(data) { \/\/\/\u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u043e\u0432\u044b\u0445 \u0438\u0433\u0440\u043e\u043a\u043e\u0432  for(var key in data){   if(data[key].id != userId){                \/\/\/\u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0442\u0438\u043f \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430 pType                 addTileCommon(data[key].id, HM.$props().sprites[data[key].pType],                                data[key].point);                   }else{                  \/\/id \u044e\u0437\u0435\u0440\u0430 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 \u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u0435 \u043e\u0442\u043b\u0438\u0447\u0430\u0435\u0442\u0441\u044f                   \/\/\u043f\u043e\u044d\u0442\u043e\u043c\u0443, \u0434\u043b\u044f \u0438\u0437\u0431\u0435\u0436\u0430\u043d\u0438\u044f \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u044b\u0445 \u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u043e\u043a                  \/\/\u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043e\u0431\u044a\u0435\u043a\u0442 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e   addTileCommon(personageId, HM.$props().sprites[data[key].pType],                                data[key].point);                     }   }         \/\/\u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0438 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u043a\u0430\u0434\u0440 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440 \u043a\u0430\u0436\u0434\u044b\u0435  100ms   var interval = setInterval(function() {                                                                                                                   \/\/\/\u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0438\u0433\u0440\u043e\u043a\u0430\u043c     socket.send('coord', {id: userId, point: modules.personage.point,                         frame_index: modules.personage.frame_index, msg:     modules.personage.message,                           \/\/\/\u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0442\u0438\u043f \u0440\u0435\u0441\u043e\u043d\u0430\u0436\u0430    pType: pesonageType});   }, 100);        \/* ....\u043a\u043e\u0434 \u0431\u0435\u0437 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439... *\/  }    }      \/\/\/\u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u043e\u0431\u044a\u0435\u043a\u0442 \u0441\u0446\u0435\u043d\u044b, \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u043d\u043e\u0432\u043e\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e \u0441 \u0442\u0435\u043a\u0441\u0442\u043e\u043c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f function addTileCommon(id, sprite, point){ \/\/if(id == \"msg\"){return;}  \u0443\u0434\u0430\u043b\u044f\u0435\u043c \u043b\u0438\u0448\u043d\u0438\u0439 \u043a\u043e\u0434 \u0442. \u043a. \u0441\u043f\u0440\u0430\u0439\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f      \/\/\u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 render var tile = new Tile(id, sprite, point); tile.message = false; tiles_common.push(tile);      \/\/\/\u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043f\u0440\u044f\u043c\u0443\u044e \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u044e \u043a\u043e\u0441\u0442\u0440\u0430 if(id == \"fire_1\")modules.fire_1 = tile;     return tile; }     \/\/\/\u0444\u043e\u0440\u043c\u0430 \u0432\u044b\u0431\u043e\u0440\u0430 \u0442\u0438\u043f\u0430 \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430  StateMap.chose_personage = {  container: \"chose_personage\", props: [[\"personage_1\", \"mousedown\", \"[name='personage_1']\"], [\"personage_2\", \"mousedown\", \"[name='personage_2']\"],           ], methods: { personage_1: function(){ this.parent.htmlLink.style.display = \"none\";                 \/\/\/\u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430 modules.personage =  addTileCommon(personageId, this.$props().sprites[\"personage_1\"], [200, 200]); pesonageType = \"personage_1\";               \/\/\/\u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0441\u043e\u043a\u0435\u0442 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u043f\u043e\u0441\u043b\u0435 \u0432\u044b\u0431\u043e\u0440\u0430 \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430 createSocket();             }, personage_2: function(){ this.parent.htmlLink.style.display = \"none\"; modules.personage =  addTileCommon(personageId, this.$props().sprites[\"personage_2\"], [200, 200]); pesonageType = \"personage_2\";                 createSocket();             } }   }        \/\/\/\u0442\u0430\u043a\u0436\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u0448\u0440\u0438\u0444\u0442\u0430 \u0434\u043b\u044f \u043f\u0440\u0435\u0434\u043e\u0442\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u043e\u0448\u0438\u0431\u043e\u043a \u0432 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439  StateMap.user_message = {  container: \"user_message\", props: [[\"user_msg_btn\", \"mousedown\", \"[name='user_msg_btn']\"], [\"user_msg\", \"inputvalue\", \"[name='user_msg']\"],           ], methods: { user_msg_btn: function(){     var text  = this.props(\"user_msg\").getProp();                 \/\/\u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0448\u0440\u0438\u0444\u0442\u0430                 var isKyr = function (str) {                    return \/[\u0430-\u044f]\/i.test(str);                  }                 if(isKyr(text)){alert(\"\u0447\u0430\u0442 \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u043a\u0438\u0440\u0438\u043b\u0438\u0446\u0443\"); return};  \/\/\/\/\u0442\u0435\u0441\u0442\u043e\u0432\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435                 modules.personage.message = text;             } }   }        <\/code><\/pre>\n<p>\u0427\u0430\u0442 \u0441 \u0432\u044b\u0431\u043e\u0440\u043e\u043c \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430 \u0433\u043e\u0442\u043e\u0432, \u043f\u0440\u043e\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u0438\u043c\u0435\u0440 \u043c\u043e\u0436\u043d\u043e \u0432 \u043f\u0430\u043f\u043a\u0435  games\/glitch_forest_2  forever start server.js. <\/p>\n<p>\u0421\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u0433\u043b\u0438\u0442\u0447 \u0434\u0435\u043c\u043e:  <a href=\"https:\/\/cloudy-axiomatic-marscapone.glitch.me\/\" rel=\"noopener noreferrer nofollow\">https:\/\/cloudy-axiomatic-marscapone.glitch.me\/<\/a><\/p>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/787088\/\"> https:\/\/habr.com\/ru\/articles\/787088\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width\"><\/figure>\n<p>\u0412 \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u0431\u0443\u0434\u0435\u0442 \u043e\u043f\u0438\u0441\u0430\u043d \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0441\u0435\u0442\u0435\u0432\u043e\u0439 \u043e\u043d\u043b\u0430\u0439\u043d \u043c\u0438\u043d\u0438 \u0438\u0433\u0440\u044b \u043d\u0430\u043f\u043e\u0434\u043e\u0431\u0438\u0435 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0447\u0430\u0442 \u043a\u043e\u043c\u043d\u0430\u0442\u044b.  \u0418\u0433\u0440\u043e\u043a\u0438 \u043c\u043e\u0433\u0443\u0442 \u043f\u0435\u0440\u0435\u0434\u0432\u0438\u0433\u0430\u0442\u044c\u0441\u044f \u043f\u043e \u043f\u043e\u043b\u044e \u0438\u0433\u0440\u044b, \u043f\u0440\u044f\u0442\u0430\u0442\u044c\u0441\u044f \u0437\u0430 \u0434\u0435\u0440\u0435\u0432\u044c\u044f\u043c\u0438, \u0442\u0430\u043a\u0436\u0435 \u0435\u0441\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u043a\u0430\u043c\u0435\u0440\u043e\u0439 \u0432\u0438\u0434\u0430. \u0414\u043b\u044f \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438\u0433\u0440\u044b \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u043a\u0430\u0447\u0430\u0442\u044c <a href=\"https:\/\/github.com\/Sergey1234Ovechkin\/collagen_2\" rel=\"noopener noreferrer nofollow\">\u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440<\/a>, \u0437\u0430\u0439\u0442\u0438 \u0432 \u043f\u0430\u043f\u043a\u0443 collagen_2\/games\/game_3, \u0432\u0432\u0435\u0441\u0442\u0438 \u0432 \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0435 <code>forever start app.js. <\/code>\u0414\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0438\u0433\u0440\u044b \u0442\u0440\u0435\u0431\u0443\u044e\u0442\u0441\u044f \u043c\u043e\u0434\u0443\u043b\u0438 socket.js \u0438 forever(\u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u0430\u044f \u0438\u043d\u0441\u0442\u0430\u043b\u044f\u0446\u0438\u044f).<code> <\/code><\/p>\n<h2>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0441\u0446\u0435\u043d\u044b \u0438\u0433\u0440\u044b<\/h2>\n<p>\u0414\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0441\u0446\u0435\u043d\u044b \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u0442\u044c \u0432\u0441\u0435 \u0441\u043f\u0440\u0430\u0439\u0442\u044b: \u0444\u043e\u043d\u043e\u0432\u043e\u0439 \u043f\u043e\u0434\u043b\u043e\u0436\u043a\u0438, \u0434\u0435\u0440\u0435\u0432\u044c\u0435\u0432, \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430 \u0441 \u043f\u043e\u043a\u0430\u0434\u0440\u043e\u0432\u043e\u0439 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0435\u0439, \u0437\u0430\u0442\u0435\u043c \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0438\u0445. \u0414\u0430\u043b\u0435\u0435 \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u0432 \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440 \u0441\u0446\u0435\u043d\u044b, \u0434\u043b\u044f \u044d\u0442\u043e \u043d\u0430\u0436\u0430\u0442\u044c \u043a\u043d\u043e\u043f\u043a\u0443 code \u0441\u0438\u043d\u0435\u0433\u043e \u0446\u0432\u0435\u0442\u0430, \u0437\u0430\u0442\u0435\u043c \u043a\u043d\u043e\u043f\u043a\u0443 test. \u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0444\u043e\u043d\u043e\u0432\u043e\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0442\u043e\u0433\u043e \u0436\u0435 \u0440\u0430\u0437\u043c\u0435\u0440\u0430, \u0447\u0442\u043e \u0438 \u0441\u0446\u0435\u043d\u0430, \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0432\u0441\u0435 \u0441\u043f\u0440\u0430\u0439\u0442\u044b. \u0420\u0430\u0437\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u0441\u043f\u0440\u0430\u0439\u0442\u044b \u0431\u0435\u043a\u0433\u0440\u043e\u0443\u043d\u0434\u0430, \u0434\u0435\u0440\u0435\u0432\u044c\u0435\u0432 \u0438 \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430 \u043d\u0430 \u0441\u0446\u0435\u043d\u0435. \u0414\u043b\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u0449\u0435\u043d\u0438\u044f \u043a\u0430\u043c\u0435\u0440\u044b \u0432\u0438\u0434\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u043d\u043e\u043f\u043a\u0438 &#8212; a, w, s, d. \u0414\u0430\u043b\u0435\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0441\u043f\u0440\u0430\u0439\u0442\u044b \u0431\u0435\u043a\u0433\u0440\u043e\u0443\u043d\u0434\u0430 \u043a\u043d\u043e\u043f\u043a\u043e\u0439 add tile bg &#8212; \u0441\u0438\u043d\u0435\u0433\u043e \u0446\u0432\u0435\u0442\u0430, \u0441\u043f\u0440\u0430\u0439\u0442\u044b \u0441\u0446\u0435\u043d\u044b \u0438 \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430 \u043a\u043d\u043e\u043f\u043a\u043e\u0439 add tile.<\/p>\n<p>\u041e\u0434\u0438\u043d \u0438 \u0442\u043e\u0442 \u0436\u0435 \u0441\u043f\u0440\u0430\u0439\u0442 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0441\u0446\u0435\u043d\u044b, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0434\u0435\u0440\u0435\u0432\u044c\u0435\u0432, \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u0441\u043f\u0440\u0430\u0439\u0442 \u0432 \u043d\u043e\u0432\u043e\u0435 \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0438 \u0441\u043d\u043e\u0432\u0430 \u043d\u0430\u0436\u0430\u0442\u044c \u043a\u043d\u043e\u043f\u043a\u0443 add tile \u0438\u043b\u0438 add tile bg.  Id \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0441\u0446\u0435\u043d\u044b \u043c\u043e\u0436\u043d\u043e \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c, \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u043d\u0435\u043d\u0443\u0436\u043d\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 \u0438\u0437 \u043c\u0430\u0441\u0441\u0438\u0432\u043e\u0432 tile_common \u0438 tilt_bg,  \u043f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u043d\u0430\u0436\u0430\u0442\u044c \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0443 update \u0437\u0435\u043b\u0435\u043d\u043e\u0433\u043e \u0446\u0432\u0435\u0442\u0430. \u0412 \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u043c \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u0435 \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u0438\u0441\u0430\u0442\u044c \u043a\u043e\u0434 \u0434\u043b\u044f <a href=\"https:\/\/habr.com\/ru\/articles\/762652\/\" rel=\"noopener noreferrer nofollow\">\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438<\/a> \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0432 \u0431\u0440\u043e\u0443\u0437\u0435\u0440\u0435.  \u041f\u043e\u0441\u043b\u0435 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0438 \u0441\u0446\u0435\u043d\u044b &#8212; \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0435\u0435 \u0432 \u043f\u0430\u043f\u043a\u0435 \u0434\u043b\u044f \u0438\u0433\u0440 collagen_2\/games\/game_name \u0432 json \u0444\u0430\u0439\u043b ,\u043d\u0430\u0436\u0430\u0432 \u043a\u043d\u043e\u043f\u043a\u0443 save project &#8212; \u0432 \u043d\u0438\u0437\u0443 \u043f\u0430\u043d\u0435\u043b\u0435\u0439 \u0441 \u043a\u043d\u043e\u043f\u043a\u0430\u043c\u0438.<\/p>\n<h2>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u043b\u043e\u0433\u0438\u043a\u0438 \u0438\u0433\u0440\u044b \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u043e\u0439 \u0447\u0430\u0441\u0442\u0438<\/h2>\n<p>\u0412 \u0444\u0430\u0439\u043b\u0435 index.html \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043f\u0443\u0442\u044c \u043a \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c\u0443 \u0441\u043a\u0440\u0438\u043f\u0442\u0443 \u0438\u0433\u0440\u044b &#8212; ..\/..\/..\/collagen_2\/games\/game_name\/game_name.js, \u0432  \u0444\u0430\u0439\u043b\u0435 game_name.js \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043f\u0443\u0442\u044c \u043a json \u0444\u0430\u0439\u043b\u0443 \u0441\u0446\u0435\u043d\u044b \u0432 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 gameUrl, \u0442\u0430\u043a\u0436\u0435 \u043c\u0435\u043d\u044f\u0435\u043c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043f\u0430\u043f\u043a\u0438 \u0438\u0433\u0440\u044b \u0432 \u0444\u0430\u0439\u043b\u0435 app.js.<\/p>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043b\u043e\u0433\u0438\u043a\u0443 \u0438\u0433\u0440\u044b \u0432  \u0444\u0430\u0439\u043b\u0435 game_name.js: <\/p>\n<pre><code class=\"javascript\">\/\/\/\/\/\/\/\/\/\/\/\/\/\/\u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u0440\u0430\u0437\u043c\u0435\u0440 \u043a\u0430\u0440\u0442\u044b \u0441\u043c\u0435\u0449\u0435\u043d\u0438\u044f \u043a\u0430\u043c\u0435\u0440\u044b \u0432\u0438\u0434\u0430  var maxTranslate = [-1000, -0]; \/\/\u0430\u0434\u0440\u0435\u0441 json \u0444\u0430\u0439\u043b\u0430 \u0441\u043f\u0440\u0430\u0439\u0442\u043e\u0432 var gameUrl = \"http:\/\/localhost:3000\/collagen_2\/games\/game_1\/game_1.json\"; var personageId = \"personage\";   \/\/\u0430\u043d\u0438\u043c\u0430\u0446\u0438\u044f \u0441\u0446\u0435\u043d\u044b function apply_code(){         \/\/\u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u0432\u043a\u043e\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438   mode = \"animation\"; if (modules.animation)modules.animation.isOff = true; updateCommonTiles(HM.$props().sprites); updateBgTiles(HM.$props().sprites); \/\/\u0440\u0435\u0436\u0438\u043c code \u0447\u0442\u043e\u0431\u044b \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e Tiles HM.$$(\"emiter-operation-with\").set(\"code\");   \/\/\/\u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u044e \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430 modules.personage = null;  \/\/\u043d\u0430\u0445\u043e\u0434\u0438\u043c \u043e\u0431\u044a\u0435\u043a\u0442 \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430 \u0432 \u043c\u0430\u0441\u0441\u0438\u0432\u0435 tiles_common \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u043e\u043c \u0432 test  for(var i=0; i&lt;tiles_common.length; i++){ if(tiles_common[i].id == personageId){ modules.personage = tiles_common[i]; } }  \/\/\/\u0444\u043b\u0430\u0433 \u043b\u0438\u043a\u0430 \u043f\u043e \u043a\u043d\u043e\u043f\u043a\u0430\u043c \u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u044b var click  = false; \/\/\/\u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430 var interval  = 100;  \/\/\/id \u0442\u0430\u0439\u043c\u0435\u0440\u0430 \u0434\u043b\u044f \u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b\u0430 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438 var timerId  = 0;  \/\/\/\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u043d\u0430\u0436\u0430\u0442\u0438\u044f \u0441\u0442\u0440\u0435\u043b\u043e\u043a modules.keydown = function(key){ if(key == \"ArrowUp\"){  if (click == true)return; click = true; clearInterval(timerId);     timerId = setInterval(move, interval, 11, 15, 12, 0, -10); }else if(key == \"ArrowDown\"){ if (click == true)return; click = true; clearInterval(timerId);     timerId = setInterval(move, interval, -1, 3, 0, 0, 10); }else if(key == \"ArrowRight\"){  if (click == true)return; click = true; clearInterval(timerId);     timerId = setInterval(move, interval, 7, 11, 8, 10, 0);  }else if(key == \"ArrowLeft\"){ if (click == true)return; click = true; clearInterval(timerId);     timerId = setInterval(move, interval, 3, 7, 4, -10, 0); } } \/\/\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u043e\u0442\u0436\u0430\u0442\u0438\u044f \u043a\u043d\u043e\u043f\u043e\u043a-\u0441\u0442\u0440\u0435\u043b\u043e\u043a modules.keyup = function(key){ clearInterval(timerId); click = false; }  \/\/\/\u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430 \u0438 \u0441\u043c\u0435\u043d\u044b \u043a\u0430\u0434\u0440\u043e\u0432 function move(arg1,arg2,arg3, arg4, arg5) {      if(modules.personage.frame_index > arg1 &amp;&amp;  modules.personage.frame_index &lt; arg2){              modules.personage.nextFrame();}else{             modules.personage.nextFrame(arg3); } modules.personage.move(arg4, arg5); }  \/\/\u0437\u0430\u043f\u0443\u0441\u043a \u0446\u0438\u043a\u043b\u0430 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0444\u043e\u043d\u043e\u0432\u044b\u0445 \u0438 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u0441\u043f\u0440\u0430\u0439\u0442\u043e\u0432, \u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435 \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430 modules.animation=animationLopLayer(tiles_bg,tiles_common, 40);  }   \/\/\/\u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 json \u0444\u0430\u0439\u043b\u0430, \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0441\u043f\u0440\u0430\u0439\u0442\u043e\u0432 \u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0441\u0446\u0435\u043d\u044b - Tile fetch(gameUrl)   .then((response) => {     if (!response.ok) {       throw new Error(`HTTP error: ${response.status}`);     }     return response.json();   })   .then((json) => {     \/\/console.log(json)     var dataURL = 'data:image\/png;base64,' + json.backImg;     var context  = HM; \/\/\u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043a\u043e\u0440\u0435\u043d\u044c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f                        \/\/\/ tiles_bg_save, tiles_common_save - \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043c\u0430\u0441\u0441\u0438\u0432\u044b                        \/\/\/\u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 - \u0444\u0430\u0439\u043b js\/games\/main_games.js                     tiles_common_save = JSON.parse(json.tiles_common_save);         tiles_bg_save = JSON.parse(json.tiles_bg_save);  mainImgScale_x = 1; mainImgScale_y = 1;  img.src = dataURL;                         \/\/\/\u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u0444\u043e\u043d\u043e\u0432\u0443\u044e \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0443 img.onload = function(){  startImg(); }                         \/\/\/\u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0441\u043f\u0440\u0430\u0439\u0442\u043e\u0432 \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u0441\u044b\u043b\u0430\u044e\u0442\u0441\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0441\u0446\u0435\u043d\u044b \u0438                          \/\/\/\u0431\u0435\u043a\u0433\u0440\u043e\u0443\u043d\u0434\u0430 \u043f\u0440\u0438 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0438 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438 for(var key in  json.sprites){    var sprite = createFromPC(key, context, false, json.sprites[key]);    if(sprite)context.$$(\"emiter-create-sprite\").set(key); }                 \/\/\u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0431\u0435\u043a\u0433\u0440\u043e\u0443\u043d\u0434\u0430                tiles_bg = []; for(var i=0; i&lt;tiles_bg_save.length; i++){ if(context.$props().sprites[tiles_bg_save[i].parent])tiles_bg.push(new Tile(tiles_bg_save[i].id, context.$props().sprites[tiles_bg_save[i].parent], tiles_bg_save[i].point)); }                 \/\/\/\u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0441\u0446\u0435\u043d\u044b \u0438 \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430 tiles_common = []; for(var i=0; i&lt;tiles_common_save.length; i++){ if(context.$props().sprites[tiles_common_save[i].parent])tiles_common.push(new Tile(tiles_common_save[i].id, context.$props().sprites[tiles_common_save[i].parent], tiles_common_save[i].point)); } \/\/\/\u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438 apply_code();   })   .catch((err) => console.error(`Fetch problem: ${err.message}`));<\/code><\/pre>\n<p> \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u043b\u043e\u0433\u0438\u043a\u0438 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438 \u0441\u0446\u0435\u043d\u044b \u0438 \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430 \u0437\u0430\u043a\u043e\u043d\u0447\u0435\u043d\u0430, \u043f\u0440\u043e\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043c\u043e\u0436\u043d\u043e \u0432 \u043f\u0430\u043f\u043a\u0435  collagen_2\/games\/game_1.<\/p>\n<h2>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u043e\u0439 \u0441\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0435\u0439 \u0438\u0433\u0440\u044b<\/h2>\n<p>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0441\u0435\u0440\u0432\u0435\u0440\u0430.<\/p>\n<p>\u0414\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u043e\u0439 \u0447\u0430\u0441\u0442\u0438  \u0431\u044b\u043b\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 socket.js \u0438 \u043c\u043e\u0434\u0443\u043b\u044c forever \u0434\u043b\u044f  \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0430.<\/p>\n<pre><code class=\"javascript\">\/\/\u043f\u0440\u0438 \u0432\u044b\u0445\u043e\u0434\u0435 \u0438\u0433\u0440\u043e\u043a\u0430 \u0441\u0435\u0440\u0432\u0435\u0440 \u043f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u0442\u0441\u044f  \/\/\/ \u0434\u043b\u044f \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043c\u043e\u0434\u0443\u043b\u044c forever.  \u0417\u0430\u043f\u0443\u0441\u043a \u0441\u0435\u0440\u0432\u0435\u0440\u0430:   forever start app.js  var users = {}; \/\/\/\u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0438 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u043a\u0430\u0434\u0440 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 var socketjs = require('socket.js');   \/\/\/\/\/\/\/\u0441\u0432\u044f\u0437\u044c \u0441 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u0430\u043c\u0438 \/\/\/\/\u0434\u0430\u043d\u043d\u044b\u0435 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438 \u0432\u0441\u0435\u0445 \u0438\u0433\u0440\u043e\u043a\u043e\u0432 socketjs(server, function(socket, reconnectData) {     console.log(reconnectData);       \/\/\u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043d\u043e\u0432\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f   if (reconnectData === null) {     console.log('A user connected.');   } else {     console.log('A user reconnected with: ', reconnectData);   }     \/\/\/\u043d\u043e\u0432\u044b\u0439 \u0438\u0433\u0440\u043e\u043a \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c users    socket.receive('newuser', function(message) { users[message.id] = message;   });         \/\/ \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0441 \u043a\u043b\u0438\u0435\u043d\u0442\u0430   socket.receive('coord', function(message) { users[message.id] = message;     });    \/\/\u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0438\u0433\u0440\u043e\u043a\u0430\u043c \u043a\u0430\u0436\u0434\u044b\u0435 100ms   var interval = setInterval(function() { socket.send('coord', users);   }, 100);     socket.close(function(data) {     console.log('A user disconnected.');     clearInterval(interval); return data;   }); });<\/code><\/pre>\n<p>\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u043e\u043a\u0435\u0442-\u0441\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0449\u0435\u0439 \u0432 \u0444\u0430\u0439\u043b \u043a\u043b\u0438\u0435\u043d\u0442\u0430.<\/p>\n<pre><code class=\"javascript\">\/\/\u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \/\/\u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0435 id \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440 (\u0442.\u043a. \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0438 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0435 \u0434\u043b\u044f \u0432\u0441\u0435\u0445) var userId = \"user_\" + Math.floor(Math.random() * 1000); \/\/\/\u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0441\u0446\u0435\u043d\u044b var numTiles = 0; \/\/\/\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0438\u0433\u0440\u043e\u043a\u043e\u0432 var numUsers = 1;  \/\/\/\u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0437\u0430\u043f\u0443\u0441\u043a \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0432 fetch \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 json \u0441\u0446\u0435\u043d\u044b                 \/\/\/\u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0441\u0446\u0435\u043d\u044b numTiles = tiles_common.length; \/\/\/\u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438 apply_code();  createSocket();  \/\/\/\u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043b\u043e\u0433\u0438\u043a\u0443 \u0441\u043e\u043a\u0435\u0442 \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u044f function createSocket(){ \/\/\/\u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0441 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u0438\u0433\u0440\u043e\u043a\u0430\u043c\u0438   if (socketjs.isSupported()) {   \/\/ connect to the server   var socket = socketjs.connect();      \/\/\/\u043f\u0435\u0440\u0432\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435   \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440 \u0441 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430\u043c\u0438 \u043f\u0440\u0438 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0435    socket.send('newuser', {id: userId, point: modules.personage.point, frame_index: modules.personage.frame_index});    \/\/ log a message if we get disconnected   socket.disconnect(function(data) {     console.log('Temporarily disconnected.');   });    \/\/ log a message when we reconnect   socket.reconnect(function() {     console.log('Reconnected.');      \/\/ whatever we return here is sent back to the server     return 'reconnected';   });     \/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/      \/\/ \u043a\u043e\u0440\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0438\u0433\u0440\u043e\u043a\u043e\u0432 \u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u0430    socket.receive('coord', function(data) {  \/\/\u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0441\u0446\u0435\u043d\u044b \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0438\u043b\u0438 \u0432\u044b\u0445\u043e\u0434\u0430 \u0438\u0433\u0440\u043e\u043a\u0430   if(Object.keys(data).length != numUsers){ \/\/\u0443\u0434\u0430\u043b\u044f\u0435\u043c \u0432\u0441\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0441\u0446\u0435\u043d\u044b tiles_common.splice(0, tiles_common.length); \/\/\u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0435 \u043e\u0431\u0435\u043a\u0442\u044b  for(var i=0; i&lt;tiles_common_save.length; i++){               \/\/HM - \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043a\u043e\u0440\u0435\u043d\u044c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f  if(HM.$props().sprites[tiles_common_save[i].parent]){                      tiles_common.push(new Tile(tiles_common_save[i].id, HM.$props().sprites[tiles_common_save[i].parent], tiles_common_save[i].point));  }          }                    \/\/\/\u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u043e\u0432\u044b\u0445 \u0438\u0433\u0440\u043e\u043a\u043e\u0432  for(var key in data){   if(data[key].id != userId){ var tile = new Tile(data[key].id, HM.$props().sprites[modules.personage.parent], data[key].point);  tiles_common.push(tile);   }   }  \/\/\u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436\u0430  for(var i=0; i&lt;tiles_common.length; i++){                if(tiles_common[i].id == personageId){            tiles_common[i] = modules.personage;             }          }     \/\/ console.log(tiles_common);  numUsers  = Object.keys(data).length;\/\/\u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0438\u0433\u0440\u043e\u043a\u043e\u0432  }; \/\/\/\u0432\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u044e<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-365574","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/365574","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=365574"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/365574\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=365574"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=365574"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=365574"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}