{"id":340874,"date":"2022-11-07T15:00:19","date_gmt":"2022-11-07T15:00:19","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=340874"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=340874","title":{"rendered":"<span>\u041a\u0430\u043a \u044f \u0442\u043e\u0436\u0435 \u041f\u043e\u043d\u0433 \u043d\u0430 JS \u0434\u0435\u043b\u0430\u043b<\/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<p>\u041a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u044f \u043d\u0430\u0447\u0430\u043b \u0447\u0442\u043e-\u0442\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u0442\u044c \u0432 JavaScript, \u044f \u043f\u0440\u0438\u043d\u044f\u043b\u0441\u044f \u0438\u0441\u043a\u0430\u0442\u044c \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0435 \u0433\u0430\u0439\u0434\u044b \u0447\u0442\u043e\u0431 \u043f\u043e\u0432\u0442\u043e\u0440\u0438\u0442\u044c \u043a\u0430\u043a\u0443\u044e-\u043d\u0438\u0431\u0443\u0434\u044c \u0438\u0433\u0440\u0443. \u041f\u0435\u0440\u0432\u043e\u0439 \u0442\u0430\u043a\u043e\u0439 \u0438\u0433\u0440\u043e\u0439 \u0441\u0442\u0430\u043b\u0430 <a href=\"https:\/\/buninman.github.io\/Snake\/\" rel=\"noopener noreferrer nofollow\">\u0437\u043c\u0435\u0439\u043a\u0430<\/a>.<\/p>\n<p>\u041d\u0435 \u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u043e\u043d\u0430 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u0432\u0442\u043e\u0440\u0435\u043d\u0438\u0435\u043c \u0447\u0443\u0436\u043e\u0433\u043e \u0433\u0430\u0439\u0434\u0430, \u0438\u0437-\u0437\u0430 \u0442\u043e\u0433\u043e \u044f \u043f\u0440\u043e\u0430\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043b \u0432 \u043d\u0435\u0439 \u043a\u0430\u0436\u0434\u0443\u044e \u0441\u0442\u0440\u043e\u0447\u043a\u0443 \u043a\u043e\u0434\u0430, \u043c\u043d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043f\u043e\u0447\u0435\u0440\u043f\u043d\u0443\u0442\u044c \u043d\u0435\u043c\u0430\u043b\u043e \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0445 \u0437\u043d\u0430\u043d\u0438\u0439 \u0438 \u043d\u0430\u0432\u044b\u043a\u043e\u0432. \u042f \u0442\u0430\u043a\u0436\u0435 \u0441\u043c\u043e\u0433 \u0441\u0430\u043c \u0432\u043d\u0435\u0441\u0442\u0438 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432 \u0435\u0435 \u043a\u043e\u0434.<\/p>\n<h2>\u041f\u043e\u0432\u0442\u043e\u0440\u0438\u043b<\/h2>\n<p>\u041f\u043e\u0441\u043b\u0435, \u043f\u043e\u0434 \u0432\u043f\u0435\u0447\u0430\u0442\u043b\u0435\u043d\u0438\u0435\u043c \u043e\u0442 \u043f\u0440\u043e\u0434\u0435\u043b\u0430\u043d\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u044b \u044f \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043b \u043a \u043f\u043e\u0432\u0442\u043e\u0440\u0435\u043d\u0438\u044e \u0438\u0433\u0440\u044b \u041f\u043e\u043d\u0433. \u041f\u043e\u0432\u0442\u043e\u0440\u0438\u0442\u044c \u0441\u0430\u043c \u0433\u0430\u0439\u0434 \u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c \u0443\u0436\u0435 \u043d\u0435 \u0442\u0440\u0443\u0434\u043d\u043e, \u043d\u043e \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u0430\u043d\u0430\u043b\u0438\u0437\u0430 \u0441\u0442\u0430\u043b\u043e \u044f\u0441\u043d\u043e, \u0447\u0442\u043e \u043a\u043e\u0434 \u043e\u0447\u0435\u043d\u044c \u0441\u043b\u043e\u0436\u043d\u044b\u0439 \u0434\u043b\u044f \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u044f, \u0432\u0441\u0435 \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u043f\u0435\u0440\u0435\u043f\u043b\u0435\u0442\u0435\u043d\u043e \u0438 \u0437\u0430\u043f\u0443\u0442\u0430\u043d\u043e.<\/p>\n<p>\u0415\u0449\u0435 \u043d\u0435\u0434\u0430\u0432\u043d\u043e \u044f \u0431\u044b \u043f\u043e\u0434\u0443\u043c\u0430\u043b, \u0447\u0442\u043e \u044d\u0442\u043e \u044f \u043d\u0435 \u0432\u0441\u0435 \u043f\u043e\u043d\u0438\u043c\u0430\u044e, \u043d\u043e \u0441\u0435\u0439\u0447\u0430\u0441 \u044f \u0443\u0436\u0435 \u0432\u0438\u0434\u0435\u043b \u043a\u0430\u043a \u044d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043b\u0443\u0447\u0448\u0435.<\/p>\n<h2>\u041f\u0435\u0440\u0435\u043e\u0441\u043c\u044b\u0441\u043b\u0438\u043b<\/h2>\n<p>\u042f \u043f\u0438\u0441\u0430\u043b \u044d\u0442\u043e\u0442 \u041f\u043e\u043d\u0433 \u0441 \u043d\u0443\u043b\u044f, \u0432\u0437\u044f\u0432 \u0438\u0437 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0430 \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438 \u043a\u043e\u043d\u0446\u0435\u043f\u0446\u0438\u0438. \u041f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u043f\u043e\u043c\u0435\u043d\u044f\u043b \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443, \u0434\u043e\u0431\u0430\u0432\u0438\u043b \u043c\u043e\u0434\u0443\u043b\u044c \u0441 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u043c\u0438, \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u0432\u044b\u043d\u0435\u0441 \u0432\u0441\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0440\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u044f \u0438 \u043c\u043d\u043e\u0433\u043e\u0435 \u0434\u0440\u0443\u0433\u043e\u0435.<\/p>\n<p>\u0423\u0447\u0438\u0442\u044b\u0432\u0430\u044f \u043c\u043e\u0439 \u0441\u043e\u0432\u0441\u0435\u043c \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0438\u0439 \u043e\u043f\u044b\u0442 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u0447\u0443\u0442\u044c \u043c\u0435\u043d\u044c\u0448\u0435 2 \u043c\u0435\u0441\u044f\u0446\u0435\u0432, \u044f \u043e\u0447\u0435\u043d\u044c \u0433\u043e\u0440\u0436\u0443\u0441\u044c \u043f\u0440\u043e\u0434\u0435\u043b\u0430\u043d\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u043e\u0439.<\/p>\n<h2>\u0420\u0430\u0441\u043f\u0438\u0441\u0430\u043b  <\/h2>\n<p>\u0412 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u043f\u043e\u0441\u0442\u0430\u0440\u0430\u043b\u0441\u044f \u0440\u0430\u0441\u043f\u0438\u0441\u0430\u0442\u044c \u043a\u0430\u0436\u0434\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0438 \u0438\u0437\u043b\u043e\u0436\u0438\u0442\u044c \u0445\u043e\u0434 \u0441\u0432\u043e\u0438\u0445 \u043c\u044b\u0441\u043b\u0435\u0439. \u042d\u0442\u043e \u0437\u0430\u043d\u044f\u043b\u043e \u043f\u0440\u0438\u043b\u0438\u0447\u043d\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438, \u043d\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u043a\u043e\u043c\u0443-\u0442\u043e \u0437\u0430\u0439\u0434\u0435\u0442 \u0442\u0430\u043a\u043e\u0439 \u0433\u0430\u0439\u0434, \u043b\u0438\u0447\u043d\u043e \u043c\u043d\u0435 \u0438\u043d\u043e\u0433\u0434\u0430 \u043c\u043d\u0435 \u043d\u0435 \u0445\u0432\u0430\u0442\u0430\u043b\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0439 \u043b\u043e\u0433\u0438\u043a\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0439, \u043f\u043e\u044f\u0441\u043d\u0435\u043d\u0438\u0439 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u043a\u0443\u0434\u0430 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f \u0438 \u0437\u0430\u0447\u0435\u043c.<\/p>\n<p>\u0411\u0443\u0434\u0443 \u0440\u0430\u0434, \u0435\u0441\u043b\u0438 \u043f\u043e\u0434\u0441\u043a\u0430\u0436\u0438\u0442\u0435 \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0443\u043b\u0443\u0447\u0448\u0438\u0442\u044c \u043a\u043e\u0434 \u0438\u043b\u0438 \u043d\u0430\u0439\u0434\u0435\u0442\u0435 \u0438 \u0443\u043a\u0430\u0436\u0438\u0442\u0435 \u043d\u0430 \u043e\u0448\u0438\u0431\u043a\u0438 \u0432 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f\u0445, \u0434\u0430\u0436\u0435 \u043e\u0440\u0444\u043e\u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0435.<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td>\n<p align=\"center\">\u0413\u0438\u0442\u0445\u0430\u0431 \u0441 \u043c\u043e\u0438\u043c \u041f\u043e\u043d\u0433\u043e\u043c \u0442\u0443\u0442: <a href=\"https:\/\/github.com\/buninman\/pong\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/buninman\/pong<\/a>  <\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u0410 \u0432\u043e\u0442 <a href=\"https:\/\/youtu.be\/tHnPWQKX-wE\" rel=\"noopener noreferrer nofollow\">\u0432\u0438\u0434\u0435\u043e-\u0433\u0430\u0439\u0434<\/a> \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0438\u043d\u0433-\u043f\u043e\u043d\u0433\u0430 \u043e\u0442 \u0430\u0432\u0442\u043e\u0440\u0430, \u0430 \u0432\u043e\u0442 \u0435\u0433\u043e <a href=\"https:\/\/github.com\/EpicLegend\/ping-pong\" rel=\"noopener noreferrer nofollow\">\u043a\u043e\u0434 \u043d\u0430 \u0433\u0438\u0442\u0445\u0430\u0431\u0435<\/a>.<\/p>\n<blockquote>\n<p>\u041a\u0441\u0442\u0430\u0442\u0438, \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u0430\u044f \u0438\u0433\u0440\u0430 1972 \u0433\u043e\u0434\u0430 \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f Pong, \u0430 \u043f\u0438\u043d\u0433-\u043f\u043e\u043d\u0433. \u0425\u043e\u0442\u044f \u0438\u0434\u0435\u0435\u0439-\u043f\u0440\u0430\u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u0438\u0446\u0435\u0439 \u0434\u043b\u044f \u043d\u0435\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0431\u044b\u043b \u043d\u0430\u0441\u0442\u043e\u043b\u044c\u043d\u044b\u0439 \u0442\u0435\u043d\u043d\u0438\u0441.<\/p>\n<p>\u0427\u0442\u043e \u043f\u0440\u0438\u043c\u0435\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u043e, \u041f\u043e\u043d\u0433 \u0431\u044b\u043b\u0430 \u043f\u0435\u0440\u0432\u043e\u0439 \u043a\u043e\u043c\u043c\u0435\u0440\u0447\u0435\u0441\u043a\u0438 \u0443\u0441\u043f\u0435\u0448\u043d\u043e\u0439 \u0432\u0438\u0434\u0435\u043e\u0438\u0433\u0440\u043e\u0439.<\/p>\n<\/blockquote>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/3ef\/587\/64c\/3ef58764cd61836408e7d7101dc99e02.gif\" width=\"800\" height=\"500\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/3ef\/587\/64c\/3ef58764cd61836408e7d7101dc99e02.gif\"\/><figcaption><\/figcaption><\/figure>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td>\n<p align=\"center\"><a href=\"https:\/\/buninman.github.io\/Pong\/\" rel=\"noopener noreferrer nofollow\"> \u0422\u0443\u0442 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0438\u0433\u0440\u0430\u0442\u044c \u0432 \u0433\u043e\u0442\u043e\u0432\u044b\u0439 \u041f\u043e\u043d\u0433<\/a><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<hr\/>\n<p><a class=\"anchor\" name=\"begin\" id=\"begin\"><\/a><\/p>\n<h2>\u041d\u0430\u0447\u0430\u043b\u043e<\/h2>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/9a4\/c80\/ac5\/9a4c80ac55501718d603b621f75e4ad2.png\" width=\"1920\" height=\"700\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/9a4\/c80\/ac5\/9a4c80ac55501718d603b621f75e4ad2.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u041d\u0430\u0431\u0440\u043e\u0441\u0430\u043b \u0441\u0445\u0435\u043c\u0443, \u0447\u0442\u043e\u0431 \u0431\u044b\u043b\u043e \u043f\u043e\u043d\u044f\u0442\u043d\u0435\u0435, \u0447\u0442\u043e \u043a\u0443\u0434\u0430 \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u0442\u0441\u044f. \u041d\u043e \u043d\u0430 \u044d\u0442\u043e\u0442 \u0440\u0430\u0437 \u043c\u044b \u043f\u043e\u0439\u0434\u0435\u043c \u043d\u0435 \u043f\u043e \u043f\u043e\u0440\u044f\u0434\u043a\u0443 \u0441\u0445\u0435\u043c\u044b, \u0430 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043f\u043e-\u0434\u0440\u0443\u0433\u043e\u043c\u0443. \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0442\u0435 \u043c\u043e\u0434\u0443\u043b\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0432\u0435\u0437\u0434\u0435, \u0442\u0430\u043a\u0438\u0435 \u043a\u0430\u043a \u0444\u0430\u0439\u043b \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a \u0438 \u0440\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u0435.<\/p>\n<ol>\n<li>\n<p><a href=\"#setting\" rel=\"noopener noreferrer nofollow\">setting.js<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#canvas\" rel=\"noopener noreferrer nofollow\">canvas.js<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#printer\" rel=\"noopener noreferrer nofollow\">printer.js<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#game\" rel=\"noopener noreferrer nofollow\">game.js<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#ball\" rel=\"noopener noreferrer nofollow\">ball.js<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#player\" rel=\"noopener noreferrer nofollow\">player.js<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#index\" rel=\"noopener noreferrer nofollow\">index.html<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#style\" rel=\"noopener noreferrer nofollow\">style.css<\/a><\/p>\n<\/li>\n<\/ol>\n<hr\/>\n<p><a class=\"anchor\" name=\"setting\" id=\"setting\"><\/a><\/p>\n<h2>setting.js<\/h2>\n<p>\u041c\u043e\u0434\u0443\u043b\u044c \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a. \u042f \u0441\u043b\u043e\u0436\u0438\u043b \u0441\u044e\u0434\u0430 \u0432\u0441\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0432 \u0438\u0433\u0440\u0435, \u043a\u0440\u043e\u043c\u0435 \u043d\u0430\u0434\u043f\u0438\u0441\u0435\u0439 \u0438 \u0440\u0430\u0437\u043c\u0435\u0440\u043e\u0432 \u0448\u0440\u0438\u0444\u0442\u043e\u0432. \u0414\u043e\u0441\u0442\u0443\u043f \u043a \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u0443 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a \u0435\u0441\u0442\u044c \u0443 \u0432\u0441\u0435\u0445 \u043c\u043e\u0434\u0443\u043b\u0435\u0439 \u0438 \u043e\u043d \u0432\u0441\u0435\u0433\u0434\u0430 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0438\u0441\u0432\u043e\u0435\u043d \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 set.<\/p>\n<pre><code class=\"javascript\">export default class Setting {   constructor() {     this.boxWidth = 800     this.boxHeight = 500     \/\/ \u0412\u044b\u0441\u043e\u0442\u0430 \u0438 \u0448\u0438\u0440\u0438\u043d\u0430 \u0438\u0433\u0440\u043e\u0432\u043e\u0433\u043e \u043f\u043e\u043b\u044f, \u0438 \u0432\u0441\u0435\u0445 \u0441\u043b\u043e\u0435\u0432 \u043a\u0430\u043d\u0432\u0430\u0441\u0430     this.boxRound = 20     \/\/ \u0420\u0430\u0434\u0438\u0443\u0441 \u0437\u0430\u043a\u0440\u0443\u0433\u043b\u0435\u043d\u0438\u044f \u0443\u0433\u043b\u043e\u0432 \u0438\u0433\u0440\u043e\u0432\u043e\u0433\u043e \u043f\u043e\u043b\u044f     this.boxColor = '#333333'     \/\/ \u0421\u0435\u0440\u044b\u0439 \u0446\u0432\u0435\u0442 \u0437\u0430\u043b\u0438\u0432\u043a\u0438 \u0438\u0433\u0440\u043e\u0432\u043e\u0433\u043e \u043f\u043e\u043b\u044f.      this.lineWidth = 6     \/\/ \u0422\u043e\u043b\u0449\u0438\u043d\u0430 \u043b\u0438\u043d\u0438\u0439     this.lineColor = '#232323'     \/\/ \u0426\u0432\u0435\u0442 \u043b\u0438\u043d\u0438\u0439. \u0422\u0435\u043c\u043d\u043e-\u0441\u0435\u0440\u044b\u0439, \u043a\u0430\u043a \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0444\u043e\u043d \u043e\u043a\u043d\u0430 \u0431\u0440\u0443\u0437\u0435\u0440\u0430 \u0432 CSS     this.textColor = '#EBEBEB'     \/\/ \u0421\u0432\u0435\u0442\u043b\u043e-\u0441\u0435\u0440\u044b\u0439 \u0446\u0432\u0435\u0442, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0442\u0435\u043a\u0441\u0442\u0430 \u0442\u0430\u0439\u043c\u0435\u0440\u0430 \u0438 \u0431\u0435\u0433\u0443\u043d\u043a\u0430     this.supportColorRed = '#FA0556'     this.supportColorYellow = '#FAC405'     \/\/ \u0412\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043a\u0440\u0430\u0441\u043d\u044b\u0439 \u0438 \u0436\u0435\u043b\u0442\u044b\u0439 \u0446\u0432\u0435\u0442\u0430,     \/\/ \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0434\u043b\u044f \u043f\u043e\u0434\u0441\u0432\u0435\u0442\u043a\u0438 \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u043d\u044e\u0430\u043d\u0441\u043e\u0432<\/code><\/pre>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0438\u0434\u0443\u0442 \u0432\u0441\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043c\u044f\u0447\u0438\u043a\u0430. \u0412 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 \u0432\u044b\u043d\u0435\u0441\u0435\u043d\u044b \u0442\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0437\u043c\u0435\u043d\u044f\u044e\u0442\u0441\u044f \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0438\u0433\u0440\u044b.  <\/p>\n<pre><code class=\"javascript\">    this.ballSpeed = 7     \/\/ \u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043c\u044f\u0447\u0438\u043a\u0430     this.ballRadius = 8     \/\/ \u0420\u0430\u0434\u0438\u0443\u0441 \u043c\u044f\u0447\u043a\u0430, \u0434\u0438\u0430\u043c\u0435\u0442\u0440 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f 16px     this.ballXDefault = (this.boxWidth \/ 2)     this.ballYDefault = (this.boxHeight \/ 2)     \/\/ \u041a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u043c\u044f\u0447\u0438\u043a\u0430 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e,     \/\/ \u0440\u0430\u0432\u043d\u044b \u043f\u043e\u043b\u043e\u0432\u0438\u043d\u0435 \u0434\u043b\u0438\u043d\u044b \u0438 \u0448\u0438\u0440\u0438\u043d\u044b \u043f\u043e\u043b\u044f, \u044d\u0442\u043e \u0446\u0435\u043d\u0442\u0440     this.ballColor = '#EBEBEB'     \/\/ \u0426\u0432\u0435\u0442 \u043c\u044f\u0447\u0438\u043a\u0430, \u044f \u0441\u0434\u0435\u043b\u0430\u043b \u0442\u0430\u043a\u0438\u043c \u0436\u0435 \u0441\u0432\u0435\u0442\u043b\u043e-\u0441\u0435\u0440\u044b\u043c \u043a\u0430\u043a textColor      this.ballHitScore = 0     \/\/ \u0421\u0447\u0435\u0442\u0447\u0438\u043a \u043e\u0442\u0431\u0438\u0442\u044b\u0445 \u043c\u044f\u0447\u0435\u0439, \u0442\u0430\u043a\u0436\u0435 \u043a \u043d\u0435\u043c\u0443 \u043f\u0440\u0438\u0432\u044f\u0437\u0430\u043d\u043e \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u0435     \/\/ \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u043c\u044f\u0447\u0438\u043a\u0430. \u0423\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u043c \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043f\u0440\u0438 \u043a\u0430\u0436\u0434\u043e\u043c \u0443\u0434\u0430\u0440\u0435     this.ball = {       x: this.ballXDefault,       y: this.ballYDefault,       \/\/ \u0422\u0435\u043a\u0443\u0449\u0438\u0435 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u043c\u044f\u0447\u0438\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u0435\u043d\u044f\u044e\u0442\u0441\u044f \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435       \/\/ \u0438\u0433\u0440\u044b, \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u043e\u043d\u0438 \u0440\u0430\u0432\u043d\u044b \u0434\u0435\u0444\u043e\u043b\u0442\u043d\u044b\u043c - \u043c\u044f\u0447\u0438\u043a \u0432 \u0446\u0435\u043d\u0442\u0440\u0435 \u043f\u043e\u043b\u044f       dx: 0,       dy: 0,       \/\/ \u0423\u0441\u043a\u043e\u0440\u0435\u043d\u0438\u0435 \u043c\u044f\u0447\u0438\u043a\u0430 \u043f\u043e \u043e\u0441\u044f\u043c. \u0418\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u0440\u0430\u0432\u043d\u043e 0, \u043d\u043e       \/\/ \u043f\u043e\u0437\u0436\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u0440\u0430\u043d\u0434\u043e\u043c\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043e\u0442 0.8 \u0434\u043e 1, \u0441 + \u0438\u043b\u0438 -        speed: this.ballSpeed,       \/\/ \u0415\u0449\u0435 \u043e\u0434\u043d\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438, \u043e\u043d\u043e \u043d\u0443\u0436\u043d\u043e, \u0442.\u043a. \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043c\u044f\u0447\u0430       \/\/ \u043f\u043e\u0441\u0442\u0435\u043f\u0435\u043d\u043e \u0440\u0430\u0441\u0442\u0435\u0442 \u0438 \u043f\u0435\u0440\u0435\u043e\u0434\u0438\u0447\u0435\u0441\u043a\u0438 \u043d\u0430\u0434\u043e \u0435\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c       \/\/ \u043a \u0434\u0435\u0444\u043e\u043b\u0442\u043d\u043e\u043c\u0443 this.ballSpeed     }<\/code><\/pre>\n<p>\u0414\u0430\u043b\u044c\u0448\u0435 \u0438\u0434\u0443\u0442 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043e\u0431\u043e\u0438\u0445 \u0438\u0433\u0440\u043e\u043a\u043e\u0432. \u0412 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0432\u044b\u043d\u0435\u0441\u0435\u043d\u044b \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0435 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0438\u0433\u0440\u043e\u043a\u0430. \u041c\u044b \u0431\u0443\u0434\u0435\u043c \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u044d\u0442\u0438 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u043f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u0430 \u043a\u043b\u0430\u0441\u0441\u0430 <a href=\"#player\" rel=\"noopener noreferrer nofollow\"><em>Player<\/em><\/a>.<\/p>\n<pre><code class=\"javascript\">    this.playerRadius = 7             \/\/ \u0420\u0430\u0434\u0438\u0443\u0441 \u0438\u0433\u0440\u043e\u043a\u0430. \u041f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u0435\u0435 \u0431\u044b\u043b\u043e \u0431\u044b \u043d\u0430\u0437\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u0449\u0438\u043d\u043e\u0439, \u0442.\u043a.     \/\/ \u0438\u0433\u0440\u043e\u043a \u044d\u0442\u043e \u0432\u0435\u043a\u0442\u043e\u0440\u043d\u0430\u044f \u043b\u0438\u043d\u0438\u044f. \u041d\u043e \u0432 \u0440\u0430\u0441\u0447\u0435\u0442\u0430\u0445 \u0441\u0442\u043e\u043b\u043a\u043d\u043e\u0432\u0435\u043d\u0438\u0439,      \/\/ \u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e \u043a\u0440\u0430\u0439\u043d\u0438\u0435 \u0442\u043e\u0447\u043a\u0438 \u043a\u0430\u043a \u043e\u043a\u0440\u0443\u0436\u043d\u043e\u0441\u0442\u0438, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u044d\u0442\u043e \u0440\u0430\u0434\u0438\u0443\u0441.     \/\/ \u0420\u0435\u0430\u043b\u044c\u043d\u0430\u044f \u0442\u043e\u043b\u0449\u0438\u043d\u0430 \u0438\u0433\u0440\u043e\u043a\u0430 - \u044d\u0442\u043e \u0434\u0432\u0430 \u0435\u0433\u043e \u0440\u0430\u0434\u0438\u0443\u0441\u0430, 14px.     this.playerHeight = 80     \/\/ \u0412\u044b\u0441\u043e\u0442\u0430 \u0438\u0433\u0440\u043e\u043a\u0430. \u0420\u0430\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043e\u0442 \u0432\u0435\u0440\u0445\u043d\u0435\u0439 \u0434\u043e \u043d\u0438\u0436\u043d\u0435\u0439 \u0442\u043e\u0447\u043a\u0438 \u0438\u0433\u0440\u043e\u043a\u0430.     \/\/ \u041d\u043e \u0442.\u043a. \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b \u0438\u0433\u0440\u043e\u043a\u043e\u0432 \u0438\u043c\u0435\u044e\u0442 \u0437\u0430\u043a\u0440\u0443\u0433\u043b\u0435\u043d\u0438\u044f, \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0439 \u0440\u0430\u0437\u043c\u0435\u0440     \/\/ \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u0434\u0432\u0430 \u0440\u0430\u0434\u0438\u0443\u0441\u0430 \u0431\u043e\u043b\u044c\u0448\u0435, 94px     this.playerSpeed = 8     \/\/ \u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0438\u0433\u0440\u043e\u043a\u0430. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043a\u0430\u043a \u043a\u043e\u044d\u0444\u0444\u0438\u0446\u0438\u0435\u043d\u0442 \u0434\u043b\u044f \u0443\u0441\u043a\u043e\u0440\u0435\u043d\u0438\u044f     this.playerBorder = this.playerRadius * 3     \/\/ \u041f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e \u043e\u0442 \u043a\u0440\u0430\u0435\u0432 \u0438\u0433\u0440\u043e\u043a\u0430 \u0434\u043e \u0441\u0442\u0435\u043d\u043a\u0438 \u0441\u0432\u0435\u0440\u0445\u0443 \u0438 \u0441\u043d\u0438\u0437\u0443     this.playerSpace = this.playerRadius * 6     \/\/ \u041f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e \u043e\u0442 \u0446\u0435\u043d\u0442\u0440\u0430 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b \u0438\u0433\u0440\u043e\u043a\u0430 \u0434\u043e \u0441\u0442\u0435\u043d\u043a\u0438 \u0437\u0430 \u043d\u0438\u043c     this.playerYDefault =                    (this.boxHeight \/ 2) - (this.playerHeight \/ 2)     \/\/ \u0418\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u0430\u044f \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430 \u0438\u0433\u0440\u043e\u043a\u0430 Y \u0440\u0430\u0432\u043d\u0430 \u043f\u043e\u043b\u043e\u0432\u0438\u043d\u0435 \u0432\u044b\u0441\u043e\u0442\u044b     \/\/ \u0438\u0433\u0440\u043e\u0432\u043e\u0433\u043e \u043f\u043e\u043b\u044f \u043c\u0438\u043d\u0443\u0441 \u043f\u043e\u043b\u043e\u0432\u0438\u043d\u0430 \u0432\u044b\u0441\u043e\u0442\u044b \u0438\u0433\u0440\u043e\u043a\u0430, \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c     \/\/ \u0438\u0433\u0440\u043e\u043a \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0433\u0430\u0442\u044c\u0441\u044f \u043f\u043e\u0441\u0435\u0440\u0435\u0434\u0438\u043d\u0435 \u043f\u0440\u0438 \u043b\u044e\u0431\u043e\u0439 \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u0439 \u0434\u043b\u0438\u043d\u0435     this.playerL = {       score: 0,       \/\/ \u0421\u0447\u0435\u0442\u0447\u0438\u043a \u043e\u0447\u043a\u043e\u0432       goalPointX: this.boxWidth - this.playerSpace * 2,       \/\/ \u041a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430 \u0425 \u0434\u043b\u044f \u043f\u043e\u044f\u0432\u043b\u0435\u043d\u0438\u044f \u043d\u0430\u0434\u043f\u0438\u0441\u0435\u0439 \"+1\" \u043d\u0430 \u0438\u0433\u0440\u043e\u0432\u043e\u043c \u043f\u043e\u043b\u0435       \/\/ \u0414\u043b\u044f \u043b\u0435\u0432\u043e\u0433\u043e \u0438\u0433\u0440\u043e\u043a\u0430 \u0440\u0430\u0432\u043d\u0430 \u0448\u0438\u0440\u0438\u043d\u0435 \u043f\u043e\u043b\u044f \u043c\u0438\u043d\u0443\u0441 2 \u0440\u0430\u0441\u0442\u043e\u044f\u043d\u0438\u044f       \/\/ \u0434\u043e \u0438\u0433\u0440\u043e\u043a\u0430       \/\/ \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e \u043e\u043d\u0430 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043d\u0430 \u043f\u043e\u043b\u0435 \u043f\u0440\u043e\u0442\u0438\u0432\u043d\u0438\u043a\u0430, \u0441\u043f\u0440\u0430\u0432\u0430       align: 'right',       \/\/ \u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u0432\u044b\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u043d\u0438\u0435 \u0442\u0435\u043a\u0441\u0442\u0430 \"+1\".       \/\/ \u042f \u0442\u0430\u043a\u0436\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e \u044d\u0442\u043e\u0442 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u0434\u043b\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0441\u0442\u043e\u0440\u043e\u043d\u044b       \/\/ \u0432 \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043f\u043e\u043b\u0435\u0442\u0438\u0442 \u043c\u044f\u0447 \u043f\u043e\u0441\u043b\u0435 \u0437\u0430\u0431\u0438\u0442\u0438\u044f \u0433\u043e\u043b\u0430       x: this.playerSpace,       y: this.playerYDefault,       \/\/ \u041a\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0438\u0433\u0440\u043e\u043a\u0430. X \u0440\u0430\u0432\u0435\u043d \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u043c\u0443 \u0440\u0430\u0441\u0442\u043e\u044f\u043d\u0438\u044e playerSpace,       \/\/ \u0430 Y \u0434\u0435\u0444\u043e\u043b\u0442\u043d\u043e\u043c\u0443 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044e, \u043e\u0431\u0449\u0435\u043c\u0443 \u0434\u043b\u044f \u043e\u0431\u043e\u0438\u0445 \u0438\u0433\u0440\u043e\u043a\u043e\u0432       yDefault: (this.boxHeight \/ 2) - (this.playerHeight \/ 2),       \/\/ \u0417\u0430\u0440\u0435\u0437\u0435\u0440\u0432\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0430\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f \u0441\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c Y \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e       color: '#A55F02',            \/\/ \u0426\u0432\u0435\u0442 \u0438\u0433\u0440\u043e\u043a\u0430. \u041e\u0440\u0430\u043d\u0436\u0435\u0432\u044b\u0439       keys: [[87,'up'], [83,'down']],       \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043c\u0430\u0441\u0441\u0438\u0432 \u0441 \u043f\u0430\u0440\u0430\u043c\u0438 \u043a\u043b\u044e\u0447-\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435.       \/\/ \u041d\u043e\u043c\u0435\u0440 \u043a\u043b\u0430\u0432\u0438\u0448\u0438 \u0438 \u0441\u0442\u0440\u043e\u043a\u0430       \/\/ \u0441 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435\u043c. \u0423\u0437\u043d\u0430\u0442\u044c \u043d\u043e\u043c\u0435\u0440 \u043a\u043b\u0430\u0432\u0438\u0448 \u043c\u043e\u0436\u043d\u043e \u0442\u0443\u0442:       \/\/ https:\/\/puzzleweb.ru\/javascript\/char_codes-key_codes.php      }             this.playerR = {       score: 0,       goalPointX: this.playerSpace * 2,       align: 'left',       x: this.boxWidth - (this.playerSpace),       \/\/ \u041a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430 X \u0434\u043b\u044f \u043f\u0440\u0430\u0432\u043e\u0433\u043e \u0438\u0433\u0440\u043e\u043a\u0430 \u0440\u0430\u0432\u043d\u0430 \u0432\u0441\u0435\u0439 \u0448\u0438\u0440\u0438\u043d\u0435 \u043f\u043e\u043b\u044f,       \/\/ \u043c\u0438\u043d\u0443\u0441 \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u0435 \u0440\u0430\u0441\u0442\u043e\u044f\u043d\u0438\u0435 playerSpace       y: this.playerYDefault,       color: '#38887A',       \/\/ \u0413\u043e\u043b\u0443\u0431\u043e\u0439       keys: [[38,'up'], [40,'down']],     }   } }<\/code><\/pre>\n<p><a href=\"#begin\" rel=\"noopener noreferrer nofollow\">\u041d\u0430\u0432\u0435\u0440\u0445<\/a><\/p>\n<hr\/>\n<p><a class=\"anchor\" name=\"canvas\" id=\"canvas\"><\/a><\/p>\n<h3>canvas.js<\/h3>\n<p>\u041c\u043e\u0434\u0443\u043b\u044c \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u0434\u0440\u0443\u0433\u0438\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u0445, \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0432 \u043d\u0435\u0438\u0437\u043c\u0435\u043d\u043d\u043e\u043c \u0432\u0438\u0434\u0435, \u0442.\u043a. \u043e\u043d \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0440\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043e\u0432 \u043d\u0430 2D-\u043a\u0430\u043d\u0432\u0430\u0441\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u043c\u043e\u0434\u0443\u043b\u0435\u043c <a href=\"#printer\" rel=\"noopener noreferrer nofollow\"><em>printer.js<\/em><\/a>.<\/p>\n<pre><code class=\"javascript\">export default class Canvas {   constructor(setting) {     this.set = setting     \/\/ \u041f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 set \u043e\u0431\u0449\u0438\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438     this.canvas = document.createElement('canvas')     \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u044d\u043b\u0435\u043c\u0435\u043d\u0442 canvas \u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u0434\u043b\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u043d\u0435\u043c\u0443     this.ctx = this.canvas.getContext('2d')     \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0432 \u043a\u0430\u043d\u0432\u0430\u0441\u0435 2d-\u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442, \u043d\u0443\u0436\u0435\u043d \u0434\u043b\u044f \u0440\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u044f \u0444\u0438\u0433\u0443\u0440     this.canvas.width = this.set.boxWidth     this.canvas.height = this.set.boxHeight     \/\/ \u0417\u0430\u0434\u0430\u0435\u043c \u043a\u0430\u043d\u0432\u0430\u0441\u0443 \u0432\u044b\u0441\u043e\u0442\u0443 \u0438 \u0448\u0438\u0440\u0438\u043d\u0443     document.querySelector('#game').appendChild(this.canvas)     \/\/ \u041d\u0430\u0445\u043e\u0434\u0438\u043c \u0432 html \u0442\u0435\u0433 game (id=\"game\") \u0438 \u043a\u0430\u043a \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0439 \u044d\u043b\u043b\u0435\u043c\u0435\u043d\u0442     \/\/ \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0432 \u043d\u0435\u043c \u043d\u0430\u0448 canvas   }<\/code><\/pre>\n<p>\u0420\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u0435 \u0442\u0435\u043a\u0441\u0442\u0430. \u0412 \u043d\u0435\u0433\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f \u0441\u0430\u043c \u0442\u0435\u043a\u0441\u0442, \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b, \u0440\u0430\u0437\u043c\u0435\u0440 \u0442\u0435\u043a\u0441\u0442\u0430, \u0446\u0432\u0435\u0442, \u0432\u044b\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u043d\u0438\u0435 \u0438 \u0432\u044b\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u043d\u0438\u0435 \u043f\u043e \u0431\u0430\u0437\u043e\u0432\u043e\u0439 \u043b\u0438\u043d\u0438\u0438 (\u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0435 <code>y<\/code>) <\/p>\n<pre><code class=\"javascript\">  drawText(text, x, y, fontSize, color = this.set.textColor,                              align = \"center\", baseline = 'middle') {     this.ctx.fillStyle = color     \/\/ \u0423\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0446\u0432\u0435\u0442 \u0437\u0430\u043b\u0438\u0432\u043a\u0438     this.ctx.font = `bold ${fontSize} 'Fira Mono', monospace`     \/\/ \u0423\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0448\u0440\u0438\u0444\u0442 \u0438 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b     this.ctx.textAlign = align     \/\/ \u0423\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0432\u044b\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u043d\u0438\u0435 \u043f\u043e \u043a\u0440\u0430\u044e     this.ctx.textBaseline = baseline     \/\/ \u0423\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0432\u044b\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u043d\u0438\u0435 \u043f\u043e \u0431\u0430\u0437\u043e\u0432\u043e\u0439 \u043b\u0438\u043d\u0438\u0438     this.ctx.fillText(text, x, y)     \/\/ \u041f\u0438\u0448\u0435\u043c \u0442\u0435\u043a\u0441\u0442, \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0442\u0443\u0434\u0430 \u0441\u0442\u0440\u043e\u043a\u0443 \u0441 \u0442\u0435\u043a\u0441\u0442\u043e\u043c     \/\/ \u0438 \u043a\u043a\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0439 \u0442\u043e\u0447\u043a\u0438   }<\/code><\/pre>\n<p>\u0421 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0442\u0440\u0435\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u043d\u0438\u0436\u0435 \u043c\u044b \u0440\u0438\u0441\u0443\u0435\u043c \u0438\u0433\u0440\u043e\u0432\u043e\u0435 \u043f\u043e\u043b\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 \u043f\u0440\u044f\u043c\u043e\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u0430 \u0441 \u0437\u0430\u043a\u0440\u0443\u0433\u043b\u0435\u043d\u043d\u044b\u043c\u0438 \u043a\u0440\u0430\u044f\u043c\u0438, \u043a\u0440\u0443\u0433\u0430 \u043f\u043e\u0441\u0435\u0440\u0435\u0434\u0438\u043d\u0435 \u0438 \u0442\u0440\u0435\u0445 \u043b\u0438\u043d\u0438\u0439.<\/p>\n<p>\u041f\u043e\u043c\u0438\u043c\u043e \u0438\u0433\u0440\u043e\u0432\u043e\u0433\u043e \u043f\u043e\u043b\u044f, \u043b\u0438\u043d\u0438\u0435\u0439 \u043c\u044b \u0440\u0438\u0441\u0443\u0435\u043c \u0438\u0433\u0440\u043e\u043a\u0430, \u0430 \u043a\u0440\u0443\u0433 \u0442\u0430\u043a\u0436\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043c\u044f\u0447\u0438\u043a\u0430.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/2dc\/419\/2c4\/2dc4192c448b7075c65843e20955e1a6.png\" width=\"1320\" height=\"526\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/2dc\/419\/2c4\/2dc4192c448b7075c65843e20955e1a6.png\"\/><figcaption><\/figcaption><\/figure>\n<pre><code class=\"javascript\">  drawLine(xS, yS, xF, yF, lineWidth, color) {     this.ctx.lineCap = 'round'     \/\/ \u0423\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c, \u0447\u0442\u043e \u043b\u0438\u043d\u0438\u044f \u0431\u0443\u0434\u0435\u0442 \u0441 \u0437\u0430\u043a\u0440\u0443\u0433\u043b\u0435\u043d\u0438\u044f\u043c\u0438 \u043d\u0430 \u043a\u043e\u043d\u0446\u0430\u0445     this.ctx.beginPath()      \/\/ beginPath() \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u0432\u0435\u043a\u0442\u043e\u0440     this.ctx.moveTo(xS, yS)     \/\/ \u0410\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430\u043c\u0438 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0439 \u0442\u043e\u0447\u043a\u0438 \u043b\u0438\u043d\u0438\u0438     this.ctx.lineTo(xF, yF)     \/\/ \u0410\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430\u043c\u0438  \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u043a\u043e\u043d\u0435\u0447\u043d\u043e\u0439 \u0442\u043e\u0447\u043a\u0438 \u043b\u0438\u043d\u0438\u0438     this.ctx.lineWidth = lineWidth     \/\/ \u0423\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0442\u043e\u043b\u0449\u0438\u043d\u0443 \u043b\u0438\u043d\u0438\u0438, \u0435\u0435 \u043c\u044b \u0442\u0430\u043a\u0436\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u043c     this.ctx.strokeStyle = color     \/\/ \u0423\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0446\u0432\u0435\u0442 \u043e\u0431\u0432\u043e\u0434\u043a\u0438     this.ctx.stroke()     \/\/ \u0420\u0438\u0441\u0443\u0435\u043c \u043e\u0431\u0432\u043e\u0434\u043a\u0443 (\u043b\u0438\u043d\u0438\u044e)     this.ctx.closePath()     \/\/ \u0417\u0430\u0432\u0435\u0440\u0448\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0432\u0435\u043a\u0442\u043e\u0440\u0430   }      drawRectangleRound(x, y, width, height, radius, color) {     this.ctx.beginPath()     \/\/ beginPath() \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u0432\u0435\u043a\u0442\u043e\u0440     this.ctx.moveTo(x + radius, y)     \/\/ \u0423\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0439 \u0442\u043e\u0447\u043a\u0438 \u043b\u0438\u043d\u0438\u0438     this.ctx.lineTo(x + width - radius, y)     \/\/ \u0423\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0442\u043e\u0447\u043a\u0438 \u043b\u0438\u043d\u0438\u0438     this.ctx.quadraticCurveTo(x + width, y, x + width, y + radius)     \/\/ \u0423\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0442\u043e\u0447\u043a\u0438, \u0434\u043e \u043a\u0443\u0434\u0430 \u0431\u0443\u0434\u0435\u0442 \u0438\u0434\u0442\u0438 \u0437\u0430\u043a\u0440\u0443\u0433\u043b\u0435\u043d\u0438\u0435     this.ctx.lineTo(x + width, y + height - radius)     \/\/ \u0423\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0442\u043e\u0447\u043a\u0438 \u043b\u0438\u043d\u0438\u0438 \u0438 \u0442.\u0434     this.ctx.quadraticCurveTo(x + width, y + height,                                      x + width - radius, y + height)     this.ctx.lineTo(x + radius, y + height)     this.ctx.quadraticCurveTo(x, y + height, x, y + height - radius)     this.ctx.lineTo(x, y + radius)     this.ctx.quadraticCurveTo(x, y, x + radius, y)     this.ctx.closePath()     \/\/ \u0417\u0430\u0432\u0435\u0440\u0448\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0432\u0435\u043a\u0442\u043e\u0440\u0430     this.ctx.fillStyle = color     \/\/ \u0423\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0446\u0432\u0435\u0442 \u0437\u0430\u043b\u0438\u0432\u043a\u0438     this.ctx.fill()     \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0437\u0430\u043b\u0438\u0432\u043a\u0443   }      drawCircle(x, y, radius, fillColor, stroke = true) {     this.ctx.beginPath()     \/\/ beginPath() \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u0432\u0435\u043a\u0442\u043e\u0440     this.ctx.arc(x, y, radius, 0, Math.PI * 2)     \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0430\u0440\u043a\u0443. \u0410\u0433\u0440\u0443\u0433\u0443\u043c\u0435\u043d\u0442\u0430\u043c\u0438 \u0432\u044b\u0441\u0442\u0443\u043f\u0430\u044e\u0442 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b     \/\/ \u0446\u0435\u043d\u0442\u0440\u0430 \u043e\u043a\u0440\u0443\u0436\u043d\u043e\u0441\u0442\u0438, \u0440\u0430\u0434\u0438\u0443\u0441, \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0439 \u0443\u0433\u043e\u043b \u0432 \u0440\u0430\u0434\u0438\u0430\u043d\u0430\u0445     \/\/ \u0438 \u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0439 \u0443\u0433\u043e\u043b \u0432 \u0440\u0430\u0434\u0438\u0430\u043d\u0430\u0445.     \/\/ Math.PI*2 \u044d\u0442\u043e \u0447\u0438\u0441\u043b\u043e \u041f\u0438 \u0443\u043c\u043d\u043e\u0436\u0435\u043d\u043d\u043e\u0435 \u043d\u0430 2, \u0434\u0430\u0435\u0442 \u0437\u0430\u043c\u043a\u043d\u0443\u0442\u044b\u0439 \u043a\u0440\u0443\u0433.      this.ctx.fillStyle = fillColor     \/\/ \u0423\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0446\u0432\u0435\u0442 \u0437\u0430\u043b\u0438\u0432\u043a\u0438     this.ctx.fill()     \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0437\u0430\u043b\u0438\u0432\u043a\u0443     if (stroke) {     \/\/ \u0415\u0441\u043b\u0438 \u043d\u0430\u043c \u043d\u0435 \u043d\u0443\u0436\u043d\u0430 \u043e\u0431\u0432\u043e\u0434\u043a\u0430, \u0442\u043e \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430\u043c \u043c\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c false,     \/\/ \u0430 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u043e\u0431\u0432\u043e\u0434\u043a\u0430 \u0435\u0441\u0442\u044c       this.ctx.lineWidth = 6       \/\/ \u0423\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0442\u043e\u043b\u0449\u0438\u043d\u0443 \u043b\u0438\u043d\u0438\u0438       this.ctx.strokeStyle = this.set.lineColor       \/\/ \u0423\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0446\u0432\u0435\u0442 \u043e\u0431\u0432\u043e\u0434\u043a\u0438       this.ctx.stroke()       \/\/ \u0420\u0438\u0441\u0443\u0435\u043c \u043e\u0431\u0432\u043e\u0434\u043a\u0443     }     this.ctx.closePath()     \/\/ \u0417\u0430\u0432\u0435\u0440\u0448\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0432\u0435\u043a\u0442\u043e\u0440\u0430   }<\/code><\/pre>\n<p>\u0412 \u043e\u0441\u043d\u043e\u0432\u0435 \u0440\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u044f \u043a\u0440\u0443\u0433\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439 <code>drawCircle()<\/code> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043c\u0435\u0442\u043e\u0434 <code>arc()<\/code> \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0443\u0433\u043b\u0430 \u0432 \u0440\u0430\u0434\u0438\u0430\u043d\u0430\u0445. \u041f\u0440\u043e \u0440\u0430\u0434\u0438\u0430\u043d\u044b \u043d\u0430 \u0432\u0438\u043a\u0438\u043f\u0435\u0434\u0438\u0438 \u0435\u0441\u0442\u044c <a href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%A0%D0%B0%D0%B4%D0%B8%D0%B0%D0%BD\" rel=\"noopener noreferrer nofollow\">\u043f\u043e\u043d\u044f\u0442\u043d\u0430\u044f \u0441\u0442\u0430\u0442\u044c\u044f \u0441 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u043e\u0439<\/a>, \u0435\u0441\u043b\u0438 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e. \u0f3c \u3064 \u25d5_\u25d5 \u0f3d\u3064<\/p>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f <code>drawArc()<\/code>,  \u0442\u0430\u043a\u0436\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0432 \u043e\u0441\u043d\u043e\u0432\u0435 \u0441\u0432\u043e\u0435\u0439 \u043c\u0435\u0442\u043e\u0434 <code>arc()<\/code>, \u043d\u043e \u0442\u0443\u0442 \u043c\u044b \u043d\u0435 \u0437\u0430\u043c\u044b\u043a\u0430\u0435\u043c \u0434\u0443\u0433\u0443, \u0430 \u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0435\u0435 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043a\u0443\u0441\u043e\u0447\u0435\u043a. \u041c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0431\u044b \u043e\u0431\u043e\u0439\u0442\u0438\u0441\u044c \u043e\u0434\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439, \u043d\u043e \u043d\u0443\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0431\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0432 \u043d\u0435\u0435 \u0431\u043e\u043b\u044c\u0448\u0435 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u043b\u044f \u0442\u0430\u0439\u043c\u0435\u0440\u0430 \u044f \u0441\u0434\u0435\u043b\u0430\u043b \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e.<\/p>\n<pre><code class=\"javascript\">  drawArc(radius, sAngle, eAngle, color = this.set.textColor) {     const centerW = (this.set.boxWidth \/ 2)     const centerH = (this.set.boxHeight \/ 2)          this.ctx.lineCap = 'round'     this.ctx.beginPath()     this.ctx.arc(centerW, centerH, radius, sAngle, eAngle)     this.ctx.lineWidth = 6     this.ctx.strokeStyle = color     this.ctx.stroke()     this.ctx.closePath()   }<\/code><\/pre>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f \u043e\u0442\u0447\u0438\u0449\u0430\u0435\u0442 \u043a\u0430\u043d\u0432\u0430\u0441. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0432 \u043c\u0435\u0442\u043e\u0434 <code>clearRect()<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0435 \u0438 \u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0435 \u0442\u043e\u0447\u043a\u0438 \u043f\u0440\u044f\u043c\u043e\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0430\u0434\u043e \u043e\u0442\u0447\u0438\u0441\u0442\u0438\u0442\u044c. \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043c\u044b \u0447\u0438\u0441\u0442\u0438\u043c \u043a\u0430\u043d\u0432\u0430\u0441 \u0446\u0435\u043b\u0438\u043a\u043e\u043c.  <\/p>\n<pre><code class=\"javascript\">  clear() {             this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height)   } }<\/code><\/pre>\n<p><a href=\"#begin\" rel=\"noopener noreferrer nofollow\">\u041d\u0430\u0432\u0435\u0440\u0445<\/a><\/p>\n<hr\/>\n<p><a class=\"anchor\" name=\"printer\" id=\"printer\"><\/a><\/p>\n<h3>printer.js<\/h3>\n<p>\u041c\u043e\u0434\u0443\u043b\u044c \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e \u0441 \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u043c\u0438 \u043a\u0430\u043d\u0432\u0430\u0441\u0430. \u0412 \u043d\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u044e\u0442\u0441\u044f \u0441\u0440\u0430\u0437\u0443 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043a\u0430\u043d\u0432\u0430\u0441\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u044b\u0441\u0442\u0443\u043f\u0430\u044e\u0442 \u0441\u043b\u043e\u044f\u043c\u0438 \u0438 \u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e \u0434\u0440\u0443\u0433 \u043e\u0442 \u0434\u0440\u0443\u0433\u0430. <\/p>\n<p>\u0412\u0441\u0435 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u0445 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u044b\u00a0\u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430 \u0447\u0438\u0442\u0430\u0435\u043c\u043e\u0441\u0442\u0438 \u0438 \u043a\u043e\u043c\u043f\u0430\u043a\u0442\u043d\u043e\u0441\u0442\u0438\u00a0\u043a\u043e\u0434\u0430 \u0432 \u0433\u0430\u0439\u0434\u0435.<\/p>\n<pre><code class=\"javascript\">import Canvas from '.\/canvas.js' \/\/ \u0412 \u0444\u0430\u0439\u043b \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u043a\u043b\u0430\u0441\u0441 Canvas  export default class Printer {   constructor(setting) {       \/\/ \u0412 \u043f\u0440\u0438\u043d\u0442\u0435\u0440 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438     this.set = setting     this.ball = setting.ball     \/\/ \u041f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u043e\u0431\u0449\u0438\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 set,     \/\/ \u0430 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 ball \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043c\u044f\u0447\u0438\u043a\u0430, \u0434\u043b\u044f \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430          this.canvas = new Map([             \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u043e\u0432\u044b\u0439 Map \u0441 \u043f\u044f\u0442\u044c\u044e \u043a\u043b\u0430\u0441\u0441\u0430\u043c\u0438 Canvas \u043f\u043e\u0434 \u0440\u0430\u0437\u043d\u044b\u0435 \u043d\u0443\u0436\u0434\u044b,     \/\/ \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u0431\u0443\u0434\u0443\u0449\u0438\u0445 \u0441\u043b\u043e\u0435\u0432 \u0432\u043b\u0438\u044f\u0435\u0442 \u043d\u0430 \u0438\u0445 \u0432\u0438\u0434\u0438\u043c\u043e\u0441\u0442\u044c, \u043f\u0435\u0440\u0432\u044b\u0439 \u0431\u0443\u0434\u0435\u0442      \/\/ \u043f\u0435\u0440\u0435\u043a\u0440\u044b\u0432\u0430\u0442\u044c \u0432\u0442\u043e\u0440\u044b\u043c \u0438 \u0442.\u0434.               ['background', new Canvas(this.set)],                   \/\/ \u041d\u0430 \u0441\u043b\u043e\u0435 background \u0440\u0438\u0441\u0443\u0435\u0442\u0441\u044f \u043d\u0435\u043f\u043e\u0434\u0432\u0438\u0436\u043d\u044b\u0435 \u0438 \u043d\u0435\u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c\u044b\u0435       \/\/ \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u0438\u0433\u0440\u044b. \u0418\u0433\u0440\u043e\u0432\u043e\u0435 \u043f\u043e\u043b\u0435                   ['score', new Canvas(this.set)],                   \/\/ \u0421\u043b\u043e\u0439 \u0434\u043b\u044f \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438 \u0441\u0447\u0435\u0442\u0430 \u0438\u0433\u0440\u043e\u043a\u043e\u0432                   ['support', new Canvas(this.set)],                   \/\/ \u0421\u043b\u043e\u0439 \u0434\u043b\u044f \u0432\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439,                   \/\/ \u043d\u0435 \u043d\u0443\u0436\u0435\u043d \u0434\u043b\u044f \u0438\u0433\u0440\u044b                   ['other', new Canvas(this.set)],                   \/\/ \u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0441\u043b\u043e\u0439 \u0434\u043b\u044f \u0440\u0430\u0437\u043d\u044b\u0445 \u0437\u0430\u0434\u0430\u0447                   ['text', new Canvas(this.set)],                   \/\/ \u0421\u043b\u043e\u0439 \u0434\u043b\u044f \u0442\u0435\u043a\u0441\u0442\u0430, \u043f\u043e\u044f\u0432\u043b\u044f\u044e\u0449\u0435\u0433\u043e\u0441\u044f \u043d\u0430 \u044d\u043a\u0440\u0430\u043d\u0435                   ['gamelayer', new Canvas(this.set)]                   \/\/ \u0421\u043b\u043e\u0439 \u0434\u043b\u044f \u0438\u0433\u0440\u043e\u0432\u044b\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0441 \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e\u0439 \u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u043a\u043e\u0439,              \/\/ \u0442\u0430\u043a\u0438\u0445 \u043a\u0430\u043a \u043c\u044f\u0447\u0438\u043a \u0438 \u0438\u0433\u0440\u043e\u043a\u0438                   ])             this.bgCan = this.canvas.get('background')             this.scoreCan = this.canvas.get('score')             this.supCan = this.canvas.get('support')             this.othCan = this.canvas.get('other')             this.txtCan = this.canvas.get('text')             this.gameCan = this.canvas.get('gamelayer')             \/\/ \u0414\u043b\u044f \u0441\u043e\u043a\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u0448\u0438\u0440\u0438\u043d\u044b \u043a\u043e\u0434\u0430, \u043f\u043e\u043c\u0435\u0449\u0430\u044e \u043f\u0443\u0442\u0438 \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u044f     \/\/ \u043a Canvas \u0432 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435, \u043c\u043e\u0436\u043d\u043e \u044d\u0442\u043e\u0433\u043e \u043d\u0435 \u0434\u0435\u043b\u0430\u0442\u044c          this.ballDirectionAngle = 0             \/\/ \u041f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f ballDirectionAngle \u043d\u0443\u0436\u043d\u0430 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0443\u0433\u043b\u0430,     \/\/ \u043f\u043e\u0434 \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0440\u0438\u0441\u043e\u0432\u0430\u0442\u044c \u0431\u0435\u043b\u044b\u0439 \u0431\u0435\u0433\u0443\u043d\u043e\u043a, \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u044e\u0449\u0438\u0439         \/\/ \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0431\u0440\u043e\u0441\u043a\u0430 \u043c\u044f\u0447\u0438\u043a\u0430       }<\/code><\/pre>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f \u043d\u0438\u0436\u0435 \u0440\u0438\u0441\u0443\u0435\u0442 \u0438\u0433\u0440\u043e\u0432\u043e\u0435 \u043f\u043e\u043b\u0435, \u044d\u0442\u043e \u0444\u043e\u043d \u0441 \u0437\u0430\u043a\u0440\u0443\u0433\u043b\u0435\u043d\u043d\u044b\u043c\u0438 \u043a\u0440\u0430\u044f\u043c\u0438 \u0438 \u0440\u0430\u0437\u043d\u044b\u0435 \u0442\u0435\u043c\u043d\u044b\u0435 \u043b\u0438\u043d\u0438\u0438. \u0420\u0438\u0441\u0443\u0435\u0442\u0441\u044f \u043d\u0430 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u043c \u0441\u043b\u043e\u0435 \u043a\u0430\u043d\u0432\u0430\u0441\u0430 &#8212; &#8216;background&#8217;.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/117\/5e4\/a5f\/1175e4a5f224fc8fab49b4ddeb272c27.png\" width=\"1320\" height=\"576\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/117\/5e4\/a5f\/1175e4a5f224fc8fab49b4ddeb272c27.png\"\/><figcaption><\/figcaption><\/figure>\n<pre><code class=\"javascript\">  drawBackground() {             const width = this.set.boxWidth             const height = this.set.boxHeight             \/\/ \u0412\u044b\u0441\u043e\u0442\u0430 \u0438 \u0448\u0438\u0440\u0438\u043d\u0430 \u0438\u0433\u0440\u043e\u0432\u043e\u0433\u043e \u043f\u043e\u043b\u044f \u0438 \u0432\u0441\u0435\u0445 \u0441\u043b\u043e\u0435\u0432 \u043a\u0430\u043d\u0432\u0430\u0441\u0430     const boxRound = this.set.boxRound             \/\/ \u0420\u0430\u0434\u0438\u0443\u0441 \u0437\u0430\u043a\u0440\u0443\u0433\u043b\u0435\u043d\u0438\u044f \u0443\u0433\u043b\u043e\u0432 \u0438\u0433\u0440\u043e\u0432\u043e\u0433\u043e \u043f\u043e\u043b\u044f             const boxColor = this.set.boxColor             \/\/ \u0426\u0432\u0435\u0442 \u0437\u0430\u043b\u0438\u0432\u043a\u0438 \u0438\u0433\u0440\u043e\u0432\u043e\u0433\u043e \u043f\u043e\u043b\u044f             const lineW = this.set.lineWidth             const lineColor = this.set.lineColor             \/\/ \u0422\u043e\u043b\u0449\u0438\u043d\u0430 \u0438 \u0446\u0432\u0435\u0442 \u043b\u0438\u043d\u0438\u0439             const plSpace = this.set.playerSpace             \/\/ \u041f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e \u043e\u0442 \u0446\u0435\u043d\u0442\u0440\u0430 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b \u0438\u0433\u0440\u043e\u043a\u0430 \u0434\u043e \u0441\u0442\u0435\u043d\u043a\u0438 \u0437\u0430 \u043d\u0438\u043c     const plBorder = this.set.playerBorder             \/\/ \u041f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e \u043e\u0442 \u043a\u0440\u0430\u0435\u0432 \u0438\u0433\u0440\u043e\u043a\u0430 \u0434\u043e \u0441\u0442\u0435\u043d\u043a\u0438 \u0441\u0432\u0435\u0440\u0445\u0443 \u0438 \u0441\u043d\u0438\u0437\u0443        this.bgCan.drawRectangleRound(0, 0, width, height,                                                boxRound, boxColor)     \/\/ \u0420\u0438\u0441\u0443\u0435\u043c \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u043f\u0440\u044f\u043c\u043e\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a \u0438\u0433\u0440\u043e\u0432\u043e\u0433\u043e \u043f\u043e\u043b\u044f \u0441 \u0437\u0430\u043a\u0440\u0443\u0433\u043b\u0435\u043d\u0438\u044f\u043c\u0438          this.bgCan.drawLine((width \/ 2), 0, (width \/ 2),                                            height, lineW, lineColor)     \/\/ \u0420\u0438\u0441\u0443\u0435\u043c \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u0443\u044e \u043b\u0438\u043d\u0438\u044e \u043f\u043e\u0441\u0435\u0440\u0435\u0434\u0438\u043d\u0435          this.bgCan.drawCircle((width \/ 2), (height \/ 2),                                     (height \/ 4), boxColor)     \/\/ \u0420\u0438\u0441\u0443\u0435\u043c \u043a\u0440\u0443\u0433 \u043f\u043e\u0441\u0435\u0440\u0435\u0434\u0438\u043d\u0435, \u0441 \u0440\u0430\u0434\u0438\u0443\u0441\u043e\u043c \u0432 1\/4 \u0432\u044b\u0441\u043e\u0442\u044b \u043f\u043e\u043b\u044f          this.bgCan.drawLine(plSpace, plBorder, plSpace,                              (height - plBorder), lineW, lineColor)     this.bgCan.drawLine((width - plSpace), plBorder,           (width - plSpace), (height - plBorder), lineW, lineColor)     \/\/ \u0420\u0438\u0441\u0443\u0435\u043c 2 \u043b\u0438\u043d\u0438\u0438 \u043f\u043e\u0434 \u0438\u0433\u0440\u043e\u043a\u0430\u043c\u0438 \u0441 \u043e\u0442\u0441\u0442\u0443\u043f\u0430\u043c\u0438 \u043e\u0442 \u043a\u0440\u0430\u044f   }<\/code><\/pre>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f <code>drawBriefing()<\/code> \u0440\u0438\u0441\u0443\u0435\u0442 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e \u0441 \u043a\u043b\u0430\u0432\u0438\u0448\u0430\u043c\u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f.<\/p>\n<p>\u0420\u0438\u0441\u0443\u044e \u0435\u0435 \u043d\u0430 \u0441\u043b\u043e\u0435 \u0434\u043b\u044f \u0438\u0433\u0440\u044b &#8216;game&#8217;, \u0442.\u043a. \u043f\u0440\u0438 \u043f\u0435\u0440\u0432\u043e\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u043c \u043e\u0442\u0447\u0435\u0442\u0435 \u043e\u043d \u043d\u0435 \u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0438 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u043c \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f.<\/p>\n<p>\u041a \u043c\u043e\u043c\u0435\u043d\u0442\u0443 \u0432\u044b\u0437\u043e\u0432\u0430 <code>drawBriefing()<\/code> \u0443 \u043d\u0430\u0441 \u0443\u0436\u0435 \u0431\u0443\u0434\u0443\u0442 \u043d\u0430\u0440\u0438\u0441\u043e\u0432\u0430\u043d\u044b \u0438\u0433\u0440\u043e\u043a\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>drawPlayer()<\/code>, \u043e \u043d\u0435\u0439 \u043d\u0438\u0436\u0435.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/76e\/e94\/a2c\/76ee94a2c34e1273515bffa19542120c.png\" width=\"1320\" height=\"260\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/76e\/e94\/a2c\/76ee94a2c34e1273515bffa19542120c.png\"\/><figcaption><\/figcaption><\/figure>\n<pre><code class=\"javascript\">  drawBriefing() {     const plLColor = this.set.playerL.color     const plRColor = this.set.playerR.color     \/\/ \u0426\u0432\u0435\u0442\u0430 \u043b\u0435\u0432\u043e\u0433\u043e \u0438 \u043f\u0440\u0430\u0432\u043e\u0433\u043e \u0438\u0433\u0440\u043e\u043a\u043e\u0432     const controlXL = (this.set.playerSpace * 2)     const controlXR = this.set.boxWidth - (this.set.playerSpace * 2)     const controlY = (this.set.boxHeight \/ 17)     \/\/ \u041a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b x \u0438 y \u0434\u043b\u044f \u0442\u0435\u043a\u0441\u0442\u0430 \u0441 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0435\u0439     \/\/ \u041d\u0435\u043c\u043d\u043e\u0433\u043e \u0441\u043b\u043e\u0436\u043d\u043e, \u043d\u043e \u0432\u0441\u0435 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u043e\u0442\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u043e\u0442 \u0441\u0442\u0430\u0442\u0438\u0447\u043d\u044b\u0445     \/\/ \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u0438 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u0441 \u0438\u0433\u0440\u043e\u0432\u044b\u043c \u043f\u043e\u043b\u0435\u043c      this.gameCan.drawText('keys:', controlXL , (controlY * 8),                                          '15px', plLColor, 'left')     this.gameCan.drawText('W and S', controlXL, (controlY * 9),                                          '20px', plLColor, 'left')     this.gameCan.drawText('keys:', controlXR, (controlY * 8),                                         '15px', plRColor, 'right')     this.gameCan.drawText('Arrows', controlXR, (controlY * 9),                                         '20px', plRColor, 'right')     \/\/ \u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 'left' \u0440\u0438\u0441\u0443\u0435\u0442 \u0442\u0435\u043a\u0441\u0442 \u0441\u043f\u0440\u0430\u0432\u0430 \u043e\u0442 \u0442\u043e\u0447\u043a\u0438 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442,     \/\/ \u0430 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 'right', \u043d\u0430\u043e\u0431\u043e\u0440\u043e\u0442, \u0441\u043b\u0435\u0432\u0430.     \/\/ \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u0446\u0438\u0444\u0440\u044b \u0441\u0447\u0435\u0442\u0430 \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0441\u043b\u0438\u043f\u043d\u0443\u0442\u0441\u044f (\u2299_\u2299)   }<\/code><\/pre>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f drawScore() \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u043e\u0435 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0441\u0447\u0435\u0442\u0430 \u043d\u0430 \u0438\u0433\u0440\u043e\u0432\u043e\u043c \u043f\u043e\u043b\u0435. \u0420\u0438\u0441\u0443\u0435\u0442\u0441\u044f \u043d\u0430 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u043c \u0441\u043b\u043e\u0435 &#8216;score&#8217;.  <\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/8f0\/549\/867\/8f05498679776826ef097fcee22ac397.png\" width=\"1320\" height=\"260\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/8f0\/549\/867\/8f05498679776826ef097fcee22ac397.png\"\/><figcaption><\/figcaption><\/figure>\n<pre><code class=\"javascript\">  drawScore() {     const plLColor = this.set.playerL.color     const plRColor = this.set.playerR.color     \/\/ \u0426\u0432\u0435\u0442\u0430 \u043b\u0435\u0432\u043e\u0433\u043e \u0438 \u043f\u0440\u0430\u0432\u043e\u0433\u043e \u0438\u0433\u0440\u043e\u043a\u043e\u0432     const plLScore = this.set.playerL.score     const plRScore = this.set.playerR.score     \/\/ \u0417\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u043e\u0447\u043a\u043e\u0432 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0438\u0433\u0440\u043e\u043a\u0430     const scoreXL = (this.set.boxWidth \/ 9 * 4)     const scoreXR = (this.set.boxWidth \/ 9 * 5)     const scoreY = (this.set.boxHeight \/ 20)     \/\/ \u041a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b x \u0438 y \u0434\u043b\u044f \u043e\u0442\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043e\u0447\u043a\u043e\u0432 \u0438\u0433\u0440\u043e\u043a\u043e\u0432     \/\/ \u043e\u0442\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u043e\u0442 \u0441\u0442\u0430\u0442\u0438\u0447\u043d\u044b\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u0448\u0438\u0440\u0438\u043d\u044b \u0438 \u0432\u044b\u0441\u043e\u0442\u044b \u043f\u043e\u043b\u044f          this.scoreCan.drawText(plLScore, scoreXL, scoreY, '40px',                                          plLColor, 'right', 'top')     this.scoreCan.drawText(plRScore, scoreXR, scoreY, '40px',                                           plRColor, 'left', 'top')     \/\/ \u0420\u0438\u0441\u0443\u0435\u043c \u0442\u0435\u043a\u0441\u0442 \u0441\u0447\u0435\u0442\u0430. \u0414\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0438\u0433\u0440\u043e\u043a\u0430 \u0441\u0432\u043e\u0439 \u0446\u0432\u0435\u0442,     \/\/ \u0438 \u0441\u0432\u043e\u0435 \u0432\u044b\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u043d\u0438\u0435   }<\/code><\/pre>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u0438 \u043d\u0438\u0436\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u044e\u0442 \u043a\u0430\u043a\u043e\u0435 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u043c\u044f\u0447\u0430 \u0432\u044b\u0431\u0440\u0430\u043d\u043e \u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u044e\u0442 \u0446\u0438\u043a\u043b \u0440\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u044f \u0431\u0435\u043b\u043e\u0439 \u043f\u043e\u043b\u043e\u0441\u043e\u0447\u043a\u0438 \u0431\u0435\u0433\u0430\u044e\u0449\u0435\u0439 \u043f\u043e \u043a\u0440\u0443\u0433\u0443. \u0412\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f drawBallDirection() \u0438\u0437 \u043c\u043e\u0434\u0443\u043b\u044f game.js, \u043f\u0440\u0438 \u0441\u0442\u0430\u0440\u0442\u0435 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043c\u0430\u0442\u0447\u0430.  <\/p>\n<p>\u0412 \u043e\u0441\u043d\u043e\u0432\u0435 \u0440\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u044f \u044d\u0442\u043e\u0433\u043e &#171;\u0431\u0435\u043b\u043e\u0433\u043e \u0431\u0435\u0433\u0443\u043d\u043a\u0430&#187; \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043c\u0435\u0442\u043e\u0434 <code>arc()<\/code> \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0443\u0433\u043b\u0430 \u0432 \u0440\u0430\u0434\u0438\u0430\u043d\u0430\u0445. \u041f\u0440\u043e \u0440\u0430\u0434\u0438\u0430\u043d\u044b \u043d\u0430 \u0432\u0438\u043a\u0438\u043f\u0435\u0434\u0438\u0438 \u0435\u0441\u0442\u044c <a href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%A0%D0%B0%D0%B4%D0%B8%D0%B0%D0%BD\" rel=\"noopener noreferrer nofollow\">\u043f\u043e\u043d\u044f\u0442\u043d\u0430\u044f \u0441\u0442\u0430\u0442\u044c\u044f \u0441 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u043e\u0439<\/a>, \u0435\u0441\u043b\u0438 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e. \u0f3c \u3064 \u25d5_\u25d5 \u0f3d\u3064  <\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/d45\/1e2\/e65\/d451e2e65f08c3180b063f7fb40962ed.gif\" width=\"1200\" height=\"455\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/d45\/1e2\/e65\/d451e2e65f08c3180b063f7fb40962ed.gif\"\/><figcaption><\/figcaption><\/figure>\n<pre><code class=\"javascript\">  drawBallDirection(int = 2) {      \/\/ \u0412 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f int, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442   \/\/ \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0449\u0438\u043a \u043a\u043e\u044d\u044d\u0444\u0438\u0446\u0438\u0435\u043d\u0442\u0430 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0443\u0433\u043b\u0430. \u041e\u043d\u0430 \u043c\u043e\u0436\u0435\u0442 \u0438\u043c\u0435\u0442\u044c   \/\/ \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 2 \u0434\u043b\u044f \u0442\u0430\u0439\u043c\u0435\u0440\u0430 \u043f\u043e\u0441\u043b\u0435 \u0433\u043e\u043b\u0430 \u0438 4 \u0434\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0442\u0430\u0439\u043c\u0435\u0440\u0430      if (this.ball.dx > 0 &amp;&amp; this.ball.dy > 0) {     \/\/ \u041e\u0441\u044c \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442 \u043a\u0430\u043d\u0432\u0430\u0441\u0430 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0441\u0432\u0435\u0440\u0445\u0443 \u0441\u043b\u0435\u0432\u0430, \u043f\u043e\u044d\u0442\u043e\u043c\u0443     \/\/ \u0435\u0441\u043b\u0438 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043c\u044f\u0447\u0438\u043a\u0430 \u043f\u043e X \u0431\u043e\u043b\u044c\u0448\u0435 0, \u0442\u043e \u043e\u043d \u043b\u0435\u0442\u0438\u0442 \u0432\u043f\u0440\u0430\u0432\u043e,     \/\/ \u0435\u0441\u043b\u0438 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043c\u044f\u0447\u0438\u043a\u0430 \u043f\u043e Y \u0431\u043e\u043b\u044c\u0448\u0435 0, \u0442\u043e \u043e\u043d \u043b\u0435\u0442\u0438\u0442 \u0432\u043d\u0438\u0437          \/\/ \u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0437\u0434\u0435\u0441\u044c \u043c\u044f\u0447\u0438\u043a \u043b\u0435\u0442\u0438\u0442 \u043f\u043e \u0434\u0438\u0430\u0433\u043e\u043d\u0430\u043b\u0438 \u0432\u043f\u0440\u0430\u0432\u043e \u0432\u043d\u0438\u0437       this.ballDirectionAngle = 6.3           \/\/ \u042f \u043f\u043e\u0434\u043e\u0431\u0440\u0430\u043b \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u043a\u043e\u044d\u0444\u0444\u0438\u0446\u0438\u0435\u043d\u0442\u044b \u0434\u043b\u044f              \/\/ \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u0443\u0433\u043b\u0430 \u043e\u043a\u0440\u0443\u0436\u043d\u043e\u0441\u0442\u0438, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0431\u0435\u0433\u0443\u043d\u043e\u043a        \/\/ \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u0443\u0434\u0435\u0442 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c\u0441\u044f                \/\/ \u0412 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u0435\u0442\u0430 \u043c\u044f\u0447\u0438\u043a\u0430       \/\/ \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u043d\u0443\u0436\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432\u043e \u0432\u043d\u0435\u0448\u043d\u044e\u044e \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e     }     if (this.ball.dx &lt; 0 &amp;&amp; this.ball.dy > 0) {         this.ballDirectionAngle = 6.8     }             if (this.ball.dx &lt; 0 &amp;&amp; this.ball.dy &lt; 0) {         this.ballDirectionAngle = 7.3     }     if (this.ball.dx > 0 &amp;&amp; this.ball.dy &lt; 0) {          this.ballDirectionAngle = 7.8     }     this.loopBallDirection(this.ballDirectionAngle - int)      \/\/ \u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0446\u0438\u043a\u043b \u0440\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u044f \u0431\u0435\u043b\u043e\u0433\u043e \u0431\u0435\u0433\u0443\u043d\u043a\u0430,             \/\/ \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0432 \u043d\u0435\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0443\u0433\u043b\u0430 \u043c\u0438\u043d\u0443\u0441 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 int.     \/\/ \u042f \u043d\u0430\u0440\u043e\u0447\u043d\u043e \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u043b \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0443\u0433\u043b\u043e\u0432 \u043d\u0430 2 \u043e\u0431\u043e\u0440\u043e\u0442\u0430 \u043e\u043a\u0440\u0443\u0436\u043d\u043e\u0441\u0442\u0438,     \/\/ \u0447\u0442\u043e\u0431 \u043f\u0440\u0438 \u0432\u044b\u0447\u0438\u0442\u0430\u043d\u0438\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043e\u0441\u0442\u0430\u0432\u0430\u043b\u0438\u0441\u044c \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u043c\u0438.     \/\/ \u0412 \u043f\u0440\u043e\u0442\u0438\u0432\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043f\u043e\u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043f\u043e\u0433\u0440\u0435\u0448\u043d\u043e\u0441\u0442\u0438\u00af\\_(\u30c4)_\/\u00af   }      loopBallDirection(someAngle) {       \/\/ \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 \u0446\u0438\u043a\u043b, \u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u044e\u0449\u0438\u0439 \u0431\u0435\u0433\u0443\u043d\u043e\u043a,   \/\/ \u043f\u043e\u043a\u0430 \u043e\u043d \u043d\u0435 \u0434\u043e\u0441\u0442\u0438\u0433\u043d\u0435\u0442 \u043d\u0443\u0436\u043d\u043e\u0433\u043e \u0443\u0433\u043b\u0430 \u043d\u0430 \u043e\u043a\u0440\u0443\u0436\u043d\u043e\u0441\u0442\u0438             const rad = (this.set.boxHeight \/ 4)             \/\/ \u0420\u0430\u0434\u0438\u0443\u0441 \u043e\u043a\u0440\u0443\u0436\u043d\u043e\u0441\u0442\u0438 \u0442\u0430\u043a\u043e\u0439 \u0436\u0435, \u043a\u0430\u043a \u0440\u0430\u0434\u0438\u0443\u0441 \u043a\u0440\u0443\u0433\u0430 \u043d\u0430 \u0438\u0433\u0440\u043e\u0432\u043e\u043c \u043f\u043e\u043b\u0435     let angle = someAngle             \/\/ \u041f\u0440\u0438 \u043f\u0435\u0440\u0432\u043e\u043c \u0432\u044b\u0437\u043e\u0432\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 angle \u043f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u0435\u0442\u0441\u044f        \/\/ \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0443\u0433\u043b\u0430, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u043e\u0433\u043e \u0438\u0437 drawBallDirection(),     \/\/ \u043d\u043e \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u0441\u0442\u0432\u0438\u0438 \u043e\u043d\u043e \u0431\u0435\u0440\u0435\u0442\u0441\u044f \u0438\u0437 \u0446\u0438\u043a\u043b\u0430                this.othCan.drawArc(rad, Math.PI * angle - 0.3, Math.PI * angle)     \/\/ \u0420\u0438\u0441\u0443\u0435\u043c \u0447\u0430\u0441\u0442\u044c \u043e\u043a\u0440\u0443\u0436\u043d\u043e\u0441\u0442\u0438 \u0447\u0435\u0440\u0435\u0437 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043a\u0430\u043d\u0432\u0430\u0441\u0435             setTimeout(() => {       angle += 0.1        if(angle &lt;= this.ballDirectionAngle) {                       this.clear('other')                       this.loopBallDirection(angle)                   }             }, '60')              \/\/ \u0421 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u043e\u0439 \u0432 JS \u0444\u0443\u043d\u043a\u0446\u0438\u0438 setTimeout(),             \/\/ \u0434\u0435\u043b\u0430\u0435\u043c \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0443 \u0432 0.06 \u0441\u0435\u043a\u0443\u043d\u0434, \u0438\u043b\u0438 '60' \u043c\u0438\u043b\u0438\u0441\u0435\u043a\u0443\u043d\u0434       }<\/code><\/pre>\n<p>\u041f\u0435\u0440\u0432\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043d\u0438\u0436\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u043e\u0441\u0440\u0435\u0434\u043d\u0438\u0447\u0435\u0441\u043a\u043e\u0439, \u043e\u043d\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0440\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u044f \u0442\u0435\u043a\u0441\u0442\u0430 \u043f\u043e \u0446\u0435\u043d\u0442\u0440\u0443 \u0438\u0433\u0440\u043e\u0432\u043e\u0433\u043e \u043f\u043e\u043b\u044f, \u0430 \u0434\u0432\u0435 \u0434\u0440\u0443\u0433\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0443\u0436\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u0435\u0435 \u0432\u043d\u0443\u0442\u0440\u0438 \u0441\u0435\u0431\u044f \u0434\u043b\u044f \u0440\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u044f \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u043e\u0433\u043e \u0442\u0435\u043a\u0441\u0442\u0430 \u043d\u0430 \u043f\u043e\u043b\u0435.  <\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/96c\/474\/b3c\/96c474b3c534286d9de8e81ffec6e028.png\" width=\"1320\" height=\"260\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/96c\/474\/b3c\/96c474b3c534286d9de8e81ffec6e028.png\"\/><figcaption><\/figcaption><\/figure>\n<pre><code class=\"javascript\">  centerText(text, fontSize = '90px', color = this.set.textColor) {   \/\/ \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0440\u0438\u0441\u0443\u0435\u0442 \u0442\u0435\u043a\u0441\u0442 \u0432 \u0446\u0435\u043d\u0442\u0440\u0435 \u044d\u043a\u0440\u0430\u043d\u0430, \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442       \/\/ \u0431\u0435\u043b\u044b\u0439 \u0446\u0432\u0435\u0442 \u0438 '90px' \u0440\u0430\u0437\u043c\u0435\u0440 \u0448\u0440\u0438\u0444\u0442\u0430, \u044d\u0442\u043e \u0441\u0447\u0435\u0442\u0447\u0438\u043a \u0441\u0442\u0430\u0440\u0442\u043e\u0432\u043e\u0433\u043e \u0442\u0430\u0439\u043c\u0435\u0440\u0430     const centerW = (this.set.boxWidth \/ 2)             const centerH = (this.set.boxHeight \/ 2)             \/\/ \u041a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0446\u0435\u043d\u0442\u0440\u0430 \u0438\u0433\u0440\u043e\u0432\u043e\u0433\u043e \u043f\u043e\u043b\u044f          this.txtCan.drawText(text, centerW, centerH, fontSize, color)       }          drawBallHit() {       \/\/ \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0440\u0438\u0441\u0443\u0435\u0442 \u0441\u0447\u0435\u0442\u0447\u0438\u043a \u0443\u0434\u0430\u0440\u043e\u0432 \u043f\u043e \u0446\u0435\u0442\u0440\u0443 \u044d\u043a\u0440\u0430\u043d\u0430.       \/\/ \u041c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043e\u0431\u043e\u0439\u0442\u0438\u0441\u044c \u043e\u0434\u043d\u043e\u0439 \u0444\u0443\u043d\u0446\u0438\u0435\u0439 centerText(), \u043d\u043e \u0442\u0430\u043a \u043f\u043e\u043d\u044f\u0442\u043d\u0435\u0435     this.centerText(this.set.ballHitScore, '70px', this.set.lineColor)     \/\/ \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0446\u0432\u0435\u0442 \u043b\u0438\u043d\u0438\u0439, \u0447\u0442\u043e\u0431 \u0441\u0447\u0435\u0442\u0441\u0447\u0438\u043a \u043d\u0435 \u043e\u0442\u0432\u043b\u0435\u043a\u0430\u043b \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435       }          drawGoal(x, color, align) {       \/\/ \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0438\u0437 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u0430 Player \u0438 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0443 \u0425,   \/\/ \u0446\u0432\u0435\u0442 \u0438\u0433\u0440\u043e\u043a\u0430 \u0438 \u0432\u044b\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u043d\u0438\u0435             this.txtCan.drawText('+1', x, this.ball.y, '20px', color, align)     \/\/ \u0440\u0438\u0441\u0443\u0435\u043c \"+1\" \u043d\u0430 \u043f\u043e\u043b\u0435 \u043f\u0440\u043e\u0438\u0433\u0440\u0430\u0432\u0448\u0435\u0433\u043e. \u0426\u0432\u0435\u0442\u043e\u043c \u0437\u0430\u0431\u0438\u0432\u0448\u0435\u0433\u043e \u0438\u0433\u0440\u043e\u043a\u0430       this.centerText('Goal!', '50px', color)             \/\/ \u0420\u0438\u0441\u0443\u0435\u043c \u043d\u0430\u0434\u043f\u0438\u0441\u044c \"Goal\" \u0432 \u0446\u0435\u043d\u0442\u0440\u0435. \u0426\u0432\u0435\u0442\u043e\u043c \u0437\u0430\u0431\u0438\u0432\u0448\u0435\u0433\u043e \u0438\u0433\u0440\u043e\u043a\u0430             setTimeout(() => {                   this.clear('text') }, '800')                   \/\/ \u0427\u0435\u0440\u0435\u0437 0.8 \u0441\u0443\u043a\u0443\u043d\u0434 \u043e\u0442\u0447\u0438\u0449\u0430\u0435\u043c \u0441\u043b\u043e\u0439 'text'       }<\/code><\/pre>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u0438 \u0440\u0438\u0441\u0443\u044e\u0442 \u043c\u044f\u0447\u0438\u043a \u0438 \u0438\u0433\u0440\u043e\u043a\u0430. \u041c\u044f\u0447\u0438\u043a \u044d\u0442\u043e \u043a\u0440\u0443\u0433, \u0430 \u0438\u0433\u0440\u043e\u043a \u044d\u0442\u043e \u043b\u0438\u043d\u0438\u044f \u0441 \u043e\u0431\u0432\u043e\u0434\u043a\u043e\u0439 \u0438 \u0437\u0430\u043a\u0440\u0443\u0433\u043b\u0435\u043d\u043d\u044b\u043c\u0438 \u043a\u0440\u0430\u044f\u043c\u0438.  <\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/43f\/2e4\/a0d\/43f2e4a0d1f844b888835ea2116bc2b7.png\" width=\"1320\" height=\"260\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/43f\/2e4\/a0d\/43f2e4a0d1f844b888835ea2116bc2b7.png\"\/><figcaption><\/figcaption><\/figure>\n<pre><code class=\"javascript\">  drawBall() {       \/\/ \u0420\u0438\u0441\u0443\u0435\u0442 \u043c\u044f\u0447\u0438\u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0435\u0433\u043e \u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u043c\u0435\u0441\u0442\u043e\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435     let ballX = this.ball.x             let ballY = this.ball.y             let radius = this.set.ballRadius             let color = this.set.ballColor          this.gameCan.drawCircle(ballX, ballY, radius, color, false)   }       drawPlayer(xS, yS, yF, lineWidth, color) {       \/\/ \u0420\u0438\u0441\u0443\u0435\u0442 \u0438\u0433\u0440\u043e\u043a\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0435\u0433\u043e \u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u043c\u0435\u0441\u0442\u043e\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435.       \/\/ \u041f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0443 \u0425 \u0438 \u0434\u0432\u0435 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b Y, \u0432\u0435\u0440\u0445\u043d\u044e\u044e \u0438 \u043d\u0438\u0436\u043d\u044e\u044e       \/\/ \u0420\u0438\u0441\u0443\u0435\u0442 \u043c\u0435\u0436\u0434\u0443 \u043d\u0438\u043c\u0438 \u043b\u0438\u043d\u0438\u044e. \u0422\u0430\u043a\u0436\u0435 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0442\u043e\u043b\u0449\u0438\u043d\u0443 \u043b\u0438\u043d\u0438\u0438   \/\/ \u0438 \u0446\u0432\u0435\u0442 \u0438\u0433\u0440\u043e\u043a\u0430     this.gameCan.drawLine(xS, yS, xS, yF, lineWidth, color)       }<\/code><\/pre>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f \u043e\u0442\u0447\u0438\u0441\u0442\u043a\u0438 \u043a\u0430\u043d\u0432\u0430\u0441\u0430. \u041a\u0430\u043a \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0441\u043b\u043e\u044f \u043a\u0430\u043d\u0432\u0430\u0441\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0430\u0434\u043e \u043f\u043e\u0447\u0438\u0441\u0442\u0438\u0442\u044c \u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u0434\u043b\u044f \u043d\u0435\u0433\u043e \u043c\u0435\u0442\u043e\u0434 <code>clear()<\/code>.    <\/p>\n<pre><code class=\"javascript\">  clear(canvas) {     \/\/ \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u043e\u0442\u0447\u0438\u0449\u0430\u0435\u0442 \u043d\u0443\u0436\u043d\u044b\u0439 \u043a\u0430\u043d\u0432\u0430\u0441         \/\/ \u041f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0432 \u043d\u0435\u0435 \u0438\u043c\u044f \u043d\u0443\u0436\u043d\u043e\u0433\u043e \u0441\u043b\u043e\u044f \u0432 \u0432\u0438\u0434\u0435 '\u0441\u0442\u0440\u043e\u043a\u0438' \u0442\u0435\u043a\u0441\u0442\u0430     this.canvas.get(canvas).clear()       }<\/code><\/pre>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u0438 \u043d\u0438\u0436\u0435 \u043d\u0443\u0436\u043d\u044b \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0438\u0433\u0440\u043e\u0432\u044b\u0445 \u043c\u0435\u0445\u0430\u043d\u0438\u043a,\u00a0\u043e\u043d\u0438 \u0434\u0435\u043b\u0430\u044e\u0442 \u0432\u0438\u0434\u0438\u043c\u044b\u043c\u0438 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0435 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c\u044b \u0438\u0433\u0440\u044b, \u0442\u0430\u043a\u0438\u0435 \u043a\u0430\u043a &#171;\u0442\u0435\u043d\u044c&#187; \u0438\u0433\u0440\u043e\u043a\u043e\u0432, \u0436\u0435\u043b\u0442\u0430\u044f \u0437\u043e\u043d\u0430 \u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0435 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0432\u044b\u043b\u0435\u0442\u0430 \u043c\u044f\u0447\u0438\u043a\u0430  <\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/458\/541\/fbc\/458541fbc8064c1e166e19f98e7dd4cf.png\" width=\"1320\" height=\"296\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/458\/541\/fbc\/458541fbc8064c1e166e19f98e7dd4cf.png\"\/><figcaption><\/figcaption><\/figure>\n<pre><code class=\"javascript\">  drawShadowPlayer(xS, yS, yF) {       \/\/ \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0440\u0438\u0441\u0443\u0435\u0442 \u0444\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0440\u0430\u0437\u043c\u0435\u0440 \u0438\u0433\u0440\u043e\u043a\u0430.   \/\/ \u0412 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u0438 \u0437\u043e\u043d\u0430 \u043e\u0442\u0431\u0438\u0442\u0438\u044f \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f     const color = this.set.supportColorYellow     const plWidth = (this.set.playerRadius * 2)        this.supCan.drawLine(xS, yS, xS, yF, plWidth, color)   }      drawYellowZone(x, yS, yF) {       \/\/ \u0415\u0441\u043b\u0438 \u043c\u044f\u0447\u0438\u043a \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0436\u0435\u043b\u0442\u043e\u0439 \u0437\u043e\u043d\u0435 (\u043f\u0435\u0440\u0435\u0434 \u0438\u0433\u0440\u043e\u043a\u043e\u043c),   \/\/ \u0442\u043e \u043e\u043d \u043e\u0442\u0441\u043a\u0430\u043a\u0438\u0432\u0430\u0435\u0442 \u043e\u0442 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b X \u0438\u0433\u0440\u043e\u043a\u0430. \u0422\u0443\u0442 \u043c\u044b \u043f\u043e\u0434\u0441\u0432\u0435\u0447\u0438\u0432\u0430\u0435\u043c   \/\/ \u044d\u0442\u0443 \u0436\u0435\u043b\u0442\u0443\u044e \u0437\u043e\u043d\u0443     const color = this.set.supportColorYellow     const center = (this.set.boxWidth \/ 2)      this.supCan.drawLine(x, yS, center, yS, 1, color)     this.supCan.drawLine(x, yF, center, yF, 1, color)   }      drawAngleZone() {       \/\/ \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u043e\u0434\u0441\u0432\u0435\u0447\u0438\u0432\u0430\u0435\u0442 \u0432\u0441\u0435 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0432\u044b\u043b\u0435\u0442\u0430 \u043c\u044f\u0447\u0430,   \/\/\u043d\u0443\u0436\u043d\u044b \u0431\u044b\u043b\u0438 \u0434\u043b\u044f \u0440\u0430\u0441\u0447\u0435\u0442\u0430 \u0443\u0433\u043b\u0430 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0431\u0435\u043b\u043e\u0433\u043e \u0431\u0435\u0433\u0443\u043d\u043a\u0430     const color = this.set.supportColorRed     const radius = (this.set.boxHeight \/ 4)          this.supCan.drawArc(radius, Math.PI * 0.2, Math.PI * 0.3, color)     this.supCan.drawArc(radius, Math.PI * 0.7, Math.PI * 0.8, color)     this.supCan.drawArc(radius, Math.PI * 1.2, Math.PI * 1.3, color)     this.supCan.drawArc(radius, Math.PI * 1.7, Math.PI * 1.8, color)     }   }<\/code><\/pre>\n<p><a href=\"#begin\" rel=\"noopener noreferrer nofollow\">\u041d\u0430\u0432\u0435\u0440\u0445<\/a><\/p>\n<hr\/>\n<p><a class=\"anchor\" name=\"game\" id=\"game\"><\/a><\/p>\n<h2>game.js<\/h2>\n<p>\u041d\u0430 \u044d\u0442\u043e\u0442 \u043c\u043e\u0434\u0443\u043b\u044c \u0441\u0441\u044b\u043b\u0430\u0435\u0442\u0441\u044f <a href=\"#index\" rel=\"noopener noreferrer nofollow\">index.html<\/a> \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u0437\u0430\u043f\u0443\u0441\u043a \u0441\u0430\u043c\u043e\u0439 \u0438\u0433\u0440\u044b. \u0412 \u043d\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u044e\u0442\u0441\u044f \u043f\u043e\u0447\u0442\u0438 \u0432\u0441\u0435 \u043a\u043b\u0430\u0441\u0441\u044b \u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u0446\u0438\u043a\u043b \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438 \u043a\u0430\u0434\u0440\u043e\u0432 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438. \u041e\u043d \u0442\u0430\u043a\u0436\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0445\u0430\u0431\u043e\u043c, \u0447\u0435\u0440\u0435\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0434\u0443\u043b\u0438 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0443\u044e \u0434\u0440\u0443\u0433 \u0441 \u0434\u0440\u0443\u0433\u043e\u043c.<\/p>\n<pre><code class=\"javascript\">import Setting from '.\/setting.js' import Player from '.\/player.js' import Ball from '.\/ball.js' import Printer from '.\/printer.js' \/\/ \u0412 \u0444\u0430\u0439\u043b \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438, \u0418\u0433\u0440\u043e\u043a\u0430, \u041c\u044f\u0447\u0438\u043a \u0438 \u041f\u0440\u0438\u043d\u0442\u0435\u0440  class Game {   constructor() {             this.set = new Setting()             \/\/ \u041f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 set \u043e\u0431\u0449\u0438\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438                  this.print = new Printer(this.set)             \/\/ \u0412 Printer \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438                  this.ball = new Ball(this)             \/\/ \u0412 Ball \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0432\u0435\u0441\u044c \u043a\u043b\u0430\u0441\u0441 Game                  this.playerL = new Player(this, this.set.playerL)             this.playerR = new Player(this, this.set.playerR)             \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0434\u0432\u0430 \u043a\u043b\u0430\u0441\u0441\u0430 Player \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0442\u0443\u0434\u0430 \u0432\u0435\u0441\u044c \u043a\u043b\u0430\u0441\u0441 Game,      \/\/ \u0430 \u0442\u0430\u043a\u0436\u0435 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0438\u0433\u0440\u043e\u043a\u0430                  this.reqId = true             \/\/ \u041f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f \"requestId\" \u0441\u043b\u0443\u0436\u0438\u0442 \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0438 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438.     \/\/ \u041c\u0435\u043d\u044f\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043d\u0430 false, \u043c\u044b \u0441\u043c\u043e\u0436\u0435\u043c \u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0442\u044c \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u044e           this.firstLaunch()             \/\/ \u0418\u043d\u0438\u0446\u0438\u0438\u0440\u0443\u0435\u043c \u043f\u0435\u0440\u0432\u044b\u0439 \u0437\u0430\u043f\u0443\u0441\u043a \u0438\u0433\u0440\u044b   }<\/code><\/pre>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f <code>firstLaunch()<\/code> \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0437\u0430 \u043f\u0435\u0440\u0432\u044b\u0439 \u0437\u0430\u043f\u0443\u0441\u043a \u0438 \u0441\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u043e\u0434\u0438\u043d \u0440\u0430\u0437 \u043f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435. \u0424\u0443\u043d\u043a\u0446\u0438\u0438 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u043d\u0430 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u0432\u043d\u0443\u0442\u0440\u0438 \u0441\u0435\u0431\u044f \u0431\u0443\u0434\u0443\u0442 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0440\u0430\u0441\u043f\u0438\u0441\u0430\u043d\u044b \u0432\u043d\u0443\u0442\u0440\u0438 \u0441\u0432\u043e\u0438\u0445 \u043a\u043b\u0430\u0441\u0441\u043e\u0432.<\/p>\n<pre><code class=\"javascript\">  firstLaunch() {      this.print.drawBackground()             \/\/ \u0420\u0438\u0441\u0443\u0435\u043c \u0438\u0433\u0440\u043e\u0432\u043e\u0435 \u043f\u043e\u043b\u0435            this.support()             \/\/ \u0412\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438. \u0412\u044b\u0437\u0432\u0430\u0432 \u0435\u0435 \u0437\u0434\u0435\u0441\u044c, \u043c\u044b \u0443\u0432\u0438\u0434\u0438\u043c     \/\/ 4 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0445 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u043f\u043e\u043b\u0435\u0442\u0430 \u043c\u044f\u0447\u0438\u043a\u0430        this.playerL.draw()             this.playerR.draw()             \/\/ \u0420\u0438\u0441\u0443\u0435\u043c \u0438\u0433\u0440\u043e\u043a\u043e\u0432        this.print.drawScore()             \/\/ \u0420\u0438\u0441\u0443\u0435\u043c \u0446\u0438\u0444\u0440\u044b \u0441\u0447\u0435\u0442\u0430, \u043e\u043d\u0438 \u043f\u043e\u043a\u0430 \u0440\u0430\u0432\u043d\u044b 0                this.print.drawBriefing()             \/\/ \u0424\u0443\u043d\u043a\u0446\u0438\u044f drawBriefing() \u0440\u0438\u0441\u0443\u0435\u0442 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e \u043f\u043e \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044e                this.ball.dropBall()             \/\/ dropBall() \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u0442 \u0440\u0430\u043d\u0434\u043e\u043c\u043d\u043e\u0435 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u043c\u044f\u0447\u0438\u043a\u0430                this.print.drawBallDirection(4)             \/\/ drawBallDirection(4) \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u043a\u0430\u043a\u043e\u0435 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u043c\u044f\u0447\u0430      \/\/ \u0432\u044b\u0431\u0440\u0430\u043d\u043e \u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u0446\u0438\u043a\u043b \u0440\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u044f \u0431\u0435\u043b\u043e\u0439 \u043f\u043e\u043b\u043e\u0441\u043e\u0447\u043a\u0438,      \/\/ \u0431\u0435\u0433\u0430\u044e\u0449\u0435\u0439 \u043f\u043e \u043a\u0440\u0443\u0433\u0443        this.print.centerText('3')             \/\/ \u0420\u0438\u0441\u0443\u0435\u043c \u0446\u0438\u0444\u0440\u0443 3. \u041f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432 \u043c\u0435\u0442\u043e\u0434 \u043a\u043b\u0430\u0441\u0441\u0430 Print                setTimeout(() => {       this.print.clear('text'),       this.print.centerText('2') }, '800')       \/\/ \u041e\u0442\u0447\u0438\u0449\u0430\u0435\u043c \u0441\u043b\u043e\u0439 \u0441 \u0446\u0438\u0444\u0440\u043e\u0439 3 \u0438 \u0440\u0438\u0441\u0443\u0435\u043c \u0446\u0438\u0444\u0440\u0443 2       \/\/ \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u043e\u0439 \u0432 JS \u0444\u0443\u043d\u043a\u0446\u0438\u0438 setTimeout(),       \/\/ \u0434\u0435\u043b\u0430\u0435\u043c \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0443 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0439 \u0431\u043b\u043e\u043a\u0430 {} \u043a\u043e\u0434\u0430 \u0432 0.8 \u0441\u0435\u043a\u0443\u043d\u0434,        \/\/ \u0438\u043b\u0438 '800' \u043c\u0438\u043b\u0438\u0441\u0435\u043a\u0443\u043d\u0434        setTimeout(() => {                   this.print.clear('text'),                   this.print.centerText('1') }, '1600')                   \/\/ \u041a\u0430\u0436\u0434\u043e\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0435\u0449\u0435 \u043d\u0430 '800' \u043c\u0438\u043b\u0438\u0441\u0435\u043a\u0443\u043d\u0434       \/\/ \u043f\u043e\u0437\u0434\u043d\u0435\u0435 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0433\u043e                setTimeout(() => {       this.print.clear('text'),       this.print.centerText('Go')}, '2400')       \/\/ \u0421\u0442\u0438\u0440\u0430\u0435\u043c \u0446\u0438\u0444\u0440\u0443 \u0438 \u043f\u0438\u0448\u0435\u043c \"Go\"        setTimeout(() => {       this.print.clear('text'),       this.print.clear('other')       this.start(this.reqId) }, '3200')       \/\/ \u041d\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043e\u0442\u0447\u0438\u0449\u0430\u0435\u043c \u0441\u043b\u043e\u0438 \u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0438\u0433\u0440\u0443.       \/\/ \u0412 \u0444\u0443\u043d\u043a\u0446\u0438\u044e start() \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e this.reqId,        \/\/ \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u0441\u0442\u043e\u0438\u0442 true     }<\/code><\/pre>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0434\u0432\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0441\u043e\u0437\u0434\u0430\u044e\u0449\u0438\u0435 \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u044b\u0439 \u0446\u0438\u043a\u043b \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438. \u0422\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>requestAnimationFrame()<\/code>, \u043e \u043d\u0435\u0439 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0432 <a href=\"https:\/\/developer.mozilla.org\/ru\/docs\/Web\/API\/window\/requestAnimationFrame\" rel=\"noopener noreferrer nofollow\">\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438<\/a>, \u043e\u043d\u0430 \u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0435\u0442 \u043a\u0430\u0434\u0440.  <\/p>\n<pre><code class=\"javascript\">  start(reqId) {       \/\/ \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u044e, \u043f\u0440\u0438 \u0443\u0441\u043b\u043e\u0432\u0438\u0438 \u0447\u0442\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043d\u0430\u044f   \/\/ \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f \u0440\u0430\u0432\u043d\u0430 true             if (reqId) {                   this.reqId = requestAnimationFrame((t) => this.timeLoop(t))       \/\/ \u0415\u0441\u043b\u0438 reqId \u0431\u044b\u043b\u0430 true, \u0442\u043e \u043c\u0435\u0442\u043e\u0434 requestAnimationFrame()       \/\/ \u0432\u044b\u0437\u0432\u0430\u0435\u0442 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0434\u043b\u044f \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u0435\u0440\u0435\u0434       \/\/ \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043f\u0435\u0440\u0435\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u043d\u0438\u0435\u043c      }   }      timeLoop(t) {      this.print.clear('gamelayer')             \/\/ \u041e\u0442\u0447\u0438\u0449\u0430\u0435\u043c \u0438\u0433\u0440\u043e\u0432\u043e\u0439 \u0441\u043b\u043e\u0439, \u044d\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0447\u0442\u043e\u0431 \u0438\u0433\u0440\u043e\u043a\u0438 \u0438 \u043c\u044f\u0447     \/\/ \u043d\u0435 \u043e\u0441\u0442\u0430\u0432\u043b\u044f\u043b\u0438 \u0437\u0430 \u0441\u043e\u0431\u043e\u0439 \u0441\u043b\u0435\u0434 \u0438\u0437 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0445 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043e\u043a                 this.ball.update()             this.playerL.update()             this.playerR.update()             \/\/ \u0424\u0443\u043d\u043a\u0446\u0438\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u043c\u044f\u0447\u0438\u043a\u0430 \u0438 \u0438\u0433\u0440\u043e\u043a\u043e\u0432, \u043e\u043d\u0438, \u0432 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c,      \/\/ \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0442 \u0432\u0441\u0435 \u043d\u0443\u0436\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0432\u043d\u0443\u0442\u0440\u0438 \u0441\u0432\u043e\u0438\u0445 \u043a\u043b\u0430\u0441\u0441\u043e\u0432          this.support()             \/\/ \u0412\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438. \u0412\u044b\u0437\u0432\u0430\u0432 \u0435\u0435 \u0437\u0434\u0435\u0441\u044c, \u043c\u044b \u0443\u0432\u0438\u0434\u0438\u043c     \/\/ \u0433\u0440\u0430\u043d\u0438\u0446\u044b \u0436\u0435\u043b\u0442\u044b\u0445 \u0437\u043e\u043d, \u043e\u0442 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435     \/\/ \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043e\u0442\u0431\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043c\u044f\u0447\u0438\u043a \u043e\u0442 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b          this.start(this.reqId)             \/\/ \u0421\u043d\u043e\u0432\u0430 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c start() \u0432\u044b\u0437\u044b\u0432\u0430\u044f \u0437\u0430\u0446\u0438\u043a\u043b\u0435\u043d\u043d\u043e\u0441\u0442\u044c \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438.     \/\/ \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c requestId, \u043e\u043d \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442     \/\/ \u043c\u0435\u0442\u043e\u0434 requestAnimationFrame() \u0438 \u0432\u044b\u0434\u0430\u0441\u0442 true   }<\/code><\/pre>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f <code>reStart()<\/code> \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0443 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438 \u0438 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a \u043c\u0430\u0442\u0447\u0430. \u0415\u0435 \u0437\u0430\u0434\u0430\u0447\u0438 \u0447\u0430\u0441\u0442\u0438\u0447\u043d\u043e \u0441\u0445\u043e\u0436\u0438 \u0441 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439 <code>firstLaunch()<\/code>.<\/p>\n<p>\u042d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0441\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u043f\u0440\u0438 \u0437\u0430\u0431\u0438\u0442\u0438\u0438 \u0433\u043e\u043b\u0430 \u0438 \u0432 \u043d\u0435\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e <code>align<\/code> \u0442\u043e\u0433\u043e \u0438\u0433\u0440\u043e\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0437\u0430\u0431\u0438\u043b \u043c\u044f\u0447.<\/p>\n<pre><code class=\"javascript\">  reStart(align) {     this.reqId = false             \/\/ \u043f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u0435\u043c reqId \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 false, \u044d\u0442\u043e \u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u044e                setTimeout(() => {             \/\/ \u0414\u0435\u043b\u0430\u0435\u043c \u0437\u0430\u0434\u0435\u0440\u0436\u043a\u0443 \u0432 0.8 \u0441\u0435\u043a\u0443\u043d\u0434, \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:       this.print.clear('gamelayer')                   \/\/ \u041e\u0442\u0447\u0438\u0449\u0430\u0435\u043c \u0438\u0433\u0440\u043e\u0432\u043e\u0439 \u0441\u043b\u043e\u0439                    this.playerL.defaultSet()                   this.playerR.defaultSet()                   this.ball.defaultSet()                   \/\/ \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0438\u0433\u0440\u043e\u043a\u0430\u043c \u0438 \u043c\u044f\u0447\u0438\u043a\u0443 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043f\u043e\u0437\u0438\u0446\u0438\u0439 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e           this.playerL.draw()       this.playerR.draw()       this.ball.draw()       \/\/ \u0421\u043d\u043e\u0432\u0430 \u0440\u0438\u0441\u0443\u0435\u043c \u0438\u0433\u0440\u043e\u043a\u043e\u0432 \u0438 \u043c\u044f\u0447\u0438\u043a, \u0443\u0436\u0435 \u0432 \u0441\u0442\u0430\u0440\u0442\u043e\u0432\u044b\u0445 \u043f\u043e\u0437\u0438\u0446\u0438\u044f\u0445           this.support()                   \/\/ \u0412\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438. \u0412\u044b\u0437\u0432\u0430\u0432 \u0435\u0435 \u0437\u0434\u0435\u0441\u044c, \u043c\u044b \u0443\u0432\u0438\u0434\u0438\u043c       \/\/ 4 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0445 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u043f\u043e\u043b\u0435\u0442\u0430 \u043c\u044f\u0447\u0438\u043a\u0430        this.ball.dropBall(align)                   \/\/ dropBall() \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u0442 \u0440\u0430\u043d\u0434\u043e\u043c\u043d\u043e\u0435 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u043c\u044f\u0447\u0438\u043a\u0430        \/\/ \u0417\u043d\u0430\u0447\u0435\u043d\u0438\u0435 align \u0443\u043a\u0430\u0436\u0435\u0442 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0431\u0440\u043e\u0441\u043a\u0430 \u0432 \u0437\u0430\u0431\u0438\u0432\u0448\u0435\u0433\u043e       \/\/ \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0439 \u0433\u043e\u043b. \u0420\u0430\u043d\u0434\u043e\u043c\u043e\u0441\u0442\u044c \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0432        \/\/ \u043d\u0430\u043f\u0440\u0432\u043b\u0435\u043d\u0438\u0438 \u0432\u0432\u0435\u0440\u0445 \u0438\u043b\u0438 \u0432\u043d\u0438\u0437        this.print.drawBallDirection()                   \/\/ \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u0431\u0435\u043b\u044b\u0439 \u0431\u0435\u0433\u0443\u043d\u043e\u043a \u043f\u043e \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044e,       \/\/ \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u043c\u0443 \u0432\u044b\u0448\u0435 \u0432 dropBall()      }, '800')     setTimeout(() => {     \/\/ \u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u043f\u0440\u043e\u0438\u0437\u043e\u0439\u0434\u0443\u0442 \u0443\u0436\u0435 \u0447\u0435\u0440\u0435\u0437 1.6 \u0441\u0435\u043a\u0443\u043d\u0434\u044b       this.print.clear('other')       \/\/ \u041e\u0442\u0447\u0438\u0449\u0430\u0435\u043c \u0441\u043b\u043e\u0439 other, \u044d\u0442\u043e \u0443\u0434\u0430\u043b\u0438\u0442 \u0431\u0435\u043b\u044b\u0439 \u0431\u0435\u0433\u0443\u043d\u043e\u043a \u0441 \u044d\u043a\u0440\u0430\u043d\u0430       this.reqId = true       this.start(this.reqId)       \/\/ \u0421\u043d\u043e\u0432\u0430 \u043f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u0435\u043c reqId \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 true       \/\/ \u0438 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0438\u0433\u0440\u043e\u0432\u043e\u0439 \u0446\u0438\u043a\u043b       \/\/ \u042d\u0442\u0438 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u043f\u0440\u043e\u0438\u0437\u043e\u0439\u0434\u0443\u0442 \u0443\u0436\u0435 \u0447\u0435\u0440\u0435\u0437 1.6 \u0441\u0435\u043a\u0443\u043d\u0434\u044b,       \/\/ \u043f\u043e\u0441\u043b\u0435 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0433\u043e setTimeout()     }, '2400')   }<\/code><\/pre>\n<p>\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043d\u0435 \u0432\u043b\u0438\u044f\u0435\u0442 \u043d\u0430 \u0440\u0430\u0431\u043e\u0442\u043e\u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0441\u0442\u044c \u0438 \u043d\u0443\u0436\u043d\u0430 \u0438\u0441\u043a\u043b\u044e\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0434\u043b\u044f \u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u044f \u0440\u0430\u0431\u043e\u0442\u044b &#171;\u0436\u0435\u043b\u0442\u043e\u0439 \u0437\u043e\u043d\u044b&#187; \u0438 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c\u0430 \u043e\u0442\u0431\u0438\u0442\u0438\u044f \u043c\u044f\u0447\u0438\u043a\u0430 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0430\u043c\u0438.<\/p>\n<pre><code class=\"javascript\">  support() {     \/\/ \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432 firstLaunch(), timeLoop() \u0438 reStart()    \/\/ \u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0443 \u0432\u0441\u0435\u0445 \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439     this.print.clear('support')     \/\/ \u041e\u0442\u0447\u0438\u0449\u0430\u0435\u0442 \u0441\u0432\u043e\u0439 \u0441\u043b\u043e\u0439 \u043a\u0430\u043d\u0432\u0430\u0441\u0430     this.playerL.support()     this.playerR.support()     \/\/ \u0420\u0438\u0441\u0443\u0435\u0442 \u0436\u0435\u043b\u0442\u044b\u0435 \u0437\u043e\u043d\u044b \u0438\u0433\u0440\u043e\u043a\u043e\u0432     this.print.drawAngleZone()     \/\/ \u0420\u0438\u0441\u0443\u0435\u0442 4 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u043c\u044f\u0447\u0430   } }<\/code><\/pre>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f \u043d\u0438\u0436\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0432\u043e\u0439, \u043f\u043e\u0441\u043b\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 <code>index.html<\/code>, \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u043a\u043b\u0430\u0441\u0441 <em>Game<\/em> \u0438 \u043f\u043e \u0444\u0430\u043a\u0442\u0443 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u0432\u0435\u0441\u044c \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0439 JavaScript \u043a\u043e\u0434  <\/p>\n<pre><code class=\"javascript\">window.onload = () => { \/\/ \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u043e\u0431\u044a\u0435\u043a\u0442 Game \u043f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e \u043a\u0430\u043a \u0432\u0441\u0435 \u0444\u0430\u0439\u043b\u044b \/\/ \u0431\u0443\u0434\u0443\u0442 \u043f\u043e\u0434\u0433\u0440\u0443\u0436\u0435\u043d\u044b \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u043e\u043c     const game = new Game() }<\/code><\/pre>\n<p><a href=\"#begin\" rel=\"noopener noreferrer nofollow\">\u041d\u0430\u0432\u0435\u0440\u0445<\/a><\/p>\n<hr\/>\n<p><a class=\"anchor\" name=\"ball\" id=\"ball\"><\/a><\/p>\n<h2>ball.js<\/h2>\n<p>\u041c\u043e\u0434\u0443\u043b\u044c \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u043c\u044f\u0447\u0438\u043a. \u0417\u0430 \u0440\u0430\u043d\u0434\u043e\u043c\u043d\u043e\u0441\u0442\u044c \u0435\u0433\u043e \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f, \u0440\u0430\u0437\u0432\u043e\u0440\u043e\u0442, \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0443 \u0438 \u0442.\u043f.  <\/p>\n<pre><code class=\"javascript\">export default class Ball {   constructor(Game) {     \/\/ \u041f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0432 Ball \u043c\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u043b\u0438 \u0432 \u043d\u0435\u0433\u043e \u0432\u0435\u0441\u044c \u043a\u043b\u0430\u0441\u0441 Game             this.game = Game     \/\/ \u0427\u0435\u0440\u0435\u0437 game \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u0432 \u043c\u0435\u0442\u043e\u0434\u0443 reStart()          this.set = Game.set     \/\/ \u041f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 set \u043e\u0431\u0449\u0438\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438          this.ball = Game.set.ball     \/\/ \u0414\u043b\u044f \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430, \u0441\u0440\u0430\u0437\u0443 \u0432\u044b\u0434\u0435\u043b\u0438\u043c \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0443\u044e \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e ball,     \/\/ \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043c\u044f\u0447\u0438\u043a\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0437\u043c\u0435\u043d\u044f\u044e\u0441\u044f \u043f\u043e \u0445\u043e\u0434\u0443 \u0438\u0433\u0440\u044b          this.print = Game.print             \/\/ \u0414\u043b\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u043c\u043e\u0434\u0443\u043b\u044e Printer       }<\/code><\/pre>\n<p>\u0414\u0432\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043d\u0438\u0436\u0435 \u043e\u0442\u0432\u0435\u0447\u0430\u044e\u0442 \u0437\u0430 \u0440\u0430\u043d\u0434\u043e\u043c\u043d\u043e\u0441\u0442\u044c \u043f\u043e\u043b\u0435\u0442\u0430 \u043c\u044f\u0447\u0438\u043a\u0430. \u041f\u0435\u0440\u0432\u0430\u044f \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u0442 \u0432\u0435\u043b\u0438\u0447\u0438\u043d\u0443 \u0443\u0441\u043a\u043e\u0440\u0435\u043d\u0438\u044f \u043e\u0442 0.8 \u0434\u043e 1, \u0430 \u0432\u0442\u043e\u0440\u0430\u044f \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u0442 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u0433\u043e \u0443\u0441\u043a\u043e\u0440\u0435\u043d\u0438\u044f &#8212; \u0441 \u043c\u0438\u043d\u0443\u0441\u043e\u043c \u0438\u043b\u0438 \u043f\u043b\u044e\u0441\u043e\u043c.<\/p>\n<p>\u041c\u044f\u0447\u0438\u043a \u0434\u0432\u0438\u0433\u0430\u0435\u0442\u0441\u044f \u043f\u0443\u0442\u0435\u043c \u043f\u0440\u0438\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0443\u0441\u043a\u043e\u0440\u0435\u043d\u0438\u044f \u043a \u0435\u0433\u043e \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430\u043c. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0447\u0442\u043e\u0431\u044b \u0441\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u043c\u044f\u0447\u0438\u043a \u0432\u043f\u0440\u0430\u0432\u043e, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0440\u0438\u0431\u0430\u0432\u0438\u0442\u044c <code>1<\/code> \u043a \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0435 <code>x<\/code>, \u0430 \u0447\u0442\u043e\u0431\u044b \u0441\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u0435\u0433\u043e \u0432\u043d\u0438\u0437, \u043f\u0440\u0438\u0431\u0430\u0432\u0438\u0442\u044c <code>1<\/code> \u043a \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0435 <code>y<\/code> (\u043e\u0441\u044c \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0432 \u0432\u0435\u0440\u0445\u043d\u0435\u043c \u043b\u0435\u0432\u043e\u043c \u0443\u0433\u043b\u0443). \u041d\u043e \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043c\u044f\u0447\u0438\u043a \u0431\u0443\u0434\u0435\u0442 \u043b\u0435\u0442\u0435\u0442\u044c \u0441\u0442\u0440\u043e\u0433\u043e \u043f\u043e\u0434 45\u00b0.<\/p>\n<p>\u0427\u0442\u043e\u0431 \u044d\u0442\u043e\u0433\u043e \u043d\u0435 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u043b\u043e \u0435\u0441\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>getRandom()<\/code>, \u043e\u043d\u0430 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0440\u0430\u043d\u0434\u043e\u043c\u043d\u043e\u0435 \u0447\u0438\u0441\u043b\u043e \u0432 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043a\u0435 \u043e\u0442 0.8 \u0434\u043e 1. \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u043c\u044b \u043f\u0440\u0438\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043a \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430\u043c <code>x<\/code> \u0438 <code>y<\/code> \u0440\u0430\u0437\u043d\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0438 \u043c\u044f\u0447\u0438\u043a \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u041d\u0415 \u0434\u0432\u0438\u0433\u0430\u0435\u0442\u0441\u044f \u0441\u0442\u0440\u043e\u0433\u043e \u043f\u043e\u0434 45\u00b0. \u042d\u0442\u043e\u0433\u043e \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043d\u0435 \u0437\u0430\u043c\u0435\u0442\u043d\u043e, \u043d\u043e \u0442\u0430\u043a\u043e\u0435 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u043d\u0435 \u0434\u0430\u0435\u0442 \u043c\u044f\u0447\u0438\u043a\u0443 \u0437\u0430\u0446\u0438\u043a\u043b\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u0432 \u043e\u0434\u043d\u043e\u0439 \u0442\u0440\u0430\u0435\u043a\u0442\u043e\u0440\u0438\u0438 \u0438 \u0434\u0435\u043b\u0430\u0435\u0442 \u0438\u0433\u0440\u0443 \u0431\u043e\u043b\u0435\u0435 \u0440\u0430\u0437\u043d\u043e\u043e\u0431\u0440\u0430\u0437\u043d\u043e\u0439.<\/p>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f <code>getRandomDirection()<\/code> \u0432 \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u043e\u043c \u043f\u043e\u0440\u044f\u0434\u043a\u0435 \u043f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u0435\u0442 \u043e\u0442\u0440\u0438\u0446\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u0438\u043b\u0438 \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0443 <code>getRandom()<\/code>. <\/p>\n<pre><code class=\"javascript\">  getRandom() {            return Math.random() * (1 - 0.8) + 0.8             \/\/ \u041c\u0435\u0442\u043e\u0434 Math.random() \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u043e\u0435 \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435             \/\/ \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432 \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0435 \u043e\u0442 0 \u0434\u043e &lt;1,            \/\/ \u0430 \u0444\u043e\u0440\u043c\u0443\u043b\u0430 Math.random() * (max - min) + min \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442              \/\/ \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0440\u0430\u043d\u0434\u043e\u043c\u043d\u043e\u0435 \u0447\u0438\u0441\u043b\u043e \u0432 \u043d\u0443\u0436\u043d\u043e\u043c \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0435 \u043e\u0442 min \u0434\u043e max       }      getRandomDirection() {               if (Boolean(Math.round(Math.random()))) {             \/\/ Math.random() \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435             \/\/ Math.round() \u043e\u043a\u0440\u0443\u0433\u043b\u044f\u0435\u0442 \u044d\u0442\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0434\u043e \u0446\u0435\u043b\u043e\u0433\u043e 0 \u0438\u043b\u0438 1             \/\/ Boolean() \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 0 \u043a\u0430\u043a false, \u0430 1 \u043a\u0430\u043a true                   return this.getRandom()                   \/\/ \u0415\u0441\u043b\u0438 Boolean() \u0432\u0435\u0440\u043d\u0443\u043b true, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u043e\u0435 \u0447\u0438\u0441\u043b\u043e          \/\/ \u0432 \u043d\u0443\u0436\u043d\u043e\u043c \u043d\u0430\u043c \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439 getRandom()             } else { return -this.getRandom() }             \/\/ \u0415\u0441\u043b\u0438 Boolean() \u0432\u0435\u0440\u043d\u0443\u043b false, \u0442\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0442\u043e\u0436\u0435 \u0441\u0430\u043c\u043e\u0435,        \/\/ \u043d\u043e \u0441\u043e \u0437\u043d\u0430\u043a\u043e\u043c \"\u043c\u0438\u043d\u0443\u0441\"       }<\/code><\/pre>\n<p>\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0434\u0432\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u0435 \u043c\u044f\u0447\u0438\u043a\u0430.  <\/p>\n<p>\u0422\u0430\u043a, \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>dropBall()<\/code> \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u0442 \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0435 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u043f\u043e\u043b\u0435\u0442\u0430 \u043c\u044f\u0447\u0438\u043a\u0430. \u0427\u0442\u043e\u0431 \u043e\u043d \u043c\u043e\u0433 \u043f\u043e\u043b\u0435\u0442\u0435\u0442\u044c \u0438\u0437 \u0446\u0435\u043d\u0442\u0440\u0430 \u0432 \u043b\u044e\u0431\u043e\u0439 \u0438\u0437 4 \u0443\u0433\u043b\u043e\u0432 \u043f\u043e\u043b\u044f.<\/p>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0435 \u0432\u044b\u0448\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043e\u043d\u0430 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u0440\u0430\u043d\u0434\u043e\u043c\u043d\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0438 \u043f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u0435\u0442 \u0438\u0445 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u043c <code>dx<\/code> \u0438 <code>dy<\/code>, \u044d\u0442\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0443\u0441\u043a\u043e\u0440\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u0438\u0437 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442 \u043c\u044f\u0447\u0438\u043a\u0430.<\/p>\n<p>\u0410 \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>move()<\/code> \u043f\u0440\u0438\u0441\u0432\u0430\u0435\u0432\u0430\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0438\u0432\u0448\u0438\u0435\u0441\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f <code>dx<\/code> \u0438 <code>dy<\/code> \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u043c \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430\u043c \u043c\u044f\u0447\u0438\u043a\u0430. \u0415\u0435 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u043d\u0430 \u043a\u0430\u0436\u0434\u043e\u043c \u043a\u0430\u0434\u0440\u0435.<\/p>\n<pre><code class=\"javascript\">  dropBall(player) {           \/\/ \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 align \u043e\u0442 \u0438\u0433\u0440\u043e\u043a\u0430,   \/\/ \u044d\u0442\u043e \u0434\u0430\u0435\u0442 \u043d\u0430\u043c \u043f\u043e\u043d\u044f\u0442\u044c \u043a\u0430\u043a\u043e\u0439 \u0438\u0433\u0440\u043e\u043a \u0437\u0430\u0431\u0438\u043b \u0433\u043e\u043b \u0432 \u043f\u0440\u043e\u0448\u043b\u043e\u043c \u043c\u0430\u0442\u0447\u0435     this.ball.dx = this.getRandomDirection()       this.ball.dy = this.getRandomDirection()             \/\/ \u0421 \u043f\u043e\u043c\u043e\u0449\u044c\u044e getRandomDirection() \u043c\u044b \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c             \/\/ \u0440\u0430\u043d\u0434\u043e\u043c\u043d\u043e\u0435 \u0443\u0441\u043a\u043e\u0440\u0435\u043d\u0438\u0435 \u0441 \u0440\u0430\u043d\u0434\u043e\u043c\u043d\u044b\u043c \u0437\u043d\u0430\u043a\u043e\u043c + \u0438\u043b\u0438 -                 switch (player) {             \/\/ \u0415\u0441\u043b\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 left, \u0442\u043e \u043f\u043e\u0434\u0430\u0435\u0442 \u043b\u0435\u0432\u044b\u0439 \u0438\u0433\u0440\u043e\u043a,             \/\/ \u0437\u043d\u0430\u0447\u0438\u0442 \u043c\u044f\u0447\u0438\u043a \u0434\u043e\u043b\u0436\u0435\u043d \u043b\u0435\u0442\u0435\u0442\u044c \u0432\u043f\u0440\u0430\u0432\u043e.             \/\/ \u041d\u043e \u0442\u0430\u043a \u043a\u0430\u043a \u043c\u044b \u043d\u0435 \u0437\u043d\u0430\u0435\u043c \u043a\u0430\u043a\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043d\u0430\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043e,             \/\/ \u043f\u0440\u0438\u043c\u0438\u043d\u044f\u0435\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:                   case 'left':                         this.ball.dx = Math.abs(this.ball.dx)                         \/\/ \u0427\u0442\u043e\u0431 \u0438\u0441\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u043e\u043b\u0435\u0442\u0430 \u0432\u043b\u0435\u0432\u043e                         \/\/ \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043c\u0435\u0442\u043e\u0434 Math.abs(), \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442             \/\/ \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435         \/\/ \u041f\u0440\u0438\u0441\u0432\u0430\u0435\u0432\u0430\u0435\u043c dx \u0435\u0433\u043e \u0436\u0435, \u043d\u043e \u0442\u043e\u0447\u043d\u043e \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439                break                   case 'right':                         this.ball.dx = -Math.abs(this.ball.dx)                         \/\/ \u0414\u043b\u044f \u043f\u043e\u043b\u0435\u0442\u0430 \u0432\u043b\u0435\u0432\u043e \u043c\u044b \u0442\u0430\u043a\u0436\u0435 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u043c Math.abs(),           \/\/ \u043d\u043e \u043f\u043e\u0441\u043b\u0435 \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0432 \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435,                \/\/ \u0434\u0435\u043b\u0430\u0435\u043c \u0435\u0433\u043e \u043e\u0442\u0440\u0438\u0446\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u043c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e -                         break             }             \/\/ \u0415\u0441\u043b\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 player \u043d\u0435 \u0431\u044b\u043b\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043e, \u0442.\u0435 \u043e\u043d\u043e undefined,      \/\/ \u0442\u043e \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u0438 \u0432\u0441\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043e\u0441\u0442\u0430\u043d\u0443\u0442\u0441\u044f                 \/\/ \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u044b, \u0442\u0430\u043a\u043e\u0435 \u0441\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u043f\u0435\u0440\u0432\u043e\u043c \u0441\u0442\u0430\u0440\u0442\u0435 \u0438\u0433\u0440\u044b       }      move() {   \/\/ \u0414\u0432\u0438\u0433\u0430\u0435\u0442 \u043c\u044f\u0447 \u0432 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0435 \u043f\u0440\u0438\u0431\u0430\u0432\u043b\u044f\u044f \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0440\u0430\u043d\u0435\u0435   \/\/ \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043a \u0435\u0433\u043e \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430\u043c, \u0443\u043c\u043d\u043e\u0436\u0430\u044f \u043d\u0430 \u043a\u043e\u044d\u0444\u0444\u0435\u0446\u0438\u0435\u043d\u0442 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438   \/\/ \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u0437\u0430\u0434\u0430\u043b\u0438 \u0432 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u0445 \u043c\u044f\u0447\u0438\u043a\u0430 \u043a\u0430\u043a speed     this.ball.x += (this.ball.dx * this.ball.speed)             this.ball.y += (this.ball.dy * this.ball.speed)             \/\/ \u041e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 += \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u0442 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 (\u044d\u0442\u043e \u0445)     \/\/ \u0438 \u0440\u0430\u0441\u0447\u0435\u0442\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 (\u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0443\u043c\u043d\u043e\u0436\u0435\u043d\u0438\u044f),     \/\/ \u0430 \u043f\u043e\u0442\u043e\u043c \u043f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u0445   }<\/code><\/pre>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f <code>checkCollisionWithWalls()<\/code> \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u043f\u0440\u043e\u0441\u0447\u0435\u0442 \u0441\u0442\u043e\u043b\u043a\u043d\u043e\u0432\u0435\u043d\u0438\u0439 \u043c\u044f\u0447\u0438\u043a\u0430 \u0441\u043e \u0441\u0442\u0435\u043d\u043a\u0430\u043c\u0438 \u0438\u0433\u0440\u043e\u0432\u043e\u0433\u043e \u043f\u043e\u043b\u044f \u0438, \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0441\u0442\u043e\u043b\u043a\u043d\u043e\u0432\u0435\u043d\u0438\u044f \u043c\u044f\u0447\u0430 \u0441\u043e \u0441\u0442\u0435\u043d\u043a\u043e\u0439 \u0437\u0430 \u0438\u0433\u0440\u043e\u043a\u043e\u043c, \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>goalProcess()<\/code>.<\/p>\n<p>\u041e\u0441\u044c \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442 \u0432 JavaScript \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0441 \u0432\u0435\u0440\u0445\u043d\u0435\u0433\u043e \u043b\u0435\u0432\u043e\u0433\u043e \u0443\u0433\u043b\u0430, \u0447\u0442\u043e \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u043e \u043d\u0430 \u0440\u0438\u0441\u0443\u043d\u043a\u0435 \u043d\u0438\u0436\u0435. \u0421\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0432\u0435\u0440\u0445\u043d\u044f\u044f \u0438 \u043b\u0435\u0432\u0430\u044f \u0441\u0442\u0435\u043d\u043a\u0438 \u0431\u0443\u0434\u0443\u0442 \u0438\u043c\u0435\u0442\u044c \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b 0, \u0430 \u043f\u0440\u0430\u0432\u0430\u044f \u0438 \u043d\u0438\u0436\u043d\u044f\u044f \u0440\u0430\u0432\u043d\u044b \u0434\u043b\u0438\u043d\u0435 \u0438 \u0448\u0438\u0440\u0438\u043d\u0435 \u043f\u043e\u043b\u044f.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/f3d\/ef1\/bcc\/f3def1bcc578615a71d7ba414082a997.png\" width=\"1320\" height=\"526\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/f3d\/ef1\/bcc\/f3def1bcc578615a71d7ba414082a997.png\"\/><figcaption><\/figcaption><\/figure>\n<pre><code class=\"javascript\">  checkCollisionWithWalls() {       let ballX = (this.ball.x + this.ball.dx)        let ballY = (this.ball.y + this.ball.dy)         \/\/ \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 ballX \u0438 ballY \u044d\u0442\u043e \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u043c\u044f\u0447\u0430 \u0432 \u0431\u0443\u0434\u0443\u044e\u0449\u0435\u043c,     \/\/ \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u043d\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c \u043a\u0430\u0434\u0440\u0435, \u043d\u043e \u0431\u0435\u0437 \u0443\u0447\u0435\u0442\u0430 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438     const rightWall = (this.set.boxWidth - this.set.ballRadius)         \/\/ \u041a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430 \u0425 \u043f\u0440\u0430\u0432\u043e\u0439 \u0441\u0442\u0435\u043d\u044b (\u0448\u0438\u0440\u0438\u043d\u0430 \u043f\u043e\u043b\u044f) \u043c\u0438\u043d\u0443\u0441 \u0440\u0430\u0437\u043c\u0435\u0440      \/\/ \u0440\u0430\u0434\u0438\u0443\u0441\u0430 \u043c\u044f\u0447\u0430, \u0447\u0442\u043e\u0431 \u043f\u0440\u0438 \u0441\u0442\u043e\u043b\u043a\u043d\u043e\u0432\u0435\u043d\u0438\u0438 \u043c\u044f\u0447 \u043d\u0435 \u0443\u0442\u043e\u043f\u0430\u043b \u0432 \u0441\u0442\u0435\u043d\u0443        const leftWall = this.set.ballRadius     \/\/ \u041a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430 \u0425 \u043b\u0435\u0432\u043e\u0439 \u0441\u0442\u0435\u043d\u044b (\u044d\u0442\u043e 0) \u043f\u043b\u044e\u0441 \u0440\u0430\u0437\u043c\u0435\u0440 \u0440\u0430\u0434\u0438\u0443\u0441\u0430 \u043c\u044f\u0447\u0430.         \/\/ \u041f\u0440\u043e\u0441\u0442\u043e \u043e\u0442\u0441\u0442\u0443\u043f \u043e\u0442 \u043a\u0440\u0430\u044f \u0440\u0430\u0437\u043c\u0435\u0440\u043e\u043c \u0441 \u043f\u043e\u043b\u043e\u0432\u0438\u043d\u043a\u0443 \u043c\u044f\u0447\u0438\u043a\u0430         const TopWall = this.set.ballRadius         \/\/ \u041a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430 Y \u0432\u0435\u0440\u0445\u043d\u0435\u0439 \u0441\u0442\u0435\u043d\u044b (\u0442\u0430\u043a\u0436\u0435 0),     \/\/ \u041f\u0440\u043e\u0441\u0442\u043e \u0431\u0435\u0440\u0435\u043c \u0440\u0430\u0434\u0438\u0443\u0441 \u043c\u044f\u0447\u0438\u043a\u0430     const BottomWall = (this.set.boxHeight - this.set.ballRadius)         \/\/ \u041a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430 Y \u043d\u0438\u0436\u043d\u0435\u0439 \u0441\u0442\u0435\u043d\u044b (\u0432\u044b\u0441\u043e\u0442\u0430 \u043f\u043e\u043b\u044f) \u043c\u0438\u043d\u0443\u0441 \u0440\u0430\u0434\u0438\u0443\u0441              if (ballX >= rightWall) {               \/\/ \u0415\u0441\u043b\u0438 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u043c\u044f\u0447\u0438\u043a\u0430 \u0441\u0442\u0430\u043b\u0438 \u0431\u043e\u043b\u044c\u0448\u0435 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442 \u043f\u0440\u0430\u0432\u043e\u0439 \u0441\u0442\u0435\u043d\u044b,       \/\/ \u0442\u043e:                     this.ball.dx = this.reverseBall(this.ball.dx)                     \/\/ \u041c\u0435\u043d\u044f\u0435\u043c \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u043e \u043e\u0441\u0438 \u0425 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u0438 reverseBall()         this.goalProcess(this.set.playerL)                     \/\/ \u0412\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e goalProcess() \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u0435\u0442 \u043c\u0430\u0442\u0447         }               if (ballX &lt;= leftWall) {               \/\/ \u0415\u0441\u043b\u0438 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u043c\u044f\u0447\u0438\u043a\u0430 \u0441\u0442\u0430\u043b\u0438 \u043c\u0435\u043d\u044c\u0448\u0435 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442 \u043b\u0435\u0432\u043e\u0439 \u0441\u0442\u0435\u043d\u044b,       \/\/ \u0442\u043e:                    this.ball.dx = this.reverseBall(this.ball.dx)                     this.goalProcess(this.set.playerR)               }               if (ballY >= BottomWall || ballY &lt;= TopWall) {               \/\/ \u0415\u0441\u043b\u0438 \u043c\u044f\u0447\u0438\u043a \u043a\u043e\u0441\u043d\u0443\u043b\u0441\u044f \u0432\u0435\u0440\u0445\u043d\u0435\u0439 \u0438\u043b\u0438 \u043d\u0438\u0436\u043d\u0435\u0439 \u0441\u0442\u0435\u043d\u043a\u0438, \u0442\u043e:               this.ball.dy = this.reverseBall(this.ball.dy)                     \/\/ \u0420\u0430\u0437\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u043c \u043c\u044f\u0447 \u043f\u043e \u043e\u0441\u0438 Y               }     }<\/code><\/pre>\n<p>\u041a\u0430\u043a \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0438\u0437 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f, \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>reverseBall()<\/code> \u0440\u0430\u0437\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u0442 \u043c\u044f\u0447\u0438\u043a \u043f\u043e \u043e\u0434\u043d\u043e\u0439 \u0438\u0437 \u043e\u0441\u0438 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442, \u043c\u0435\u043d\u044f\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0435\u0433\u043e \u0443\u0441\u043a\u043e\u0440\u0435\u043d\u0438\u044f \u0441 \u043e\u0442\u0440\u0438\u0446\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u043d\u0430 \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u0438 \u043d\u0430\u043e\u0431\u043e\u0440\u043e\u0442.  <\/p>\n<pre><code class=\"javascript\">  reverseBall(dir) {       \/\/ \u0412 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0443\u0441\u043a\u043e\u0440\u0435\u043d\u0438\u044f dx \u0438\u043b\u0438 dy     if (dir > 0) {             \/\/ \u0415\u0441\u043b\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0443\u0441\u043a\u043e\u0440\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435, \u0442\u043e       return -this.getRandom()                  \/\/ \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u043d\u043e\u0432\u043e\u0435 \u0440\u0430\u043d\u0434\u043e\u043c\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0443\u0441\u043a\u043e\u0440\u0435\u043d\u0438\u044f       \/\/ \u0441\u043e \u0437\u043d\u0430\u043a\u043e\u043c \u043c\u0438\u043d\u0443\u0441, \u0442.\u0435. \u043e\u0442\u0440\u0438\u0446\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0435     } else {     \/\/ \u0415\u0441\u043b\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0443\u0441\u043a\u043e\u0440\u0435\u043d\u0438\u044f \u043e\u0442\u0440\u0438\u0446\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0435, \u0442\u043e       return this.getRandom()                   \/\/ \u0422\u0430\u043a\u0436\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u043d\u043e\u0432\u043e\u0435 \u0440\u0430\u043d\u0434\u043e\u043c\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435,       \/\/ \u043d\u043e \u0443\u0436\u0435 \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435            }   }<\/code><\/pre>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f <code>goalProcess()<\/code> \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u043c\u0430\u0442\u0447\u0430 \u043f\u043e\u0441\u043b\u0435 \u0433\u043e\u043b\u0430.     \u0410\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u043c \u0432 \u043d\u0435\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u044e\u0442\u0441\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0438\u0433\u0440\u043e\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0437\u0430\u0431\u0438\u043b \u043c\u044f\u0447  <\/p>\n<pre><code class=\"javascript\">  goalProcess(winner) {   \/\/ \u0417\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442 \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u043c\u0430\u0442\u0447\u0430 \u043f\u043e\u0441\u043b\u0435 \u0433\u043e\u043b\u0430.   \/\/ \u0421\u044e\u0434\u0430 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f align \u0438\u0433\u0440\u043e\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0437\u0430\u0431\u0438\u043b \u043c\u044f\u0447     winner.score++     this.print.clear('score')     this.print.drawScore()     \/\/ \u041f\u0440\u0438\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043a \u0441\u0447\u0435\u0442\u0443 \u0437\u0430\u0431\u0438\u0432\u0448\u0435\u0433\u043e +1 \u043e\u0447\u043a\u043e,     \/\/ \u043e\u0442\u0447\u0438\u0449\u0430\u0435\u043c \u0441\u0442\u0430\u0440\u044b\u0439 \u0441\u0447\u0435\u0442 \u0441\u043e \u0441\u043b\u043e\u044f 'score' \u0438 \u0440\u0438\u0441\u0443\u0435\u043c \u043d\u043e\u0432\u044b\u0439 \u0441\u0447\u0435\u0442     this.print.clear('text')     \/\/ \u041e\u0442\u0447\u0438\u0449\u0430\u0435\u043c \u0441\u043b\u043e\u0439 'text', \u0447\u0442\u043e\u0431 \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u0441 \u0446\u0435\u043d\u0442\u0440\u0430 \u043f\u043e\u043b\u044f     \/\/ \u0441\u0447\u0435\u0442\u0447\u0438\u043a \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u043e\u0442\u0431\u0438\u0442\u0438\u0439 \u043c\u044f\u0447\u0430 \u0432 \u043c\u0430\u0442\u0447\u0435     this.set.ballHitScore = 0     \/\/ \u041e\u0431\u043d\u0443\u043b\u044f\u0435\u043c \u0441\u0447\u0435\u0442\u0447\u0438\u043a \u043e\u0442\u0431\u0438\u0442\u0438\u0439, \u0447\u0442\u043e\u0431 \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c \u043c\u0430\u0442\u0447\u0435     \/\/ \u043e\u043d \u043f\u043e\u0448\u0435\u043b \u0441 \u043d\u0443\u043b\u044f     this.print.drawGoal(winner.goalPointX, winner.color, winner.align)     \/\/ \u0412\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0440\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u044f \u0413\u043e\u043b\u0430, \u043e\u043d\u0430 \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0438\u0448\u0435\u0442     \/\/ \u0432 \u0446\u0435\u043d\u0442\u0440\u0435 \u043d\u0430\u0434\u043f\u0438\u0441\u044c \"Goal!\" \u0438 \u0440\u0438\u0441\u0443\u0435\u0442 \"+1\" \u043d\u0430 \u043f\u043e\u043b\u0435 \u0441\u043e\u043f\u0435\u0440\u043d\u0438\u043a\u0430     this.game.reStart(winner.align)     \/\/ \u0412\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u043c\u0435\u0442\u043e\u0434 reStart() \u043a\u043b\u0430\u0441\u0441\u0430 Game, \u043e\u043d \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u044e,     \/\/ \u043e\u0431\u043d\u0443\u043b\u0438\u0442 \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0432\u0441\u0435\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0438 \u043d\u0430\u0440\u0438\u0441\u0443\u0435\u0442 \u0438\u0445 \u0437\u0430\u043d\u043e\u0433\u043e   }<\/code><\/pre>\n<p>\u0414\u043b\u044f \u0431\u043e\u043b\u044c\u0448\u0435\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0430, \u044f \u0441\u043e\u0437\u0434\u0430\u043b \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u0442 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043c\u044f\u0447\u0438\u043a\u0430 \u043d\u0430 <code>0.1<\/code> \u043a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437, \u043a\u043e\u0433\u0434\u0430 \u043e\u043d \u043e\u0442\u0440\u0430\u0436\u0430\u0435\u0442\u0441\u044f \u043e\u0442 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b \u0438\u0433\u0440\u043e\u043a\u0430.<\/p>\n<p>\u041e\u043d\u0430 \u0442\u0430\u043a\u0436\u0435 \u043f\u0440\u0438\u0431\u0430\u0432\u043b\u044f\u0435\u0442 <code>1<\/code> \u043a \u0441\u0447\u0435\u0442\u0447\u0438\u043a\u0443 \u0443\u0434\u0430\u0440\u043e\u0432 \u043c\u044f\u0447\u0430 \u043e \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0443, \u0442\u0430\u043a \u043c\u044b \u0432\u0438\u0434\u0438\u043c \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0437 \u0438\u0433\u0440\u043e\u043a\u0430\u043c \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043e\u0442\u0431\u0438\u0442\u044c \u043c\u044f\u0447<\/p>\n<pre><code class=\"javascript\">  speed\u041cagnifier() {     \/\/ \u0423\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u0442 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043c\u044f\u0447\u0430 \u043d\u0430 0.1       \/\/ \u0438 \u043f\u0440\u0438\u0431\u0430\u0432\u043b\u044f\u0435\u0442 1 \u043a \u0441\u0447\u0435\u0442\u0447\u0438\u043a\u0443 \u0443\u0434\u0430\u0440\u043e\u0432 \u043c\u044f\u0447\u0430 \u043e \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0443.       \/\/ \u041e\u0442\u0447\u0438\u0449\u0430\u0435\u0442 \u0441\u043b\u043e\u0439 'text' \u0438 \u0440\u0438\u0441\u0443\u0435\u0442 \u0437\u0430\u043d\u043e\u0433\u043e             this.ball.speed += 0.1             \/\/ \u041e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 += \u0441\u043d\u0430\u0447\u0430\u043b\u043e \u043f\u0440\u0438\u0431\u0430\u0432\u043b\u044f\u0435\u0442 0.1,             \/\/\u0430 \u043f\u043e\u0442\u043e\u043c \u043f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435             this.set.ballHitScore++             \/\/ \u041e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 ++ \u043f\u0440\u0438\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u043a \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044e 1 \u043a \u0441\u0447\u0435\u0442\u0447\u0438\u043a\u0443 \u0443\u0434\u0430\u0440\u043e\u0432     this.print.clear('text')             this.print.drawBallHit()             \/\/ \u041e\u0442\u0447\u0438\u0449\u0430\u0435\u0442 \u0441\u043b\u043e\u0439 'text' \u0438 \u0440\u0438\u0441\u0443\u0435\u0442 \u043d\u043e\u0432\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0441\u0447\u0435\u0442\u0447\u0438\u043a\u0430     \/\/ \u043d\u0430 \u0438\u0433\u0440\u043e\u0432\u043e\u043c \u043f\u043e\u043b\u0435   }<\/code><\/pre>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0438\u0434\u0443\u0442 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438. <\/p>\n<p><code>defaultSet()<\/code> \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043c\u044f\u0447\u0438\u043a\u0430 \u043a \u0434\u0435\u0444\u043e\u043b\u0442\u043d\u044b\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f\u043c, \u044d\u0442\u043e \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043f\u0430\u0440\u0442\u0438\u0438 \u043f\u0440\u0438 \u0437\u0430\u0431\u0438\u0442\u0438\u0438 \u0433\u043e\u043b\u0430.<\/p>\n<p><code>draw()<\/code> \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0440\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u044f \u043c\u044f\u0447\u0430. \u041c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043e\u0431\u043e\u0439\u0442\u0438\u0441\u044c \u0431\u0435\u0437 \u043d\u0435\u0435, \u0432\u044b\u0437\u044b\u0432\u0430\u044f \u0440\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u0435 \u043c\u044f\u0447\u0430 \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e \u0438\u0437 \u043a\u043b\u0430\u0441\u0441\u0430 <a href=\"#printer\" rel=\"noopener noreferrer nofollow\"><em>Printer<\/em><\/a> \u0432\u0435\u0437\u0434\u0435 \u0433\u0434\u0435 \u044d\u0442\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e, \u043d\u043e \u0442\u0430\u043a \u043c\u043d\u0435 \u043c\u043e\u0439 \u043a\u043e\u0434 \u043d\u0440\u0430\u0432\u0438\u0442\u0441\u044f \u0431\u043e\u043b\u044c\u0448\u0435.<\/p>\n<p><code>update()<\/code> \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u0432\u0441\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u0435\u0440\u0435\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438 \u043a\u0430\u0434\u0440\u043e\u0432, \u043e\u043d\u0430 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u0446\u0438\u043a\u043b\u0435 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438 \u0438\u0437 \u043a\u043b\u0430\u0441\u0441\u0430 <a href=\"#game\" rel=\"noopener noreferrer nofollow\"><em>Game<\/em><\/a>.<\/p>\n<pre><code class=\"javascript\">  defaultSet() {     this.ball.x = this.set.ballXDefault     this.ball.y = this.set.ballYDefault     \/\/ \u0421\u0442\u0430\u0432\u0438\u0442 \u043c\u044f\u0447\u0438\u043a \u043d\u0430 \u0446\u0435\u043d\u0442\u0440 \u043f\u043e\u043b\u044f \u043e\u0431\u043d\u0443\u043b\u044f\u044f \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b     this.ball.speed = this.set.ballSpeed     \/\/ \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0438\u0441\u0445\u043e\u0434\u043d\u0443\u044e \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c   }      draw() {   \/\/ \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0437\u0430\u043f\u0440\u043e\u0441 \u043d\u0430 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0443 \u043c\u044f\u0447\u0438\u043a\u0430.   \/\/ \u0421\u043e\u0437\u0434\u0430\u043d\u0430 \u0434\u043b\u044f \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430     this.print.drawBall()       }      update() {       \/\/ \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0441\u0442\u043e\u043b\u043a\u043d\u043e\u0432\u0435\u043d\u0438\u0439,   \/\/ \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f \u043c\u044f\u0447\u0438\u043a\u0430 \u0438 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438. \u0421\u043e\u0437\u0434\u0430\u043d\u0430 \u0434\u043b\u044f \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430,   \/\/ \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0438\u0437 \u043c\u0435\u0442\u043e\u0434\u0430 timeLoop() \u0432 \u043a\u043b\u0430\u0441\u0441\u0435 Game   this.checkCollisionWithWalls()   this.move()   this.draw()   } }<\/code><\/pre>\n<p><a href=\"#begin\" rel=\"noopener noreferrer nofollow\">\u041d\u0430\u0432\u0435\u0440\u0445<\/a><\/p>\n<hr\/>\n<p><a class=\"anchor\" name=\"player\" id=\"player\"><\/a><\/p>\n<h2>player.js<\/h2>\n<p>\u041c\u043e\u0434\u0443\u043b\u044c \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0443 \u0438\u0433\u0440\u043e\u043a\u0430, \u0435\u0435 \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0438 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0441 \u043c\u044f\u0447\u0438\u043a\u043e\u043c. \u041a\u043b\u0430\u0441\u0441\u0430 <em>Player<\/em> \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u0434\u0432\u0430, \u0438 \u0432 \u043a\u0430\u0436\u0434\u044b\u0439 \u043f\u0435\u0440\u0435\u0434\u0430\u044e\u0442\u0441\u044f \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u0440\u0430\u0437\u043d\u044b\u0445 \u0438\u0433\u0440\u043e\u043a\u043e\u0432, \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f \u0432 \u043a\u043b\u0430\u0441\u0441\u0435 <a href=\"#game%5C\" rel=\"noopener noreferrer nofollow\"><em>Game<\/em><\/a>.<\/p>\n<pre><code class=\"javascript\">export default class Player {   constructor(Game, playerSet) {   \/\/ \u0412 Player \u043c\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u043b\u0438 \u0432\u0435\u0441\u044c \u043a\u043b\u0430\u0441\u0441 Game \u0438 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u0438\u0433\u0440\u043e\u043a\u0430     this.set = Game.set     \/\/ \u041f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 set \u043e\u0431\u0449\u0438\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438              this.ball = Game.set.ball     this.classBall = Game.ball     \/\/ \u0414\u043b\u044f \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430, \u0432\u044b\u0434\u0435\u043b\u0438\u043c \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0443\u044e \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e ball     \/\/ \u0432\u0441\u0435 \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u044b\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043c\u044f\u0447\u0438\u043a\u0430, \u0430 \u0447\u0435\u0440\u0435\u0437 classBall,     \/\/ \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u043a\u043b\u0430\u0441\u0441\u0443 Ball \u0438 \u0435\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430\u043c      this.print = Game.print     \/\/ \u0414\u043b\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u043c\u043e\u0434\u0443\u043b\u044e Printer      this.player = playerSet     \/\/ \u041f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 player \u043f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u0435\u043c \u0441\u0432\u043e\u0439\u0441\u0432\u0430 \u0438\u0433\u0440\u043e\u043a\u0430 \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043d\u044b\u0435     \/\/ \u0432 \u043a\u043b\u0430\u0441\u0441 Player, \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0435 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u0430 Player       this.keyMap = new Map(playerSet.keys)     \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u043e\u0432\u044b\u0439 Map (\u044d\u0442\u043e \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044f \u043a\u043b\u044e\u0447\/\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435) \u0438\u0437 keys.     \/\/ \u0412 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435\u043c \u043a\u043b\u044e\u0447 - \u044d\u0442\u043e \u043d\u043e\u043c\u0435\u0440 \u043a\u043b\u0430\u0432\u0438\u0448\u0438,      \/\/ \u0430 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 - \u044d\u0442\u043e \u0441\u0442\u0440\u043e\u043a\u0430 \u0441 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435\u043c \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f     \/\/ \u041f\u0440\u0438\u043c\u0435\u0440 => keys: [[87,'up'], [83,'down']],      document.addEventListener('keydown',                              (e) => this.keyController(e, true))     document.addEventListener('keyup',                              (e) => this.keyController(e, false))     \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0434\u0432\u0430 \u0441\u043b\u0443\u0448\u0430\u0442\u0435\u043b\u044f \u0441\u043e\u0431\u044b\u0442\u0438\u0439. \u0412 \u043d\u0438\u0445 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0441\u043e\u0431\u044b\u0442\u0438\u0435     \/\/ (\u043d\u0430\u0436\u0430\u0442\u0438\u0435 \u0438\u043b\u0438 \u043e\u0442\u0436\u0430\u0442\u0438\u0435 \u043a\u043b\u0430\u0432\u0438\u0448\u0438) \u0438 \u0441\u043b\u0443\u0448\u0430\u0442\u0435\u043b\u044f      this.shadowUp = 0     this.shadowDown = 0     \/\/ \u0414\u0432\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0443\u0436\u043d\u044b \u0434\u043b\u044f \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0433\u043e     \/\/ \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f, \u0447\u0442\u043e\u0431 \u0431\u044b\u043b \u0448\u0430\u043d\u0441     \/\/ \u043e\u0442\u0431\u0438\u0442\u044c \u043c\u044f\u0447 \"\u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u043c\u043e\u043c\u0435\u043d\u0442\" \u2570(*\u00b0\u25bd\u00b0*)\u256f     \/\/ \u0442\u043e \u043a\u0430\u043a \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u043f\u043e\u043a\u0430\u0436\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u044f support()      this.yellowZone = true     \/\/ \u041f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f \u0441\u043b\u0443\u0436\u0438\u0442 \u0438\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440\u043e\u043c \u043d\u0430\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u044f \u043c\u044f\u0447\u0430 \u0432 \u0436\u0435\u043b\u0442\u043e\u0439 \u0437\u043e\u043d\u0435.     \/\/ \u042d\u0442\u043e \u0437\u043e\u043d\u0430 \u043f\u0435\u0440\u0435\u0434 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u043e\u0439.     \/\/ \u0416\u0435\u043b\u0442\u0443\u044e \u0437\u043e\u043d\u0443 \u0442\u0430\u043a\u0436\u0435 \u043f\u043e\u043a\u0430\u0436\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u044f support()          this.ballReversStatus = true     \/\/ \u041f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f \u0441\u043b\u0443\u0436\u0438\u0442 \u0434\u043b\u044f \u0437\u0430\u043f\u0440\u0435\u0442\u0430 \u0440\u0430\u0437\u0432\u043e\u0440\u043e\u0442\u0430 \u043c\u044f\u0447\u0438\u043a\u0430, \u0447\u0442\u043e\u0431 \u043e\u043d     \/\/ \u043d\u0435 \u043c\u043e\u0433 \u043c\u0435\u043d\u044f\u0442\u044c \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0447\u0430\u0449\u0435 \u0447\u0435\u043c \u043a\u0430\u0436\u0434\u044b\u0435 \u043f\u043e\u043b\u0441\u0435\u043a\u0443\u043d\u0434\u044b     \/\/ \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 checkCollisionWithBall()   }<\/code><\/pre>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u0438 \u043d\u0438\u0436\u0435 \u0437\u0430\u043d\u0438\u043c\u0430\u044e\u0442\u0441\u044f \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u0435\u043c \u0438\u0433\u0440\u043e\u043a\u043e\u0432. <code>keyController()<\/code> \u043e\u0442\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u043d\u0430\u0436\u0430\u0442\u0438\u044f \u0441 \u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u044b, \u0430 <code>move()<\/code> \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u043d\u0430\u0436\u0430\u0442\u044b\u0445 \u043a\u043b\u0430\u0432\u0438\u0448.<\/p>\n<p>\u041d\u0443\u0436\u043d\u043e \u043f\u043e\u043c\u043d\u0438\u0442\u044c, \u0447\u0442\u043e \u043e\u0441\u044c \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442 \u0432 JavaScript \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0441 \u0432\u0435\u0440\u0445\u043d\u0435\u0433\u043e \u043b\u0435\u0432\u043e\u0433\u043e \u0443\u0433\u043b\u0430, \u043a\u0430\u043a \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u043e \u043d\u0430 \u0440\u0438\u0441\u0443\u043d\u043a\u0435 \u043d\u0438\u0436\u0435. \u0421\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0432\u0435\u0440\u0445\u043d\u044f\u044f \u0438 \u043b\u0435\u0432\u0430\u044f \u0441\u0442\u0435\u043d\u043a\u0438 \u0431\u0443\u0434\u0443\u0442 \u0438\u043c\u0435\u0442\u044c \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b 0, \u0430 \u043f\u0440\u0430\u0432\u0430\u044f \u0438 \u043d\u0438\u0436\u043d\u044f\u044f \u0440\u0430\u0432\u043d\u044b \u0434\u043b\u0438\u043d\u0435 \u0438 \u0448\u0438\u0440\u0438\u043d\u0435 \u043f\u043e\u043b\u044f.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/3cb\/ab8\/32d\/3cbab832d977de2c1895669112374ee8.png\" width=\"1320\" height=\"526\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/3cb\/ab8\/32d\/3cbab832d977de2c1895669112374ee8.png\"\/><figcaption><\/figcaption><\/figure>\n<pre><code class=\"javascript\">  keyController(e, state) {     if(this.keyMap.has(e.keyCode)) {     \/\/ \u041c\u0435\u0442\u043e\u0434 has() \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043b\u0438 \u044d\u043b\u0435\u043c\u0435\u043d\u0442     \/\/ \u0441 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c \u0432 \u043e\u0431\u044a\u0435\u043a\u0442\u0435     \/\/ \u0418 \u0435\u0441\u043b\u0438 \u043d\u0430\u0436\u0430\u0442\u0430 \u043a\u043b\u0430\u0432\u0438\u0448\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0435\u0441\u0442\u044c \u0432 keyMap,     \/\/ \u0442\u043e \u043e\u043d \u0432\u044b\u0434\u0430\u0435\u0442 true       this[this.keyMap.get(e.keyCode)] = state       \/\/ get() \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0439 \u0441 \u043a\u043b\u044e\u0447\u0435\u043c \u044d\u043b\u0435\u043c\u0435\u043d\u0442, \u043e\u043d       \/\/ \u0432\u0435\u0440\u043d\u0435\u0442 'up' \u0438\u043b\u0438 'down' \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u043d\u0430\u0436\u0430\u0442\u043e\u0439 \u043a\u043b\u0430\u0432\u0438\u0448\u0438.       \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u0441 \u0438\u043c\u0435\u043d\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u043c\u0435\u0442\u043e\u0434\u0430 get()       \/\/ \u0438 \u043f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u0435\u043c \u0435\u0439 \u0441\u0442\u0430\u0442\u0443\u0441 true \u0438\u043b\u0438 false     }   }      move() {   \/\/ \u0414\u0432\u0438\u0433\u0430\u0435\u0442 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0443 \u0438\u0433\u0440\u043e\u043a\u0430, \u043f\u0440\u0438\u0431\u0430\u0432\u043b\u044f\u044f 1 \u043a \u0435\u0433\u043e \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430\u043c,   \/\/ \u0443\u043c\u043d\u043e\u0436\u0430\u044f \u043d\u0430 \u043a\u043e\u044d\u0444\u0444\u0435\u0446\u0438\u0435\u043d\u0442 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438     const plHeight = this.set.playerHeight     const plSpeed = this.set.playerSpeed     const plBorder = this.set.playerBorder     const boxHeight = this.set.boxHeight     \/\/ \u041f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0432\u044b\u0448\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u044b \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0438\u044f \u0448\u0438\u0440\u0438\u043d\u044b \u043a\u043e\u0434\u0430,     \/\/ \u0447\u0442\u043e\u0431 \u043e\u043d \u0432\u043b\u0435\u0437 \u0432 \u0441\u0442\u0430\u0442\u044c\u044e \u0431\u0435\u0437 \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u043e\u0439 \u043f\u0440\u043e\u043a\u0440\u0443\u0442\u043a\u0438\u00af\\_(\u30c4)_\/\u00af         if (this.up) {     \/\/ \u0415\u0441\u043b\u0438 this.up = true, \u0442.\u0435. \u043a\u043b\u0430\u0432\u0438\u0448\u0430 '\u0432\u0432\u0435\u0440\u0445' \u043d\u0430\u0436\u0430\u0442\u0430, \u0442\u043e       if (this.player.y > plBorder) {       \/\/ \u0411\u043e\u0440\u0434\u0435\u0440 \u044d\u0442\u043e \u0440\u0430\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043e\u0442 \u0437\u0430\u0434\u043d\u0435\u0439 \u0441\u0442\u0435\u043d\u044b, \u0434\u043e \u0446\u0435\u043d\u0442\u0440\u0430 \u0438\u0433\u0440\u043e\u043a\u0430.       \/\/ \u041d\u0430 \u0442\u0430\u043a\u043e\u0435 \u0436\u0435 \u0440\u0430\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b '\u043d\u0435\u0434\u043e\u0435\u0437\u0436\u0430\u044e\u0442' \u0434\u043e \u043a\u0440\u0430\u0435\u0432 \u043f\u043e\u043b\u044f.       \/\/ \u0415\u0441\u043b\u0438 \u0440\u0430\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043e\u0442 Y \u0438\u0433\u0440\u043e\u043a\u0430 (\u044d\u0442\u043e \u0432\u0435\u0440\u0445\u043d\u0438\u0439 \u043a\u0440\u0430\u0439 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b)       \/\/ \u0431\u043e\u043b\u044c\u0448\u0435 \u0447\u0435\u043c \u0431\u043e\u0440\u0434\u0435\u0440, \u0442\u043e         this.player.y -= plSpeed         \/\/ \u041c\u044b \u0443\u043c\u0435\u043d\u044c\u0448\u0430\u0435\u043c \u0442\u0435\u043a\u0443\u0449\u0443\u044e \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0443 Y \u043d\u0430 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c          \/\/ \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b \u0438\u0433\u0440\u043e\u043a\u0430 \u0438\u0437 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a (\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u044d\u0442\u043e 10).         \/\/ \u0422.\u0435. \u0434\u0432\u0438\u0433\u0430\u0435\u043c \u0438\u0433\u0440\u043e\u043a\u0430 \u0432\u0432\u0435\u0440\u0445 \u043d\u0430 10 \u043f\u0438\u043a\u0441\u0435\u043b\u0435\u0439       } else {       \/\/ \u0415\u0441\u043b\u0438 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0430 \u0434\u043e\u0441\u0442\u0438\u0433\u043b\u0430 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f \u0438\u043b\u0438 \u043f\u0435\u0440\u0435\u0441\u043a\u043e\u0447\u0438\u043b\u0430 \u0435\u0433\u043e       \/\/ (\u044d\u0442\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0442.\u043a. \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b \u0434\u0432\u0438\u0436\u0443\u0442\u044c\u0441\u044f \u043f\u043e 8 \u043f\u0438\u043a\u0441\u0435\u043b\u0435\u0439), \u0442\u043e         this.player.y = plBorder         \/\/ \u041c\u044b \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0443 \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0435 \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435,         \/\/ \u043d\u0430 \u0440\u0430\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0431\u043e\u0440\u0434\u0435\u0440\u0430 \u043e\u0442 \u043a\u0440\u0430\u044f \u043f\u043e\u043b\u044f        }       this.shadowUp = (plSpeed * 2)       \/\/ \u0415\u0441\u043b\u0438 this.up = true, \u0442.\u0435. \u043a\u043b\u0430\u0432\u0438\u0448\u0430 '\u0432\u0432\u0435\u0440\u0445' \u043d\u0430\u0436\u0430\u0442\u0430, \u0442\u043e       \/\/ \u043f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u0435\u043c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 shadowUp \u0434\u0432\u043e\u0439\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438       \/\/ \u044d\u0442\u043e 16 \u043f\u0438\u043a\u0441\u0435\u043b\u0435\u0439     }     else if (this.down) {     \/\/ \u0415\u0441\u043b\u0438 this.down = true, \u0442.\u0435. \u043a\u043b\u0430\u0432\u0438\u0448\u0430 '\u0432\u043d\u0438\u0437' \u043d\u0430\u0436\u0430\u0442\u0430, \u0442\u043e       if ((this.player.y + plHeight + plBorder) &lt; boxHeight) {       \/\/ \u0422.\u043a. \u0438\u0433\u0440\u043e\u043a \u044d\u0442\u043e \u0432\u0435\u0440\u0445\u043d\u044f\u044f \u0442\u043e\u0447\u043a\u0430 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b, \u043d\u0430\u0434\u043e \u043f\u0440\u0438\u0431\u0430\u0432\u0438\u0442\u044c       \/\/ \u0434\u043b\u0438\u043d\u0443 \u0438\u0433\u0440\u043e\u043a\u0430, \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u043d\u0438\u0436\u043d\u0435\u0439 \u0435\u0433\u043e \u0442\u043e\u0447\u043a\u0438         this.player.y += plSpeed         \/\/ \u041c\u044b \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u043c \u0442\u0435\u043a\u0443\u0449\u0443\u044e \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0443 Y \u043d\u0430 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c          \/\/ \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b \u0438\u0433\u0440\u043e\u043a\u0430 \u0438\u0437 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a (\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u044d\u0442\u043e 10).         \/\/ \u0422.\u0435. \u0434\u0432\u0438\u0433\u0430\u0435\u043c \u0438\u0433\u0440\u043e\u043a\u0430 \u0432\u043d\u0438\u0437 \u043d\u0430 10 \u043f\u0438\u043a\u0441\u0435\u043b\u0435\u0439       } else {         this.player.y = (boxHeight - plHeight - plBorder)         \/\/ \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0443 \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0435 \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435,         \/\/ \u043d\u0430 \u0440\u0430\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0431\u043e\u0440\u0434\u0435\u0440\u0430 \u043e\u0442 \u043d\u0438\u0436\u043d\u0435\u0433\u043e \u043a\u0440\u0430\u044f \u043f\u043e\u043b\u044f       }       this.shadowDown = (plSpeed * 2)       \/\/ \u0415\u0441\u043b\u0438 this.down = true, \u0442.\u0435. \u043a\u043b\u0430\u0432\u0438\u0448\u0430 '\u0432\u043d\u0438\u0437' \u043d\u0430\u0436\u0430\u0442\u0430, \u0442\u043e       \/\/ \u043f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u0435\u043c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 shadowDown \u0434\u0432\u043e\u0439\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438       \/\/ \u044d\u0442\u043e 16 \u043f\u0438\u043a\u0441\u0435\u043b\u0435\u0439     } else {       this.shadowUp = 0       this.shadowDown = 0       \/\/ \u0415\u0441\u043b\u0438 \u043a\u043b\u0430\u0432\u0438\u0448\u0438 \u043d\u0435 \u043d\u0430\u0436\u0430\u0442\u044b, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u043d\u0430\u0448\u0443 \"\u0442\u0435\u043d\u044c\" \u0432 \u043d\u043e\u043b\u044c     }   }<\/code><\/pre>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/eea\/826\/fca\/eea826fca718a88df182f0fbf5413169.png\" width=\"1320\" height=\"526\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/eea\/826\/fca\/eea826fca718a88df182f0fbf5413169.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>checkYellowZone()<\/code> \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043b\u0438 \u043c\u044f\u0447\u0438\u043a \u0432 \u0436\u0435\u043b\u0442\u043e\u0439 \u0437\u043e\u043d\u0435 \u043f\u0435\u0440\u0435\u0434 \u0438\u0433\u0440\u043e\u043a\u043e\u043c \u0438 \u043f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u0435\u0442 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 <code>yellowZone<\/code> \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f <code>true<\/code> \u0438\u043b\u0438 <code>false<\/code> \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438. <\/p>\n<p>\u0415\u0441\u043b\u0438 \u043c\u044f\u0447\u0438\u043a \u0431\u044b\u043b \u043e\u0442\u0431\u0438\u0442 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u043e\u0439 \u043d\u0430\u0445\u043e\u0434\u044f\u0441\u044c \u0432 \u0436\u0435\u043b\u0442\u043e\u0439 \u0437\u043e\u043d\u0435, \u0437\u043d\u0430\u0447\u0438\u0442 \u043e\u043d \u0431\u044b\u043b \u043e\u0442\u0431\u0438\u0442 \u043f\u043b\u043e\u0441\u043a\u043e\u0441\u0442\u044c\u044e \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b. \u0410 \u0435\u0441\u043b\u0438 \u043e\u043d \u0437\u0430\u0434\u0435\u043b \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0443, \u043d\u043e \u043d\u0435 \u0431\u044b\u043b \u0432 \u0436\u0435\u043b\u0442\u043e\u0439 \u0437\u043e\u043d\u0435, \u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442 \u044d\u0442\u043e \u0431\u044b\u043b\u043e \u0440\u0435\u0431\u0440\u043e \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b.<\/p>\n<pre><code class=\"javascript\">  checkYellowZone() {      const plHeight = this.set.playerHeight     \/\/ \u0414\u043b\u0438\u043d\u0430 \u0438\u0433\u0440\u043e\u043a\u0430, \u0440\u0430\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043e\u0442 \u0435\u0433\u043e \u0432\u0435\u0440\u0445\u043d\u0435\u0439 \u0434\u043e \u043d\u0438\u0436\u043d\u0435\u0439 \u0442\u043e\u0447\u043a\u0438           if (this.ball.y > (this.player.y - this.shadowUp)     \/\/ \u0415\u0441\u043b\u0438 Y \u043c\u044f\u0447\u0438\u043a\u0430 \u0431\u043e\u043b\u044c\u0448\u0435 (\u043c\u044f\u0447\u0438\u043a \u043d\u0438\u0436\u0435) \u0432\u0435\u0440\u0445\u043d\u0435\u0439 \u0442\u043e\u0447\u043a\u0438 \u0438\u0433\u0440\u043e\u043a\u0430     &amp;&amp; this.ball.y &lt; (this.player.y + plHeight + this.shadowDown)) {     \/\/ \u0438 Y \u043c\u044f\u0447\u0438\u043a\u0430 \u043c\u0435\u043d\u044c\u0448\u0435 (\u043c\u044f\u0447\u0438\u043a \u0432\u044b\u0448\u0435) \u043d\u0438\u0436\u043d\u0435\u0439 \u0442\u043e\u0447\u043a\u0438 \u0438\u0433\u0440\u043e\u043a\u0430       this.yellowZone = true       \/\/ \u0417\u043d\u0430\u0447\u0438\u0442 \u043c\u044f\u0447\u0438\u043a \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0434 \u0438\u0433\u0440\u043e\u043a\u043e\u043c, \u0432 \u0436\u0435\u043b\u0442\u043e\u0439 \u0437\u043e\u043d\u0435     } else {       this.yellowZone = false       \/\/ \u0415\u0441\u043b\u0438 \u043d\u0435 \u0442\u0430\u043a, \u0442\u043e \u043d\u0435 \u0432 \u0436\u0435\u043b\u0442\u043e\u0439 \u00af\\_(\u30c4)_\/\u00af     }   }  <\/code><\/pre>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f <code>checkCollisionWithBall()<\/code> \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u0441\u0442\u043e\u043b\u043a\u043d\u043e\u0432\u0435\u043d\u0438\u0435 \u043c\u044f\u0447\u0430 \u0441 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u043e\u0439. \u041e\u043d\u0430 \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u0442 \u0440\u0430\u0437\u043d\u0438\u0446\u0443 \u043c\u0435\u0436\u0434\u0443 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430\u043c\u0438 <code>x<\/code> \u0438 <code>y<\/code> \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432, \u0430 \u0437\u0430\u0442\u0435\u043c \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u0442 \u0438\u0445 \u0444\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u0435 <code>d<\/code>. \u0418 \u0435\u0441\u043b\u0438 \u0441\u0443\u043c\u043c\u0430 \u0440\u0430\u0434\u0438\u0443\u0441\u043e\u0432 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u043c\u0435\u043d\u044c\u0448\u0435, \u0447\u0435\u043c \u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043c\u0435\u0436\u0434\u0443 \u043d\u0438\u043c\u0438, \u0437\u043d\u0430\u0447\u0438\u0442 \u0438\u043c\u0435\u043b\u043e \u043c\u0435\u0441\u0442\u043e \u0441\u0442\u043e\u043b\u043a\u043d\u043e\u0432\u0435\u043d\u0438\u0435 \u044d\u0442\u0438\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0438 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u044c \u043d\u0443\u0436\u043d\u044b\u0435 \u043d\u0430\u043c \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f, \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>hitBall()<\/code>.<\/p>\n<p>\u0424\u043e\u0440\u043c\u0443\u043b\u0443 \u0440\u0430\u0441\u0447\u0435\u0442\u0430 \u0441\u0442\u043e\u043b\u043a\u043d\u043e\u0432\u0435\u043d\u0438\u0439 \u044f \u0432\u0437\u044f\u043b \u0438\u0437 \u044d\u0442\u043e\u0439 <a href=\"https:\/\/habr.com\/ru\/post\/487962\/?ysclid=l9qra0gr6r515789840\" rel=\"noopener noreferrer nofollow\">\u0441\u0442\u0430\u0442\u044c\u0438<\/a>.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/1b9\/68c\/b4c\/1b968cb4c2ee8d3575b46bea1a13f6e9.png\" width=\"1320\" height=\"606\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/1b9\/68c\/b4c\/1b968cb4c2ee8d3575b46bea1a13f6e9.png\"\/><figcaption><\/figcaption><\/figure>\n<pre><code class=\"javascript\">  checkCollisionWithBall() {     const plHeight = this.set.playerHeight     \/\/ \u0414\u043b\u0438\u043d\u0430 \u0438\u0433\u0440\u043e\u043a\u0430, \u0440\u0430\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043e\u0442 \u0435\u0433\u043e \u0432\u0435\u0440\u0445\u043d\u0435\u0439 \u0434\u043e \u043d\u0438\u0436\u043d\u0435\u0439 \u0442\u043e\u0447\u043a\u0438          let dx = this.ball.x - this.player.x     \/\/ \u0412\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u043c \u0440\u0430\u0437\u043d\u0438\u0446\u0443 \u043c\u0435\u0436\u0434\u0443 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430\u043c\u0438 X \u043c\u044f\u0447\u0438\u043a\u0430 \u0438 Y \u0438\u0433\u0440\u043e\u043a\u0430     let dy = this.ball.y - (this.player.y - this.shadowUp)     \/\/ \u0420\u0430\u0437\u043d\u0438\u0446\u0430 \u043c\u0435\u0436\u0434\u0443 Y \u043c\u044f\u0447\u0438\u043a\u0430 \u0438 Y \u0438\u0433\u0440\u043e\u043a\u0430 (\u0432\u0435\u0440\u0445\u043d\u0438\u043c \u043a\u0440\u0430\u0435\u043c \u0438\u0433\u0440\u043e\u043a\u0430),     \/\/ \u0442\u0430\u043a\u0436\u0435 \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u043c \u0442\u0435\u043d\u044c, \u0435\u0441\u043b\u0438 \u043e\u043d\u0430 \u0435\u0441\u0442\u044c     let dyF =this.ball.y -(this.player.y + plHeight + this.shadowDown)     \/\/ \u0420\u0430\u0437\u043d\u0438\u0446\u0430 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b Y \u043c\u044f\u0447\u0438\u043a\u0430 \u0438 \u043d\u0438\u0436\u043d\u0435\u0433\u043e \u043a\u0440\u0430\u044f \u0438\u0433\u0440\u043e\u043a\u0430,     \/\/ \u0441 \u0443\u0447\u0435\u0442\u043e\u043c \u0435\u0433\u043e \u0442\u0435\u043d\u0438, \u0435\u0441\u043b\u0438 \u043e\u043d\u0430 \u0435\u0441\u0442\u044c     let radSum = this.set.ballRadius + this.set.playerRadius     \/\/ \u0421\u0443\u043c\u043c\u0430 \u0440\u0430\u0434\u0438\u0443\u0441\u043e\u0432 \u043c\u044f\u0447\u0438\u043a\u0430 \u0438 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b          let dY = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2))     \/\/ \u0420\u0430\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043e\u0442 \u0446\u0435\u043d\u0442\u0440\u0430 \u043c\u044f\u0447\u0438\u043a\u0430, \u0434\u043e \u043a\u0440\u0430\u044f \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b.     \/\/ Math.sqrt() \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u0442 \u043a\u0432\u0430\u0434\u0440\u0430\u0442\u043d\u044b\u0439 \u043a\u043e\u0440\u0435\u043d\u044c, \u0430     \/\/ Math.pow() \u0432\u043e\u0437\u0432\u043e\u0434\u0438\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 dx \u0432 \u0441\u0442\u0435\u043f\u0435\u043d\u044c 2 (\u0432 \u043a\u0432\u0430\u0434\u0440\u0430\u0442)     let dYF = Math.sqrt(Math.pow(dx, 2) + Math.pow(dyF, 2))     \/\/ \u0420\u0430\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043e\u0442 \u0446\u0435\u043d\u0442\u0440\u0430 \u043c\u044f\u0447\u0438\u043a\u0430, \u0434\u043e \u043d\u0438\u0436\u043d\u0435\u0433\u043e \u043a\u0440\u0430\u044f \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b.     let dX = Math.sqrt(Math.pow(dx, 2))     \/\/ \u0423\u0431\u0440\u0430\u043b \u0438\u0437 \u0440\u0430\u0441\u0447\u0435\u0442\u0430 \u043a\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0443 Y, \u0447\u0442\u043e\u0431\u044b \u0432\u0438\u0434\u0435\u0442\u044c \u0441\u0442\u043e\u043b\u043a\u043d\u043e\u0432\u0435\u043d\u0438\u0435     \/\/ \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442 \u0425 \u043d\u0435\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e \u043e\u0442 \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043c\u044f\u0447\u0438\u043a\u0430 \u043f\u043e Y.     \/\/ \u042d\u0442\u043e \u043d\u0430\u0434\u043e \u0434\u043b\u044f \u0440\u0430\u0441\u0447\u0435\u0442\u0430 \u0443\u0434\u0430\u0440\u0430 \u043e \u043f\u043b\u043e\u0441\u043a\u043e\u0441\u0442\u044c \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b          if (dX &lt;= radSum) {     \/\/ \u0415\u0441\u043b\u0438 \u0440\u0430\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043c\u0435\u0436\u0434\u0443 \u0446\u0435\u043d\u0442\u0440\u0430\u043c\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u043c\u0435\u043d\u044c\u0448\u0435 \u0441\u0443\u043c\u043c\u044b \u0438\u0445     \/\/ \u0440\u0430\u0434\u0438\u0443\u0441\u043e\u0432 (\u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u044d\u0442\u043e \u0425 \u043c\u044f\u0447\u0438\u043a\u0430 \u0438 \u0425 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b), \u0442\u043e       if (this.yellowZone &amp;&amp; this.ballReversStatus) {       \/\/ \u0415\u0441\u043b\u0438 \u043c\u044f\u0447\u0438\u043a \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0436\u0435\u043b\u0442\u043e\u0439 \u0437\u043e\u043d\u0435       \/\/ \u0438 \u043e\u043d \u043d\u0435 \u043c\u0435\u043d\u044f\u043b \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0435 \u043f\u043e\u043b\u0441\u0435\u043a\u0443\u043d\u0434\u044b, \u0442\u043e         this.hitBall(this.ball.dx)         \/\/ \u0412\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e hitBall() \u0434\u043b\u044f \u0440\u0430\u0437\u0432\u043e\u0440\u043e\u0442\u0430 \u043c\u044f\u0447\u0430         \/\/ \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0432 \u043d\u0435\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 dx, \u0442.\u043a \u0432 \u0436\u0435\u043b\u043e\u0439 \u0437\u043e\u043d\u0435         \/\/ \u043c\u044f\u0447\u0438\u043a \u043e\u0442\u0431\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043e\u0442 \u043f\u043b\u043e\u0441\u043a\u043e\u0441\u0442\u0438 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e \u043e\u0441\u0438 \u0425       }     }     if (this.ball.dy > 0) {     \/\/ \u0415\u0441\u043b\u0438 \u0443\u0441\u043a\u043e\u0440\u0435\u043d\u0438\u0435 \u043c\u044f\u0447\u0438\u043a\u0430 \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435, \u0442.\u0435. \u043c\u044f\u0447\u0438\u043a \u043b\u0435\u0442\u0438\u0442 \u0432\u043d\u0438\u0437, \u0442\u043e       if (dY &lt;= radSum) {       \/\/ \u0415\u0441\u043b\u0438 \u0435\u0441\u0442\u044c \u0441\u0442\u043e\u043b\u043a\u043d\u043e\u0432\u0435\u043d\u0438\u0435 \u0441 \u0432\u0435\u0440\u0445\u043d\u0438\u043c \u043a\u0440\u0430\u0435\u043c \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b, \u0442\u043e         if (!this.yellowZone) {         \/\/ \u0415\u0441\u043b\u0438 \u043c\u044f\u0447\u0438\u043a \u043d\u0435 \u0432 \u0436\u0435\u043b\u0442\u043e\u0439 \u0437\u043e\u043d\u0435, \u0442\u043e           this.hitBall(this.ball.dx, this.ball.dy)           \/\/ \u0412\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e hitBall() \u0434\u043b\u044f \u0440\u0430\u0437\u0432\u043e\u0440\u043e\u0442\u0430 \u043c\u044f\u0447\u0430 \u043f\u043e \u043e\u0431\u043e\u0438           \/\/ \u043e\u0441\u044f\u043c, \u043c\u044f\u0447\u0438\u043a \u0440\u0430\u0437\u0432\u0435\u0440\u043d\u0443\u0442\u0441\u044f \u043d\u0430 180\u00b0         }       }     }     if (this.ball.dy &lt; 0) {     \/\/ \u0415\u0441\u043b\u0438 \u0443\u0441\u043a\u043e\u0440\u0435\u043d\u0438\u0435 \u043c\u044f\u0447\u0438\u043a\u0430 \u043e\u0442\u0440\u0438\u0446\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0435, \u0442.\u0435. \u043c\u044f\u0447\u0438\u043a \u043b\u0435\u0442\u0438\u0442 \u0432\u0432\u0435\u0440\u0445, \u0442\u043e       if (dYF &lt;= radSum) {       \/\/ \u0415\u0441\u043b\u0438 \u0435\u0441\u0442\u044c \u0441\u0442\u043e\u043b\u043a\u043d\u043e\u0432\u0435\u043d\u0438\u0435 \u0441 \u043d\u0438\u0436\u043d\u0438\u043c \u043a\u0440\u0430\u0435\u043c \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b, \u0442\u043e         if (!this.yellowZone) {         \/\/ \u0415\u0441\u043b\u0438 \u043c\u044f\u0447\u0438\u043a \u043d\u0435 \u0432 \u0436\u0435\u043b\u0442\u043e\u0439 \u0437\u043e\u043d\u0435, \u0442\u043e           this.hitBall(this.ball.dx, this.ball.dy)           \/\/ \u0412\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e hitBall() \u0434\u043b\u044f \u0440\u0430\u0437\u0432\u043e\u0440\u043e\u0442\u0430 \u043c\u044f\u0447\u0430 \u043f\u043e \u043e\u0431\u043e\u0438           \/\/ \u043e\u0441\u044f\u043c, \u043c\u044f\u0447\u0438\u043a \u0442\u0430\u043a\u0436\u0435 \u0440\u0430\u0437\u0432\u0435\u0440\u043d\u0443\u0442\u0441\u044f \u043d\u0430 180\u00b0         }       }     }   }      hitBall(dx, dy) {   \/\/ \u0410\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u043c \u043c\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0442\u043e\u043b\u044c\u043a\u043e dx \u0438\u043b\u0438 dx \u0438 dy \u043c\u044f\u0447\u0438\u043a\u0430     this.ball.dx = this.classBall.reverseBall(dx)     \/\/ \u0420\u0430\u0437\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u043c \u043c\u044f\u0447\u0438\u043a \u043f\u043e \u043e\u0441\u0438 \u0425 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u0435\u0442\u043e\u0434\u0430 reverseBall().     \/\/ \u041e\u043d \u0432\u0441\u0435\u0433\u0434\u0430 \u0440\u0430\u0437\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u043e \u043e\u0441\u0438 \u0425 \u043f\u0440\u0438 \u0443\u0434\u0430\u0440\u0435 \u043e \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0443     if (dy) {     \/\/ \u0415\u0441\u043b\u0438 \u043c\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u043b\u0438 \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 dy, \u0442\u043e       this.ball.dy = this.classBall.reverseBall(dy)       \/\/ \u0420\u0430\u0437\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u043c \u043c\u044f\u0447\u0438\u043a \u043f\u043e \u043e\u0441\u0438 Y. \u042d\u0442\u043e \u0443\u0434\u0430\u0440 \u043e \u0440\u0435\u0431\u0440\u043e \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b     }     this.classBall.speed\u041cagnifier()     \/\/ \u0422.\u043a. \u043c\u044f\u0447\u0438\u043a \u043e\u0442\u0431\u0438\u0442 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u043e\u0439, \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e,     \/\/ \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0442 \u0435\u0433\u043e \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c     this.ballReversStatus = false     \/\/ \u0417\u0430\u043f\u0440\u0435\u0449\u0430\u0435\u043c \u043c\u044f\u0447\u0438\u043a\u0443 \u0440\u0430\u0437\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0442\u044c\u0441\u044f     setTimeout(() => {       this.ballReversStatus = true     }, '500')     \/\/ \u0410 \u0447\u0435\u0440\u0435\u0437 500 \u043c\u0438\u043b\u0438\u0441\u0435\u043a\u0443\u043d\u0434 \u0440\u0430\u0437\u0440\u0435\u0448\u0430\u0435\u043c \u043c\u044f\u0447\u0438\u043a\u0443 \u0440\u0430\u0437\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0442\u044c\u0441\u044f.     \/\/ \u0422\u0430\u043a\u043e\u0435 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u043d\u0443\u0436\u043d\u043e, \u0447\u0442\u043e\u0431 \u043e\u043d \u043d\u0435 \u043c\u043e\u0433 \u0437\u0430\u0441\u0442\u0440\u044f\u0442\u044c \u0432 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435     \/\/ \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u0440\u0430\u0437\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u044f\u0441\u044c   }<\/code><\/pre>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0438\u0434\u0443\u0442 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438. <\/p>\n<p><code>defaultSet()<\/code> \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0438\u0433\u0440\u043e\u043a\u0430 \u043a \u0434\u0435\u0444\u043e\u043b\u0442\u043d\u043e\u043c\u0443 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044e, \u044d\u0442\u043e \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043f\u0430\u0440\u0442\u0438\u0438 \u043f\u0440\u0438 \u0437\u0430\u0431\u0438\u0442\u0438\u0438 \u0433\u043e\u043b\u0430.<\/p>\n<p><code>draw()<\/code> \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0440\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u044f \u0438\u0433\u0440\u043e\u043a\u0430. \u041c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043e\u0431\u043e\u0439\u0442\u0438\u0441\u044c \u0431\u0435\u0437 \u043d\u0435\u0435, \u0432\u044b\u0437\u044b\u0432\u0430\u044f \u0440\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u0435 \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e \u0438\u0437 \u043a\u043b\u0430\u0441\u0441\u0430 <a href=\"#printer\" rel=\"noopener noreferrer nofollow\"><em>Printer<\/em><\/a> \u0432\u0435\u0437\u0434\u0435 \u0433\u0434\u0435 \u044d\u0442\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e, \u043d\u043e \u0442\u0430\u043a \u043c\u043d\u0435 \u043c\u043e\u0439 \u043a\u043e\u0434 \u043d\u0440\u0430\u0432\u0438\u0442\u0441\u044f \u0431\u043e\u043b\u044c\u0448\u0435.<\/p>\n<p><code>update()<\/code> \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u0432\u0441\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u0435\u0440\u0435\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438 \u043a\u0430\u0434\u0440\u043e\u0432, \u043e\u043d\u0430 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u0446\u0438\u043a\u043b\u0435 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438 \u0438\u0437 \u043a\u043b\u0430\u0441\u0441\u0430 <a href=\"#game\" rel=\"noopener noreferrer nofollow\"><em>Game<\/em><\/a>.<\/p>\n<pre><code class=\"javascript\">  defaultSet() {   \/\/ \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u043e\u0431\u043d\u0443\u043b\u044f\u0435\u0442 \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0438\u0433\u0440\u043e\u043a\u0430,   \/\/ \u0442\u0430\u043a \u043a\u0430\u043a X \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0438\u0433\u0440\u044b \u043d\u0435 \u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f, \u0430 \u0432\u0442\u043e\u0440\u0430\u044f \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430 Y   \/\/ \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u0442\u0441\u044f \u0438\u0437 \u043f\u0435\u0440\u0432\u043e\u0439, \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043e\u0431\u043d\u0443\u043b\u0438\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e Y     this.player.y = this.set.playerYDefault   }      draw() {     let x = this.player.x     let yStart = this.player.y     \/\/ \u041a\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430 \u0432\u0435\u0440\u0445\u043d\u0435\u0439 \u0442\u043e\u0447\u043a\u0438 \u0438\u0433\u0440\u043e\u043a\u0430     let yFinish = (this.player.y + this.set.playerHeight)     \/\/ \u041a\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430 \u043d\u0438\u0436\u043d\u0435\u0439 \u0442\u043e\u0447\u043a\u0438 \u0438\u0433\u0440\u043e\u043a\u0430     const plColor = this.player.color     const plWidth = (this.set.playerRadius * 2)          this.print.drawPlayer(x, yStart, yFinish, plWidth, plColor)     \/\/ \u0422.\u043a. \u0438\u0433\u0440\u043e\u043a \u044d\u0442\u043e \u0432\u0435\u043a\u0442\u043e\u0440\u043d\u0430\u044f \u043b\u0438\u043d\u0438\u044f \u0441 \u0437\u0430\u043a\u0440\u0443\u0433\u043b\u0435\u043d\u043d\u044b\u043c\u0438 \u043a\u0440\u0430\u044f\u043c\u0438,     \/\/ \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0432 \u043f\u0440\u0438\u043d\u0442\u0435\u0440 \u043a\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0432\u0435\u0440\u0445\u043d\u0435\u0439 \u0438 \u043d\u0438\u0436\u043d\u0435\u0439 \u0442\u043e\u0447\u043a\u0438,     \/\/ \u0430 \u0442\u0430\u043a\u0436\u0435 \u0442\u043e\u043b\u0449\u0438\u043d\u0443 \u043b\u0438\u043d\u0438\u0438 (2 \u0440\u0430\u0434\u0438\u0443\u0441\u0430) \u0438 \u0446\u0432\u0435\u0442   }      update() {   \/\/ \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0436\u0435\u043b\u0442\u043e\u0439 \u0437\u043e\u043d\u044b, \u0441\u0442\u043e\u043b\u043a\u043d\u043e\u0432\u0435\u043d\u0438\u0439,   \/\/ \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f \u0438\u0433\u0440\u043e\u043a\u0430 \u0438 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438. \u0421\u043e\u0437\u0434\u0430\u043d\u0430 \u0434\u043b\u044f \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430.   \/\/ \u0412\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0438\u0437 \u043c\u0435\u0442\u043e\u0434\u0430 timeLoop() \u0432 \u043a\u043b\u0430\u0441\u0441\u0435 Game     this.checkYellowZone()     this.checkCollisionWithBall()     this.move()     this.draw()   }<\/code><\/pre>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f <code>support()<\/code> \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442\u0441\u044f \u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u043e\u0439 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u043e\u0439 \u0436\u0435\u043b\u0442\u043e\u0439 \u0437\u043e\u043d\u044b \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0435\u0435 \u0440\u0430\u0431\u043e\u0442\u044b. \u0412\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0438\u0437 \u043a\u043b\u0430\u0441\u0441\u0430 <a href=\"#game\" rel=\"noopener noreferrer nofollow\"><em>Game<\/em><\/a>.  <\/p>\n<pre><code class=\"javascript\">  support() {     const plHeight = this.set.playerHeight     let x = this.player.x             let yS = this.player.y - this.shadowUp     let yF = this.player.y + this.set.playerHeight + this.shadowDown          this.print.drawShadowPlayer(x, yS, yF)     \/\/if (this.yellowZone) {       this.print.drawYellowZone(x, yS, yF)     \/\/}   } }<\/code><\/pre>\n<p><a href=\"#begin\" rel=\"noopener noreferrer nofollow\">\u041d\u0430\u0432\u0435\u0440\u0445<\/a><\/p>\n<hr\/>\n<p><a class=\"anchor\" name=\"index\" id=\"index\"><\/a><\/p>\n<h2>index.html<\/h2>\n<p>\u0412 \u0442\u0435\u0433\u0435 <code>&lt;body><\/code> \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u043d <code>id=\"game\"<\/code> \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043a\u0430\u043d\u0432\u0430\u0441\u0430. \u0425\u043e\u0442\u044f \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u043e\u0431\u043e\u0439\u0442\u0438\u0441\u044c \u0431\u0435\u0437 \u043d\u0435\u0433\u043e \u0438 \u043f\u043e\u0441\u044b\u043b\u0430\u0442\u044c <em>canvas<\/em> \u043f\u0440\u044f\u043c\u043e \u043d\u0430 \u0442\u0435\u0433 <code>&lt;body><\/code>. \u0412\u043d\u0443\u0442\u0440\u0438 \u0442\u0435\u0433\u0430 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u043a\u0440\u0438\u043f\u0442.<\/p>\n<pre><code class=\"xml\">&lt;!DOCTYPE html> &lt;html lang=\"en\"> &lt;head>       &lt;meta charset=\"UTF-8\">       &lt;title>Pong by Buninman.ru&lt;\/title>       &lt;meta name=\"description\" content=\"Created by Buninman.ru\">       &lt;meta property=\"og:title\" content=\"The best Pong game\">       &lt;meta property=\"og:image\" content=\"img\/pongOG.png\">       &lt;meta property=\"og:description\" content=\"Created by Buninman.ru\">       &lt;meta http-equiv=\"expires\" content=\"0\">       &lt;link rel=\"stylesheet\" href=\"pong\/style.css\">       &lt;link rel=\"apple-touch-icon\" sizes=\"180x180\" href=\"img\/icon.png\">    &lt;link rel=\"icon\" type=\"image\/png\" sizes=\"32x32\" href=\"img\/fv32.png\">   &lt;link rel=\"icon\" type=\"image\/png\" sizes=\"16x16\" href=\"img\/fv16.png\"> &lt;\/head>  &lt;body id=\"game\">       &lt;script src=\"pong\/game.js\" type=\"module\">&lt;\/script> &lt;\/body>  &lt;\/html><\/code><\/pre>\n<p><a href=\"#begin\" rel=\"noopener noreferrer nofollow\">\u041d\u0430\u0432\u0435\u0440\u0445<\/a><\/p>\n<hr\/>\n<p><a class=\"anchor\" name=\"style\" id=\"style\"><\/a><\/p>\n<h2>style.css<\/h2>\n<p>\u0412 css \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u043d\u0430\u0431\u043e\u0440 \u0441\u0442\u0438\u043b\u0435\u0439. \u041c\u044b \u0434\u0435\u043b\u0430\u0435\u043c \u0432\u0435\u0441\u044c <code>&lt;body><\/code> \u043e\u0434\u043d\u0438\u043c \u0431\u043e\u043b\u044c\u0448\u0438\u043c \u0444\u043b\u0435\u043a\u0441-\u0431\u043e\u043a\u0441\u043e\u043c \u0432\u043e \u0432\u0435\u0441\u044c \u044d\u043a\u0440\u0430\u043d.  <\/p>\n<pre><code class=\"css\">body {   margin: 0px;       height: 100vh;       width: 100vw;       display: flex;       justify-content: center;       align-items: center;       background-color: #232323;     }  #game canvas {     display: block;       position: absolute; }<\/code><\/pre>\n<p><a href=\"#begin\" rel=\"noopener noreferrer nofollow\">\u041d\u0430\u0432\u0435\u0440\u0445<\/a><\/p>\n<h2>\u0421\u043f\u0430\u0441\u0438\u0431\u043e \u0437\u0430 \u0447\u0442\u0435\u043d\u0438\u0435!<\/h2>\n<p>\u0417\u0430\u0445\u043e\u0434\u0438\u0442\u0435 \u043d\u0430 \u043c\u043e\u0439 <a href=\"https:\/\/t.me\/buninman\" rel=\"noopener noreferrer nofollow\">\u0442\u0435\u043b\u0435\u0433\u0440\u0430\u043c \u043a\u0430\u043d\u0430\u043b<\/a><\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"v-portal\" style=\"display:none;\"><\/div>\n<\/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\/post\/697870\/\"> https:\/\/habr.com\/ru\/post\/697870\/<\/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<p>\u041a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u044f \u043d\u0430\u0447\u0430\u043b \u0447\u0442\u043e-\u0442\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u0442\u044c \u0432 JavaScript, \u044f \u043f\u0440\u0438\u043d\u044f\u043b\u0441\u044f \u0438\u0441\u043a\u0430\u0442\u044c \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0435 \u0433\u0430\u0439\u0434\u044b \u0447\u0442\u043e\u0431 \u043f\u043e\u0432\u0442\u043e\u0440\u0438\u0442\u044c \u043a\u0430\u043a\u0443\u044e-\u043d\u0438\u0431\u0443\u0434\u044c \u0438\u0433\u0440\u0443. \u041f\u0435\u0440\u0432\u043e\u0439 \u0442\u0430\u043a\u043e\u0439 \u0438\u0433\u0440\u043e\u0439 \u0441\u0442\u0430\u043b\u0430 <a href=\"https:\/\/buninman.github.io\/Snake\/\" rel=\"noopener noreferrer nofollow\">\u0437\u043c\u0435\u0439\u043a\u0430<\/a>.<\/p>\n<p>\u041d\u0435 \u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u043e\u043d\u0430 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u0432\u0442\u043e\u0440\u0435\u043d\u0438\u0435\u043c \u0447\u0443\u0436\u043e\u0433\u043e \u0433\u0430\u0439\u0434\u0430, \u0438\u0437-\u0437\u0430 \u0442\u043e\u0433\u043e \u044f \u043f\u0440\u043e\u0430\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043b \u0432 \u043d\u0435\u0439 \u043a\u0430\u0436\u0434\u0443\u044e \u0441\u0442\u0440\u043e\u0447\u043a\u0443 \u043a\u043e\u0434\u0430, \u043c\u043d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043f\u043e\u0447\u0435\u0440\u043f\u043d\u0443\u0442\u044c \u043d\u0435\u043c\u0430\u043b\u043e \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0445 \u0437\u043d\u0430\u043d\u0438\u0439 \u0438 \u043d\u0430\u0432\u044b\u043a\u043e\u0432. \u042f \u0442\u0430\u043a\u0436\u0435 \u0441\u043c\u043e\u0433 \u0441\u0430\u043c \u0432\u043d\u0435\u0441\u0442\u0438 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432 \u0435\u0435 \u043a\u043e\u0434.<\/p>\n<h2>\u041f\u043e\u0432\u0442\u043e\u0440\u0438\u043b<\/h2>\n<p>\u041f\u043e\u0441\u043b\u0435, \u043f\u043e\u0434 \u0432\u043f\u0435\u0447\u0430\u0442\u043b\u0435\u043d\u0438\u0435\u043c \u043e\u0442 \u043f\u0440\u043e\u0434\u0435\u043b\u0430\u043d\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u044b \u044f \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043b \u043a \u043f\u043e\u0432\u0442\u043e\u0440\u0435\u043d\u0438\u044e \u0438\u0433\u0440\u044b \u041f\u043e\u043d\u0433. \u041f\u043e\u0432\u0442\u043e\u0440\u0438\u0442\u044c \u0441\u0430\u043c \u0433\u0430\u0439\u0434 \u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c \u0443\u0436\u0435 \u043d\u0435 \u0442\u0440\u0443\u0434\u043d\u043e, \u043d\u043e \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u0430\u043d\u0430\u043b\u0438\u0437\u0430 \u0441\u0442\u0430\u043b\u043e \u044f\u0441\u043d\u043e, \u0447\u0442\u043e \u043a\u043e\u0434 \u043e\u0447\u0435\u043d\u044c \u0441\u043b\u043e\u0436\u043d\u044b\u0439 \u0434\u043b\u044f \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u044f, \u0432\u0441\u0435 \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u043f\u0435\u0440\u0435\u043f\u043b\u0435\u0442\u0435\u043d\u043e \u0438 \u0437\u0430\u043f\u0443\u0442\u0430\u043d\u043e.<\/p>\n<p>\u0415\u0449\u0435 \u043d\u0435\u0434\u0430\u0432\u043d\u043e \u044f \u0431\u044b \u043f\u043e\u0434\u0443\u043c\u0430\u043b, \u0447\u0442\u043e \u044d\u0442\u043e \u044f \u043d\u0435 \u0432\u0441\u0435 \u043f\u043e\u043d\u0438\u043c\u0430\u044e, \u043d\u043e \u0441\u0435\u0439\u0447\u0430\u0441 \u044f \u0443\u0436\u0435 \u0432\u0438\u0434\u0435\u043b \u043a\u0430\u043a \u044d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043b\u0443\u0447\u0448\u0435.<\/p>\n<h2>\u041f\u0435\u0440\u0435\u043e\u0441\u043c\u044b\u0441\u043b\u0438\u043b<\/h2>\n<p>\u042f \u043f\u0438\u0441\u0430\u043b \u044d\u0442\u043e\u0442 \u041f\u043e\u043d\u0433 \u0441 \u043d\u0443\u043b\u044f, \u0432\u0437\u044f\u0432 \u0438\u0437 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0430 \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438 \u043a\u043e\u043d\u0446\u0435\u043f\u0446\u0438\u0438. \u041f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u043f\u043e\u043c\u0435\u043d\u044f\u043b \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443, \u0434\u043e\u0431\u0430\u0432\u0438\u043b \u043c\u043e\u0434\u0443\u043b\u044c \u0441 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u043c\u0438, \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u0432\u044b\u043d\u0435\u0441 \u0432\u0441\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0440\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u044f \u0438 \u043c\u043d\u043e\u0433\u043e\u0435 \u0434\u0440\u0443\u0433\u043e\u0435.<\/p>\n<p>\u0423\u0447\u0438\u0442\u044b\u0432\u0430\u044f \u043c\u043e\u0439 \u0441\u043e\u0432\u0441\u0435\u043c \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0438\u0439 \u043e\u043f\u044b\u0442 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u0447\u0443\u0442\u044c \u043c\u0435\u043d\u044c\u0448\u0435 2 \u043c\u0435\u0441\u044f\u0446\u0435\u0432, \u044f \u043e\u0447\u0435\u043d\u044c \u0433\u043e\u0440\u0436\u0443\u0441\u044c \u043f\u0440\u043e\u0434\u0435\u043b\u0430\u043d\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u043e\u0439.<\/p>\n<h2>\u0420\u0430\u0441\u043f\u0438\u0441\u0430\u043b  <\/h2>\n<p>\u0412 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u043f\u043e\u0441\u0442\u0430\u0440\u0430\u043b\u0441\u044f \u0440\u0430\u0441\u043f\u0438\u0441\u0430\u0442\u044c \u043a\u0430\u0436\u0434\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0438 \u0438\u0437\u043b\u043e\u0436\u0438\u0442\u044c \u0445\u043e\u0434 \u0441\u0432\u043e\u0438\u0445 \u043c\u044b\u0441\u043b\u0435\u0439. \u042d\u0442\u043e \u0437\u0430\u043d\u044f\u043b\u043e \u043f\u0440\u0438\u043b\u0438\u0447\u043d\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438, \u043d\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u043a\u043e\u043c\u0443-\u0442\u043e \u0437\u0430\u0439\u0434\u0435\u0442 \u0442\u0430\u043a\u043e\u0439 \u0433\u0430\u0439\u0434, \u043b\u0438\u0447\u043d\u043e \u043c\u043d\u0435 \u0438\u043d\u043e\u0433\u0434\u0430 \u043c\u043d\u0435 \u043d\u0435 \u0445\u0432\u0430\u0442\u0430\u043b\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0439 \u043b\u043e\u0433\u0438\u043a\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0439, \u043f\u043e\u044f\u0441\u043d\u0435\u043d\u0438\u0439 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u043a\u0443\u0434\u0430 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f \u0438 \u0437\u0430\u0447\u0435\u043c.<\/p>\n<p>\u0411\u0443\u0434\u0443 \u0440\u0430\u0434, \u0435\u0441\u043b\u0438 \u043f\u043e\u0434\u0441\u043a\u0430\u0436\u0438\u0442\u0435 \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0443\u043b\u0443\u0447\u0448\u0438\u0442\u044c \u043a\u043e\u0434 \u0438\u043b\u0438 \u043d\u0430\u0439\u0434\u0435\u0442\u0435 \u0438 \u0443\u043a\u0430\u0436\u0438\u0442\u0435 \u043d\u0430 \u043e\u0448\u0438\u0431\u043a\u0438 \u0432 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f\u0445, \u0434\u0430\u0436\u0435 \u043e\u0440\u0444\u043e\u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0435.<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td>\n<p align=\"center\">\u0413\u0438\u0442\u0445\u0430\u0431 \u0441 \u043c\u043e\u0438\u043c \u041f\u043e\u043d\u0433\u043e\u043c \u0442\u0443\u0442: <a href=\"https:\/\/github.com\/buninman\/pong\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/buninman\/pong<\/a>  <\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u0410 \u0432\u043e\u0442 <a href=\"https:\/\/youtu.be\/tHnPWQKX-wE\" rel=\"noopener noreferrer nofollow\">\u0432\u0438\u0434\u0435\u043e-\u0433\u0430\u0439\u0434<\/a> \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0438\u043d\u0433-\u043f\u043e\u043d\u0433\u0430 \u043e\u0442 \u0430\u0432\u0442\u043e\u0440\u0430, \u0430 \u0432\u043e\u0442 \u0435\u0433\u043e <a href=\"https:\/\/github.com\/EpicLegend\/ping-pong\" rel=\"noopener noreferrer nofollow\">\u043a\u043e\u0434 \u043d\u0430 \u0433\u0438\u0442\u0445\u0430\u0431\u0435<\/a>.<\/p>\n<blockquote>\n<p>\u041a\u0441\u0442\u0430\u0442\u0438, \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u0430\u044f \u0438\u0433\u0440\u0430 1972 \u0433\u043e\u0434\u0430 \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f Pong, \u0430 \u043f\u0438\u043d\u0433-\u043f\u043e\u043d\u0433. \u0425\u043e\u0442\u044f \u0438\u0434\u0435\u0435\u0439-\u043f\u0440\u0430\u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u0438\u0446\u0435\u0439 \u0434\u043b\u044f \u043d\u0435\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0431\u044b\u043b \u043d\u0430\u0441\u0442\u043e\u043b\u044c\u043d\u044b\u0439 \u0442\u0435\u043d\u043d\u0438\u0441.<\/p>\n<p>\u0427\u0442\u043e \u043f\u0440\u0438\u043c\u0435\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u043e, \u041f\u043e\u043d\u0433 \u0431\u044b\u043b\u0430 \u043f\u0435\u0440\u0432\u043e\u0439 \u043a\u043e\u043c\u043c\u0435\u0440\u0447\u0435\u0441\u043a\u0438 \u0443\u0441\u043f\u0435\u0448\u043d\u043e\u0439 \u0432\u0438\u0434\u0435\u043e\u0438\u0433\u0440\u043e\u0439.<\/p>\n<\/blockquote>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td>\n<p align=\"center\"><a href=\"https:\/\/buninman.github.io\/Pong\/\" rel=\"noopener noreferrer nofollow\"> \u0422\u0443\u0442 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0438\u0433\u0440\u0430\u0442\u044c \u0432 \u0433\u043e\u0442\u043e\u0432\u044b\u0439 \u041f\u043e\u043d\u0433<\/a><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<hr\/>\n<p><a class=\"anchor\" name=\"begin\" id=\"begin\"><\/a><\/p>\n<h2>\u041d\u0430\u0447\u0430\u043b\u043e<\/h2>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u041d\u0430\u0431\u0440\u043e\u0441\u0430\u043b \u0441\u0445\u0435\u043c\u0443, \u0447\u0442\u043e\u0431 \u0431\u044b\u043b\u043e \u043f\u043e\u043d\u044f\u0442\u043d\u0435\u0435, \u0447\u0442\u043e \u043a\u0443\u0434\u0430 \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u0442\u0441\u044f. \u041d\u043e \u043d\u0430 \u044d\u0442\u043e\u0442 \u0440\u0430\u0437 \u043c\u044b \u043f\u043e\u0439\u0434\u0435\u043c \u043d\u0435 \u043f\u043e \u043f\u043e\u0440\u044f\u0434\u043a\u0443 \u0441\u0445\u0435\u043c\u044b, \u0430 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043f\u043e-\u0434\u0440\u0443\u0433\u043e\u043c\u0443. \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0442\u0435 \u043c\u043e\u0434\u0443\u043b\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0432\u0435\u0437\u0434\u0435, \u0442\u0430\u043a\u0438\u0435 \u043a\u0430\u043a \u0444\u0430\u0439\u043b \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a \u0438 \u0440\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u0435.<\/p>\n<ol>\n<li>\n<p><a href=\"#setting\" rel=\"noopener noreferrer nofollow\">setting.js<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#canvas\" rel=\"noopener noreferrer nofollow\">canvas.js<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#printer\" rel=\"noopener noreferrer nofollow\">printer.js<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#game\" rel=\"noopener noreferrer nofollow\">game.js<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#ball\" rel=\"noopener noreferrer nofollow\">ball.js<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#player\" rel=\"noopener noreferrer nofollow\">player.js<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#index\" rel=\"noopener noreferrer nofollow\">index.html<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"#style\" rel=\"noopener noreferrer nofollow\">style.css<\/a><\/p>\n<\/li>\n<\/ol>\n<hr\/>\n<p><a class=\"anchor\" name=\"setting\" id=\"setting\"><\/a><\/p>\n<h2>setting.js<\/h2>\n<p>\u041c\u043e\u0434\u0443\u043b\u044c \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a. \u042f \u0441\u043b\u043e\u0436\u0438\u043b \u0441\u044e\u0434\u0430 \u0432\u0441\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0432 \u0438\u0433\u0440\u0435, \u043a\u0440\u043e\u043c\u0435 \u043d\u0430\u0434\u043f\u0438\u0441\u0435\u0439 \u0438 \u0440\u0430\u0437\u043c\u0435\u0440\u043e\u0432 \u0448\u0440\u0438\u0444\u0442\u043e\u0432. \u0414\u043e\u0441\u0442\u0443\u043f \u043a \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u0443 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a \u0435\u0441\u0442\u044c \u0443 \u0432\u0441\u0435\u0445 \u043c\u043e\u0434\u0443\u043b\u0435\u0439 \u0438 \u043e\u043d \u0432\u0441\u0435\u0433\u0434\u0430 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0438\u0441\u0432\u043e\u0435\u043d \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 set.<\/p>\n<pre><code class=\"javascript\">export default class Setting {   constructor() {     this.boxWidth = 800     this.boxHeight = 500     \/\/ \u0412\u044b\u0441\u043e\u0442\u0430 \u0438 \u0448\u0438\u0440\u0438\u043d\u0430 \u0438\u0433\u0440\u043e\u0432\u043e\u0433\u043e \u043f\u043e\u043b\u044f, \u0438 \u0432\u0441\u0435\u0445 \u0441\u043b\u043e\u0435\u0432 \u043a\u0430\u043d\u0432\u0430\u0441\u0430     this.boxRound = 20     \/\/ \u0420\u0430\u0434\u0438\u0443\u0441 \u0437\u0430\u043a\u0440\u0443\u0433\u043b\u0435\u043d\u0438\u044f \u0443\u0433\u043b\u043e\u0432 \u0438\u0433\u0440\u043e\u0432\u043e\u0433\u043e \u043f\u043e\u043b\u044f     this.boxColor = '#333333'     \/\/ \u0421\u0435\u0440\u044b\u0439 \u0446\u0432\u0435\u0442 \u0437\u0430\u043b\u0438\u0432\u043a\u0438 \u0438\u0433\u0440\u043e\u0432\u043e\u0433\u043e \u043f\u043e\u043b\u044f.      this.lineWidth = 6     \/\/ \u0422\u043e\u043b\u0449\u0438\u043d\u0430 \u043b\u0438\u043d\u0438\u0439     this.lineColor = '#232323'     \/\/ \u0426\u0432\u0435\u0442 \u043b\u0438\u043d\u0438\u0439. \u0422\u0435\u043c\u043d\u043e-\u0441\u0435\u0440\u044b\u0439, \u043a\u0430\u043a \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0444\u043e\u043d \u043e\u043a\u043d\u0430 \u0431\u0440\u0443\u0437\u0435\u0440\u0430 \u0432 CSS     this.textColor = '#EBEBEB'     \/\/ \u0421\u0432\u0435\u0442\u043b\u043e-\u0441\u0435\u0440\u044b\u0439 \u0446\u0432\u0435\u0442, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0442\u0435\u043a\u0441\u0442\u0430 \u0442\u0430\u0439\u043c\u0435\u0440\u0430 \u0438 \u0431\u0435\u0433\u0443\u043d\u043a\u0430     this.supportColorRed = '#FA0556'     this.supportColorYellow = '#FAC405'     \/\/ \u0412\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043a\u0440\u0430\u0441\u043d\u044b\u0439 \u0438 \u0436\u0435\u043b\u0442\u044b\u0439 \u0446\u0432\u0435\u0442\u0430,     \/\/ \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0434\u043b\u044f \u043f\u043e\u0434\u0441\u0432\u0435\u0442\u043a\u0438 \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u043d\u044e\u0430\u043d\u0441\u043e\u0432<\/code><\/pre>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0438\u0434\u0443\u0442 \u0432\u0441\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043c\u044f\u0447\u0438\u043a\u0430. \u0412 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 \u0432\u044b\u043d\u0435\u0441\u0435\u043d\u044b \u0442\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0437\u043c\u0435\u043d\u044f\u044e\u0442\u0441\u044f \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0438\u0433\u0440\u044b.  <\/p>\n<pre><code class=\"javascript\">    this.ballSpeed = 7     \/\/ \u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043c\u044f\u0447\u0438\u043a\u0430     this.ballRadius = 8     \/\/ \u0420\u0430\u0434\u0438\u0443\u0441 \u043c\u044f\u0447\u043a\u0430, \u0434\u0438\u0430\u043c\u0435\u0442\u0440 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f 16px     this.ballXDefault = (this.boxWidth \/ 2)     this.ballYDefault = (this.boxHeight \/ 2)     \/\/ \u041a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u043c\u044f\u0447\u0438\u043a\u0430 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e,     \/\/ \u0440\u0430\u0432\u043d\u044b \u043f\u043e\u043b\u043e\u0432\u0438\u043d\u0435 \u0434\u043b\u0438\u043d\u044b \u0438 \u0448\u0438\u0440\u0438\u043d\u044b \u043f\u043e\u043b\u044f, \u044d\u0442\u043e \u0446\u0435\u043d\u0442\u0440     this.ballColor = '#EBEBEB'     \/\/ \u0426\u0432\u0435\u0442 \u043c\u044f\u0447\u0438\u043a\u0430, \u044f \u0441\u0434\u0435\u043b\u0430\u043b \u0442\u0430\u043a\u0438\u043c \u0436\u0435 \u0441\u0432\u0435\u0442\u043b\u043e-\u0441\u0435\u0440\u044b\u043c \u043a\u0430\u043a textColor      this.ballHitScore = 0     \/\/ \u0421\u0447\u0435\u0442\u0447\u0438\u043a \u043e\u0442\u0431\u0438\u0442\u044b\u0445 \u043c\u044f\u0447\u0435\u0439, \u0442\u0430\u043a\u0436\u0435 \u043a \u043d\u0435\u043c\u0443 \u043f\u0440\u0438\u0432\u044f\u0437\u0430\u043d\u043e \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u0438\u0435     \/\/ \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u043c\u044f\u0447\u0438\u043a\u0430. \u0423\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u043c \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043f\u0440\u0438 \u043a\u0430\u0436\u0434\u043e\u043c \u0443\u0434\u0430\u0440\u0435     this.ball = {       x: this.ballXDefault,       y: this.ballYDefault,       \/\/ \u0422\u0435\u043a\u0443\u0449\u0438\u0435 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u043c\u044f\u0447\u0438\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u0435\u043d\u044f\u044e\u0442\u0441\u044f \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435       \/\/ \u0438\u0433\u0440\u044b, \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u043e\u043d\u0438 \u0440\u0430\u0432\u043d\u044b \u0434\u0435\u0444\u043e\u043b\u0442\u043d\u044b\u043c - \u043c\u044f\u0447\u0438\u043a \u0432 \u0446\u0435\u043d\u0442\u0440\u0435 \u043f\u043e\u043b\u044f       dx: 0,       dy: 0,       \/\/ \u0423\u0441\u043a\u043e\u0440\u0435\u043d\u0438\u0435 \u043c\u044f\u0447\u0438\u043a\u0430 \u043f\u043e \u043e\u0441\u044f\u043c. \u0418\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u0440\u0430\u0432\u043d\u043e 0, \u043d\u043e       \/\/ \u043f\u043e\u0437\u0436\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u0440\u0430\u043d\u0434\u043e\u043c\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043e\u0442 0.8 \u0434\u043e 1, \u0441 + \u0438\u043b\u0438 -        speed: this.ballSpeed,       \/\/ \u0415\u0449\u0435 \u043e\u0434\u043d\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438, \u043e\u043d\u043e \u043d\u0443\u0436\u043d\u043e, \u0442.\u043a. \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043c\u044f\u0447\u0430       \/\/ \u043f\u043e\u0441\u0442\u0435\u043f\u0435\u043d\u043e \u0440\u0430\u0441\u0442\u0435\u0442 \u0438 \u043f\u0435\u0440\u0435\u043e\u0434\u0438\u0447\u0435\u0441\u043a\u0438 \u043d\u0430\u0434\u043e \u0435\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c       \/\/ \u043a \u0434\u0435\u0444\u043e\u043b\u0442\u043d\u043e\u043c\u0443 this.ballSpeed     }<\/code><\/pre>\n<p>\u0414\u0430\u043b\u044c\u0448\u0435 \u0438\u0434\u0443\u0442 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043e\u0431\u043e\u0438\u0445 \u0438\u0433\u0440\u043e\u043a\u043e\u0432. \u0412 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0432\u044b\u043d\u0435\u0441\u0435\u043d\u044b \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0435 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0438\u0433\u0440\u043e\u043a\u0430. \u041c\u044b \u0431\u0443\u0434\u0435\u043c \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u044d\u0442\u0438 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u043f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u0430 \u043a\u043b\u0430\u0441\u0441\u0430 <a href=\"#player\" rel=\"noopener noreferrer nofollow\"><em>Player<\/em><\/a>.<\/p>\n<pre><code class=\"javascript\">    this.playerRadius = 7             \/\/ \u0420\u0430\u0434\u0438\u0443\u0441 \u0438\u0433\u0440\u043e\u043a\u0430. \u041f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u0435\u0435 \u0431\u044b\u043b\u043e \u0431\u044b \u043d\u0430\u0437\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u0449\u0438\u043d\u043e\u0439, \u0442.\u043a.     \/\/ \u0438\u0433\u0440\u043e\u043a \u044d\u0442\u043e \u0432\u0435\u043a\u0442\u043e\u0440\u043d\u0430\u044f \u043b\u0438\u043d\u0438\u044f. \u041d\u043e \u0432 \u0440\u0430\u0441\u0447\u0435\u0442\u0430\u0445 \u0441\u0442\u043e\u043b\u043a\u043d\u043e\u0432\u0435\u043d\u0438\u0439,      \/\/ \u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e \u043a\u0440\u0430\u0439\u043d\u0438\u0435 \u0442\u043e\u0447\u043a\u0438 \u043a\u0430\u043a \u043e\u043a\u0440\u0443\u0436\u043d\u043e\u0441\u0442\u0438, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u044d\u0442\u043e \u0440\u0430\u0434\u0438\u0443\u0441.     \/\/ \u0420\u0435\u0430\u043b\u044c\u043d\u0430\u044f \u0442\u043e\u043b\u0449\u0438\u043d\u0430 \u0438\u0433\u0440\u043e\u043a\u0430 - \u044d\u0442\u043e \u0434\u0432\u0430 \u0435\u0433\u043e \u0440\u0430\u0434\u0438\u0443\u0441\u0430, 14px.     this.playerHeight = 80     \/\/ \u0412\u044b\u0441\u043e\u0442\u0430 \u0438\u0433\u0440\u043e\u043a\u0430. \u0420\u0430\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043e\u0442 \u0432\u0435\u0440\u0445\u043d\u0435\u0439 \u0434\u043e \u043d\u0438\u0436\u043d\u0435\u0439 \u0442\u043e\u0447\u043a\u0438 \u0438\u0433\u0440\u043e\u043a\u0430.     \/\/ \u041d\u043e \u0442.\u043a. \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b \u0438\u0433\u0440\u043e\u043a\u043e\u0432 \u0438\u043c\u0435\u044e\u0442 \u0437\u0430\u043a\u0440\u0443\u0433\u043b\u0435\u043d\u0438\u044f, \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0439 \u0440\u0430\u0437\u043c\u0435\u0440     \/\/ \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u0434\u0432\u0430 \u0440\u0430\u0434\u0438\u0443\u0441\u0430 \u0431\u043e\u043b\u044c\u0448\u0435, 94px     this.playerSpeed = 8     \/\/ \u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0438\u0433\u0440\u043e\u043a\u0430. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043a\u0430\u043a \u043a\u043e\u044d\u0444\u0444\u0438\u0446\u0438\u0435\u043d\u0442 \u0434\u043b\u044f \u0443\u0441\u043a\u043e\u0440\u0435\u043d\u0438\u044f     this.playerBorder = this.playerRadius * 3     \/\/ \u041f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e \u043e\u0442 \u043a\u0440\u0430\u0435\u0432 \u0438\u0433\u0440\u043e\u043a\u0430 \u0434\u043e \u0441\u0442\u0435\u043d\u043a\u0438 \u0441\u0432\u0435\u0440\u0445\u0443 \u0438 \u0441\u043d\u0438\u0437\u0443     this.playerSpace = this.playerRadius * 6     \/\/ \u041f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e \u043e\u0442 \u0446\u0435\u043d\u0442\u0440\u0430 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u044b \u0438\u0433\u0440\u043e\u043a\u0430 \u0434\u043e \u0441\u0442\u0435\u043d\u043a\u0438 \u0437\u0430 \u043d\u0438\u043c     this.playerYDefault =                    (this.boxHeight \/ 2) - (this.playerHeight \/ 2)     \/\/ \u0418\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u0430\u044f \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430 \u0438\u0433\u0440\u043e\u043a\u0430 Y \u0440\u0430\u0432\u043d\u0430 \u043f\u043e\u043b\u043e\u0432\u0438\u043d\u0435 \u0432\u044b\u0441\u043e\u0442\u044b     \/\/ \u0438\u0433\u0440\u043e\u0432\u043e\u0433\u043e \u043f\u043e\u043b\u044f \u043c\u0438\u043d\u0443\u0441 \u043f\u043e\u043b\u043e\u0432\u0438\u043d\u0430 \u0432\u044b\u0441\u043e\u0442\u044b \u0438\u0433\u0440\u043e\u043a\u0430, \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c     \/\/ \u0438\u0433\u0440\u043e\u043a \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0433\u0430\u0442\u044c\u0441\u044f \u043f\u043e\u0441\u0435\u0440\u0435\u0434\u0438\u043d\u0435 \u043f\u0440\u0438 \u043b\u044e\u0431\u043e\u0439 \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u0439 \u0434\u043b\u0438\u043d\u0435     this.playerL = {       score: 0,       \/\/ \u0421\u0447\u0435\u0442\u0447\u0438\u043a \u043e\u0447\u043a\u043e\u0432       goalPointX: this.boxWidth - this.playerSpace * 2,       \/\/ \u041a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430 \u0425 \u0434\u043b\u044f \u043f\u043e\u044f\u0432\u043b\u0435\u043d\u0438\u044f \u043d\u0430\u0434\u043f\u0438\u0441\u0435\u0439 \"+1\" \u043d\u0430 \u0438\u0433\u0440\u043e\u0432\u043e\u043c \u043f\u043e\u043b\u0435       \/\/ \u0414\u043b\u044f \u043b\u0435\u0432\u043e\u0433\u043e \u0438\u0433\u0440\u043e\u043a\u0430 \u0440\u0430\u0432\u043d\u0430 \u0448\u0438\u0440\u0438\u043d\u0435 \u043f\u043e\u043b\u044f \u043c\u0438\u043d\u0443\u0441 2 \u0440\u0430\u0441\u0442\u043e\u044f\u043d\u0438\u044f       \/\/ \u0434\u043e \u0438\u0433\u0440\u043e\u043a\u0430       \/\/ \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e \u043e\u043d\u0430 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043d\u0430 \u043f\u043e\u043b\u0435 \u043f\u0440\u043e\u0442\u0438\u0432\u043d\u0438\u043a\u0430, \u0441\u043f\u0440\u0430\u0432\u0430       align: 'right',       \/\/ \u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u0432\u044b\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u043d\u0438\u0435 \u0442\u0435\u043a\u0441\u0442\u0430 \"+1\".       \/\/ \u042f \u0442\u0430\u043a\u0436\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e \u044d\u0442\u043e\u0442 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u0434\u043b\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0441\u0442\u043e\u0440\u043e\u043d\u044b       \/\/ \u0432 \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043f\u043e\u043b\u0435\u0442\u0438\u0442 \u043c\u044f\u0447 \u043f\u043e\u0441\u043b\u0435 \u0437\u0430\u0431\u0438\u0442\u0438\u044f \u0433\u043e\u043b\u0430       x: this.playerSpace,       y: this.playerYDefault,       \/\/ \u041a\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0438\u0433\u0440\u043e\u043a\u0430. X \u0440\u0430\u0432\u0435\u043d \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u043c\u0443 \u0440\u0430\u0441\u0442\u043e\u044f\u043d\u0438\u044e playerSpace,       \/\/ \u0430 Y \u0434\u0435\u0444\u043e\u043b\u0442\u043d\u043e\u043c\u0443 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044e, \u043e\u0431\u0449\u0435\u043c\u0443 \u0434\u043b\u044f \u043e\u0431\u043e\u0438\u0445 \u0438\u0433\u0440\u043e\u043a\u043e\u0432       yDefault: (this.boxHeight \/ 2) - (this.playerHeight \/ 2),       \/\/ \u0417\u0430\u0440\u0435\u0437\u0435\u0440\u0432\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0430\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f \u0441\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c Y \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e       color: '#A55F02',            \/\/ \u0426\u0432\u0435\u0442 \u0438\u0433\u0440\u043e\u043a\u0430. \u041e\u0440\u0430\u043d\u0436\u0435\u0432\u044b\u0439       keys: [[87,'up'], [83,'down']],       \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043c\u0430\u0441\u0441\u0438\u0432 \u0441 \u043f\u0430\u0440\u0430\u043c\u0438 \u043a\u043b\u044e\u0447-\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435.       \/\/ \u041d\u043e\u043c\u0435\u0440 \u043a\u043b\u0430\u0432\u0438\u0448\u0438 \u0438 \u0441\u0442\u0440\u043e\u043a\u0430       \/\/ \u0441 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435\u043c. \u0423\u0437\u043d\u0430\u0442\u044c \u043d\u043e\u043c\u0435\u0440 \u043a\u043b\u0430\u0432\u0438\u0448 \u043c\u043e\u0436\u043d\u043e \u0442\u0443\u0442:       \/\/ https:\/\/puzzleweb.ru\/javascript\/char_codes-key_codes.php      }             this.playerR = {       score: 0,       goalPointX: this.playerSpace * 2,       align: 'left',       x: this.boxWidth - (this.playerSpace),       \/\/ \u041a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430 X \u0434\u043b\u044f \u043f\u0440\u0430\u0432\u043e\u0433\u043e \u0438\u0433\u0440\u043e\u043a\u0430 \u0440\u0430\u0432\u043d\u0430 \u0432\u0441\u0435\u0439 \u0448\u0438\u0440\u0438\u043d\u0435 \u043f\u043e\u043b\u044f,       \/\/ \u043c\u0438\u043d\u0443\u0441 \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u0435 \u0440\u0430\u0441\u0442\u043e\u044f\u043d\u0438\u0435 playerSpace       y: this.playerYDefault,       color: '#38887A',       \/\/ \u0413\u043e\u043b\u0443\u0431\u043e\u0439       keys: [[38,'up'], [40,'down']],     }   } }<\/code><\/pre>\n<p><a href=\"#begin\" rel=\"noopener noreferrer nofollow\">\u041d\u0430\u0432\u0435\u0440\u0445<\/a><\/p>\n<hr\/>\n<p><a class=\"anchor\" name=\"canvas\" id=\"canvas\"><\/a><\/p>\n<h3>canvas.js<\/h3>\n<p>\u041c\u043e\u0434\u0443\u043b\u044c \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u0434\u0440\u0443\u0433\u0438\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u0445, \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0432 \u043d\u0435\u0438\u0437\u043c\u0435\u043d\u043d\u043e\u043c \u0432\u0438\u0434\u0435, \u0442.\u043a. \u043e\u043d \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0440\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043e\u0432 \u043d\u0430 2D-\u043a\u0430\u043d\u0432\u0430\u0441\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432 \u0441\u0432\u043e\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u043c\u043e\u0434\u0443\u043b\u0435\u043c <a href=\"#printer\" rel=\"noopener noreferrer nofollow\"><em>printer.js<\/em><\/a>.<\/p>\n<pre><code class=\"javascript\">export default class Canvas {   constructor(setting) {     this.set = setting     \/\/ \u041f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 set \u043e\u0431\u0449\u0438\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438     this.canvas = document.createElement('canvas')     \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u044d\u043b\u0435\u043c\u0435\u043d\u0442 canvas \u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u0434\u043b\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u043d\u0435\u043c\u0443     this.ctx = this.canvas.getContext('2d')     \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0432 \u043a\u0430\u043d\u0432\u0430\u0441\u0435 2d-\u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442, \u043d\u0443\u0436\u0435\u043d \u0434\u043b\u044f \u0440\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u044f \u0444\u0438\u0433\u0443\u0440     this.canvas.width = this.set.boxWidth     this.canvas.height = this.set.boxHeight     \/\/ \u0417\u0430\u0434\u0430\u0435\u043c \u043a\u0430\u043d\u0432\u0430\u0441\u0443 \u0432\u044b\u0441\u043e\u0442\u0443 \u0438 \u0448\u0438\u0440\u0438\u043d\u0443     document.querySelector('#game').appendChild(this.canvas)     \/\/ \u041d\u0430\u0445\u043e\u0434\u0438\u043c \u0432 html \u0442\u0435\u0433 game (id=\"game\") \u0438 \u043a\u0430\u043a \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0439 \u044d\u043b\u043b\u0435\u043c\u0435\u043d\u0442     \/\/ \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0432 \u043d\u0435\u043c \u043d\u0430\u0448 canvas   }<\/code><\/pre>\n<p>\u0420\u0438\u0441\u043e\u0432\u0430\u043d\u0438\u0435 \u0442\u0435\u043a\u0441\u0442\u0430. \u0412 \u043d\u0435\u0433\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f \u0441\u0430\u043c \u0442\u0435\u043a\u0441\u0442, \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b, \u0440\u0430\u0437\u043c\u0435\u0440 \u0442\u0435\u043a\u0441\u0442\u0430, \u0446\u0432\u0435\u0442, \u0432\u044b\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u043d\u0438\u0435 \u0438 \u0432\u044b\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u043d\u0438\u0435 \u043f\u043e \u0431\u0430\u0437\u043e\u0432\u043e\u0439 \u043b\u0438\u043d\u0438\u0438 (\u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0435 <code>y<\/code>) <\/p>\n<pre><code class=\"javascript\">  drawText(text, x, y, fontSize, color = this.set.textColor,                              align = \"center\", baseline = 'middle') {     this.ctx.fillStyle = color     \/\/ \u0423\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0446\u0432\u0435\u0442 \u0437\u0430\u043b\u0438\u0432\u043a\u0438     this.ctx.font = `bold ${fontSize} 'Fira Mono', monospace`     \/\/ \u0423\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0448\u0440\u0438\u0444\u0442 \u0438 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u044b     this.ctx.textAlign = align     \/\/ \u0423\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0432\u044b\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u043d\u0438\u0435 \u043f\u043e \u043a\u0440\u0430\u044e     this.ctx.textBaseline = baseline     \/\/ \u0423\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0432\u044b\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u043d\u0438\u0435 \u043f\u043e \u0431\u0430\u0437\u043e\u0432\u043e\u0439 \u043b\u0438\u043d\u0438\u0438     this.ctx.fillText(text, x, y)     \/\/ \u041f\u0438\u0448\u0435\u043c \u0442\u0435\u043a\u0441\u0442, \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0442\u0443\u0434\u0430 \u0441\u0442\u0440\u043e\u043a\u0443 \u0441 \u0442\u0435\u043a\u0441\u0442\u043e\u043c     \/\/ \u0438 \u043a\u043a\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0439 \u0442\u043e\u0447\u043a\u0438   }<\/code><\/pre>\n<p>\u0421 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0442\u0440\u0435\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u043d\u0438\u0436\u0435 \u043c\u044b \u0440\u0438\u0441\u0443\u0435\u043c \u0438\u0433\u0440\u043e\u0432\u043e\u0435 \u043f\u043e\u043b\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 \u043f\u0440\u044f\u043c\u043e\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u0430 \u0441 \u0437\u0430\u043a\u0440\u0443\u0433\u043b\u0435\u043d\u043d\u044b\u043c\u0438 \u043a\u0440\u0430\u044f\u043c\u0438, \u043a\u0440\u0443\u0433\u0430 \u043f\u043e\u0441\u0435\u0440\u0435\u0434\u0438\u043d\u0435 \u0438 \u0442\u0440\u0435\u0445 \u043b\u0438\u043d\u0438\u0439.<\/p>\n<p>\u041f\u043e\u043c\u0438\u043c\u043e \u0438\u0433\u0440\u043e\u0432\u043e\u0433\u043e \u043f\u043e\u043b\u044f, \u043b\u0438\u043d\u0438\u0435\u0439 \u043c\u044b \u0440\u0438\u0441\u0443\u0435\u043c \u0438\u0433\u0440\u043e\u043a\u0430, \u0430 \u043a\u0440\u0443\u0433 \u0442\u0430\u043a\u0436\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043c\u044f\u0447\u0438\u043a\u0430.<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<pre><code class=\"javascript\">  drawLine(xS, yS, xF, yF, lineWidth, color) {     this.ctx.lineCap = 'round'     \/\/ \u0423\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c, \u0447\u0442\u043e \u043b\u0438\u043d\u0438\u044f \u0431\u0443\u0434\u0435\u0442 \u0441 \u0437\u0430\u043a\u0440\u0443\u0433\u043b\u0435\u043d\u0438\u044f\u043c\u0438 \u043d\u0430 \u043a\u043e\u043d\u0446\u0430\u0445     this.ctx.beginPath()      \/\/ beginPath() \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u0432\u0435\u043a\u0442\u043e\u0440     this.ctx.moveTo(xS, yS)     \/\/ \u0410\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430\u043c\u0438 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0439 \u0442\u043e\u0447\u043a\u0438 \u043b\u0438\u043d\u0438\u0438     this.ctx.lineTo(xF, yF)     \/\/ \u0410\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430\u043c\u0438  \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u043a\u043e\u043d\u0435\u0447\u043d\u043e\u0439 \u0442\u043e\u0447\u043a\u0438 \u043b\u0438\u043d\u0438\u0438     this.ctx.lineWidth = lineWidth     \/\/ \u0423\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0442\u043e\u043b\u0449\u0438\u043d\u0443 \u043b\u0438\u043d\u0438\u0438, \u0435\u0435 \u043c\u044b \u0442\u0430\u043a\u0436\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u043c     this.ctx.strokeStyle = color     \/\/ \u0423\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u0446\u0432\u0435\u0442 \u043e\u0431\u0432\u043e\u0434\u043a\u0438     this.ctx.stroke()     \/\/ \u0420\u0438\u0441\u0443\u0435\u043c \u043e\u0431\u0432\u043e\u0434\u043a\u0443 (\u043b\u0438\u043d\u0438\u044e)     this.ctx.closePath()     \/\/ \u0417\u0430\u0432\u0435\u0440\u0448\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0432\u0435\u043a\u0442\u043e\u0440\u0430   }      drawRectangleRound(x, y, width, height, radius, color) {     this.ctx.beginPath()     \/\/ beginPath() \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u0432\u0435\u043a\u0442\u043e\u0440     this.ctx.moveTo(x + radius, y)     \/\/ \u0423\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0439 \u0442\u043e\u0447\u043a\u0438 \u043b\u0438\u043d\u0438\u0438   <\/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-340874","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/340874","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=340874"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/340874\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=340874"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=340874"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=340874"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}