{"id":302717,"date":"2020-04-29T09:00:32","date_gmt":"2020-04-29T09:00:32","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=302717"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=302717","title":{"rendered":"\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043f\u0441\u0435\u0432\u0434\u043e\u0442\u0440\u0451\u0445\u043c\u0435\u0440\u043d\u043e\u0439 \u0433\u043e\u043d\u043e\u0447\u043d\u043e\u0439 \u0438\u0433\u0440\u044b"},"content":{"rendered":"\n<div class=\"post__text post__text-html post__text_v1\" id=\"post-content-body\" data-io-article-url=\"https:\/\/habr.com\/ru\/post\/499252\/\">\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/d16\/6e3\/cff\/d166e3cff9c2a3cefeb68f5c1ddc02d1.jpg\"><\/div>\n<p>  \u0412 \u0434\u0435\u0442\u0441\u0442\u0432\u0435 \u044f \u0440\u0435\u0434\u043a\u043e \u0445\u043e\u0434\u0438\u043b \u0432 \u0437\u0430\u043b\u044b \u0430\u0440\u043a\u0430\u0434\u043d\u044b\u0445 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u043e\u0432, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043e\u0441\u043e\u0431\u043e \u0432 \u043d\u0438\u0445 \u043d\u0435 \u043d\u0443\u0436\u0434\u0430\u043b\u0441\u044f, \u0432\u0435\u0434\u044c \u0434\u043e\u043c\u0430 \u0443 \u043c\u0435\u043d\u044f \u0431\u044b\u043b\u0438 \u043f\u043e\u0442\u0440\u044f\u0441\u0430\u044e\u0449\u0438\u0435 \u0438\u0433\u0440\u044b \u0434\u043b\u044f C64\u2026 \u043d\u043e \u0435\u0441\u0442\u044c \u0442\u0440\u0438 \u0430\u0440\u043a\u0430\u0434\u043d\u044b\u0435 \u0438\u0433\u0440\u044b, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0443 \u043c\u0435\u043d\u044f \u0432\u0441\u0435\u0433\u0434\u0430 \u043d\u0430\u0445\u043e\u0434\u0438\u043b\u0438\u0441\u044c \u0434\u0435\u043d\u044c\u0433\u0438 \u2014 Donkey Kong, Dragons Lair \u0438 Outrun\u2026<\/p>\n<p>  \u2026 \u0438 \u044f \u043e\u0447\u0435\u043d\u044c \u043b\u044e\u0431\u0438\u043b Outrun \u2014 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c, \u0445\u043e\u043b\u043c\u044b, \u043f\u0430\u043b\u044c\u043c\u044b \u0438 \u043c\u0443\u0437\u044b\u043a\u0430, \u0434\u0430\u0436\u0435 \u043d\u0430 \u0441\u043b\u0430\u0431\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 \u0434\u043b\u044f C64.<\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/48e\/aee\/56f\/48eaee56f43d8a25e840c6ae13268db4.gif\"><\/div>\n<p>  \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u044f \u0440\u0435\u0448\u0438\u043b \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043e\u043b\u0434\u0441\u043a\u0443\u043b\u044c\u043d\u0443\u044e \u043f\u0441\u0435\u0432\u0434\u043e\u0442\u0440\u0451\u0445\u043c\u0435\u0440\u043d\u0443\u044e \u0433\u043e\u043d\u043e\u0447\u043d\u0443\u044e \u0438\u0433\u0440\u0443 \u0432 \u0441\u0442\u0438\u043b\u0435 Outrun, Pitstop \u0438\u043b\u0438 Pole position. \u042f \u043d\u0435 \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u044e \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u043f\u043e\u043b\u043d\u0443\u044e \u0438 <a href=\"https:\/\/codeincomplete.com\/articles\/defining-finished\" rel=\"nofollow\">\u0437\u0430\u0432\u0435\u0440\u0448\u0451\u043d\u043d\u0443\u044e<\/a> \u0438\u0433\u0440\u0443, \u043d\u043e \u043c\u043d\u0435 \u043a\u0430\u0436\u0435\u0442\u0441\u044f, \u0431\u0443\u0434\u0435\u0442 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e \u0437\u0430\u043d\u043e\u0432\u043e \u0438\u0437\u0443\u0447\u0438\u0442\u044c \u043c\u0435\u0445\u0430\u043d\u0438\u043a\u0438, \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u044d\u0442\u0438 \u0438\u0433\u0440\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u043b\u0438 \u0441\u0432\u043e\u0438 \u0442\u0440\u044e\u043a\u0438. \u041a\u0440\u0438\u0432\u044b\u0435, \u0445\u043e\u043b\u043c\u044b, \u0441\u043f\u0440\u0430\u0439\u0442\u044b \u0438 \u043e\u0449\u0443\u0449\u0435\u043d\u0438\u0435 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438\u2026<\/p>\n<p>  \u0418\u0442\u0430\u043a, \u0432\u043e\u0442 \u043c\u043e\u0439 \u00ab\u043f\u0440\u043e\u0435\u043a\u0442 \u043d\u0430 \u0432\u044b\u0445\u043e\u0434\u043d\u044b\u0435\u00bb, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432 \u0438\u0442\u043e\u0433\u0435 \u0437\u0430\u043d\u044f\u043b \u043f\u044f\u0442\u044c \u0438\u043b\u0438 \u0448\u0435\u0441\u0442\u044c \u043d\u0435\u0434\u0435\u043b\u044c \u043f\u043e \u0432\u044b\u0445\u043e\u0434\u043d\u044b\u043c<\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/7ec\/27b\/d28\/7ec27bd28630dbbaf7b81c87233c28ac.png\"><\/div>\n<p>  <\/p>\n<ul>\n<li><a href=\"https:\/\/codeincomplete.com\/games\/racer\" rel=\"nofollow\">\u0421\u044b\u0433\u0440\u0430\u0442\u044c \u0432 \u0438\u0433\u0440\u0443<\/a><\/li>\n<li>\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c <a href=\"https:\/\/github.com\/jakesgordon\/javascript-racer\/\" rel=\"nofollow\">\u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434<\/a><\/li>\n<\/ul>\n<p>  \u0418\u0433\u0440\u0430\u0431\u0435\u043b\u044c\u043d\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u0435\u0442 \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0434\u0435\u043c\u043e, \u0447\u0435\u043c \u0440\u0435\u0430\u043b\u044c\u043d\u0443\u044e \u0438\u0433\u0440\u0443. \u041d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435, \u0435\u0441\u043b\u0438 \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0443\u044e \u043f\u0441\u0435\u0432\u0434\u043e\u0442\u0440\u0451\u0445\u043c\u0435\u0440\u043d\u0443\u044e \u0433\u043e\u043d\u043a\u0443, \u0442\u043e \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0441\u0430\u043c\u044b\u0439 \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u0430\u044f \u043e\u0441\u043d\u043e\u0432\u0430, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u0441\u0442\u0435\u043f\u0435\u043d\u043d\u043e \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u0438\u0442\u044c \u0432 \u0438\u0433\u0440\u0443.<\/p>\n<p>  \u041e\u043d\u0430 \u043d\u0435 \u043e\u0442\u0448\u043b\u0438\u0444\u043e\u0432\u0430\u043d\u0430, \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0443\u0440\u043e\u0434\u043b\u0438\u0432\u0430, \u043d\u043e \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u0430. \u042f \u043f\u043e\u043a\u0430\u0436\u0443, \u043a\u0430\u043a \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0435\u0451 \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e \u0437\u0430 \u0447\u0435\u0442\u044b\u0440\u0435 \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u0448\u0430\u0433\u0430.<\/p>\n<p>  \u041c\u043e\u0436\u043d\u043e \u0442\u0430\u043a\u0436\u0435 \u043f\u043e\u0438\u0433\u0440\u0430\u0442\u044c<\/p>\n<ul>\n<li>\u0432 <a href=\"https:\/\/codeincomplete.com\/games\/racer\/v1-straight\" rel=\"nofollow\">\u0434\u0435\u043c\u043e \u0441 \u043f\u0440\u044f\u043c\u043e\u0439 \u0434\u043e\u0440\u043e\u0433\u043e\u0439<\/a><\/li>\n<li>\u0432 <a href=\"https:\/\/codeincomplete.com\/games\/racer\/v2-curves\" rel=\"nofollow\">\u0434\u0435\u043c\u043e \u0441 \u043a\u0440\u0438\u0432\u044b\u043c\u0438<\/a><\/li>\n<li>\u0432 <a href=\"https:\/\/codeincomplete.com\/games\/racer\/v3-hills\" rel=\"nofollow\">\u0434\u0435\u043c\u043e \u0441 \u0445\u043e\u043b\u043c\u0430\u043c\u0438<\/a><\/li>\n<li>\u0432 <a href=\"https:\/\/codeincomplete.com\/games\/racer\" rel=\"nofollow\">\u0433\u043e\u0442\u043e\u0432\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e<\/a><\/li>\n<\/ul>\n<p><a name=\"habracut\"><\/a>  <\/p>\n<h2>\u041e \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438<\/h2>\n<p>  \u041f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u044d\u0442\u043e\u0439 \u0438\u0433\u0440\u044b <strong>\u043e\u0447\u0435\u043d\u044c \u0441\u0438\u043b\u044c\u043d\u043e<\/strong> \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u043c\u0430\u0448\u0438\u043d\u044b\/\u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430. \u0412 \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430\u0445 \u043e\u043d\u0430 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0445\u043e\u0440\u043e\u0448\u043e, \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u0432 \u0442\u0435\u0445, \u0433\u0434\u0435 \u0435\u0441\u0442\u044c GPU-\u0443\u0441\u043a\u043e\u0440\u0435\u043d\u0438\u0435 canvas, \u043d\u043e \u043f\u043b\u043e\u0445\u043e\u0439 \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0434\u0440\u0430\u0439\u0432\u0435\u0440 \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u043a \u0437\u0430\u0432\u0438\u0441\u0430\u043d\u0438\u044e. \u0412 \u0438\u0433\u0440\u0435 \u043c\u043e\u0436\u043d\u043e \u043c\u0435\u043d\u044f\u0442\u044c \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 \u0438 \u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438.<\/p>\n<h2>\u041e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435 \u043a\u043e\u0434\u0430<\/h2>\n<p>  \u0422\u0430\u043a \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c, \u0447\u0442\u043e \u043f\u0440\u043e\u0435\u043a\u0442 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d \u043d\u0430 Javascript (\u0438\u0437-\u0437\u0430 \u043f\u0440\u043e\u0441\u0442\u043e\u0442\u044b \u043f\u0440\u043e\u0442\u043e\u0442\u0438\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f), \u043d\u043e \u043e\u043d \u043d\u0435 \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d \u0434\u043b\u044f \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0442\u0435\u0445\u043d\u0438\u043a \u0438\u043b\u0438 \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043f\u0440\u0438\u0451\u043c\u043e\u0432 Javascript. \u041d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435, \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u0442\u043e\u0442\u044b \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u044f Javascript \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u0432\u0441\u0442\u0440\u043e\u0435\u043d \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0432 HTML-\u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 (\u0443\u0436\u0430\u0441!); \u0445\u0443\u0436\u0435 \u0442\u043e\u0433\u043e, \u0432 \u043d\u0451\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438.<\/p>\n<p>  \u0415\u0441\u043b\u0438 \u0431\u044b \u044f \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u043b \u0440\u0435\u0430\u043b\u044c\u043d\u0443\u044e \u0438\u0433\u0440\u0443, \u0442\u043e \u043a\u043e\u0434 \u0431\u044b\u043b \u0431\u044b \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u0431\u043e\u043b\u0435\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d \u0438 \u0443\u043f\u043e\u0440\u044f\u0434\u043e\u0447\u0435\u043d, \u043d\u043e \u0442\u0430\u043a \u043a\u0430\u043a \u044d\u0442\u043e \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0434\u0435\u043c\u043e \u0433\u043e\u043d\u043e\u0447\u043d\u043e\u0439 \u0438\u0433\u0440\u044b, \u044f \u0440\u0435\u0448\u0438\u043b \u043f\u0440\u0438\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0442\u044c\u0441\u044f <a href=\"http:\/\/en.wikipedia.org\/wiki\/KISS_principle\" rel=\"nofollow\">KISS<\/a>.<\/p>\n<h2>\u0427\u0430\u0441\u0442\u044c 1. \u041f\u0440\u044f\u043c\u044b\u0435 \u0434\u043e\u0440\u043e\u0433\u0438.<\/h2>\n<p>  \u0418\u0442\u0430\u043a, \u043a\u0430\u043a \u0436\u0435 \u043d\u0430\u043c \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u0442\u044c \u043a \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044e \u043f\u0441\u0435\u0432\u0434\u043e\u0442\u0440\u0451\u0445\u043c\u0435\u0440\u043d\u043e\u0439 \u0433\u043e\u043d\u043e\u0447\u043d\u043e\u0439 \u0438\u0433\u0440\u044b?<\/p>\n<p>  \u041d\u0443, \u043d\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f<\/p>\n<ul>\n<li>\u041f\u043e\u0432\u0442\u043e\u0440\u0438\u0442\u044c \u0442\u0440\u0438\u0433\u043e\u043d\u043e\u043c\u0435\u0442\u0440\u0438\u044e<\/li>\n<li>\u0412\u0441\u043f\u043e\u043c\u043d\u0438\u0442\u044c \u043e\u0441\u043d\u043e\u0432\u044b 3d-\u043f\u0440\u043e\u0435\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f<\/li>\n<li>\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0438\u0433\u0440\u043e\u0432\u043e\u0439 \u0446\u0438\u043a\u043b<\/li>\n<li>\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0441\u043f\u0440\u0430\u0439\u0442\u043e\u0432\u044b\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f<\/li>\n<li>\u041f\u043e\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0433\u0435\u043e\u043c\u0435\u0442\u0440\u0438\u044e \u0434\u043e\u0440\u043e\u0433\u0438<\/li>\n<li>\u041e\u0442\u0440\u0435\u043d\u0434\u0435\u0440\u0438\u0442\u044c \u0444\u043e\u043d<\/li>\n<li>\u041e\u0442\u0440\u0435\u043d\u0434\u0435\u0440\u0438\u0442\u044c \u0434\u043e\u0440\u043e\u0433\u0443<\/li>\n<li>\u041e\u0442\u0440\u0435\u043d\u0434\u0435\u0440\u0438\u0442\u044c \u043c\u0430\u0448\u0438\u043d\u0443<\/li>\n<li>\u0420\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u044b \u0434\u043b\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043c\u0430\u0448\u0438\u043d\u043e\u0439<\/li>\n<\/ul>\n<p>  \u041d\u043e \u043f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u043c\u044b \u043d\u0430\u0447\u043d\u0451\u043c, \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0435\u043c <a href=\"http:\/\/www.extentofthejam.com\/pseudo\/\" rel=\"nofollow\">Lou\u2019s Pseudo 3d Page<\/a> [<a href=\"https:\/\/habr.com\/ru\/post\/325482\/\">\u043f\u0435\u0440\u0435\u0432\u043e\u0434<\/a> \u043d\u0430 \u0425\u0430\u0431\u0440\u0435] \u2014 \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 (\u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043d\u0430\u0439\u0442\u0438) \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043f\u0441\u0435\u0432\u0434\u043e\u0442\u0440\u0451\u0445\u043c\u0435\u0440\u043d\u0443\u044e \u0433\u043e\u043d\u043e\u0447\u043d\u0443\u044e \u0438\u0433\u0440\u0443.<\/p>\n<p>  \u0417\u0430\u043a\u043e\u043d\u0447\u0438\u043b\u0438 \u0447\u0438\u0442\u0430\u0442\u044c \u0441\u0442\u0430\u0442\u044c\u044e \u041b\u0443? \u041e\u0442\u043b\u0438\u0447\u043d\u043e! \u041c\u044b \u0431\u0443\u0434\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0432\u0430\u0440\u0438\u0430\u0446\u0438\u044e \u0435\u0433\u043e \u0442\u0435\u0445\u043d\u0438\u043a\u0438 \u00abRealistic Hills Using 3d-Projected Segments\u00bb. \u041c\u044b \u0431\u0443\u0434\u0435\u043c \u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e \u043f\u043e\u0441\u0442\u0435\u043f\u0435\u043d\u043d\u043e, \u043d\u0430 \u043f\u0440\u043e\u0442\u044f\u0436\u0435\u043d\u0438\u0438 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u0447\u0435\u0442\u044b\u0440\u0451\u0445 \u0447\u0430\u0441\u0442\u0435\u0439. \u041d\u043e \u043d\u0430\u0447\u043d\u0451\u043c \u043c\u044b \u0441\u0435\u0439\u0447\u0430\u0441, \u0441 \u0432\u0435\u0440\u0441\u0438\u0438 v1, \u0438 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0441\u0442\u0443\u044e \u0433\u0435\u043e\u043c\u0435\u0442\u0440\u0438\u044e \u043f\u0440\u044f\u043c\u043e\u0439 \u0434\u043e\u0440\u043e\u0433\u0438, \u0441\u043f\u0440\u043e\u0435\u0446\u0438\u0440\u043e\u0432\u0430\u0432 \u0435\u0451 \u043d\u0430 HTML5-\u044d\u043b\u0435\u043c\u0435\u043d\u0442 canvas.<\/p>\n<blockquote><p>\u0414\u0435\u043c\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c <a href=\"https:\/\/codeincomplete.com\/games\/racer\/v1-straight\" rel=\"nofollow\">\u0437\u0434\u0435\u0441\u044c<\/a>.<\/p><\/blockquote>\n<p>  <\/p>\n<h2>\u041d\u0435\u043c\u043d\u043e\u0433\u043e \u0442\u0440\u0438\u0433\u043e\u043d\u043e\u043c\u0435\u0442\u0440\u0438\u0438<\/h2>\n<p>  \u041f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u0437\u0430\u043d\u044f\u0442\u044c\u0441\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0435\u0439, \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0441\u044f \u043e\u0441\u043d\u043e\u0432\u0430\u043c\u0438 \u0442\u0440\u0438\u0433\u043e\u043d\u043e\u043c\u0435\u0442\u0440\u0438\u0438, \u0447\u0442\u043e\u0431\u044b \u0432\u0441\u043f\u043e\u043c\u043d\u0438\u0442\u044c, \u043a\u0430\u043a \u0441\u043f\u0440\u043e\u0435\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u0447\u043a\u0443 \u0432 3D-\u043c\u0438\u0440\u0435 \u043d\u0430 2D-\u044d\u043a\u0440\u0430\u043d.<\/p>\n<p>  \u0412 \u0441\u0430\u043c\u043e\u043c \u043f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u0435\u0441\u043b\u0438 \u043d\u0435 \u043a\u0430\u0441\u0430\u0442\u044c\u0441\u044f \u0432\u0435\u043a\u0442\u043e\u0440\u043e\u0432 \u0438 \u043c\u0430\u0442\u0440\u0438\u0446, \u0434\u043b\u044f 3D-\u043f\u0440\u043e\u0435\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0437\u0430\u043a\u043e\u043d <a href=\"http:\/\/www.khanacademy.org\/math\/geometry\/triangles\/v\/similar-triangles\" rel=\"nofollow\">\u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0445 \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u043e\u0432<\/a>.<\/p>\n<p>  \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f:<\/p>\n<ul>\n<li><strong>h<\/strong> = \u0432\u044b\u0441\u043e\u0442\u0430 \u043a\u0430\u043c\u0435\u0440\u044b<\/li>\n<li><strong>d<\/strong> = \u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043e\u0442 \u043a\u0430\u043c\u0435\u0440\u044b \u0434\u043e \u044d\u043a\u0440\u0430\u043d\u0430<\/li>\n<li><strong>z<\/strong> = \u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043e\u0442 \u043a\u0430\u043c\u0435\u0440\u044b \u0434\u043e \u043c\u0430\u0448\u0438\u043d\u044b<\/li>\n<li><strong>y<\/strong> = \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430 Y \u044d\u043a\u0440\u0430\u043d\u0430<\/li>\n<\/ul>\n<p>  \u0422\u043e\u0433\u0434\u0430 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0437\u0430\u043a\u043e\u043d \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0445 \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u043e\u0432 \u0434\u043b\u044f \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f <\/p>\n<blockquote><p><strong>y = h*d\/z<\/strong><\/p><\/blockquote>\n<p>  \u043a\u0430\u043a \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u043e \u043d\u0430 \u0441\u0445\u0435\u043c\u0435:<\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/949\/0ab\/47b\/9490ab47bb570b61218e46e5913c18bb.png\"><\/div>\n<p>  \u041c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0442\u0430\u043a\u0436\u0435 \u043d\u0430\u0440\u0438\u0441\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0445\u043e\u0436\u0443\u044e \u0441\u0445\u0435\u043c\u0443 \u0432 \u0432\u0438\u0434\u0435 \u0441\u0432\u0435\u0440\u0445\u0443 \u0432\u043c\u0435\u0441\u0442\u043e \u0432\u0438\u0434\u0430 \u0441\u0431\u043e\u043a\u0443, \u0438 \u0432\u044b\u0432\u0435\u0441\u0442\u0438 \u043f\u043e\u0445\u043e\u0436\u0435\u0435 \u0443\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b <strong>X<\/strong> \u044d\u043a\u0440\u0430\u043d\u0430:<\/p>\n<blockquote><p><strong>x = w*d\/z<\/strong><\/p><\/blockquote>\n<p>  \u0413\u0434\u0435 <strong>w<\/strong> = \u043f\u043e\u043b\u043e\u0432\u0438\u043d\u0430 \u0448\u0438\u0440\u0438\u043d\u044b \u0434\u043e\u0440\u043e\u0433\u0438 (\u043e\u0442 \u043a\u0430\u043c\u0435\u0440\u044b \u0434\u043e \u043a\u0440\u0430\u044f \u0434\u043e\u0440\u043e\u0433\u0438).<\/p>\n<p>  \u041a\u0430\u043a \u0432\u0438\u0434\u0438\u0442\u0435, \u0434\u043b\u044f <strong>x<\/strong>, \u0438 <strong>y<\/strong> \u043c\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043d\u0430 \u043a\u043e\u044d\u0444\u0444\u0438\u0446\u0438\u0435\u043d\u0442<\/p>\n<blockquote><p><strong>d\/z<\/strong><\/p><\/blockquote>\n<p>  <\/p>\n<h2>\u0421\u0438\u0441\u0442\u0435\u043c\u044b \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442<\/h2>\n<p>  \u0412 \u0432\u0438\u0434\u0435 \u0441\u0445\u0435\u043c\u044b \u044d\u0442\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043a\u0440\u0430\u0441\u0438\u0432\u043e \u0438 \u043f\u0440\u043e\u0441\u0442\u043e, \u043d\u043e \u043d\u0430\u0447\u0430\u0432 \u043a\u043e\u0434\u0438\u0442\u044c, \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0437\u0430\u043f\u0443\u0442\u0430\u0442\u044c\u0441\u044f, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043c\u044b \u0432\u044b\u0431\u0440\u0430\u043b\u0438 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u044b\u0435 \u043d\u0430\u0438\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u0438\u044f, \u0438 \u043d\u0435\u043f\u043e\u043d\u044f\u0442\u043d\u043e, \u0447\u0435\u043c \u043c\u044b \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0438\u043b\u0438 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b 3D-\u043c\u0438\u0440\u0430, \u0430 \u0447\u0435\u043c \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b 2D-\u044d\u043a\u0440\u0430\u043d\u0430. \u0422\u0430\u043a\u0436\u0435 \u043c\u044b \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u043c, \u0447\u0442\u043e \u043a\u0430\u043c\u0435\u0440\u0430 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0446\u0435\u043d\u0442\u0440\u0435 \u043d\u0430\u0447\u0430\u043b\u0430 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442 \u043c\u0438\u0440\u0430, \u0445\u043e\u0442\u044f \u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043e\u043d\u0430 \u0431\u0443\u0434\u0435\u0442 \u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u044c \u0437\u0430 \u043c\u0430\u0448\u0438\u043d\u043e\u0439.<\/p>\n<p>  \u0415\u0441\u043b\u0438 \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442\u044c \u0431\u043e\u043b\u0435\u0435 \u0444\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e, \u0442\u043e \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c:<\/p>\n<ol>\n<li><strong>\u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435<\/strong> \u0438\u0437 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442 \u043c\u0438\u0440\u0430 \u0432 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u044d\u043a\u0440\u0430\u043d\u0430<\/li>\n<li><strong>\u043f\u0440\u043e\u0435\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435<\/strong> \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442 \u043a\u0430\u043c\u0435\u0440\u044b \u043d\u0430 \u043d\u043e\u0440\u043c\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u0443\u044e \u043f\u043b\u043e\u0441\u043a\u043e\u0441\u0442\u044c \u043f\u0440\u043e\u0435\u043a\u0446\u0438\u0438<\/li>\n<li><strong>\u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435<\/strong> \u0441\u043f\u0440\u043e\u0435\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442 \u043d\u0430 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u044d\u043a\u0440\u0430\u043d\u0430 (\u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u044d\u0442\u043e canvas)<\/li>\n<\/ol>\n<p>  <\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/b59\/5d2\/30f\/b595d230f4f45b9b0c9409266d5804d8.png\"><\/div>\n<p>  <\/p>\n<blockquote><p><em>\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435: \u0432 \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0435\u0439 3d-\u0441\u0438\u0441\u0442\u0435\u043c\u0435 \u043c\u0435\u0436\u0434\u0443 \u044d\u0442\u0430\u043f\u0430\u043c\u0438 1 \u0438 2 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u044d\u0442\u0430\u043f <em>\u043f\u043e\u0432\u043e\u0440\u043e\u0442\u0430<\/em>, \u043d\u043e \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u043c\u0438\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u0440\u0438\u0432\u044b\u0435, \u0442\u043e \u043f\u043e\u0432\u043e\u0440\u043e\u0442 \u043d\u0430\u043c \u043d\u0435 \u043d\u0443\u0436\u0435\u043d.<\/em><\/p><\/blockquote>\n<p>  <\/p>\n<h2>\u041f\u0440\u043e\u0435\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435<\/h2>\n<p>  \u0424\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u044b\u0435 \u0443\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0435\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/edb\/246\/e18\/edb246e187e7fe0eb027b53c58790c34.png\"><\/div>\n<p>  <\/p>\n<ul>\n<li>\u0423\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f (<strong>translate<\/strong>) \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u044e\u0442 \u0442\u043e\u0447\u043a\u0443 \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043a\u0430\u043c\u0435\u0440\u044b<\/li>\n<li>\u0423\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0435\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f (<strong>project<\/strong>) \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0432\u0430\u0440\u0438\u0430\u0446\u0438\u044f\u043c\u0438 \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0433\u043e \u0432\u044b\u0448\u0435 \u00ab\u0437\u0430\u043a\u043e\u043d\u0430 \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0445 \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u043e\u0432\u00bb<\/li>\n<li>\u0423\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f (<strong>scale<\/strong>) \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u044e\u0442 \u0440\u0430\u0437\u043d\u043e\u0441\u0442\u044c \u043c\u0435\u0436\u0434\u0443:<br \/> \n<ul>\n<li><em>\u043c\u0430\u0442\u0435\u043c\u0430\u0442\u0438\u043a\u043e\u0439<\/em>, \u0433\u0434\u0435 0,0 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0446\u0435\u043d\u0442\u0440\u0435, \u0430 \u043e\u0441\u044c y \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0430 \u0432\u0432\u0435\u0440\u0445, \u0438 <\/li>\n<li><em>\u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440\u0430\u043c\u0438<\/em>, \u0433\u0434\u0435 0,0 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u043b\u0435\u0432\u043e\u043c \u0432\u0435\u0440\u0445\u043d\u0435\u043c \u0443\u0433\u043b\u0443, \u0430 \u043e\u0441\u044c y \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0430 \u0432\u043d\u0438\u0437:<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>  <\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/11f\/050\/aad\/11f050aadea0d1c537baefcb06f7c2f0.png\"><\/div>\n<p>  <\/p>\n<blockquote><p><em>\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435: \u0432 \u043f\u043e\u043b\u043d\u043e\u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0439 3d-\u0441\u0438\u0441\u0442\u0435\u043c\u0435 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0431\u044b \u0431\u043e\u043b\u0435\u0435 \u0444\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e \u0437\u0430\u0434\u0430\u0442\u044c \u043a\u043b\u0430\u0441\u0441 <code>Vector<\/code> \u0438 <code>Matrix<\/code> \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0431\u043e\u043b\u0435\u0435 \u043d\u0430\u0434\u0451\u0436\u043d\u043e\u0439 3d-\u043c\u0430\u0442\u0435\u043c\u0430\u0442\u0438\u043a\u0438, \u0438 \u0435\u0441\u043b\u0438 \u043c\u044b \u0431\u044b \u0441\u0434\u0435\u043b\u0430\u043b\u0438 \u044d\u0442\u043e, \u0442\u043e \u0441\u0442\u043e\u0438\u043b\u043e \u0431\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c WebGL (\u0438\u043b\u0438 \u0435\u0433\u043e \u0430\u043d\u0430\u043b\u043e\u0433)\u2026 \u043d\u043e \u0432 \u043d\u0430\u0448\u0435\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u044d\u0442\u043e \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f. \u042f \u0445\u043e\u0442\u0435\u043b \u043f\u0440\u0438\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u043e\u043b\u0434\u0441\u043a\u0443\u043b\u044c\u043d\u043e\u0439 \u043f\u0441\u0435\u0432\u0434\u043e\u0442\u0440\u0451\u0445\u043c\u0435\u0440\u043d\u043e\u0441\u0442\u0438 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0438\u0433\u0440\u044b \u0432 \u0441\u0442\u0438\u043b\u0435 Outrun.<\/em><\/p><\/blockquote>\n<p>  <\/p>\n<h2>\u0415\u0449\u0451 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0442\u0440\u0438\u0433\u043e\u043d\u043e\u043c\u0435\u0442\u0440\u0438\u0438<\/h2>\n<p>  <\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/3b7\/27b\/1bd\/3b727b1bdb285d874bd659c29db13522.png\"><\/div>\n<p>  \u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u043c \u043a\u0443\u0441\u043a\u043e\u043c \u0433\u043e\u043b\u043e\u0432\u043e\u043b\u043e\u043c\u043a\u0438 \u0441\u0442\u0430\u043d\u0435\u0442 \u0441\u043f\u043e\u0441\u043e\u0431 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f <strong>d<\/strong> \u2014 \u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043e\u0442 \u043a\u0430\u043c\u0435\u0440\u044b \u0434\u043e \u043f\u043b\u043e\u0441\u043a\u043e\u0441\u0442\u0438 \u043f\u0440\u043e\u0435\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f.<\/p>\n<p>  \u0412\u043c\u0435\u0441\u0442\u043e \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0440\u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u0436\u0451\u0441\u0442\u043a\u043e \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <strong>d<\/strong>, \u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u043b\u0435\u0437\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0442\u044c \u0435\u0433\u043e \u0438\u0437 \u043d\u0443\u0436\u043d\u043e\u0439 \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0439 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u043e\u0431\u0437\u043e\u0440\u0430. \u0411\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u0441\u043c\u043e\u0436\u0435\u043c \u043f\u0440\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u00ab\u0437\u0443\u043c\u0438\u0442\u044c\u00bb \u043a\u0430\u043c\u0435\u0440\u0443.<\/p>\n<p>  \u0415\u0441\u043b\u0438 \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u0442\u044c, \u0447\u0442\u043e \u043c\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u043f\u0440\u043e\u0435\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043d\u0430 \u043d\u043e\u0440\u043c\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u0443\u044e \u043f\u043b\u043e\u0441\u043a\u043e\u0441\u0442\u044c \u043f\u0440\u043e\u0435\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u0432 \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b\u0435 \u043e\u0442 -1 \u0434\u043e +1, \u0442\u043e <strong>d<\/strong> \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0447\u0438\u0441\u043b\u0438\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<blockquote><p><strong>d<\/strong> = 1\/tan(fov\/2)<\/p><\/blockquote>\n<p>  \u0417\u0430\u0434\u0430\u0432\u0430\u044f <strong>fov<\/strong> \u043a\u0430\u043a \u043e\u0434\u043d\u0443 (\u0438\u0437 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0430) \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445, \u043c\u044b \u0441\u043c\u043e\u0436\u0435\u043c \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0442\u044c \u043e\u0431\u043b\u0430\u0441\u0442\u044c \u043e\u0431\u0437\u043e\u0440\u0430 \u0434\u043b\u044f \u0442\u043e\u043d\u043a\u043e\u0439 \u043f\u043e\u0434\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0430 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430.<\/p>\n<h2>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043a\u043e\u0434\u0430 \u043d\u0430 Javascript<\/h2>\n<p>  \u0412 \u043d\u0430\u0447\u0430\u043b\u0435 \u0441\u0442\u0430\u0442\u044c\u0438 \u044f \u0443\u0436\u0435 \u0441\u043a\u0430\u0437\u0430\u043b, \u0447\u0442\u043e \u043a\u043e\u0434 \u043d\u0435 \u0441\u043e\u0432\u0441\u0435\u043c \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0430\u0446\u0438\u044f\u043c \u043f\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044e Javascript \u2014 \u044d\u0442\u043e \u00ab\u0431\u044b\u0441\u0442\u0440\u043e\u0435 \u0438 \u0433\u0440\u044f\u0437\u043d\u043e\u0435\u00bb \u0434\u0435\u043c\u043e \u0441 \u043f\u0440\u043e\u0441\u0442\u044b\u043c\u0438 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u043c\u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u043c\u0438 \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u043c\u0438. \u041e\u0434\u043d\u0430\u043a\u043e \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u044f \u0441\u043e\u0431\u0438\u0440\u0430\u044e\u0441\u044c \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0447\u0435\u0442\u044b\u0440\u0435 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u0432\u0435\u0440\u0441\u0438\u0438 (\u043f\u0440\u044f\u043c\u044b\u0435, \u043a\u0440\u0438\u0432\u044b\u0435, \u0445\u043e\u043b\u043c\u044b \u0438 \u0441\u043f\u0440\u0430\u0439\u0442\u044b), \u0442\u043e \u0431\u0443\u0434\u0443 \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043d\u043e\u0433\u043e\u043a\u0440\u0430\u0442\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u0432\u043d\u0443\u0442\u0440\u0438 <code>common.js<\/code> \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u043c\u043e\u0434\u0443\u043b\u0435\u0439:<\/p>\n<ul>\n<li><strong>Dom<\/strong> \u2014 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043c\u0435\u043b\u043a\u0438\u0445 \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 DOM.<\/li>\n<li><strong>Util<\/strong> \u2014 \u043e\u0431\u0449\u0438\u0435 \u0443\u0442\u0438\u043b\u0438\u0442\u044b, \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u043c \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043c\u0430\u0442\u0435\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438.<\/li>\n<li><strong>Game<\/strong> \u2014 \u043e\u0431\u0449\u0438\u0435 \u0438\u0433\u0440\u043e\u0432\u044b\u0435 \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0437\u0430\u0433\u0440\u0443\u0437\u0447\u0438\u043a \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0438 \u0438\u0433\u0440\u043e\u0432\u043e\u0439 \u0446\u0438\u043a\u043b.<\/li>\n<li><strong>Render<\/strong> \u2014 \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 \u043d\u0430 canvas.<\/li>\n<\/ul>\n<p>  \u041f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u044f \u0431\u0443\u0434\u0443 \u043e\u0431\u044a\u044f\u0441\u043d\u044f\u0442\u044c \u043c\u0435\u0442\u043e\u0434\u044b \u0438\u0437 <code>common.js<\/code>, \u0442\u043e\u043b\u044c\u043a\u043e \u0435\u0441\u043b\u0438 \u043e\u043d\u0438 \u043e\u0442\u043d\u043e\u0441\u044f\u0442\u0441\u044f \u043a \u0441\u0430\u043c\u043e\u0439 \u0438\u0433\u0440\u0435, \u0430 \u043d\u0435 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u043c\u0438 \u043c\u0430\u0442\u0435\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u043c\u0438 \u0438\u043b\u0438 DOM-\u0444\u0443\u043d\u043a\u0446\u0438\u044f\u043c\u0438. \u041d\u0430\u0434\u0435\u044e\u0441\u044c, \u0438\u0437 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u0438 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0430 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043d\u044f\u0442\u043d\u043e, \u0447\u0442\u043e \u0434\u043e\u043b\u0436\u043d\u044b \u0434\u0435\u043b\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434\u044b.<\/p>\n<blockquote><p><em>\u041a\u0430\u043a \u043e\u0431\u044b\u0447\u043d\u043e, \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u043e\u043a\u043e\u043d\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438.<\/em><\/p><\/blockquote>\n<p>  <\/p>\n<h2>\u041f\u0440\u043e\u0441\u0442\u043e\u0439 \u0438\u0433\u0440\u043e\u0432\u043e\u0439 \u0446\u0438\u043a\u043b<\/h2>\n<p>  \u041f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u0447\u0442\u043e-\u0442\u043e \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u0442\u044c, \u043d\u0430\u043c \u043d\u0443\u0436\u0435\u043d \u0438\u0433\u0440\u043e\u0432\u043e\u0439 \u0446\u0438\u043a\u043b. \u0415\u0441\u043b\u0438 \u0432\u044b \u0447\u0438\u0442\u0430\u043b\u0438 \u043b\u044e\u0431\u0443\u044e \u0438\u0437 \u043c\u043e\u0438\u0445 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0445 \u0441\u0442\u0430\u0442\u0435\u0439 \u043f\u0440\u043e \u0438\u0433\u0440\u044b (<a href=\"https:\/\/codeincomplete.com\/articles\/javascript-pong\" rel=\"nofollow\">pong<\/a>, <a href=\"https:\/\/codeincomplete.com\/articles\/javascript-breakout\" rel=\"nofollow\">breakout<\/a>, <a href=\"https:\/\/codeincomplete.com\/articles\/javascript-tetris\" rel=\"nofollow\">tetris<\/a>, <a href=\"https:\/\/codeincomplete.com\/articles\/javascript-snakes\" rel=\"nofollow\">snakes<\/a> \u0438\u043b\u0438 <a href=\"https:\/\/codeincomplete.com\/articles\/javascript-boulderdash\" rel=\"nofollow\">boulderdash<\/a>), \u0442\u043e \u0443\u0436\u0435 \u0432\u0438\u0434\u0435\u043b\u0438 \u043f\u0440\u0438\u043c\u0435\u0440\u044b \u043c\u043e\u0435\u0433\u043e \u043b\u044e\u0431\u0438\u043c\u043e\u0433\u043e \u0438\u0433\u0440\u043e\u0432\u043e\u0433\u043e \u0446\u0438\u043a\u043b\u0430 \u0441 <a href=\"http:\/\/gafferongames.com\/game-physics\/fix-your-timestep\/\" rel=\"nofollow\">\u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c \u0448\u0430\u0433\u043e\u043c \u0432\u0440\u0435\u043c\u0435\u043d\u0438<\/a>.<\/p>\n<p>  \u042f \u043d\u0435 \u0431\u0443\u0434\u0443 \u0432\u0434\u0430\u0432\u0430\u0442\u044c\u0441\u044f \u0433\u043b\u0443\u0431\u043e\u043a\u043e \u0432 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e\u0441\u0442\u0438, \u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u043a\u043e\u0434\u0430 \u0438\u0437 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0445 \u0438\u0433\u0440, \u0447\u0442\u043e\u0431\u044b \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0438\u0433\u0440\u043e\u0432\u043e\u0439 \u0446\u0438\u043a\u043b \u0441 \u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c \u0448\u0430\u0433\u043e\u043c \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 <a href=\"http:\/\/paulirish.com\/2011\/requestanimationframe-for-smart-animating\/\" rel=\"nofollow\">requestAnimationFrame<\/a>.<\/p>\n<p>  \u041f\u0440\u0438\u043d\u0446\u0438\u043f \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043a\u0430\u0436\u0434\u044b\u0439 \u0438\u0437 \u043c\u043e\u0438\u0445 \u0447\u0435\u0442\u044b\u0440\u0451\u0445 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c <code>Game.run(...)<\/code> and \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 \u0432\u0435\u0440\u0441\u0438\u0438<\/p>\n<ul>\n<li><code>update<\/code> \u2014 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0438\u0433\u0440\u043e\u0432\u043e\u0433\u043e \u043c\u0438\u0440\u0430 \u0441 \u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c \u0448\u0430\u0433\u043e\u043c \u0432\u0440\u0435\u043c\u0435\u043d\u0438.<\/li>\n<li><code>render<\/code> \u2014 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0438\u0433\u0440\u043e\u0432\u043e\u0433\u043e \u043c\u0438\u0440\u0430, \u043a\u043e\u0433\u0434\u0430 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0431\u0440\u0430\u0443\u0437\u0435\u0440.<\/li>\n<\/ul>\n<p>  <\/p>\n<pre><code class=\"javascript\">run: function(options) {    Game.loadImages(options.images, function(images) {      var update = options.update,    \/\/ method to update game logic is provided by caller         render = options.render,    \/\/ method to render the game is provided by caller         step   = options.step,      \/\/ fixed frame step (1\/fps) is specified by caller         now    = null,         last   = Util.timestamp(),         dt     = 0,         gdt    = 0;      function frame() {       now = Util.timestamp();       dt  = Math.min(1, (now - last) \/ 1000); \/\/ using requestAnimationFrame have to be able to handle large delta's caused when it 'hibernates' in a background or non-visible tab       gdt = gdt + dt;       while (gdt &gt; step) {         gdt = gdt - step;         update(step);       }       render();       last = now;       requestAnimationFrame(frame);     }     frame(); \/\/ lets get this party started   }); }<\/code><\/pre>\n<p>  \u041f\u043e\u0432\u0442\u043e\u0440\u044e\u0441\u044c, \u044d\u0442\u043e \u043f\u0435\u0440\u0435\u0434\u0435\u043b\u043a\u0430 \u0438\u0434\u0435\u0439 \u0438\u0437 \u043c\u043e\u0438\u0445 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0445 \u0438\u0433\u0440 \u043d\u0430 canvas, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0435\u0441\u043b\u0438 \u0432\u0430\u043c \u043d\u0435\u043f\u043e\u043d\u044f\u0442\u043d\u043e, \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0438\u0433\u0440\u043e\u0432\u043e\u0439 \u0446\u0438\u043a\u043b, \u0442\u043e \u0432\u0435\u0440\u043d\u0438\u0442\u0435\u0441\u044c \u043a \u043e\u0434\u043d\u043e\u0439 \u0438\u0437 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0445 \u0441\u0442\u0430\u0442\u0435\u0439.<\/p>\n<h2>\u0418\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0438 \u0441\u043f\u0440\u0430\u0439\u0442\u044b<\/h2>\n<p>  \u041f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u043d\u0430\u0447\u043d\u0451\u0442\u0441\u044f \u0438\u0433\u0440\u043e\u0432\u043e\u0439 \u0446\u0438\u043a\u043b, \u043c\u044b \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c \u0434\u0432\u0430 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0445 \u0441\u043f\u0440\u0430\u0439\u0442\u0448\u0438\u0442\u0430 (\u043b\u0438\u0441\u0442\u0430 \u0441\u043f\u0440\u0430\u0439\u0442\u043e\u0432):<\/p>\n<ul>\n<li><strong>background<\/strong> \u2014 \u0442\u0440\u0438 \u043f\u0430\u0440\u0430\u043b\u043b\u0430\u043a\u0441\u043d\u044b\u0445 \u0441\u043b\u043e\u044f \u0434\u043b\u044f \u043d\u0435\u0431\u0430, \u0445\u043e\u043b\u043c\u043e\u0432 \u0438 \u0434\u0435\u0440\u0435\u0432\u044c\u0435\u0432<\/li>\n<li><strong>sprites<\/strong> \u2014 \u0441\u043f\u0440\u0430\u0439\u0442\u044b \u043c\u0430\u0448\u0438\u043d\u044b (\u043f\u043b\u044e\u0441 \u0434\u0435\u0440\u0435\u0432\u044c\u044f \u0438 \u0431\u0438\u043b\u0431\u043e\u0440\u0434\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u044b \u0432 \u043e\u043a\u043e\u043d\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e)<\/li>\n<\/ul>\n<p>  <\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/f6f\/111\/acc\/f6f111accbba448459e25c6fe761ff05.png\"><\/div>\n<p>  \u0421\u043f\u0440\u0430\u0439\u0442\u0448\u0438\u0442 \u0431\u044b\u043b \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e \u0442\u0430\u0441\u043a\u0430 Rake \u0438 <a href=\"https:\/\/codeincomplete.com\/articles\/sprite-factory\" rel=\"nofollow\">Ruby Gem sprite-factory<\/a>.<\/p>\n<p>  \u042d\u0442\u043e\u0442 \u0442\u0430\u0441\u043a \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0451\u043d\u043d\u044b\u0435 \u0441\u043f\u0440\u0430\u0439\u0442\u0448\u0438\u0442\u044b, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b x,y,w,h, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u044c\u0441\u044f \u0432 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0430\u0445 <code>BACKGROUND<\/code> \u0438 <code>SPRITES<\/code>.<\/p>\n<blockquote><p><em>\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435: \u0444\u043e\u043d\u044b \u0441\u043e\u0437\u0434\u0430\u043d\u044b \u043c\u043d\u043e\u0439 \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 Inkscape, \u0430 \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u043e \u0441\u043f\u0440\u0430\u0439\u0442\u043e\u0432 \u2014 \u044d\u0442\u043e \u0433\u0440\u0430\u0444\u0438\u043a\u0430, <a href=\"http:\/\/pixel.garoux.net\/game\/44\" rel=\"nofollow\">\u043f\u043e\u0437\u0430\u0438\u043c\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u043d\u0430\u044f<\/a> \u0438\u0437 \u0441\u0442\u0430\u0440\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 Outrun \u0434\u043b\u044f Genesis \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u043d\u0430\u044f \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043e\u0431\u0443\u0447\u0430\u044e\u0449\u0438\u0445 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432.<\/em><\/p><\/blockquote>\n<p>  <\/p>\n<h2>\u0418\u0433\u0440\u043e\u0432\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435<\/h2>\n<p>  \u0412 \u0434\u043e\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043a \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f\u043c \u0444\u043e\u043d\u043e\u0432 \u0438 \u0441\u043f\u0440\u0430\u0439\u0442\u043e\u0432 \u043d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0438\u0433\u0440\u043e\u0432\u044b\u0445 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445, \u0430 \u0438\u043c\u0435\u043d\u043d\u043e:<\/p>\n<pre><code class=\"javascript\">var fps           = 60;                      \/\/ how many 'update' frames per second var step          = 1\/fps;                   \/\/ how long is each frame (in seconds) var width         = 1024;                    \/\/ logical canvas width var height        = 768;                     \/\/ logical canvas height var segments      = [];                      \/\/ array of road segments var canvas        = Dom.get('canvas');       \/\/ our canvas... var ctx           = canvas.getContext('2d'); \/\/ ...and its drawing context var background    = null;                    \/\/ our background image (loaded below) var sprites       = null;                    \/\/ our spritesheet (loaded below) var resolution    = null;                    \/\/ scaling factor to provide resolution independence (computed) var roadWidth     = 2000;                    \/\/ actually half the roads width, easier math if the road spans from -roadWidth to +roadWidth var segmentLength = 200;                     \/\/ length of a single segment var rumbleLength  = 3;                       \/\/ number of segments per red\/white rumble strip var trackLength   = null;                    \/\/ z length of entire track (computed) var lanes         = 3;                       \/\/ number of lanes var fieldOfView   = 100;                     \/\/ angle (degrees) for field of view var cameraHeight  = 1000;                    \/\/ z height of camera var cameraDepth   = null;                    \/\/ z distance camera is from screen (computed) var drawDistance  = 300;                     \/\/ number of segments to draw var playerX       = 0;                       \/\/ player x offset from center of road (-1 to 1 to stay independent of roadWidth) var playerZ       = null;                    \/\/ player relative z distance from camera (computed) var fogDensity    = 5;                       \/\/ exponential fog density var position      = 0;                       \/\/ current camera Z position (add playerZ to get player's absolute Z position) var speed         = 0;                       \/\/ current speed var maxSpeed      = segmentLength\/step;      \/\/ top speed (ensure we can't move more than 1 segment in a single frame to make collision detection easier) var accel         =  maxSpeed\/5;             \/\/ acceleration rate - tuned until it 'felt' right var breaking      = -maxSpeed;               \/\/ deceleration rate when braking var decel         = -maxSpeed\/5;             \/\/ 'natural' deceleration rate when neither accelerating, nor braking var offRoadDecel  = -maxSpeed\/2;             \/\/ off road deceleration is somewhere in between var offRoadLimit  =  maxSpeed\/4;             \/\/ limit when off road deceleration no longer applies (e.g. you can always go at least this speed even when off road)<\/code><\/pre>\n<p>  \u041d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0437 \u043d\u0438\u0445 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0442\u044c \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f UI \u0434\u043b\u044f \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043a\u0440\u0438\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0432\u0430\u0436\u043d\u044b\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b, \u0447\u0442\u043e\u0431\u044b \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0443\u0432\u0438\u0434\u0435\u0442\u044c, \u043a\u0430\u043a \u043e\u043d\u0438 \u0432\u043b\u0438\u044f\u044e\u0442 \u043d\u0430 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433 \u0434\u043e\u0440\u043e\u0433\u0438. \u0414\u0440\u0443\u0433\u0438\u0435 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u044e\u0442\u0441\u044f \u0438\u0437 \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u043c\u044b\u0445 UI \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u0432 \u043c\u0435\u0442\u043e\u0434\u0435 <code>reset()<\/code>.<\/p>\n<h2>\u0423\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c Ferrari<\/h2>\n<p>  \u041c\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u043f\u0440\u0438\u0432\u044f\u0437\u043a\u0443 \u043a\u043b\u0430\u0432\u0438\u0448 \u0434\u043b\u044f <code>Game.run<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u0435\u0442 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0432\u0432\u043e\u0434 \u0441 \u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u044b, \u0437\u0430\u0434\u0430\u044e\u0449\u0438\u0439 \u0438\u043b\u0438 \u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u044e\u0449\u0438\u0439 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435, \u0441\u043e\u043e\u0431\u0449\u0430\u044e\u0449\u0438\u0435 \u043e \u0442\u0435\u043a\u0443\u0449\u0438\u0445 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f\u0445 \u0438\u0433\u0440\u043e\u043a\u0430:<\/p>\n<pre><code class=\"javascript\">Game.run({   ...   keys: [     { keys: [KEY.LEFT,  KEY.A], mode: 'down', action: function() { keyLeft   = true;  } },     { keys: [KEY.RIGHT, KEY.D], mode: 'down', action: function() { keyRight  = true;  } },     { keys: [KEY.UP,    KEY.W], mode: 'down', action: function() { keyFaster = true;  } },     { keys: [KEY.DOWN,  KEY.S], mode: 'down', action: function() { keySlower = true;  } },     { keys: [KEY.LEFT,  KEY.A], mode: 'up',   action: function() { keyLeft   = false; } },     { keys: [KEY.RIGHT, KEY.D], mode: 'up',   action: function() { keyRight  = false; } },     { keys: [KEY.UP,    KEY.W], mode: 'up',   action: function() { keyFaster = false; } },     { keys: [KEY.DOWN,  KEY.S], mode: 'up',   action: function() { keySlower = false; } }   ],   ... }<\/code><\/pre>\n<p>  \u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c \u0438\u0433\u0440\u043e\u043a\u0430 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435:<\/p>\n<ul>\n<li><strong>speed<\/strong> \u2014 \u0442\u0435\u043a\u0443\u0449\u0430\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c.<\/li>\n<li><strong>position<\/strong> \u2014 \u0442\u0435\u043a\u0443\u0449\u0430\u044f \u043f\u043e\u0437\u0438\u0446\u0438\u044f \u043f\u043e Z \u043d\u0430 \u0442\u0440\u0430\u0441\u0441\u0435. \u0417\u0430\u043c\u0435\u0442\u044c\u0442\u0435, \u0447\u0442\u043e \u044d\u0442\u043e \u043f\u043e\u0437\u0438\u0446\u0438\u044f \u043a\u0430\u043c\u0435\u0440\u044b, \u0430 \u043d\u0435 Ferrari.<\/li>\n<li><strong>playerX<\/strong> \u2014 \u0442\u0435\u043a\u0443\u0449\u0430\u044f \u043f\u043e\u0437\u0438\u0446\u0438\u044f \u0438\u0433\u0440\u043e\u043a\u0430 \u043f\u043e X \u043d\u0430 \u0434\u043e\u0440\u043e\u0433\u0435. \u041d\u043e\u0440\u043c\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u0430 \u0432 \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b\u0435 \u043e\u0442 -1 \u0434\u043e +1, \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u0437\u0430\u0432\u0438\u0441\u0435\u0442\u044c \u043e\u0442 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f <code>roadWidth<\/code>.<\/li>\n<\/ul>\n<p>  \u042d\u0442\u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0437\u0430\u0434\u0430\u044e\u0442\u0441\u044f \u0432\u043d\u0443\u0442\u0440\u0438 \u043c\u0435\u0442\u043e\u0434\u0430 <code>update<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f:<\/p>\n<ul>\n<li>\u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442 <code>position<\/code> \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u0438\u0438 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 <code>speed<\/code>.<\/li>\n<li>\u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442 <code>playerX<\/code> \u043f\u0440\u0438 \u043d\u0430\u0436\u0430\u0442\u0438\u0438 \u043d\u0430 \u043a\u043b\u0430\u0432\u0438\u0448\u0438 \u00ab\u0432\u043b\u0435\u0432\u043e\u00bb \u0438\u043b\u0438 \u00ab\u0432\u043f\u0440\u0430\u0432\u043e\u00bb.<\/li>\n<li>\u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u0442 <code>speed<\/code>, \u0435\u0441\u043b\u0438 \u043d\u0430\u0436\u0430\u0442\u0430 \u043a\u043b\u0430\u0432\u0438\u0448\u0430 \u00ab\u0432\u0432\u0435\u0440\u0445\u00bb.<\/li>\n<li>\u0443\u043c\u0435\u043d\u044c\u0448\u0430\u0435\u0442 <code>speed<\/code>, \u0435\u0441\u043b\u0438 \u043d\u0430\u0436\u0430\u0442\u0430 \u043a\u043b\u0430\u0432\u0438\u0448\u0430 \u00ab\u0432\u043d\u0438\u0437\u00bb.<\/li>\n<li>\u0443\u043c\u0435\u043d\u044c\u0448\u0430\u0435\u0442 <code>speed<\/code>, \u0435\u0441\u043b\u0438 \u043d\u0435 \u043d\u0430\u0436\u0430\u0442\u044b \u043a\u043b\u0430\u0432\u0438\u0448\u0438 \u00ab\u0432\u0432\u0435\u0440\u0445\u00bb \u0438 \u00ab\u0432\u043d\u0438\u0437\u00bb.<\/li>\n<li>\u0443\u043c\u0435\u043d\u044c\u0448\u0430\u0435\u0442 <code>speed<\/code>, \u0435\u0441\u043b\u0438 <code>playerX<\/code> \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0437\u0430 \u043a\u0440\u0430\u0435\u043c \u0434\u043e\u0440\u043e\u0433\u0438 \u0438 \u043d\u0430 \u0442\u0440\u0430\u0432\u0435.<\/li>\n<\/ul>\n<p>  \u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u043f\u0440\u044f\u043c\u044b\u0445 \u0434\u043e\u0440\u043e\u0433 \u043c\u0435\u0442\u043e\u0434 <code>update<\/code> \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u044f\u0441\u0435\u043d \u0438 \u043f\u0440\u043e\u0441\u0442:<\/p>\n<pre><code class=\"javascript\">function update(dt) {    position = Util.increase(position, dt * speed, trackLength);    var dx = dt * 2 * (speed\/maxSpeed); \/\/ at top speed, should be able to cross from left to right (-1 to 1) in 1 second    if (keyLeft)     playerX = playerX - dx;   else if (keyRight)     playerX = playerX + dx;    if (keyFaster)     speed = Util.accelerate(speed, accel, dt);   else if (keySlower)     speed = Util.accelerate(speed, breaking, dt);   else     speed = Util.accelerate(speed, decel, dt);    if (((playerX &lt; -1) || (playerX &gt; 1)) &amp;&amp; (speed &gt; offRoadLimit))     speed = Util.accelerate(speed, offRoadDecel, dt);    playerX = Util.limit(playerX, -2, 2);     \/\/ dont ever let player go too far out of bounds   speed   = Util.limit(speed, 0, maxSpeed); \/\/ or exceed maxSpeed  }<\/code><\/pre>\n<p>  \u041d\u0435 \u0432\u043e\u043b\u043d\u0443\u0439\u0442\u0435\u0441\u044c, \u043e\u043d \u0441\u0442\u0430\u043d\u0435\u0442 \u043d\u0430\u043c\u043d\u043e\u0433\u043e \u0441\u043b\u043e\u0436\u043d\u0435\u0435, \u043a\u043e\u0433\u0434\u0430 \u0432 \u0433\u043e\u0442\u043e\u0432\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0441\u043f\u0440\u0430\u0439\u0442\u044b \u0438 \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u043d\u0438\u0435 \u043a\u043e\u043b\u043b\u0438\u0437\u0438\u0439.<\/p>\n<h2>\u0413\u0435\u043e\u043c\u0435\u0442\u0440\u0438\u044f \u0434\u043e\u0440\u043e\u0433\u0438<\/h2>\n<p>  \u041f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u043c\u044b \u0441\u043c\u043e\u0436\u0435\u043c \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u0442\u044c \u0438\u0433\u0440\u043e\u0432\u043e\u0439 \u043c\u0438\u0440, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u043c\u0430\u0441\u0441\u0438\u0432 \u0438\u0437 <code>segments<\/code> \u0432 \u043c\u0435\u0442\u043e\u0434\u0435 <code>resetRoad()<\/code>.<\/p>\n<p>  \u041a\u0430\u0436\u0434\u044b\u0439 \u0438\u0437 \u044d\u0442\u0438\u0445 \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u043e\u0432 \u0434\u043e\u0440\u043e\u0433\u0438 \u0432 \u043a\u043e\u043d\u0446\u0435 \u043a\u043e\u043d\u0446\u043e\u0432 \u0431\u0443\u0434\u0435\u0442 \u0441\u043f\u0440\u043e\u0435\u0446\u0438\u0440\u043e\u0432\u0430\u043d \u0438\u0437 \u0435\u0433\u043e \u043c\u0438\u0440\u043e\u0432\u044b\u0445 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442, \u0447\u0442\u043e\u0431\u044b \u043e\u043d \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u0438\u043b\u0441\u044f \u0432 2d-\u043f\u043e\u043b\u0438\u0433\u043e\u043d \u0432 \u044d\u043a\u0440\u0430\u043d\u043d\u044b\u0445 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430\u0445. \u0414\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u0430 \u043c\u044b \u0445\u0440\u0430\u043d\u0438\u043c \u0434\u0432\u0435 \u0442\u043e\u0447\u043a\u0438, <strong>p1<\/strong> \u2014 \u044d\u0442\u043e \u0446\u0435\u043d\u0442\u0440 \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u0431\u043b\u0438\u0437\u043a\u043e\u0433\u043e \u043a \u043a\u0430\u043c\u0435\u0440\u0435 \u0440\u0435\u0431\u0440\u0430, \u0430 <strong>p2<\/strong> \u2014 \u0446\u0435\u043d\u0442\u0440 \u0441\u0430\u043c\u043e\u0433\u043e \u0434\u0430\u043b\u044c\u043d\u0435\u0433\u043e \u043e\u0442 \u043a\u0430\u043c\u0435\u0440\u044b \u0440\u0435\u0431\u0440\u0430.<\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/53a\/fa4\/076\/53afa40768a00b49833703b1457a6941.png\"><\/div>\n<p>  \u0421\u0442\u0440\u043e\u0433\u043e \u0433\u043e\u0432\u043e\u0440\u044f, <strong>p2<\/strong> \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u0430 \u0438\u0434\u0435\u043d\u0442\u0438\u0447\u043d\u0430 <strong>p1<\/strong> \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0433\u043e \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u0430, \u043d\u043e \u043c\u043d\u0435 \u043a\u0430\u0436\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u043f\u0440\u043e\u0449\u0435 \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0438\u0445 \u043a\u0430\u043a \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u0442\u043e\u0447\u043a\u0438, \u0438 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u043a\u0430\u0436\u0434\u044b\u0439 \u0441\u0435\u0433\u043c\u0435\u043d\u0442 \u043f\u043e \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438.<\/p>\n<p>  \u041c\u044b \u0445\u0440\u0430\u043d\u0438\u043c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0443\u044e <code>rumbleLength<\/code> \u043f\u043e\u0442\u043e\u043c\u0443, \u0447\u0442\u043e \u0443 \u043d\u0430\u0441 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u043a\u0440\u0430\u0441\u0438\u0432\u044b\u0435 \u0434\u0435\u0442\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043a\u0440\u0438\u0432\u044b\u0435 \u0438 \u0445\u043e\u043b\u043c\u044b, \u043d\u043e \u0432 \u0442\u043e \u0436\u0435 \u0432\u0440\u0435\u043c\u044f \u0438 \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u043e\u043b\u043e\u0441\u044b. \u0415\u0441\u043b\u0438 \u043a\u0430\u0436\u0434\u044b\u0439 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0441\u0435\u0433\u043c\u0435\u043d\u0442 \u0431\u0443\u0434\u0435\u0442 \u0438\u043c\u0435\u0442\u044c \u0434\u0440\u0443\u0433\u043e\u0439 \u0446\u0432\u0435\u0442, \u0442\u043e \u044d\u0442\u043e \u0441\u043e\u0437\u0434\u0430\u0441\u0442 \u043d\u0435\u0445\u043e\u0440\u043e\u0448\u0438\u0439 \u044d\u0444\u0444\u0435\u043a\u0442 \u0441\u0442\u0440\u043e\u0431\u043e\u0441\u043a\u043e\u043f\u0430. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u0438\u043c\u0435\u0442\u044c \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u043c\u0435\u043b\u043a\u0438\u0445 \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u043e\u0432, \u043d\u043e \u0441\u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438\u0445 \u0432\u043c\u0435\u0441\u0442\u0435, \u0447\u0442\u043e\u0431\u044b \u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u043e\u043b\u043e\u0441\u044b.<\/p>\n<pre><code class=\"javascript\">function resetRoad() {   segments = [];   for(var n = 0 ; n &lt; 500 ; n++) { \/\/ arbitrary road length     segments.push({        index: n,        p1: { world: { z:  n   *segmentLength }, camera: {}, screen: {} },        p2: { world: { z: (n+1)*segmentLength }, camera: {}, screen: {} },        color: Math.floor(n\/rumbleLength)%2 ? COLORS.DARK : COLORS.LIGHT     });   }    trackLength = segments.length * segmentLength; }<\/code><\/pre>\n<p>  \u041c\u044b \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c <strong>p1<\/strong> \u0438 <strong>p2<\/strong> \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f\u043c\u0438 \u043c\u0438\u0440\u043e\u0432\u044b\u0445 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442 <strong>z<\/strong>, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u044b \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u044f\u043c\u044b\u0435 \u0434\u043e\u0440\u043e\u0433\u0438. \u041a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b <strong>y<\/strong> \u0432\u0441\u0435\u0433\u0434\u0430 \u0431\u0443\u0434\u0443\u0442 \u0440\u0430\u0432\u043d\u044b 0, \u0430 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b <strong>x<\/strong> \u0432\u0441\u0435\u0433\u0434\u0430 \u0431\u0443\u0434\u0443\u0442 \u0437\u0430\u0432\u0438\u0441\u0435\u0442\u044c \u043e\u0442 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f <code>+\/- roadWidth<\/code>. \u041f\u043e\u0437\u0436\u0435, \u043a\u043e\u0433\u0434\u0430 \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043a\u0440\u0438\u0432\u044b\u0435 \u0438 \u0445\u043e\u043b\u043c\u044b, \u044d\u0442\u0430 \u0447\u0430\u0441\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u0441\u044f.<\/p>\n<p>  \u0422\u0430\u043a\u0436\u0435 \u043c\u044b \u0437\u0430\u0434\u0430\u0434\u0438\u043c \u043f\u0443\u0441\u0442\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0439 \u044d\u0442\u0438\u0445 \u0442\u043e\u0447\u0435\u043a \u0432 \u043a\u0430\u043c\u0435\u0440\u0435 \u0438 \u043d\u0430 \u044d\u043a\u0440\u0430\u043d\u0435, \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043a\u0443\u0447\u0443 \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0432 \u043a\u0430\u0436\u0434\u043e\u043c <code>render<\/code>. \u0427\u0442\u043e\u0431\u044b \u0434\u043e \u043c\u0438\u043d\u0438\u043c\u0443\u043c\u0430 \u0441\u043d\u0438\u0437\u0438\u0442\u044c \u043e\u0431\u044a\u0451\u043c \u0441\u0431\u043e\u0440\u043a\u0438 \u043c\u0443\u0441\u043e\u0440\u0430, \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0438\u0437\u0431\u0435\u0433\u0430\u0442\u044c \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0432\u043d\u0443\u0442\u0440\u0438 \u0438\u0433\u0440\u043e\u0432\u043e\u0433\u043e \u0446\u0438\u043a\u043b\u0430.<\/p>\n<p>  \u041a\u043e\u0433\u0434\u0430 \u043c\u0430\u0448\u0438\u043d\u0430 \u0434\u043e\u0441\u0442\u0438\u0433\u0430\u0435\u0442 \u043a\u043e\u043d\u0446\u0430 \u0434\u043e\u0440\u043e\u0433\u0438, \u043c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u0441\u044f \u0432 \u043d\u0430\u0447\u0430\u043b\u043e \u0446\u0438\u043a\u043b\u0430. \u0427\u0442\u043e\u0431\u044b \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u0442\u044c \u044d\u0442\u043e, \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043c\u0435\u0442\u043e\u0434 \u0434\u043b\u044f \u043d\u0430\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u044f \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u0430 \u0434\u043b\u044f \u043b\u044e\u0431\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f Z, \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u043e\u043d \u0432\u044b\u0445\u043e\u0434\u0438\u0442 \u0437\u0430 \u043f\u0440\u0435\u0434\u0435\u043b\u044b \u0434\u043b\u0438\u043d\u044b \u0434\u043e\u0440\u043e\u0433\u0438:<\/p>\n<pre><code class=\"javascript\">function findSegment(z) {   return segments[Math.floor(z\/segmentLength) % segments.length]; }<\/code><\/pre>\n<p>  <\/p>\n<h2>\u0420\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433 \u0444\u043e\u043d\u0430<\/h2>\n<p>  \u041c\u0435\u0442\u043e\u0434 <code>render()<\/code> \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0441 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438 \u0444\u043e\u043d\u043e\u0432\u043e\u0433\u043e \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f. \u0412 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u0447\u0430\u0441\u0442\u044f\u0445, \u0433\u0434\u0435 \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043a\u0440\u0438\u0432\u044b\u0435 \u0438 \u0445\u043e\u043b\u043c\u044b, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442, \u0447\u0442\u043e\u0431\u044b \u0444\u043e\u043d \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u043b \u043f\u0430\u0440\u0430\u043b\u043b\u0430\u043a\u0441\u043d\u044b\u0439 \u0441\u043a\u0440\u043e\u043b\u043b\u0438\u043d\u0433, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u0443\u0436\u0435 \u0441\u0435\u0439\u0447\u0430\u0441 \u043d\u0430\u0447\u043d\u0451\u043c \u0434\u0432\u0438\u0433\u0430\u0442\u044c\u0441\u044f \u0432 \u044d\u0442\u043e\u043c \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0438, \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044f \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433 \u0444\u043e\u043d\u0430 \u043a\u0430\u043a \u0442\u0440\u0451\u0445 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0445 \u0441\u043b\u043e\u0451\u0432:<\/p>\n<pre><code class=\"javascript\">function render() {    ctx.clearRect(0, 0, width, height);    Render.background(ctx, background, width, height, BACKGROUND.SKY);   Render.background(ctx, background, width, height, BACKGROUND.HILLS);   Render.background(ctx, background, width, height, BACKGROUND.TREES);    ...<\/code><\/pre>\n<p>  <\/p>\n<h2>\u0420\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433 \u0434\u043e\u0440\u043e\u0433\u0438<\/h2>\n<p>  \u0417\u0430\u0442\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044f render \u0438\u0442\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u043e \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442 \u043f\u043e \u0432\u0441\u0435\u043c \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u0430\u043c \u0438 \u043f\u0440\u043e\u0435\u0446\u0438\u0440\u0443\u0435\u0442 <strong>p1<\/strong> \u0438 <strong>p2<\/strong> \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u0430 \u0438\u0437 \u043c\u0438\u0440\u043e\u0432\u044b\u0445 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442 \u0432 \u044d\u043a\u0440\u0430\u043d\u043d\u044b\u0435, \u043f\u0440\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0431\u0440\u0435\u0437\u0430\u044f \u0441\u0435\u0433\u043c\u0435\u043d\u0442, \u0430 \u0432 \u043f\u0440\u043e\u0442\u0438\u0432\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044f \u0435\u0433\u043e \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433:<\/p>\n<pre><code class=\"javascript\">  var baseSegment = findSegment(position);   var maxy        = height;   var n, segment;   for(n = 0 ; n &lt; drawDistance ; n++) {      segment = segments[(baseSegment.index + n) % segments.length];      Util.project(segment.p1, (playerX * roadWidth), cameraHeight, position, cameraDepth, width, height, roadWidth);     Util.project(segment.p2, (playerX * roadWidth), cameraHeight, position, cameraDepth, width, height, roadWidth);      if ((segment.p1.camera.z &lt;= cameraDepth) || \/\/ behind us         (segment.p2.screen.y &gt;= maxy))          \/\/ clip by (already rendered) segment       continue;      Render.segment(ctx, width, lanes,                    segment.p1.screen.x,                    segment.p1.screen.y,                    segment.p1.screen.w,                    segment.p2.screen.x,                    segment.p2.screen.y,                    segment.p2.screen.w,                    segment.color);      maxy = segment.p2.screen.y;   }<\/code><\/pre>\n<p>  \u0412\u044b\u0448\u0435 \u043c\u044b \u0443\u0436\u0435 \u0432\u0438\u0434\u0435\u043b\u0438 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0434\u043b\u044f \u043f\u0440\u043e\u0435\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0442\u043e\u0447\u043a\u0438; \u0432\u0435\u0440\u0441\u0438\u044f \u043d\u0430 javascript \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u0435\u0442 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435, \u043f\u0440\u043e\u0435\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0432 \u043e\u0434\u0438\u043d \u043c\u0435\u0442\u043e\u0434:<\/p>\n<pre><code class=\"javascript\">project: function(p, cameraX, cameraY, cameraZ, cameraDepth, width, height, roadWidth) {   p.camera.x     = (p.world.x || 0) - cameraX;   p.camera.y     = (p.world.y || 0) - cameraY;   p.camera.z     = (p.world.z || 0) - cameraZ;   p.screen.scale = cameraDepth\/p.camera.z;   p.screen.x     = Math.round((width\/2)  + (p.screen.scale * p.camera.x  * width\/2));   p.screen.y     = Math.round((height\/2) - (p.screen.scale * p.camera.y  * height\/2));   p.screen.w     = Math.round(             (p.screen.scale * roadWidth   * width\/2)); }<\/code><\/pre>\n<p>  \u041a\u0440\u043e\u043c\u0435 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u044d\u043a\u0440\u0430\u043d\u043d\u044b\u0445 <strong>x<\/strong> \u0438 <strong>y<\/strong> \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u044b\u0445 \u0442\u043e\u0447\u0435\u043a <strong>p1<\/strong> \u0438 <strong>p2<\/strong> \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0442\u0435 \u0436\u0435 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0435\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0434\u043b\u044f \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u0441\u043f\u0440\u043e\u0435\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0439 \u0448\u0438\u0440\u0438\u043d\u044b (<strong>w<\/strong>) \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u0430.<\/p>\n<p>  \u0418\u043c\u0435\u044f \u044d\u043a\u0440\u0430\u043d\u043d\u044b\u0435 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b <strong>x<\/strong> \u0438 <strong>y<\/strong> \u0442\u043e\u0447\u0435\u043a <strong>p1<\/strong> \u0438 <strong>p2<\/strong>, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0441\u043f\u0440\u043e\u0435\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0443\u044e \u0448\u0438\u0440\u0438\u043d\u0443 \u0434\u043e\u0440\u043e\u0433\u0438 <strong>w<\/strong>, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u044b\u0447\u0438\u0441\u043b\u0438\u0442\u044c \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>Render.segment<\/code> \u0432\u0441\u0435 \u043f\u043e\u043b\u0438\u0433\u043e\u043d\u044b, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0435\u0439 \u0434\u043b\u044f \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 \u0442\u0440\u0430\u0432\u044b, \u0434\u043e\u0440\u043e\u0433\u0438, \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u044b\u0445 \u043f\u043e\u043b\u043e\u0441 \u0438 \u0440\u0430\u0437\u0434\u0435\u043b\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043b\u0438\u043d\u0438\u0439, \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0432\u0448\u0438\u0441\u044c \u043e\u0431\u0449\u0435\u0439 \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439 <code>Render.polygon<\/code> <em>(\u0441\u043c. <code>common.js<\/code>)<\/em>.<\/p>\n<h2>\u0420\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433 \u043c\u0430\u0448\u0438\u043d\u044b<\/h2>\n<p>  \u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435, \u0447\u0442\u043e \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043c\u0435\u0442\u043e\u0434\u0443 <code>render<\/code> \u2014 \u044d\u0442\u043e \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433 Ferrari:<\/p>\n<pre><code class=\"javascript\">  Render.player(ctx, width, height, resolution, roadWidth, sprites, speed\/maxSpeed,                 cameraDepth\/playerZ,                 width\/2,                 height);<\/code><\/pre>\n<p>  \u042d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f <code>player<\/code>, \u0430 \u043d\u0435 <code>car<\/code>, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0432 \u043e\u043a\u043e\u043d\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 \u0438\u0433\u0440\u044b \u043d\u0430 \u0434\u043e\u0440\u043e\u0433\u0435 \u0431\u0443\u0434\u0443\u0442 \u0438 \u0434\u0440\u0443\u0433\u0438\u0435 \u043c\u0430\u0448\u0438\u043d\u044b, \u0438 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u043e\u0442\u0434\u0435\u043b\u0438\u0442\u044c Ferrari \u0438\u0433\u0440\u043e\u043a\u0430 \u043e\u0442 \u0434\u0440\u0443\u0433\u0438\u0445 \u043c\u0430\u0448\u0438\u043d.<\/p>\n<p>  \u0412\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>Render.player<\/code> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u043c\u0435\u0442\u043e\u0434 canvas \u043f\u043e\u0434 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c <code>drawImage<\/code> \u0434\u043b\u044f \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 \u0441\u043f\u0440\u0430\u0439\u0442\u0430, \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043e\u0442\u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u0432 \u0435\u0433\u043e \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u0442\u043e\u0433\u043e \u0436\u0435 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u0440\u043e\u0435\u043a\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u043e\u0441\u044c \u0440\u0430\u043d\u044c\u0448\u0435:<\/p>\n<blockquote><p><strong>d<\/strong>\/<strong>z<\/strong><\/p><\/blockquote>\n<p>  \u0413\u0434\u0435 <strong>z<\/strong> \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u2014 \u044d\u0442\u043e \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043e\u0442 \u043c\u0430\u0448\u0438\u043d\u044b \u0434\u043e \u043a\u0430\u043c\u0435\u0440\u044b, \u0445\u0440\u0430\u043d\u044f\u0449\u0435\u0435\u0441\u044f \u0432 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 <strong>playerZ<\/strong>.<\/p>\n<p>  \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u00ab\u0442\u0440\u044f\u0441\u0451\u0442\u00bb \u043c\u0430\u0448\u0438\u043d\u0443 \u043d\u0430 \u0432\u044b\u0441\u043e\u043a\u0438\u0445 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044f\u0445, \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u044f \u0432 \u0443\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u043e\u0441\u0442\u0438, \u0437\u0430\u0432\u0438\u0441\u044f\u0449\u0435\u0439 \u043e\u0442 <strong>speed\/maxSpeed<\/strong>.<\/p>\n<p>  \u0418 \u0432\u043e\u0442 \u0447\u0442\u043e \u0443 \u043d\u0430\u0441 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c:<\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/845\/dfd\/3e8\/845dfd3e88ef0a22b2c9fd021140ff3b.png\"><\/div>\n<p>  <\/p>\n<h2>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h2>\n<p>  \u041c\u044b \u043f\u0440\u043e\u0434\u0435\u043b\u0430\u043b\u0438 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043e\u0431\u044a\u0451\u043c \u0440\u0430\u0431\u043e\u0442\u044b \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0441 \u043f\u0440\u044f\u043c\u044b\u043c\u0438 \u0434\u043e\u0440\u043e\u0433\u0430\u043c\u0438. \u041c\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043b\u0438<\/p>\n<ul>\n<li>\u043e\u0431\u0449\u0438\u0439 \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043c\u043e\u0434\u0443\u043b\u044c <strong>Dom<\/strong><\/li>\n<li>\u043e\u0431\u0449\u0438\u0439 \u043c\u0430\u0442\u0435\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043c\u043e\u0434\u0443\u043b\u044c <strong>Util<\/strong><\/li>\n<li>\u043e\u0431\u0449\u0438\u0439 \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439 canvas-\u043c\u043e\u0434\u0443\u043b\u044c <strong>Render<\/strong>&#8230;<\/li>\n<li>\u2026 \u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435 <code>Render.segment<\/code>, <code>Render.polygon<\/code> \u0438 <code>Render.sprite<\/code><\/li>\n<li>\u0438\u0433\u0440\u043e\u0432\u043e\u0439 \u0446\u0438\u043a\u043b \u0441 \u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c \u0448\u0430\u0433\u043e\u043c<\/li>\n<li>\u0437\u0430\u0433\u0440\u0443\u0437\u0447\u0438\u043a \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439<\/li>\n<li>\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u043a\u043b\u0430\u0432\u0438\u0430\u0442\u0443\u0440\u044b<\/li>\n<li>\u0444\u043e\u043d \u0441 \u043f\u0430\u0440\u0430\u043b\u043b\u0430\u043a\u0441\u043d\u044b\u043c\u0438 \u0441\u043b\u043e\u044f\u043c\u0438<\/li>\n<li>\u0441\u043f\u0440\u0430\u0439\u0442\u0448\u0438\u0442 \u0441 \u0430\u0432\u0442\u043e\u043c\u043e\u0431\u0438\u043b\u044f\u043c\u0438, \u0434\u0435\u0440\u0435\u0432\u044c\u044f\u043c\u0438 \u0438 \u0431\u0438\u043b\u0431\u043e\u0440\u0434\u0430\u043c\u0438<\/li>\n<li>\u0440\u0443\u0434\u0438\u043c\u0435\u043d\u0442\u0430\u0440\u043d\u0443\u044e \u0433\u0435\u043e\u043c\u0435\u0442\u0440\u0438\u044e \u0434\u043e\u0440\u043e\u0433\u0438<\/li>\n<li>\u043c\u0435\u0442\u043e\u0434 <code>update()<\/code> \u0434\u043b\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043c\u0430\u0448\u0438\u043d\u043e\u0439<\/li>\n<li>\u043c\u0435\u0442\u043e\u0434 <code>render()<\/code> \u0434\u043b\u044f \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 \u0444\u043e\u043d\u0430, \u0434\u043e\u0440\u043e\u0433\u0438 \u0438 \u043c\u0430\u0448\u0438\u043d\u044b \u0438\u0433\u0440\u043e\u043a\u0430<\/li>\n<li>HTML5-\u0442\u0435\u0433 <code>&lt;audio&gt;<\/code> \u0441 \u0433\u043e\u043d\u043e\u0447\u043d\u043e\u0439 \u043c\u0443\u0437\u044b\u043a\u043e\u0439 (\u0441\u043a\u0440\u044b\u0442\u044b\u0439 \u0431\u043e\u043d\u0443\u0441!)<\/li>\n<\/ul>\n<p>  \u2026 \u0447\u0442\u043e \u0434\u0430\u043b\u043e \u043d\u0430\u043c \u0445\u043e\u0440\u043e\u0448\u0438\u0439 \u0444\u0443\u043d\u0434\u0430\u043c\u0435\u043d\u0442 \u0434\u043b\u044f \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u0433\u043e \u0440\u0430\u0437\u0432\u0438\u0442\u0438\u044f.<\/p>\n<h2>\u0427\u0430\u0441\u0442\u044c 2. \u041a\u0440\u0438\u0432\u044b\u0435.<\/h2>\n<p>  <\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/98f\/c3d\/6d1\/98fc3d6d13cc16f12847d253e112fcb2.png\"><\/div>\n<p>  \u0412 \u044d\u0442\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u043c\u044b \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0435\u043c, \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u043a\u0440\u0438\u0432\u044b\u0435.<\/p>\n<p>  \u0412 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 \u0447\u0430\u0441\u0442\u0438 \u043c\u044b \u0441\u043e\u0441\u0442\u0430\u0432\u0438\u043b\u0438 \u0433\u0435\u043e\u043c\u0435\u0442\u0440\u0438\u044e \u0434\u043e\u0440\u043e\u0433\u0438 \u0432 \u0432\u0438\u0434\u0435 \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u043e\u0432, \u043a\u0430\u0436\u0434\u044b\u0439 \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0438\u043c\u0435\u0435\u0442 \u043c\u0438\u0440\u043e\u0432\u044b\u0435 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b, \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u043c\u044b\u0435 \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043a\u0430\u043c\u0435\u0440\u044b, \u0430 \u0437\u0430\u0442\u0435\u043c \u043f\u0440\u043e\u0435\u0446\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u043d\u0430 \u044d\u043a\u0440\u0430\u043d.<\/p>\n<p>  \u041d\u0430\u043c \u043d\u0443\u0436\u043d\u0430 \u0431\u044b\u043b\u0430 \u0442\u043e\u043b\u044c\u043a\u043e \u043c\u0438\u0440\u043e\u0432\u0430\u044f \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u0430 <strong>z<\/strong> \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u0442\u043e\u0447\u043a\u0438, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043d\u0430 \u043f\u0440\u044f\u043c\u044b\u0445 \u0434\u043e\u0440\u043e\u0433\u0430\u0445 \u0438 <strong>x<\/strong>, \u0438 <strong>y<\/strong> \u0431\u044b\u043b\u0438 \u0440\u0430\u0432\u043d\u044b \u043d\u0443\u043b\u044e.<\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/c78\/551\/359\/c78551359ef7c11e4af48b4285d61842.png\"><\/div>\n<p>  \u0415\u0441\u043b\u0438 \u0431\u044b \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u043b\u0438 \u043f\u043e\u043b\u043d\u043e\u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u0443\u044e 3d-\u0441\u0438\u0441\u0442\u0435\u043c\u0443, \u0442\u043e \u043c\u043e\u0433\u043b\u0438 \u0431\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u0440\u0438\u0432\u044b\u0435, \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u044f <strong>x<\/strong> \u0438 <strong>z<\/strong> \u043f\u043e\u043b\u043e\u0441\u044b \u043c\u043d\u043e\u0433\u043e\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u043e\u0432, \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0445 \u0432\u044b\u0448\u0435. \u041e\u0434\u043d\u0430\u043a\u043e \u0442\u0430\u043a\u043e\u0439 \u0442\u0438\u043f \u0433\u0435\u043e\u043c\u0435\u0442\u0440\u0438\u0438 \u0431\u0443\u0434\u0435\u0442 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043d\u0435\u043f\u0440\u043e\u0441\u0442\u043e \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0442\u044c, \u0438 \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432 \u0443\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0435\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u044d\u0442\u0430\u043f 3d-\u043f\u043e\u0432\u043e\u0440\u043e\u0442\u0430\u2026<\/p>\n<p>  \u2026 \u0435\u0441\u043b\u0438 \u0431\u044b \u043c\u044b \u0434\u0432\u0438\u043d\u0443\u043b\u0438\u0441\u044c \u044d\u0442\u0438\u043c \u043f\u0443\u0442\u0451\u043c, \u0442\u043e \u043b\u0443\u0447\u0448\u0435 \u0431\u044b\u043b\u043e \u0431\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c WebGL \u0438\u043b\u0438 \u0435\u0433\u043e \u0430\u043d\u0430\u043b\u043e\u0433\u0438, \u043d\u043e \u044d\u0442\u043e\u0442 \u043f\u0440\u043e\u0435\u043a\u0442 \u043d\u0435 \u0443 \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0434\u0440\u0443\u0433\u0438\u0435 \u0437\u0430\u0434\u0430\u0447\u0438. \u041c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u0445\u043e\u0442\u0438\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u0438\u043c\u0438\u0442\u0430\u0446\u0438\u0438 \u043a\u0440\u0438\u0432\u044b\u0445 \u043e\u043b\u0434\u0441\u043a\u0443\u043b\u044c\u043d\u044b\u0435 \u043f\u0441\u0435\u0432\u0434\u043e\u0442\u0440\u0451\u0445\u043c\u0435\u0440\u043d\u044b\u0435 \u0442\u0440\u044e\u043a\u0438.<\/p>\n<p>  \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u044b \u043d\u0430\u0432\u0435\u0440\u043d\u043e \u0443\u0434\u0438\u0432\u0438\u0442\u0435\u0441\u044c, \u0443\u0437\u043d\u0430\u0432, \u0447\u0442\u043e \u043c\u044b \u0432\u043e\u043e\u0431\u0449\u0435 \u043d\u0435 \u0431\u0443\u0434\u0435\u043c \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0442\u044c \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b <strong>x<\/strong> \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u043e\u0432 \u0434\u043e\u0440\u043e\u0433\u0438\u2026<\/p>\n<p>  \u0412\u043c\u0435\u0441\u0442\u043e \u044d\u0442\u043e\u0433\u043e \u043c\u044b \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0441\u044f <a href=\"http:\/\/www.extentofthejam.com\/pseudo\/\" rel=\"nofollow\">\u0441\u043e\u0432\u0435\u0442\u043e\u043c \u041b\u0443<\/a>:<\/p>\n<blockquote><p><em>\u00ab\u0447\u0442\u043e\u0431\u044b \u0438\u0441\u043a\u0440\u0438\u0432\u0438\u0442\u044c \u0434\u043e\u0440\u043e\u0433\u0443, \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u043f\u043e\u0437\u0438\u0446\u0438\u044e \u0446\u0435\u043d\u0442\u0440\u0430\u043b\u044c\u043d\u043e\u0439 \u043b\u0438\u043d\u0438\u0438 \u0444\u043e\u0440\u043c\u044b \u043a\u0440\u0438\u0432\u043e\u0439\u2026 \u043d\u0430\u0447\u0438\u043d\u0430\u044f \u0441 \u043d\u0438\u0437\u0430 \u044d\u043a\u0440\u0430\u043d\u0430, \u0432\u0435\u043b\u0438\u0447\u0438\u043d\u0430 \u0441\u0434\u0432\u0438\u0433\u0430 \u0446\u0435\u043d\u0442\u0440\u0430 \u0434\u043e\u0440\u043e\u0433\u0438 \u0432\u043b\u0435\u0432\u043e \u0438\u043b\u0438 \u0432\u043f\u0440\u0430\u0432\u043e \u043f\u043e\u0441\u0442\u0435\u043f\u0435\u043d\u043d\u043e \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f\u00bb<\/em>.<\/p><\/blockquote>\n<p>  \u0412 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0446\u0435\u043d\u0442\u0440\u0430\u043b\u044c\u043d\u043e\u0439 \u043b\u0438\u043d\u0438\u0435\u0439 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>cameraX<\/code>, \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0435\u043c\u043e\u0435 \u0432 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0435\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f. \u042d\u0442\u043e \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u043a\u043e\u0433\u0434\u0430 \u043c\u044b \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c <code>render()<\/code> \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u0430 \u0434\u043e\u0440\u043e\u0433\u0438, \u043c\u043e\u0436\u043d\u043e \u0438\u043c\u0438\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u0440\u0438\u0432\u044b\u0435, \u0441\u0434\u0432\u0438\u0433\u0430\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>cameraX<\/code> \u043d\u0430 \u043f\u043e\u0441\u0442\u0435\u043f\u0435\u043d\u043d\u043e \u0432\u043e\u0437\u0440\u0430\u0441\u0442\u0430\u044e\u0449\u0443\u044e \u0432\u0435\u043b\u0438\u0447\u0438\u043d\u0443.<\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/c8a\/569\/19e\/c8a56919e67d6f19cc737074ce92fffb.png\"><\/div>\n<p>  \u0427\u0442\u043e\u0431\u044b \u0437\u043d\u0430\u0442\u044c, \u043d\u0430 \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0441\u0434\u0432\u0438\u0433, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0432 \u043a\u0430\u0436\u0434\u043e\u043c \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>curve<\/code>. \u042d\u0442\u0430 \u0432\u0435\u043b\u0438\u0447\u0438\u043d\u0430 \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u043d\u0430 \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u0435\u0433\u043c\u0435\u043d\u0442 \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u0441\u0434\u0432\u0438\u043d\u0443\u0442 \u043e\u0442 \u0446\u0435\u043d\u0442\u0440\u0430\u043b\u044c\u043d\u043e\u0439 \u043b\u0438\u043d\u0438\u0438 \u043a\u0430\u043c\u0435\u0440\u044b. \u041e\u043d\u0430 \u0431\u0443\u0434\u0435\u0442:<\/p>\n<ul>\n<li>\u043e\u0442\u0440\u0438\u0446\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u0434\u043b\u044f \u043f\u043e\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u044e\u0449\u0438\u0445 \u043d\u0430\u043b\u0435\u0432\u043e \u043a\u0440\u0438\u0432\u044b\u0445<\/li>\n<li>\u043f\u043e\u043b\u043e\u0436\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u0434\u043b\u044f \u043f\u043e\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u044e\u0449\u0438\u0445 \u0432\u043f\u0440\u0430\u0432\u043e \u043a\u0440\u0438\u0432\u044b\u0445<\/li>\n<li>\u043c\u0435\u043d\u044c\u0448\u0435 \u0434\u043b\u044f \u043f\u043b\u0430\u0432\u043d\u044b\u0445 \u043a\u0440\u0438\u0432\u044b\u0445<\/li>\n<li>\u0431\u043e\u043b\u044c\u0448\u0435 \u0434\u043b\u044f \u0440\u0435\u0437\u043a\u0438\u0445 \u043a\u0440\u0438\u0432\u044b\u0445<\/li>\n<\/ul>\n<p>  \u0421\u0430\u043c\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0432\u044b\u0431\u0438\u0440\u0430\u044e\u0442\u0441\u044f \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u043e; \u043f\u0443\u0442\u0451\u043c \u043f\u0440\u043e\u0431 \u0438 \u043e\u0448\u0438\u0431\u043e\u043a \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u043e\u0434\u043e\u0431\u0440\u0430\u0442\u044c \u0445\u043e\u0440\u043e\u0448\u0438\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u043f\u0440\u0438 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043a\u0440\u0438\u0432\u044b\u0435 \u043a\u0430\u0436\u0443\u0442\u0441\u044f \u00ab\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u043c\u0438\u00bb:<\/p>\n<pre><code class=\"javascript\">var ROAD = {   LENGTH: { NONE: 0, SHORT:  25, MEDIUM:  50, LONG:  100 }, \/\/ num segments   CURVE:  { NONE: 0, EASY:    2, MEDIUM:   4, HARD:    6 } };<\/code><\/pre>\n<p>  \u041a\u0440\u043e\u043c\u0435 \u043f\u043e\u0434\u0431\u043e\u0440\u0430 \u0445\u043e\u0440\u043e\u0448\u0438\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u0434\u043b\u044f \u043a\u0440\u0438\u0432\u044b\u0445 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0438\u0437\u0431\u0435\u0433\u0430\u0442\u044c \u043b\u044e\u0431\u044b\u0445 \u0440\u0430\u0437\u0440\u044b\u0432\u043e\u0432 \u0432 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430\u0445, \u043a\u043e\u0433\u0434\u0430 \u043f\u0440\u044f\u043c\u0430\u044f \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u0432 \u043a\u0440\u0438\u0432\u0443\u044e (\u0438\u043b\u0438 \u043d\u0430\u043e\u0431\u043e\u0440\u043e\u0442). \u042d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c <a href=\"http:\/\/jqueryui.com\/demos\/effect\/easing.html\" rel=\"nofollow\">\u0441\u043c\u044f\u0433\u0447\u0435\u043d\u0438\u0435\u043c<\/a> \u043f\u0440\u0438 \u0432\u0445\u043e\u0434\u0435 \u0438 \u0432\u044b\u0445\u043e\u0434\u0435 \u0438\u0437 \u043a\u0440\u0438\u0432\u044b\u0445. \u041c\u044b \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u044d\u0442\u043e, \u043f\u043e\u0441\u0442\u0435\u043f\u0435\u043d\u043d\u043e \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u044f (\u0438\u043b\u0438 \u0443\u043c\u0435\u043d\u044c\u0448\u0430\u044f) \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>curve<\/code> \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u0430 \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u0442\u0440\u0430\u0434\u0438\u0446\u0438\u043e\u043d\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u043f\u043b\u0430\u0432\u043d\u043e\u0441\u0442\u0438, \u043f\u043e\u043a\u0430 \u043e\u043d\u043e \u043d\u0435 \u0434\u043e\u0441\u0442\u0438\u0433\u043d\u0435\u0442 \u043d\u0443\u0436\u043d\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f:<\/p>\n<pre><code class=\"javascript\">easeIn:    function(a,b,percent) { return a + (b-a)*Math.pow(percent,2);                           }, easeOut:   function(a,b,percent) { return a + (b-a)*(1-Math.pow(1-percent,2));                     }, easeInOut: function(a,b,percent) { return a + (b-a)*((-Math.cos(percent*Math.PI)\/2) + 0.5);        },<\/code><\/pre>\n<p>  \u0422\u043e \u0435\u0441\u0442\u044c \u0442\u0435\u043f\u0435\u0440\u044c, \u0441 \u0443\u0447\u0451\u0442\u043e\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043e\u0434\u043d\u043e\u0433\u043e \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u0430 \u043a \u0433\u0435\u043e\u043c\u0435\u0442\u0440\u0438\u0438\u2026<\/p>\n<pre><code class=\"javascript\">function addSegment(curve) {   var n = segments.length;   segments.push({      index: n,         p1: { world: { z:  n   *segmentLength }, camera: {}, screen: {} },         p2: { world: { z: (n+1)*segmentLength }, camera: {}, screen: {} },      curve: curve,      color: Math.floor(n\/rumbleLength)%2 ? COLORS.DARK : COLORS.LIGHT   }); }<\/code><\/pre>\n<p>  \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434 \u0434\u043b\u044f \u043f\u043b\u0430\u0432\u043d\u043e\u0433\u043e \u0432\u0445\u043e\u0434\u0430, \u043d\u0430\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u044f \u0438 \u043f\u043b\u0430\u0432\u043d\u043e\u0433\u043e \u0432\u044b\u0445\u043e\u0434\u0430 \u0441 \u0438\u0441\u043a\u0440\u0438\u0432\u043b\u0451\u043d\u043d\u043e\u0439 \u0434\u043e\u0440\u043e\u0433\u0438:<\/p>\n<pre><code class=\"javascript\">function addRoad(enter, hold, leave, curve) {   var n;   for(n = 0 ; n &lt; enter ; n++)     addSegment(Util.easeIn(0, curve, n\/enter));   for(n = 0 ; n &lt; hold  ; n++)     addSegment(curve);   for(n = 0 ; n &lt; leave ; n++)     addSegment(Util.easeInOut(curve, 0, n\/leave)); }<\/code><\/pre>\n<p>  \u2026 \u0430 \u043f\u043e\u0432\u0435\u0440\u0445 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u043b\u043e\u0436\u0438\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u0443\u044e \u0433\u0435\u043e\u043c\u0435\u0442\u0440\u0438\u044e, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, S-\u043e\u0431\u0440\u0430\u0437\u043d\u044b\u0435 \u043a\u0440\u0438\u0432\u044b\u0435:<\/p>\n<pre><code class=\"javascript\">function addSCurves() {   addRoad(ROAD.LENGTH.MEDIUM, ROAD.LENGTH.MEDIUM, ROAD.LENGTH.MEDIUM,  -ROAD.CURVE.EASY);   addRoad(ROAD.LENGTH.MEDIUM, ROAD.LENGTH.MEDIUM, ROAD.LENGTH.MEDIUM,   ROAD.CURVE.MEDIUM);   addRoad(ROAD.LENGTH.MEDIUM, ROAD.LENGTH.MEDIUM, ROAD.LENGTH.MEDIUM,   ROAD.CURVE.EASY);   addRoad(ROAD.LENGTH.MEDIUM, ROAD.LENGTH.MEDIUM, ROAD.LENGTH.MEDIUM,  -ROAD.CURVE.EASY);   addRoad(ROAD.LENGTH.MEDIUM, ROAD.LENGTH.MEDIUM, ROAD.LENGTH.MEDIUM,  -ROAD.CURVE.MEDIUM); }<\/code><\/pre>\n<p>  <\/p>\n<h2>\u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432 \u043c\u0435\u0442\u043e\u0434\u0435 update()<\/h2>\n<p>  \u0415\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0432\u043d\u0435\u0441\u0442\u0438 \u0432 \u043c\u0435\u0442\u043e\u0434 <code>update()<\/code> \u2014 \u044d\u0442\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0441\u0432\u043e\u0435\u0433\u043e \u0440\u043e\u0434\u0430 \u0446\u0435\u043d\u0442\u0440\u043e\u0431\u0435\u0436\u043d\u043e\u0439 \u0441\u0438\u043b\u044b, \u043a\u043e\u0433\u0434\u0430 \u043c\u0430\u0448\u0438\u043d\u0430 \u0434\u0432\u0438\u0436\u0435\u0442\u0441\u044f \u043f\u043e \u043a\u0440\u0438\u0432\u043e\u0439.<\/p>\n<p>  \u041c\u044b \u0437\u0430\u0434\u0430\u0451\u043c \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u044b\u0439 \u043c\u043d\u043e\u0436\u0438\u0442\u0435\u043b\u044c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0442\u044c \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0438 \u0441 \u043d\u0430\u0448\u0438\u043c\u0438 \u043f\u0440\u0435\u0434\u043f\u043e\u0447\u0442\u0435\u043d\u0438\u044f\u043c\u0438.<\/p>\n<pre><code class=\"javascript\">var centrifugal = 0.3;   \/\/ centrifugal force multiplier when going around curves<\/code><\/pre>\n<p>  \u0410 \u0437\u0430\u0442\u0435\u043c \u043c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u0431\u0443\u0434\u0435\u043c \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c \u043f\u043e\u0437\u0438\u0446\u0438\u044e <code>playerX<\/code> \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0430\u043d\u0438\u0438 \u0435\u0433\u043e \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438, \u0432\u0435\u043b\u0438\u0447\u0438\u043d\u044b curve \u0438 \u043c\u043d\u043e\u0436\u0438\u0442\u0435\u043b\u044f \u0446\u0435\u043d\u0442\u0440\u043e\u0431\u0435\u0436\u043d\u043e\u0439 \u0441\u0438\u043b\u044b:<\/p>\n<pre><code class=\"javascript\">playerX = playerX - (dx * speedPercent * playerSegment.curve * centrifugal);<\/code><\/pre>\n<p>  <\/p>\n<h2>\u0420\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433 \u043a\u0440\u0438\u0432\u044b\u0445<\/h2>\n<p>  \u0412\u044b\u0448\u0435 \u043c\u044b \u0433\u043e\u0432\u043e\u0440\u0438\u043b\u0438, \u0447\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u0442\u044c \u0438\u043c\u0438\u0442\u0438\u0440\u0443\u0435\u043c\u044b\u0435 \u043a\u0440\u0438\u0432\u044b\u0435, \u0441\u043c\u0435\u0449\u0430\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>cameraX<\/code>, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u043e\u0435 \u0432 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f\u0445 \u043f\u0440\u043e\u0435\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f <code>render()<\/code> \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u0430 \u0434\u043e\u0440\u043e\u0433\u0438.<\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/c8a\/569\/19e\/c8a56919e67d6f19cc737074ce92fffb.png\"><\/div>\n<p>  \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u043d\u0430\u043a\u043e\u043f\u0438\u0442\u0435\u043b\u044f <strong>dx<\/strong>, \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u044e\u0449\u0443\u044e\u0441\u044f \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u0430 \u043d\u0430 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>curve<\/code>, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e <strong>x<\/strong>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043a\u0430\u043a \u0441\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f <code>cameraX<\/code>, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u043e\u0433\u043e \u0432 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f\u0445 \u043f\u0440\u043e\u0435\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f.<\/p>\n<p>  \u0414\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043a\u0440\u0438\u0432\u044b\u0445 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<ul>\n<li>\u0441\u043c\u0435\u0449\u0430\u0435\u043c \u043f\u0440\u043e\u0435\u043a\u0446\u0438\u044e <strong>p1<\/strong> \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u0430 \u043d\u0430 <strong>x<\/strong><\/li>\n<li>\u0441\u043c\u0435\u0449\u0430\u0435\u043c \u043f\u0440\u043e\u0435\u043a\u0446\u0438\u044e <strong>p2<\/strong> \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u0430 \u043d\u0430 <strong>x<\/strong> + <strong>dx<\/strong><\/li>\n<li>\u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u043c <strong>x<\/strong> \u0434\u043b\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u0430 \u043d\u0430 <strong>dx<\/strong><\/li>\n<\/ul>\n<p>  \u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u0447\u0442\u043e\u0431\u044b \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u0440\u0432\u0430\u043d\u044b\u0445 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u043e\u0432 \u043f\u0440\u0438 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u0438 \u0433\u0440\u0430\u043d\u0438\u0446 \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u043e\u0432, \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b <strong>dx<\/strong> \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043b\u0430\u0441\u044c \u0438\u043d\u0442\u0435\u0440\u043f\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c \u043a\u0440\u0438\u0432\u043e\u0439 \u0442\u0435\u043a\u0443\u0449\u0438\u0445 \u0431\u0430\u0437\u043e\u0432\u044b\u0445 \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u043e\u0432.<\/p>\n<p>  \u0418\u0437\u043c\u0435\u043d\u0438\u043c \u043c\u0435\u0442\u043e\u0434 <code>render()<\/code> \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code class=\"javascript\">var baseSegment = findSegment(position); var basePercent = Util.percentRemaining(position, segmentLength); var dx = - (baseSegment.curve * basePercent); var x  = 0; for(n = 0 ; n &lt; drawDistance ; n++) {    ...    Util.project(segment.p1, (playerX * roadWidth) - x,      cameraHeight, position - (segment.looped ? trackLength : 0), cameraDepth, width, height, roadWidth);   Util.project(segment.p2, (playerX * roadWidth) - x - dx, cameraHeight, position - (segment.looped ? trackLength : 0), cameraDepth, width, height, roadWidth);    x  = x + dx;   dx = dx + segment.curve;    ... }<\/code><\/pre>\n<p>  <\/p>\n<h2>\u0424\u043e\u043d \u0441 \u043f\u0430\u0440\u0430\u043b\u043b\u0430\u043a\u0441\u043d\u044b\u043c \u0441\u043a\u0440\u043e\u043b\u043b\u0438\u043d\u0433\u043e\u043c<\/h2>\n<p>  \u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0441\u043a\u0440\u043e\u043b\u043b\u0438\u043d\u0433 \u043f\u0430\u0440\u0430\u043b\u043b\u0430\u043a\u0441\u043d\u044b\u0445 \u0441\u043b\u043e\u0451\u0432 \u0444\u043e\u043d\u0430, \u0445\u0440\u0430\u043d\u044f \u0441\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0441\u043b\u043e\u044f\u2026<\/p>\n<pre><code class=\"javascript\">var skySpeed    = 0.001; \/\/ background sky layer scroll speed when going around curve (or up hill) var hillSpeed   = 0.002; \/\/ background hill layer scroll speed when going around curve (or up hill) var treeSpeed   = 0.003; \/\/ background tree layer scroll speed when going around curve (or up hill) var skyOffset   = 0;     \/\/ current sky scroll offset var hillOffset  = 0;     \/\/ current hill scroll offset var treeOffset  = 0;     \/\/ current tree scroll offset<\/code><\/pre>\n<p>  \u2026 \u0438 \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u044f \u0435\u0433\u043e \u0432\u043e \u0432\u0440\u0435\u043c\u044f <code>update()<\/code> \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0432\u0435\u043b\u0438\u0447\u0438\u043d\u044b curve \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u0430 \u0438\u0433\u0440\u043e\u043a\u0430 \u0438 \u0435\u0433\u043e \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438\u2026<\/p>\n<pre><code class=\"javascript\">skyOffset  = Util.increase(skyOffset,  skySpeed  * playerSegment.curve * speedPercent, 1); hillOffset = Util.increase(hillOffset, hillSpeed * playerSegment.curve * speedPercent, 1); treeOffset = Util.increase(treeOffset, treeSpeed * playerSegment.curve * speedPercent, 1);<\/code><\/pre>\n<p>  \u2026 \u0430 \u0437\u0430\u0442\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u043e \u0441\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u043f\u0440\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0438 <code>render()<\/code> \u0441\u043b\u043e\u0451\u0432 \u0444\u043e\u043d\u0430.<\/p>\n<pre><code class=\"javascript\">Render.background(ctx, background, width, height, BACKGROUND.SKY,   skyOffset); Render.background(ctx, background, width, height, BACKGROUND.HILLS, hillOffset); Render.background(ctx, background, width, height, BACKGROUND.TREES, treeOffset);<\/code><\/pre>\n<p>  <\/p>\n<h2>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h2>\n<p>  \u0418\u0442\u0430\u043a, \u0432\u043e\u0442 \u043c\u044b \u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u0444\u0430\u043b\u044c\u0448\u0438\u0432\u044b\u0435 \u043f\u0441\u0435\u0432\u0434\u043e\u0442\u0440\u0451\u0445\u043c\u0435\u0440\u043d\u044b\u0435 \u043a\u0440\u0438\u0432\u044b\u0435:<\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/98f\/c3d\/6d1\/98fc3d6d13cc16f12847d253e112fcb2.png\"><\/div>\n<p>  \u041e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u043d\u0430\u043c\u0438 \u043a\u043e\u0434\u0430 \u0437\u0430\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u0438 \u0433\u0435\u043e\u043c\u0435\u0442\u0440\u0438\u0438 \u0434\u043e\u0440\u043e\u0433\u0438 \u0441 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c <code>curve<\/code>. \u0420\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0432 \u0435\u0451, \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0446\u0435\u043d\u0442\u0440\u043e\u0431\u0435\u0436\u043d\u0443\u044e \u0441\u0438\u043b\u0443 \u0432\u043e \u0432\u0440\u0435\u043c\u044f <code>update()<\/code> \u043d\u0430\u043c\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0449\u0435.<\/p>\n<p>  \u0420\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433 \u043a\u0440\u0438\u0432\u044b\u0445 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0432\u0441\u0435\u0433\u043e \u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0441\u0442\u0440\u043e\u043a\u0430\u0445 \u043a\u043e\u0434\u0430, \u043d\u043e \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0441\u043b\u043e\u0436\u043d\u043e \u043f\u043e\u043d\u044f\u0442\u044c (\u0438 \u043e\u043f\u0438\u0441\u0430\u0442\u044c), \u0447\u0442\u043e \u0436\u0435 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e \u0437\u0434\u0435\u0441\u044c \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442. \u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u0432 \u0438\u043c\u0438\u0442\u0430\u0446\u0438\u0438 \u043a\u0440\u0438\u0432\u044b\u0445 \u0438 \u043e\u0447\u0435\u043d\u044c \u043b\u0435\u0433\u043a\u043e \u0437\u0430\u0431\u0440\u0435\u0441\u0442\u0438 \u043f\u0440\u0438 \u0438\u0445 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0432 \u0442\u0443\u043f\u0438\u043a. \u0415\u0449\u0451 \u043f\u0440\u043e\u0449\u0435 \u0443\u0432\u043b\u0435\u0447\u044c\u0441\u044f \u043f\u043e\u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0435\u0439 \u0437\u0430\u0434\u0430\u0447\u0435\u0439 \u0438 \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0432\u0441\u0451 \u00ab\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u00bb; \u043f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u0443\u0441\u043f\u0435\u0435\u0442\u0435 \u043e\u0441\u043e\u0437\u043d\u0430\u0442\u044c \u044d\u0442\u043e, \u0432\u044b \u043d\u0430\u0447\u043d\u0451\u0442\u0435 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043f\u043e\u043b\u043d\u043e\u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u0443\u044e 3d-\u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0441 \u043c\u0430\u0442\u0440\u0438\u0446\u0430\u043c\u0438, \u043f\u043e\u0432\u043e\u0440\u043e\u0442\u0430\u043c\u0438 \u0438 \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0435\u0439 3d-\u0433\u0435\u043e\u043c\u0435\u0442\u0440\u0438\u0435\u0439\u2026 \u043a\u043e\u0442\u043e\u0440\u044b\u0435, \u043a\u0430\u043a \u044f \u0441\u043a\u0430\u0437\u0430\u043b, \u043d\u0435 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043d\u0430\u0448\u0435\u0439 \u0437\u0430\u0434\u0430\u0447\u0435\u0439.<\/p>\n<p>  \u041f\u0440\u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u0438 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438 \u044f \u0431\u044b\u043b \u0443\u0432\u0435\u0440\u0435\u043d, \u0447\u0442\u043e \u0432 \u043c\u043e\u0435\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043a\u0440\u0438\u0432\u044b\u0445 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u043e \u0435\u0441\u0442\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b. \u041f\u044b\u0442\u0430\u044f\u0441\u044c \u0432\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c, \u044f \u043d\u0435 \u043f\u043e\u043d\u0438\u043c\u0430\u043b, \u0437\u0430\u0447\u0435\u043c \u043c\u043d\u0435 \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u043b\u0438\u0441\u044c \u0434\u0432\u0430 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043d\u0430\u043a\u043e\u043f\u0438\u0442\u0435\u043b\u0435\u0439 <strong>dx<\/strong> \u0438 <strong>x<\/strong> \u0432\u043c\u0435\u0441\u0442\u043e \u043e\u0434\u043d\u043e\u0433\u043e\u2026 \u0430 \u0435\u0441\u043b\u0438 \u044f \u043d\u0435 \u043c\u043e\u0433\u0443 \u0447\u0435\u0433\u043e-\u0442\u043e \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u043e\u0431\u044a\u044f\u0441\u043d\u0438\u0442\u044c, \u0442\u043e \u0433\u0434\u0435-\u0442\u043e \u0447\u0442\u043e-\u0442\u043e \u043f\u043e\u0448\u043b\u043e \u043d\u0435 \u0442\u0430\u043a\u2026<\/p>\n<p>  \u2026 \u043d\u043e \u0432\u0440\u0435\u043c\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u043d\u0430\u0434 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u043c <em>\u00ab\u043d\u0430 \u0432\u044b\u0445\u043e\u0434\u043d\u044b\u0435\u00bb<\/em> \u043f\u043e\u0447\u0442\u0438 \u0438\u0441\u0442\u0435\u043a\u043b\u043e, \u0438, \u0447\u0435\u0441\u0442\u043d\u043e \u0433\u043e\u0432\u043e\u0440\u044f, \u043a\u0440\u0438\u0432\u044b\u0435 \u043a\u0430\u0436\u0443\u0442\u0441\u044f \u043c\u043d\u0435 \u0432\u043f\u043e\u043b\u043d\u0435 \u043a\u0440\u0430\u0441\u0438\u0432\u044b\u043c\u0438, \u0438 \u0432 \u043a\u043e\u043d\u0435\u0447\u043d\u043e\u043c \u0438\u0442\u043e\u0433\u0435, \u044d\u0442\u043e \u0441\u0430\u043c\u043e\u0435 \u0432\u0430\u0436\u043d\u043e\u0435.<\/div>\n<p> \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\/499252\/\"> https:\/\/habr.com\/ru\/post\/499252\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"\n<div class=\"post__text post__text-html post__text_v1\" id=\"post-content-body\" data-io-article-url=\"https:\/\/habr.com\/ru\/post\/499252\/\">\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/d16\/6e3\/cff\/d166e3cff9c2a3cefeb68f5c1ddc02d1.jpg\"><\/div>\n<p>  \u0412 \u0434\u0435\u0442\u0441\u0442\u0432\u0435 \u044f \u0440\u0435\u0434\u043a\u043e \u0445\u043e\u0434\u0438\u043b \u0432 \u0437\u0430\u043b\u044b \u0430\u0440\u043a\u0430\u0434\u043d\u044b\u0445 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u043e\u0432, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043e\u0441\u043e\u0431\u043e \u0432 \u043d\u0438\u0445 \u043d\u0435 \u043d\u0443\u0436\u0434\u0430\u043b\u0441\u044f, \u0432\u0435\u0434\u044c \u0434\u043e\u043c\u0430 \u0443 \u043c\u0435\u043d\u044f \u0431\u044b\u043b\u0438 \u043f\u043e\u0442\u0440\u044f\u0441\u0430\u044e\u0449\u0438\u0435 \u0438\u0433\u0440\u044b \u0434\u043b\u044f C64\u2026 \u043d\u043e \u0435\u0441\u0442\u044c \u0442\u0440\u0438 \u0430\u0440\u043a\u0430\u0434\u043d\u044b\u0435 \u0438\u0433\u0440\u044b, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0443 \u043c\u0435\u043d\u044f \u0432\u0441\u0435\u0433\u0434\u0430 \u043d\u0430\u0445\u043e\u0434\u0438\u043b\u0438\u0441\u044c \u0434\u0435\u043d\u044c\u0433\u0438 \u2014 Donkey Kong, Dragons Lair \u0438 Outrun\u2026<\/p>\n<p>  \u2026 \u0438 \u044f \u043e\u0447\u0435\u043d\u044c \u043b\u044e\u0431\u0438\u043b Outrun \u2014 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c, \u0445\u043e\u043b\u043c\u044b, \u043f\u0430\u043b\u044c\u043c\u044b \u0438 \u043c\u0443\u0437\u044b\u043a\u0430, \u0434\u0430\u0436\u0435 \u043d\u0430 \u0441\u043b\u0430\u0431\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 \u0434\u043b\u044f C64.<\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/48e\/aee\/56f\/48eaee56f43d8a25e840c6ae13268db4.gif\"><\/div>\n<p>  \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u044f \u0440\u0435\u0448\u0438\u043b \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043e\u043b\u0434\u0441\u043a\u0443\u043b\u044c\u043d\u0443\u044e \u043f\u0441\u0435\u0432\u0434\u043e\u0442\u0440\u0451\u0445\u043c\u0435\u0440\u043d\u0443\u044e \u0433\u043e\u043d\u043e\u0447\u043d\u0443\u044e \u0438\u0433\u0440\u0443 \u0432 \u0441\u0442\u0438\u043b\u0435 Outrun, Pitstop \u0438\u043b\u0438 Pole position. \u042f \u043d\u0435 \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u044e \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u043f\u043e\u043b\u043d\u0443\u044e \u0438 <a href=\"https:\/\/codeincomplete.com\/articles\/defining-finished\" rel=\"nofollow\">\u0437\u0430\u0432\u0435\u0440\u0448\u0451\u043d\u043d\u0443\u044e<\/a> \u0438\u0433\u0440\u0443, \u043d\u043e \u043c\u043d\u0435 \u043a\u0430\u0436\u0435\u0442\u0441\u044f, \u0431\u0443\u0434\u0435\u0442 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e \u0437\u0430\u043d\u043e\u0432\u043e \u0438\u0437\u0443\u0447\u0438\u0442\u044c \u043c\u0435\u0445\u0430\u043d\u0438\u043a\u0438, \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u044d\u0442\u0438 \u0438\u0433\u0440\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u043b\u0438 \u0441\u0432\u043e\u0438 \u0442\u0440\u044e\u043a\u0438. \u041a\u0440\u0438\u0432\u044b\u0435, \u0445\u043e\u043b\u043c\u044b, \u0441\u043f\u0440\u0430\u0439\u0442\u044b \u0438 \u043e\u0449\u0443\u0449\u0435\u043d\u0438\u0435 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438\u2026<\/p>\n<p>  \u0418\u0442\u0430\u043a, \u0432\u043e\u0442 \u043c\u043e\u0439 \u00ab\u043f\u0440\u043e\u0435\u043a\u0442 \u043d\u0430 \u0432\u044b\u0445\u043e\u0434\u043d\u044b\u0435\u00bb, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432 \u0438\u0442\u043e\u0433\u0435 \u0437\u0430\u043d\u044f\u043b \u043f\u044f\u0442\u044c \u0438\u043b\u0438 \u0448\u0435\u0441\u0442\u044c \u043d\u0435\u0434\u0435\u043b\u044c \u043f\u043e \u0432\u044b\u0445\u043e\u0434\u043d\u044b\u043c<\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/7ec\/27b\/d28\/7ec27bd28630dbbaf7b81c87233c28ac.png\"><\/div>\n<p>  <\/p>\n<ul>\n<li><a href=\"https:\/\/codeincomplete.com\/games\/racer\" rel=\"nofollow\">\u0421\u044b\u0433\u0440\u0430\u0442\u044c \u0432 \u0438\u0433\u0440\u0443<\/a><\/li>\n<li>\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c <a href=\"https:\/\/github.com\/jakesgordon\/javascript-racer\/\" rel=\"nofollow\">\u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434<\/a><\/li>\n<\/ul>\n<p>  \u0418\u0433\u0440\u0430\u0431\u0435\u043b\u044c\u043d\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u0435\u0442 \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0434\u0435\u043c\u043e, \u0447\u0435\u043c \u0440\u0435\u0430\u043b\u044c\u043d\u0443\u044e \u0438\u0433\u0440\u0443. \u041d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435, \u0435\u0441\u043b\u0438 \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0443\u044e \u043f\u0441\u0435\u0432\u0434\u043e\u0442\u0440\u0451\u0445\u043c\u0435\u0440\u043d\u0443\u044e \u0433\u043e\u043d\u043a\u0443, \u0442\u043e \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0441\u0430\u043c\u044b\u0439 \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u0430\u044f \u043e\u0441\u043d\u043e\u0432\u0430, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u0441\u0442\u0435\u043f\u0435\u043d\u043d\u043e \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u0438\u0442\u044c \u0432 \u0438\u0433\u0440\u0443.<\/p>\n<p>  \u041e\u043d\u0430 \u043d\u0435 \u043e\u0442\u0448\u043b\u0438\u0444\u043e\u0432\u0430\u043d\u0430, \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0443\u0440\u043e\u0434\u043b\u0438\u0432\u0430, \u043d\u043e \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u0430. \u042f \u043f\u043e\u043a\u0430\u0436\u0443, \u043a\u0430\u043a \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0435\u0451 \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e \u0437\u0430 \u0447\u0435\u0442\u044b\u0440\u0435 \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u0448\u0430\u0433\u0430.<\/p>\n<p>  \u041c\u043e\u0436\u043d\u043e \u0442\u0430\u043a\u0436\u0435 \u043f\u043e\u0438\u0433\u0440\u0430\u0442\u044c<\/p>\n<ul>\n<li>\u0432 <a href=\"https:\/\/codeincomplete.com\/games\/racer\/v1-straight\" rel=\"nofollow\">\u0434\u0435\u043c\u043e \u0441 \u043f\u0440\u044f\u043c\u043e\u0439 \u0434\u043e\u0440\u043e\u0433\u043e\u0439<\/a><\/li>\n<li>\u0432 <a href=\"https:\/\/codeincomplete.com\/games\/racer\/v2-curves\" rel=\"nofollow\">\u0434\u0435\u043c\u043e \u0441 \u043a\u0440\u0438\u0432\u044b\u043c\u0438<\/a><\/li>\n<li>\u0432 <a href=\"https:\/\/codeincomplete.com\/games\/racer\/v3-hills\" rel=\"nofollow\">\u0434\u0435\u043c\u043e \u0441 \u0445\u043e\u043b\u043c\u0430\u043c\u0438<\/a><\/li>\n<li>\u0432 <a href=\"https:\/\/codeincomplete.com\/games\/racer\" rel=\"nofollow\">\u0433\u043e\u0442\u043e\u0432\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e<\/a><\/li>\n<\/ul>\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-302717","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/302717","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=302717"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/302717\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=302717"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=302717"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=302717"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}