{"id":350658,"date":"2023-07-23T09:00:41","date_gmt":"2023-07-23T09:00:41","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=350658"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=350658","title":{"rendered":"<span>Ray Casting 3D \u0438\u0433\u0440\u0430 \u043d\u0430 Python + PyGame<\/span>"},"content":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<h2>\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435<\/h2>\n<p>\u0412\u0441\u0435 \u043c\u044b \u043f\u043e\u043c\u043d\u0438\u043c \u0441\u0442\u0430\u0440\u044b\u0435 \u0438\u0433\u0440\u044b, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0432\u043f\u0435\u0440\u0432\u044b\u0435 \u043f\u043e\u044f\u0432\u0438\u043b\u043e\u0441\u044c \u0442\u0440\u0435\u0445\u043c\u0435\u0440\u043d\u043e\u0435 \u0438\u0437\u043c\u0435\u0440\u0435\u043d\u0438\u0435.<\/p>\n<p>\u041e\u0441\u043d\u043e\u0432\u043e\u043f\u043e\u043b\u043e\u0436\u043d\u0438\u043a\u043e\u043c 3\u0434 \u0438\u0433\u0440 \u0441\u0442\u0430\u043b\u0430 \u0438\u0433\u0440\u0430 <strong><em>Wolfenstein 3D,<\/em><\/strong> \u0432\u044b\u043f\u0443\u0449\u0435\u043d\u043d\u0430\u044f \u0432 1992 \u0433\u043e\u0434\u0443<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/683\/eb7\/bc1\/683eb7bc1af3e70557f81910f8901f03.png\" alt=\"\u0418\u0433\u0440\u0430 Wolfenstein 3D (1992 \u0433\u043e\u0434)\" title=\"\u0418\u0433\u0440\u0430 Wolfenstein 3D (1992 \u0433\u043e\u0434)\" width=\"319\" height=\"239\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/683\/eb7\/bc1\/683eb7bc1af3e70557f81910f8901f03.png\"\/><\/p>\n<div><figcaption>\u0418\u0433\u0440\u0430 Wolfenstein 3D (1992 \u0433\u043e\u0434)<\/figcaption><\/div>\n<\/figure>\n<p>\u0430 \u0437\u0430 \u043d\u0435\u0439 \u0438 <strong><em>Doom 1993<\/em><\/strong> \u0433\u043e\u0434\u0430.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/826\/692\/d33\/826692d335d936a5b9ac39beabc73b3f.png\" alt=\"\u0418\u0433\u0440\u0430 DOOM 1993 (1993)\" title=\"\u0418\u0433\u0440\u0430 DOOM 1993 (1993)\" width=\"1399\" height=\"787\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/826\/692\/d33\/826692d335d936a5b9ac39beabc73b3f.png\"\/><\/p>\n<div><figcaption>\u0418\u0433\u0440\u0430 DOOM 1993 (1993)<\/figcaption><\/div>\n<\/figure>\n<p>\u042d\u0442\u0438 \u0434\u0432\u0435 \u0438\u0433\u0440\u044b \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0430 \u043e\u0434\u043d\u0430 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u044f: <em>\u00abid Software\u00bb<\/em><\/p>\n<p>\u041e\u043d\u0430 \u0441\u043e\u0437\u0434\u0430\u043b\u0430 \u0441\u0432\u043e\u0439 \u0434\u0432\u0438\u0436\u043e\u043a \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e \u0434\u043b\u044f \u044d\u0442\u043e\u0439 \u0438\u0433\u0440\u044b, \u0438 \u0432 \u0438\u0442\u043e\u0433\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0430\u0441\u044c 3\u0434 \u0438\u0433\u0440\u0430, \u0447\u0442\u043e \u0441\u0447\u0438\u0442\u0430\u043b\u043e\u0441\u044c \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u043c \u043d\u0430 \u0442\u0435 \u0432\u0440\u0435\u043c\u0435\u043d\u0430. <\/p>\n<p>\u041d\u043e \u0447\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0435\u0441\u043b\u0438 \u044f \u0441\u043a\u0430\u0436\u0443 \u0447\u0442\u043e \u044d\u0442\u043e \u043d\u0435 3\u0434 \u0438\u0433\u0440\u0430, \u0430 \u0432\u0441\u0435\u0433\u043e \u043b\u0438\u0448\u044c \u0441\u0438\u043c\u0443\u043b\u044f\u0446\u0438\u044f \u0438 \u0438\u0433\u0440\u0430 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0432\u043e\u0442 \u0442\u0430\u043a? <\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/896\/fa0\/a3c\/896fa0a3cf4869716ae3423ff4fe7405.png\" alt=\"\u0418\u0433\u0440\u0430 Wolfenstein 3D \u0438\u0437\u043d\u0443\u0442\u0440\u0438\" title=\"\u0418\u0433\u0440\u0430 Wolfenstein 3D \u0438\u0437\u043d\u0443\u0442\u0440\u0438\" width=\"805\" height=\"604\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/896\/fa0\/a3c\/896fa0a3cf4869716ae3423ff4fe7405.png\"\/><\/p>\n<div><figcaption>\u0418\u0433\u0440\u0430 Wolfenstein 3D \u0438\u0437\u043d\u0443\u0442\u0440\u0438<\/figcaption><\/div>\n<\/figure>\n<p>\u041d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u0437\u0434\u0435\u0441\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u044f <strong>Ray Casting<\/strong>, \u0442\u0440\u0435\u0442\u044c\u0435\u0433\u043e \u0438\u0437\u043c\u0435\u0440\u0435\u043d\u0438\u044f \u0442\u0443\u0442 \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442.<\/p>\n<p>\u0427\u0442\u043e \u0436\u0435 \u0442\u0430\u043a\u043e\u0435 \u044d\u0442\u043e\u0442 \u0441\u0430\u043c\u044b\u0439 RayCasting, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u0430\u0436\u0435 \u0432 \u043d\u0430\u0448\u0438 \u0432\u0440\u0435\u043c\u0435\u043d\u0430 \u0430\u043a\u0442\u0443\u0430\u043b\u0435\u043d, \u043d\u043e \u0443\u0436\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043d\u0435 \u0434\u043b\u044f \u0438\u0433\u0440, \u0430 \u0434\u043b\u044f \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0438 \u0442\u0440\u0430\u0441\u0441\u0438\u0440\u043e\u0432\u043a\u0438 \u043b\u0443\u0447\u0435\u0439 \u0432 \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0438\u0433\u0440\u0430\u0445.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0438\u0442\u044c \u043d\u0430 \u0440\u0443\u0441\u0441\u043a\u0438\u0439, \u0442\u043e:<\/p>\n<blockquote>\n<p><strong>\u041c\u0435\u0442\u043e\u0434 \u0431\u0440\u043e\u0441\u0430\u043d\u0438\u044f \u043b\u0443\u0447\u0435\u0439<em>(Ray Casting)<\/em><\/strong> &#8212; <em>\u043e\u0434\u0438\u043d \u0438\u0437 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 \u0432 \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440\u043d\u043e\u0439 \u0433\u0440\u0430\u0444\u0438\u043a\u0435, \u043f\u0440\u0438 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0441\u0446\u0435\u043d\u0430 \u0441\u0442\u0440\u043e\u0438\u0442\u0441\u044f \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0437\u0430\u043c\u0435\u0440\u043e\u0432 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u044f \u043b\u0443\u0447\u0435\u0439 \u0441 \u0432\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c\u043e\u0439 \u043f\u043e\u0432\u0435\u0440\u0445\u043d\u043e\u0441\u0442\u044c\u044e.<\/em><\/p>\n<\/blockquote>\n<p><em>\u041c\u043d\u0435 \u0441\u0442\u0430\u043b\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e \u043d\u0430 \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u044d\u0442\u043e \u0441\u043b\u043e\u0436\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c.<\/em><\/p>\n<p>\u0418 \u044f \u043f\u0440\u0438\u043d\u044f\u043b\u0441\u044f \u0437\u0430 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0438 <strong>RayCasting<\/strong>.<\/p>\n<p>\u0411\u0443\u0434\u0443 \u0434\u0435\u043b\u0430\u0442\u044c \u0435\u0433\u043e \u043d\u0430 \u0441\u0432\u044f\u0437\u043a\u0435 <strong>python + pygame<\/strong><\/p>\n<p>Pygame \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0440\u0438\u0441\u043e\u0432\u0430\u0442\u044c \u043d\u0430 \u043f\u043b\u043e\u0441\u043a\u043e\u0441\u0442\u0438 \u043f\u0440\u043e\u0441\u0442\u044b\u0435 2D \u0444\u0438\u0433\u0443\u0440\u044b, \u0438 \u043f\u0443\u0442\u0435\u043c \u0442\u0430\u043d\u0446\u0430\u043c\u0438 \u0441 \u0431\u0443\u0431\u043d\u043e\u043c \u0432\u043e\u043a\u0440\u0443\u0433 \u043d\u0438\u0445 \u044f \u0438 \u0431\u0443\u0434\u0443 \u0434\u0435\u043b\u0430\u0442\u044c 3D \u0438\u043b\u043b\u044e\u0437\u0438\u044e<\/p>\n<h2>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f Ray Casting<\/h2>\n<p>\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0443\u044e \u043a\u0430\u0440\u0442\u0443 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432, \u0447\u0442\u043e\u0431\u044b \u0440\u0430\u0437\u0434\u0435\u043b\u044f\u0442\u044c \u043f\u0440\u0438 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0435 \u0433\u0434\u0435 \u0431\u043b\u043e\u043a \u0430 \u0433\u0434\u0435 \u043f\u0443\u0441\u0442\u043e\u0435 \u043c\u0435\u0441\u0442\u043e.<\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/62f\/bff\/22d\/62fbff22d34141789db3d560d0246b0d.png\" alt=\"\u041a\u0430\u0440\u0442\u0430 \u0438 \u0438\u0433\u0440\u043e\u043a \u043d\u0430 \u043d\u0435\u0439 (\u043f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c)&quot;.&quot; - \u043f\u0443\u0441\u0442\u043e\u0435 \u043c\u0435\u0441\u0442\u043e, \u0433\u0434\u0435 \u043c\u043e\u0436\u0435\u0442 \u0445\u043e\u0434\u0438\u0442\u044c \u0438\u0433\u0440\u043e\u043a&quot;1&quot; - \u0431\u043b\u043e\u043a\" title=\"\u041a\u0430\u0440\u0442\u0430 \u0438 \u0438\u0433\u0440\u043e\u043a \u043d\u0430 \u043d\u0435\u0439 (\u043f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c)&quot;.&quot; - \u043f\u0443\u0441\u0442\u043e\u0435 \u043c\u0435\u0441\u0442\u043e, \u0433\u0434\u0435 \u043c\u043e\u0436\u0435\u0442 \u0445\u043e\u0434\u0438\u0442\u044c \u0438\u0433\u0440\u043e\u043a&quot;1&quot; - \u0431\u043b\u043e\u043a\" width=\"492\" height=\"507\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/62f\/bff\/22d\/62fbff22d34141789db3d560d0246b0d.png\"\/><\/p>\n<div><figcaption>\u041a\u0430\u0440\u0442\u0430 \u0438 \u0438\u0433\u0440\u043e\u043a \u043d\u0430 \u043d\u0435\u0439 <em>(\u043f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c)<\/em><br \/><strong>&#171;.&#187;<\/strong> &#8212; \u043f\u0443\u0441\u0442\u043e\u0435 \u043c\u0435\u0441\u0442\u043e, \u0433\u0434\u0435 \u043c\u043e\u0436\u0435\u0442 \u0445\u043e\u0434\u0438\u0442\u044c \u0438\u0433\u0440\u043e\u043a<br \/><strong>&#171;1&#187;<\/strong> &#8212; \u0431\u043b\u043e\u043a<\/figcaption><\/div>\n<\/figure>\n<p>\u0420\u0438\u0441\u0443\u0435\u043c \u043a\u0430\u0440\u0442\u0443 \u0432 2D, \u0438 \u0438\u0433\u0440\u043e\u043a\u0430 \u0441 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c\u044e \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0438 \u0440\u0430\u0441\u0447\u0435\u0442\u043e\u043c \u0442\u043e\u0447\u043a\u0438 \u0432\u0437\u0433\u043b\u044f\u0434\u0430.<\/p>\n<pre><code class=\"python\">player.delta = delta_time() player.move(enableMoving)  display.fill((0, 0, 0))  pg.draw.circle(display, pg.Color(\"yellow\"), (player.x, player.y), 0)  drawing.world(player)<\/code><\/pre>\n<pre><code class=\"python\">class Drawing:     def __init__(self, surf, surf_map):         self.surf = surf         self.surf_map = surf_map         self.font = pg.font.SysFont('Arial', 25, bold=True)               def world(self, player):         rayCasting(self.surf, player) <\/code><\/pre>\n<pre><code class=\"python\">def rayCasting(display, player):     inBlockPos = {'left': player.x - player.x \/\/ blockSize * blockSize,                   'right': blockSize - (player.x - player.x \/\/ blockSize * blockSize),                   'top': player.y - player.y \/\/ blockSize * blockSize,                   'bottom': blockSize - (player.y - player.y \/\/ blockSize * blockSize)}      for ray in range(numRays):         cur_angle = player.angle - halfFOV + deltaRays * ray         cos_a, sin_a = cos(cur_angle), sin(cur_angle)         vl, hl = 0, 0<\/code><\/pre>\n<p>\u0414\u0432\u0438\u0436\u0435\u043d\u0438\u0435 \u0431\u0443\u0434\u0435\u0442 \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u043f\u0443\u0442\u0435\u043c \u0441\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043a\u043e\u0441\u0438\u043d\u0443\u0441\u0430 \u0443\u0433\u043b\u0430 \u0437\u0440\u0435\u043d\u0438\u044f \u043f\u043e \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u0438 \u0438 \u0441\u0438\u043d\u0443\u0441\u0430 \u0443\u0433\u043b\u0430 \u0437\u0440\u0435\u043d\u0438\u044f \u043f\u043e \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u0438<\/p>\n<pre><code class=\"python\">class Player:    def init(self)     self.x = 0     self.y = 0     self.angle = 0     self.delta = 0     self.speed = 100     self.mouse_sense = settings.mouse_sensivity    def move(self, active):     self.rect.center = self.x, self.y     key = pygame.key.get_pressed()     key2 = pygame.key.get_pressed()     cos_a, sin_a = cos(self.angle), sin(self.angle)      if key2[pygame.K_LSHIFT]:         self.speed += 5         if self.speed >= 200:             self.speed = 200     else:         self.speed = 100      if key[pygame.K_w]:         dx = cos_a * self.delta * self.speed         dy = sin_a * self.delta * self.speed     if key[pygame.K_s]:         dx = cos_a * self.delta * -self.speed         dy = sin_a * self.delta * -self.speed     if key[pygame.K_a]:         dx = sin_a * self.delta * self.speed         dy = cos_a * self.delta * -self.speed     if key[pygame.K_d]:         dx = sin_a * self.delta * -self.speed         dy = cos_a * self.delta * self.speed<\/code><\/pre>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/b9d\/589\/ead\/b9d589ead7f8523513701674a88ed0a0.png\" alt=\"\u0412\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0440\u0430\u0441\u0447\u0435\u0442\u0430 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f \u0438\u0433\u0440\u043e\u043a\u0430\" title=\"\u0412\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0440\u0430\u0441\u0447\u0435\u0442\u0430 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f \u0438\u0433\u0440\u043e\u043a\u0430\" width=\"781\" height=\"527\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/b9d\/589\/ead\/b9d589ead7f8523513701674a88ed0a0.png\"\/><\/p>\n<div><figcaption>\u0412\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0440\u0430\u0441\u0447\u0435\u0442\u0430 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f \u0438\u0433\u0440\u043e\u043a\u0430<\/figcaption><\/div>\n<\/figure>\n<p>\u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0442\u0430\u043a\u043e\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/a48\/753\/5b2\/a487535b2ec49e721edb5912222eba72.png\" alt=\"\u041f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0438\u0433\u0440\u044b\" title=\"\u041f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0438\u0433\u0440\u044b\" width=\"986\" height=\"578\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/a48\/753\/5b2\/a487535b2ec49e721edb5912222eba72.png\"\/><\/p>\n<div><figcaption>\u041f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0438\u0433\u0440\u044b<\/figcaption><\/div>\n<\/figure>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043d\u0430\u0448\u0443 \u043a\u0430\u0440\u0442\u0443 \u0432 \u0432\u0438\u0434\u0435 \u0441\u0435\u0442\u043a\u0438. \u0418 \u0432\u043e \u0432\u0441\u0435\u043c \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043a\u0435 \u0443\u0433\u043b\u0430 \u043e\u0431\u0437\u043e\u0440\u0430 \u0431\u0440\u043e\u0441\u0430\u0442\u044c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043b\u0443\u0447\u0435\u0439, \u0447\u0435\u043c \u0438\u0445 \u0431\u043e\u043b\u044c\u0448\u0435, \u0442\u0435\u043c \u043b\u0443\u0447\u0448\u0435 \u0431\u0443\u0434\u0435\u0442 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0430, \u043d\u043e \u043c\u0435\u043d\u044c\u0448\u0435 \u043a\u0430\u0434\u0440\u043e\u0432 \u0432 \u0441\u0435\u043a\u0443\u043d\u0434\u0443.<\/p>\n<p>\u041a\u0430\u0436\u0434\u044b\u0439 \u043b\u0443\u0447 \u0434\u043e\u043b\u0436\u0435\u043d \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u044c \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u0435 \u0441 \u043a\u0430\u0436\u0434\u043e\u0439 \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0439 \u0438 \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u043e\u0439 \u043b\u0438\u043d\u0438\u0435\u0439 \u0441\u0435\u0442\u043a\u0438. \u041a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u043d \u043d\u0430\u0445\u043e\u0434\u0438\u0442 \u0441\u0442\u043e\u043b\u043a\u043d\u043e\u0432\u0435\u043d\u0438\u0435 \u0441 \u0431\u043b\u043e\u043a\u043e\u043c, \u043e\u043d \u0440\u0438\u0441\u0443\u0435\u0442 \u0435\u0433\u043e \u043d\u0443\u0436\u043d\u044b\u0445 \u0440\u0430\u0437\u043c\u0435\u0440\u043e\u0432 \u0438 \u043f\u0440\u0435\u043a\u0440\u0430\u0449\u0430\u0435\u0442 \u0441\u0432\u043e\u0435 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u0435, \u0434\u0430\u043b\u0435\u0435 \u0446\u0438\u043a\u043b \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u0442 \u043a \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c\u0443 \u043b\u0443\u0447\u0443.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/8ab\/0bf\/10d\/8ab0bf10d75519df6f952cc7323a0b20.png\" alt=\"\u041f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u0435 \u043b\u0443\u0447\u0430 \u0438 \u043b\u0438\u043d\u0438\u0439 \u043d\u0430 \u0441\u0435\u0442\u043a\u0435\" title=\"\u041f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u0435 \u043b\u0443\u0447\u0430 \u0438 \u043b\u0438\u043d\u0438\u0439 \u043d\u0430 \u0441\u0435\u0442\u043a\u0435\" width=\"1310\" height=\"684\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/8ab\/0bf\/10d\/8ab0bf10d75519df6f952cc7323a0b20.png\"\/><\/p>\n<div><figcaption>\u041f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u0435 \u043b\u0443\u0447\u0430 \u0438 \u043b\u0438\u043d\u0438\u0439 \u043d\u0430 \u0441\u0435\u0442\u043a\u0435<\/figcaption><\/div>\n<\/figure>\n<p>\u0422\u0430\u043a \u0436\u0435 \u043d\u0443\u0436\u043d\u043e \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u0430\u0442\u044c \u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0434\u043e \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0445 \u0438 \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u044b\u0445 \u043b\u0438\u043d\u0438\u0439 \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u043f\u0435\u0440\u0435\u0441\u0435\u043a\u0441\u044f \u043b\u0443\u0447.<\/p>\n<p>\u0412\u0441\u043f\u043e\u043c\u0438\u043d\u0430\u0435\u043c \u0448\u043a\u043e\u043b\u044c\u043d\u0443\u044e \u0442\u0440\u0438\u0433\u043e\u043d\u043e\u043c\u0435\u0442\u0440\u0438\u044e \u0438 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u044d\u0442\u043e \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0445 \u043b\u0438\u043d\u0438\u0439<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/b46\/fef\/4b2\/b46fef4b23d56eaccbbf8f0a27d31789.png\" alt=\"\u0420\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0434\u043e \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0445 \u0438 \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u044b\u0445 \u043b\u0438\u043d\u0438\u0439 \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u043f\u0435\u0440\u0435\u0441\u0435\u043a\u0441\u044f \u043b\u0443\u0447\" title=\"\u0420\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0434\u043e \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0445 \u0438 \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u044b\u0445 \u043b\u0438\u043d\u0438\u0439 \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u043f\u0435\u0440\u0435\u0441\u0435\u043a\u0441\u044f \u043b\u0443\u0447\" width=\"1272\" height=\"676\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/b46\/fef\/4b2\/b46fef4b23d56eaccbbf8f0a27d31789.png\"\/><\/p>\n<div><figcaption>\u0420\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0434\u043e \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0445 \u0438 \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u044b\u0445 \u043b\u0438\u043d\u0438\u0439 \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u043f\u0435\u0440\u0435\u0441\u0435\u043a\u0441\u044f \u043b\u0443\u0447<\/figcaption><\/div>\n<\/figure>\n<p>\u041d\u0430\u043c \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u0430 \u0441\u0442\u043e\u0440\u043e\u043d\u0430 <strong>k \u2013 \u044d\u0442\u043e \u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0438\u0433\u0440\u043e\u043a\u0430 \u0434\u043e \u0431\u043b\u043e\u043a\u0430<\/strong><\/p>\n<p><strong>a \u2013 \u044d\u0442\u043e\u00a0\u0443\u0433\u043e\u043b \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043b\u0443\u0447\u0430<\/strong><\/p>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0434\u043b\u0438\u043d\u0443, \u0442\u0430\u043a \u043a\u0430\u043a \u043c\u044b \u0437\u043d\u0430\u0435\u043c \u0440\u0430\u0437\u043c\u0435\u0440 \u043d\u0430\u0448\u0435\u0433\u043e \u0431\u043b\u043e\u043a\u0430 \u0441\u0435\u0442\u043a\u0438.<\/p>\n<p>\u0418 \u043a\u043e\u0433\u0434\u0430 \u043b\u0443\u0447 \u0432\u0440\u0435\u0436\u0435\u0442\u0441\u044f \u0432 \u0441\u0442\u0435\u043d\u0443 \u0446\u0438\u043a\u043b \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c\u0441\u044f.<\/p>\n<p>\u041f\u043e\u0442\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u043c \u044d\u0442\u043e \u043a\u043e \u0432\u0441\u0435\u043c \u043e\u0441\u044f\u043c \u0441 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0438\u043c\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f\u043c\u0438<\/p>\n<p>\u0414\u043b\u044f \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u044b\u0445 \u043b\u0438\u043d\u0438\u0439 \u0442\u043e\u0436\u0435 \u0441\u0430\u043c\u043e\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0441 \u0441\u0438\u043d\u0443\u0441\u043e\u043c.<\/p>\n<p>\u0412 \u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043b\u0443\u0447\u0430 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u043e\u0435 \u0438\u043b\u0438 \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0435 \u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u0435, \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u0431\u043b\u0438\u0436\u0435<\/p>\n<p>\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043f\u0430\u0440\u0443 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0432\u044b\u0441\u043e\u0442\u044b, \u0433\u043b\u0443\u0431\u0438\u043d\u044b, \u0440\u0430\u0437\u043c\u0435\u0440\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u044b\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0438\u0437 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u0444\u043e\u0440\u043c\u0443\u043b<\/p>\n<pre><code class=\"python\">def rayCasting(display, player):   inBlockPos = {'left': player.x - player.x \/\/ blockSize * blockSize,                 'right': blockSize - (player.x - player.x \/\/ blockSize * blockSize),                 'top': player.y - player.y \/\/ blockSize * blockSize,                 'bottom': blockSize - (player.y - player.y \/\/ blockSize * blockSize)}    for ray in range(numRays):       cur_angle = player.angle - halfFOV + deltaRays * ray       cos_a, sin_a = cos(cur_angle), sin(cur_angle)       vl, hl = 0, 0        #\u0412\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u0438       for k in range(mapWidth):           if cos_a > 0:               vl = inBlockPos['right'] \/ cos_a + blockSize \/ cos_a * k + 1           elif cos_a &lt; 0:               vl = inBlockPos['left'] \/ -cos_a + blockSize \/ -cos_a * k + 1            xw, yw = vl * cos_a + player.x, vl * sin_a + player.y           fixed = xw \/\/ blockSize * blockSize, yw \/\/ blockSize * blockSize           if fixed in blockMap:               textureV = blockMapTextures[fixed]               break        #\u0413\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u0438       for k in range(mapHeight):           if sin_a > 0:               hl = inBlockPos['bottom'] \/ sin_a + blockSize \/ sin_a * k + 1           elif sin_a &lt; 0:               hl = inBlockPos['top'] \/ -sin_a + blockSize \/ -sin_a * k + 1            xh, yh = hl * cos_a + player.x, hl * sin_a + player.y           fixed = xh \/\/ blockSize * blockSize, yh \/\/ blockSize * blockSize           if fixed in blockMap:               textureH = blockMapTextures[fixed]               break        ray_size = min(vl, hl) * depthCoef       toX, toY = ray_size * cos(cur_angle) + player.x, ray_size * sin(cur_angle) + player.y       pg.draw.line(display, pg.Color(\"yellow\"), (player.x, player.y), (toX, toY))<\/code><\/pre>\n<p>\u0420\u0438\u0441\u0443\u0435\u043c \u043f\u0440\u044f\u043c\u043e\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u0438 \u043f\u043e \u0446\u0435\u043d\u0442\u0440\u0443 \u044d\u043a\u0440\u0430\u043d\u0430, \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043f\u043e \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u0438 \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u0432\u0438\u0441\u0435\u0442\u044c \u043e\u0442 \u043d\u043e\u043c\u0435\u0440\u0430 \u043b\u0443\u0447\u0430, \u0430 \u0432\u044b\u0441\u043e\u0442\u0430 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0432\u043d\u0430 \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u044e \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u044d\u0444\u0444\u0438\u0446\u0438\u0435\u043d\u0442\u0430 \u043d\u0430 \u0434\u043b\u0438\u043d\u0443 \u043b\u0443\u0447\u0430.<\/p>\n<pre><code class=\"python\">#def rayCasting  ray_size += cos(player.angle - cur_angle) height_c = coef \/ (ray_size + 0.0001) c = 255 \/ (1 + ray_size ** 2 * 0.0000005) color = (c, c, c) block = pg.draw.rect(display, color, (ray * scale, half_height - height_c \/\/ 2, scale, height_c))<\/code><\/pre>\n<p>\u0418 \u0432\u043e\u0442 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u0443\u0436\u0435 \u043a\u0430\u043a\u0430\u044f-\u043d\u0438\u043a\u0430\u043a\u0430\u044f \u0438\u043b\u043b\u044e\u0437\u0438\u044f 3D \u0438\u0437\u043c\u0435\u0440\u0435\u043d\u0438\u044f.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/f7e\/8e1\/ad5\/f7e8e1ad5155e980be6d74df6844bac2.png\" alt=\"\u0418\u043b\u043b\u044e\u0437\u0438\u044f 3D \u0438\u0437\u043c\u0435\u0440\u0435\u043d\u0438\u044f\" title=\"\u0418\u043b\u043b\u044e\u0437\u0438\u044f 3D \u0438\u0437\u043c\u0435\u0440\u0435\u043d\u0438\u044f\" width=\"1182\" height=\"698\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/f7e\/8e1\/ad5\/f7e8e1ad5155e980be6d74df6844bac2.png\"\/><\/p>\n<div><figcaption>\u0418\u043b\u043b\u044e\u0437\u0438\u044f 3D \u0438\u0437\u043c\u0435\u0440\u0435\u043d\u0438\u044f<\/figcaption><\/div>\n<\/figure>\n<h2>\u0422\u0435\u043a\u0441\u0442\u0443\u0440\u044b<\/h2>\n<p>1 \u0431\u043b\u043e\u043a \u0438\u043c\u0435\u0435\u0442 4 \u0441\u0442\u043e\u0440\u043e\u043d\u044b \u0438 \u043a\u0430\u0436\u0434\u0443\u044e \u0431\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u043e\u043a\u0440\u044b\u0442\u044c \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u043e\u0439.<\/p>\n<p>\u041a\u0430\u0436\u0434\u0443\u044e \u0441\u0442\u043e\u0440\u043e\u043d\u0443 \u043c\u044b \u0440\u0430\u0437\u0434\u0435\u043b\u044f\u0435\u043c \u043d\u0430 \u043f\u043e\u043b\u043e\u0441\u043a\u0438 \u0441 \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u043e\u0439 \u0448\u0438\u0440\u0438\u043d\u043e\u0439, \u0433\u043b\u0430\u0432\u043d\u043e\u0435 \u0447\u0442\u043e\u0431\u044b \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043b\u0443\u0447\u0435\u0439 \u043f\u0430\u0434\u0430\u044e\u0449\u0438\u0445 \u043d\u0430 \u0431\u043b\u043e\u043a \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u043b\u043e \u0441 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u043f\u043e\u043b\u043e\u0441\u043e\u043a \u043d\u0430 \u0441\u0442\u043e\u0440\u043e\u043d\u0435, \u0438 \u0434\u0435\u043b\u0438\u043c \u043d\u0430 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u044d\u0442\u0438\u0445 \u043f\u043e\u043b\u043e\u0441\u043e\u043a \u043d\u0430\u0448\u0443 \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u0443 \u0438 \u043f\u043e\u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0435\u043c \u043f\u043e\u043b\u043e\u0441\u043a\u0443 \u0438\u0437 \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u044b \u043d\u0430 \u043f\u043e\u043b\u043e\u0441\u043a\u0443 \u043d\u0430 \u0431\u043b\u043e\u043a\u0435.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/957\/05b\/775\/95705b775852f71fb23d9bd44985be92.png\" alt=\"\u041d\u0430\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u043e\u0441\u043e\u043a \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u044b \u043d\u0430 \u0431\u043b\u043e\u043a\" title=\"\u041d\u0430\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u043e\u0441\u043e\u043a \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u044b \u043d\u0430 \u0431\u043b\u043e\u043a\" width=\"1297\" height=\"439\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/957\/05b\/775\/95705b775852f71fb23d9bd44985be92.png\"\/><\/p>\n<div><figcaption>\u041d\u0430\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u043e\u0441\u043e\u043a \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u044b \u043d\u0430 \u0431\u043b\u043e\u043a<\/figcaption><\/div>\n<\/figure>\n<p>\u0422\u0430\u043a \u0448\u0438\u0440\u0438\u043d\u0430 \u0431\u0443\u0434\u0435\u0442 \u0432\u0430\u0440\u044c\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0443\u0434\u0430\u043b\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u0441\u0442\u043e\u0440\u043e\u043d\u044b \u0431\u043b\u043e\u043a\u0430. \u0410 \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u043e\u0441\u043a\u0438 \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u0443\u0442\u0435\u043c \u0443\u043c\u043d\u043e\u0436\u0435\u043d\u0438\u044f \u043e\u0442\u0441\u0442\u0443\u043f\u0430 \u043d\u0430 \u0440\u0430\u0437\u043c\u0435\u0440 \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u044b.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u043b\u0443\u0447 \u043f\u0430\u0434\u0430\u0435\u0442 \u043d\u0430 \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c \u0442\u043e \u043e\u0442\u0441\u0442\u0443\u043f \u0432\u044b\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u043c \u043e\u0442 \u0432\u0435\u0440\u0445\u043d\u0435\u0439 \u0442\u043e\u0447\u043a\u0438, \u0435\u0441\u043b\u0438 \u043d\u0430 \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c \u0442\u043e \u043e\u0442 \u043b\u0435\u0432\u043e\u0439 \u0442\u043e\u0447\u043a\u0438.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/383\/af4\/ef0\/383af4ef01ed1017907c64e0f99deb09.png\" alt=\"\u0420\u0430\u0441\u0447\u0435\u0442 \u043e\u0442\u0441\u0442\u0443\u043f\u0430\" title=\"\u0420\u0430\u0441\u0447\u0435\u0442 \u043e\u0442\u0441\u0442\u0443\u043f\u0430\" width=\"1273\" height=\"667\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/383\/af4\/ef0\/383af4ef01ed1017907c64e0f99deb09.png\"\/><\/p>\n<div><figcaption>\u0420\u0430\u0441\u0447\u0435\u0442 \u043e\u0442\u0441\u0442\u0443\u043f\u0430<\/figcaption><\/div>\n<\/figure>\n<pre><code class=\"python\">#def rayCasting  if hl > vl:     ray_size = vl     mr = yw     textNum = textureV else:     ray_size = hl     mr = xh     textNum = textureH  mr = int(mr) % blockSize  textures[textNum].set_alpha(c) wallLine = textures[textNum].subsurface(mr * textureScale, 0, textureScale, textureSize) wallLine = pg.transform.scale(wallLine, (scale, int(height_c))).convert_alpha() display.blit(wallLine, (ray * scale, half_height - height_c \/\/ 2))<\/code><\/pre>\n<p>\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0435\u0449\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0442\u0435\u043a\u0441\u0442\u0443\u0440 \u043d\u0430 \u043e\u0434\u043d\u043e\u0439 \u043a\u0430\u0440\u0442\u0435 \u043f\u0443\u0442\u0435\u043c \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043d\u0430 \u043a\u0430\u0440\u0442\u0443 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0445 \u0437\u043d\u0430\u043a\u043e\u0432, \u043a\u0430\u0436\u0434\u043e\u043c\u0443 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u0441\u0432\u043e\u044f \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u0430.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/4bb\/72a\/3e9\/4bb72a3e9ac5f1c8c1b4b5397a52a4a3.png\" alt=\"\u0421\u043f\u0438\u0441\u043e\u043a \u043c\u043e\u0438\u0445 \u0437\u043d\u0430\u043a\u043e\u0432 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0443\u0440\u043e\u0432\u043d\u0435\u0439\" title=\"\u0421\u043f\u0438\u0441\u043e\u043a \u043c\u043e\u0438\u0445 \u0437\u043d\u0430\u043a\u043e\u0432 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0443\u0440\u043e\u0432\u043d\u0435\u0439\" width=\"672\" height=\"836\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/4bb\/72a\/3e9\/4bb72a3e9ac5f1c8c1b4b5397a52a4a3.png\"\/><\/p>\n<div><figcaption>\u0421\u043f\u0438\u0441\u043e\u043a \u043c\u043e\u0438\u0445 \u0437\u043d\u0430\u043a\u043e\u0432 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0443\u0440\u043e\u0432\u043d\u0435\u0439<\/figcaption><\/div>\n<\/figure>\n<p>\u0412\u043e\u0442 \u043f\u0440\u0438\u043c\u0435\u0440 \u043a\u0430\u043a \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 2-\u043e\u0439 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u0432 \u0438\u0433\u0440\u0435 \u0432 \u0432\u0438\u0434\u0435 \u043a\u043e\u0434\u0430:<\/p>\n<pre><code class=\"python\">textMaplvl2 = [             \"111111111111111111111111\",             \"1111................1111\",             \"11.........1....11...111\",             \"11....151..1....31...111\",             \"1111............331...11\",             \"11111.....115..........1\",             \"1111.....11111....1113.1\",             \"115.......111......333.1\",             \"15....11.......11......1\",             \"11....11.......11..11111\",             \"111...................51\",             \"111........1......115551\",             \"11111...11111...11111111\",             \"11111%&lt;@1111111111111111\", ]<\/code><\/pre>\n<p>\u0412 \u0438\u0442\u043e\u0433\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0430\u0434\u0435\u043a\u0432\u0430\u0442\u043d\u043e\u0435 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0442\u0435\u043a\u0441\u0442\u0443\u0440:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/c20\/c18\/c97\/c20c18c97d4eb13c80a81fc7b1bbd471.png\" alt=\"\" title=\"\" width=\"1130\" height=\"663\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/c20\/c18\/c97\/c20c18c97d4eb13c80a81fc7b1bbd471.png\"\/><\/figure>\n<h2>\u041a\u043e\u043b\u043b\u0438\u0437\u0438\u044f<\/h2>\n<p>\u0413\u0434\u0435 \u0436\u0435 \u0442\u0430\u043a\u043e\u0435 \u0432\u0438\u0434\u0430\u043d\u043e \u0447\u0442\u043e \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442\u044c \u0447\u0435\u0440\u0435\u0437 \u0431\u043b\u043e\u043a\u0438\u2026   <\/p>\n<p>\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043a\u043e\u043b\u043b\u0438\u0437\u0438\u044e. \u041a \u043a\u0430\u0436\u0434\u043e\u0439 \u043f\u043e\u0437\u0438\u0446\u0438\u044f \u0431\u043b\u043e\u043a\u0430 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0442\u0430\u043a \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u043c\u044b\u0439 \u043a\u043e\u043b\u043b\u0430\u0439\u0434\u0435\u0440 \u0438 \u0442\u0430\u043a\u043e\u0439 \u0436\u0435 \u043a\u043e\u043b\u043b\u0430\u0439\u0434\u0435\u0440 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0438\u0433\u0440\u043e\u043a\u0443. \u0415\u0441\u043b\u0438 \u043e\u043d \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442 \u0438\u0434\u0442\u0438 \u0442\u0430\u043a \u043a\u0430\u043a \u0448\u0435\u043b \u0438 \u0442\u0430\u043a\u0438\u043c\u0438 \u0442\u0435\u043c\u043f\u0430\u043c\u0438 \u043d\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c \u043a\u0430\u0434\u0440\u0435 \u043f\u043e \u043f\u0440\u0435\u0434\u0441\u043a\u0430\u0437\u0430\u043d\u0438\u044e \u0437\u0430\u0439\u0434\u0435\u0442 \u0432 \u0431\u043b\u043e\u043a, \u0442\u043e \u043c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u0437\u0430\u043d\u0443\u043b\u044f\u0435\u043c \u0443\u0441\u043a\u043e\u0440\u0435\u043d\u0438\u0435 \u043f\u043e \u043d\u0443\u0436\u043d\u043e\u0439 \u043e\u0441\u0438.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/308\/c69\/a74\/308c69a74891535d1e09911d2194c412.png\" alt=\"\u0421\u0442\u043e\u043b\u043a\u043d\u043e\u0432\u0435\u043d\u0438\u0435 \u0431\u043b\u043e\u043a\u0430 \u0438 \u0438\u0433\u0440\u043e\u043a\u0430\" title=\"\u0421\u0442\u043e\u043b\u043a\u043d\u043e\u0432\u0435\u043d\u0438\u0435 \u0431\u043b\u043e\u043a\u0430 \u0438 \u0438\u0433\u0440\u043e\u043a\u0430\" width=\"962\" height=\"816\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/308\/c69\/a74\/308c69a74891535d1e09911d2194c412.png\"\/><\/p>\n<div><figcaption>\u0421\u0442\u043e\u043b\u043a\u043d\u043e\u0432\u0435\u043d\u0438\u0435 \u0431\u043b\u043e\u043a\u0430 \u0438 \u0438\u0433\u0440\u043e\u043a\u0430<\/figcaption><\/div>\n<\/figure>\n<p>\u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0447\u0443\u0442\u044c \u0434\u043e\u043f\u0438\u0448\u0435\u043c \u043a\u043b\u0430\u0441\u0441 <strong>Player<\/strong>. \u042f \u0440\u0435\u0448\u0438\u043b \u0435\u0449\u0435 \u0441\u0440\u0430\u0437\u0443 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043a\u0430\u043c\u0435\u0440\u043e\u0439 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u044b\u0448\u0438. \u0412\u043e\u0442 \u043a\u0430\u043a \u043f\u043e \u0438\u0442\u043e\u0433\u0443 \u0441\u0442\u0430\u043b \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u044d\u0442\u043e\u0442 \u043a\u043b\u0430\u0441\u0441:<\/p>\n<pre><code class=\"python\">class Player:     def __init__(self):         self.x = 0         self.y = 0          self.angle = 0         self.delta = 0         self.speed = 100         self.mouse_sense = settings.mouse_sensivity          #collision         self.side = 50         self.rect = pygame.Rect(*(self.x, self.y), self.side, self.side)      def detect_collision_wall(self, dx, dy):         next_rect = self.rect.copy()         next_rect.move_ip(dx, dy)         hit_indexes = next_rect.collidelistall(collision_walls)          if len(hit_indexes):             delta_x, delta_y = 0, 0             for hit_index in hit_indexes:                 hit_rect = collision_walls[hit_index]                 if dx > 0:                     delta_x += next_rect.right - hit_rect.left                 else:                     delta_x += hit_rect.right - next_rect.left                 if dy > 0:                     delta_y += next_rect.bottom - hit_rect.top                 else:                     delta_y += hit_rect.bottom - next_rect.top             if abs(delta_x - delta_y) &lt; 50:                 dx, dy = 0, 0             elif delta_x > delta_y:                 dy = 0             elif delta_y > delta_x:                 dx = 0          self.x += dx         self.y += dy      def move(self, active):         self.rect.center = self.x, self.y         key = pygame.key.get_pressed()         key2 = pygame.key.get_pressed()         cos_a, sin_a = cos(self.angle), sin(self.angle)          if key2[pygame.K_LSHIFT]:             self.speed += 5             if self.speed >= 200:                 self.speed = 200         else:             self.speed = 100          self.mouse_control(active=active)          if key[pygame.K_w]:             dx = cos_a * self.delta * self.speed             dy = sin_a * self.delta * self.speed             self.detect_collision_wall(dx, dy)         if key[pygame.K_s]:             dx = cos_a * self.delta * -self.speed             dy = sin_a * self.delta * -self.speed             self.detect_collision_wall(dx, dy)         if key[pygame.K_a]:             dx = sin_a * self.delta * self.speed             dy = cos_a * self.delta * -self.speed             self.detect_collision_wall(dx, dy)         if key[pygame.K_d]:             dx = sin_a * self.delta * -self.speed             dy = cos_a * self.delta * self.speed             self.detect_collision_wall(dx, dy)      def mouse_control(self, active):         if active:             if pygame.mouse.get_focused():                 diff = pygame.mouse.get_pos()[0] - half_width                 pygame.mouse.set_pos((half_width, half_height))                 self.angle += diff * self.delta * self.mouse_sense<\/code><\/pre>\n<h2>\u0413\u0435\u0439\u043c\u043f\u043b\u0435\u0439<\/h2>\n<p>\u0421\u043f\u0430\u0432\u043d\u0438\u043c \u0446\u0432\u0435\u0442\u0430 \u043d\u0430 \u043a\u0430\u0440\u0442\u0435, \u0438 \u0434\u0435\u043b\u0430\u0435\u043c \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u0438\u0433\u0440\u043e\u043a \u043c\u043e\u0433 \u0432\u0437\u044f\u0442\u044c \u0438\u0445, \u0438 \u043a\u0440\u0430\u0441\u0438\u0442\u044c \u043b\u044e\u0431\u044b\u0435 \u0431\u043b\u043e\u043a\u0438. \u0414\u043b\u044f \u0442\u043e\u0433\u043e \u0447\u0442\u043e \u043f\u043e\u043d\u044f\u0442\u044c \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u043f\u0435\u0440\u0441\u043e\u043d\u0430\u0436 \u0440\u044f\u0434\u043e\u043c \u0441 \u0431\u043b\u043e\u043a\u043e\u043c \u0438\u043b\u0438 \u043d\u0435\u0442 \u043f\u0438\u0448\u0435\u043c \u0445\u0438\u0442\u0440\u0443\u044e \u0446\u0435\u043f\u043e\u0447\u043a\u0443 \u0443\u0441\u043b\u043e\u0432\u0438\u0439:<\/p>\n<pre><code class=\"python\">for blockNow in blockMapTextures:         questBlock = False         if (blockNow[0] - blockSize \/\/ 2 &lt; player.x &lt; blockNow[0] + blockSize * 1.5 and blockNow[1] &lt; player.y &lt; blockNow[1] + blockSize) or \\         (blockNow[1] - blockSize \/\/ 2 &lt; player.y &lt; blockNow[1] + blockSize * 1.5 and blockNow[0] &lt; player.x &lt; blockNow[0] + blockSize):             if countOfDraw &lt; len(blocksActive) and doubleDrawOff:                 display.blit(                     pg.transform.scale(ui['mouse2'], (ui['mouse2'].get_width() \/\/ 2, ui['mouse2'].get_height() \/\/ 2)),                     (130, 750))                 if event.type == pg.MOUSEBUTTONDOWN and pg.mouse.get_pressed()[2]:                     if blockMapTextures[blockNow] == '&lt;':                         questBlock = True                     if questBlock == False:                         try:                             tempbackup_color.clear()                             tempbackup.clear()                             coloredBlocks.clear()                             block_in_bag.pop(-1)                              tempbackup.append(blockMapTextures[blockNow])                             tempbackup_color.append(blocks_draw_avaliable[list(blocks_draw_avaliable.keys())[-1]])                             print('tempbackup_color : ', tempbackup_color)                             blockMapTextures[blockNow] = blocks_draw_avaliable[list(blocks_draw_avaliable.keys())[-1]]                             coloredBlocks.append(blockNow)                             blocks_draw_avaliable.pop(list(blocks_draw_avaliable.keys())[-1])                             countOfDraw += 1                                      doubleDrawOff = False                             doubleBack = False                         except:                             print('Error in color drawing')<\/code><\/pre>\n<p>\u0413\u0440\u0443\u0431\u043e \u0433\u043e\u0432\u043e\u0440\u044f, \u043c\u044b \u0443\u0441\u043b\u043e\u0432\u043d\u043e \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u043c \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0437\u0430\u0445\u0432\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u043e\u0434\u0438\u043d \u0431\u043b\u043e\u043a, \u0438 \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u0437\u0430\u0445\u043e\u0434\u0438\u0442 \u043b\u0438 \u0438\u0433\u0440\u043e\u043a \u0432 \u044d\u0442\u0438 \u043a\u043e\u043e\u0440\u0434\u0438\u043d\u0430\u0442\u044b. \u0423 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0431\u043b\u043e\u043a\u0430, \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f, \u0435\u0441\u0442\u044c \u043d\u0435\u043a\u0430\u044f \u043e\u0431\u043b\u0430\u0441\u0442\u044c \u0432\u043e\u043a\u0440\u0443\u0433(\u0431\u0435\u0437 \u0443\u0433\u043b\u043e\u0432) \u0440\u0430\u0437\u043c\u0435\u0440\u043e\u043c \u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0434\u0435\u0441\u044f\u0442\u043a\u043e\u0432 \u043f\u0438\u043a\u0441\u0435\u043b\u0435\u0439, \u0438 \u043f\u0440\u0438 \u0437\u0430\u0445\u043e\u0434\u0435 \u0432 \u043d\u0435\u0435, \u0441\u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044f \u0447\u0442\u043e \u0442\u044b \u0440\u044f\u0434\u043e\u043c \u0441 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u043c \u0431\u043b\u043e\u043a\u043e\u043c.<\/p>\n<p>\u042f \u0443\u0432\u0435\u0440\u0435\u043d \u0447\u0442\u043e \u0435\u0441\u0442\u044c \u0441\u043f\u043e\u0441\u043e\u0431 \u043b\u0443\u0447\u0448\u0435 \u0447\u0442\u043e\u0431\u044b \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u0442\u044c \u0431\u043b\u043e\u043a \u0440\u044f\u0434\u043e\u043c \u0441 \u0438\u0433\u0440\u043e\u043a\u043e\u043c, \u043d\u043e \u044f \u0440\u0435\u0448\u0438\u043b \u043d\u0435 \u043f\u0440\u0438\u0434\u0443\u043c\u044b\u0432\u0430\u0442\u044c \u043a\u043e\u043b\u0435\u0441\u043e \u0438 \u0441\u0434\u0435\u043b\u0430\u043b, \u043a\u0430\u043a \u0441\u0434\u0435\u043b\u0430\u043b).<\/p>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u043a\u0432\u0435\u0441\u0442\u043e\u0432 \u0438 \u0441\u043c\u0435\u043d\u0443 \u0443\u0440\u043e\u0432\u043d\u0435\u0439 \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0442\u043e\u0433\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d \u043a\u0432\u0435\u0441\u0442 \u0438\u043b\u0438 \u043d\u0435\u0442. \u0410 \u0442\u0430\u043a \u0436\u0435 \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0430\u0442\u0435\u043b\u044c \u0443\u0440\u043e\u0432\u043d\u0435\u0439, \u0441 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u043e\u0439 \u0434\u043b\u044f \u0441\u044e\u0436\u0435\u0442\u0430 \u0432 \u043d\u0430\u0447\u0430\u043b\u0435 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f.<\/p>\n<pre><code class=\"python\">def lvlSwitch():     settings.textMap = levels.levelsList[str(settings.numOfLvl)]     with open(\"game\/settings\/settings.json\", 'w') as f:         settings.sett['numL'] = settings.numOfLvl         js.dump(settings.sett, f)     print(settings.numOfLvl)     main.tempbackup.clear()     main.coloredBlocks.clear()     main.blocksActive.clear()     main.tempbackup_color.clear()     main.block_in_bag.clear()     main.blocks_draw_avaliable.clear()     main.countOfDraw = 0     main.blockClickAvaliable = 0      def switcher():       global lvlSwitches      main.display.blit(ui[f'lvl{settings.numOfLvl+1}'], (0,0))     main.timer = False     if pg.key.get_pressed()[pg.K_SPACE]:         level5_quest.clear()         main.doubleQuest = True          settings.numOfLvl += 1          lvlSwitch()         main.timer = True         level5_quest.clear()         lvlSwitches = False       def quest(lvl):     global lvlSwitches     tmp = []     for blockNeed in blockQuest:         if blockQuest[blockNeed] == '@':             if blockMapTextures[blockNeed] == '3':                 tmp.append(1)                 if settings.numOfLvl == 5:                     level5_quest.add(1)         if blockQuest[blockNeed] == '!':             if blockMapTextures[blockNeed] == '2':                 tmp.append(2)                 if settings.numOfLvl == 5:                     level5_quest.add(2)                              if blockQuest[blockNeed] == '$':             if blockMapTextures[blockNeed] == '4':                 tmp.append(3)                 if settings.numOfLvl == 5:                     level5_quest.add(3)         if blockQuest[blockNeed] == '%':             if blockMapTextures[blockNeed] == '5':                 tmp.append(4)                 if settings.numOfLvl == 5:                     level5_quest.add(4)<\/code><\/pre>\n<p>\u0420\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u043f\u0430\u0440\u0443 \u043c\u0435\u0445\u0430\u043d\u0438\u043a:<\/p>\n<p>\u041f\u0435\u0440\u0432\u0430\u044f \u043c\u0435\u0445\u0430\u043d\u0438\u043a\u0430 \u2013 \u0431\u0430\u043d\u0430\u043b\u044c\u043d\u043e \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043d\u0443\u0436\u043d\u044b\u0439 \u0446\u0432\u0435\u0442 \u0432 \u043d\u0443\u0436\u043d\u0443\u044e \u044f\u0447\u0435\u0439\u043a\u0443. \u041e\u0431\u044a\u044f\u0441\u043d\u0435\u043d\u0438\u0439 \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f.<\/p>\n<p>\u0412\u0442\u043e\u0440\u0430\u044f \u043c\u0435\u0445\u0430\u043d\u0438\u043a\u0430 \u2013 \u0442\u0435\u043b\u0435\u043f\u043e\u0440\u0442\u0430\u0446\u0438\u044f \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u043d\u043e\u0432\u0430\u044f \u043a\u0430\u0440\u0442\u0430 \u0432 \u0432\u0438\u0434\u0435 \u043b\u0438\u0441\u0442\u0430 \u0438 \u0431\u043b\u043e\u043a\u0438 \u0432 \u043d\u0435\u0439 \u0440\u0430\u0437 \u0432 \u043a\u0430\u043a\u043e\u0435 \u0442\u043e \u0432\u0440\u0435\u043c\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u0448\u0438\u0432\u0430\u044e\u0442\u0441\u044f, \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u043e\u0449\u0443\u0449\u0435\u043d\u0438\u044f \u0442\u0435\u043b\u0435\u043f\u043e\u0440\u0442\u0430\u0446\u0438\u0439 \u0446\u0432\u0435\u0442\u043e\u0432.<\/p>\n<pre><code class=\"python\">def randomColorBlockMap(textMap):     timer = t.perf_counter()     text = textMap     newTextMap = []     generatedMap = []     for row in text:         roww = []         for column in row:             roww.append(column)         newTextMap.append(roww)     textsForShuffle = []     for row in text:         for column in row:             if column != '.' and column != '&lt;' and column != '$' and column != '%' and column != '@' and column != '!':                 textsForShuffle.append(column)     xy_original = []     for y, row in enumerate(text):         for x, column in enumerate(row):             if column != '.' and column != '&lt;' and column != '$' and column != '%' and column != '@' and column != '!':                 if (x*blockSize, y*blockSize) not in list(settings.blockQuest.keys()):                     xy_original.append([x,y])     xy_tmp = xy_original     for y, row in enumerate(newTextMap):                for x, column in enumerate(row):             if column != '.' and column != '&lt;' and column != '$' and column != '%' and column != '@' and column != '!':                 if (x*blockSize, y*blockSize) not in list(settings.blockQuest.keys()):                       ch = rn.choice(textsForShuffle)                     newTextMap[y][x] = ch                     textsForShuffle.remove(ch)                      for row in newTextMap:         generatedMap.append(''.join(row))      initMap(generatedMap)<\/code><\/pre>\n<p>\u0422\u0440\u0435\u0442\u044c\u044f \u043c\u0435\u0445\u0430\u043d\u0438\u043a\u0430 \u2013 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0427\u0411 \u0444\u0438\u043b\u044c\u0442\u0440 \u043d\u0430 \u043a\u0430\u0436\u0434\u0443\u044e \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u0443\u2026<\/p>\n<pre><code class=\"python\">def toBlack():     settings.textures['2'] = pygame.image.load('textures\/colorYellowWallBlack.png').convert()     settings.textures['3'] =  pygame.image.load('textures\/colorBlueWallBlack.png').convert()     settings.textures['4'] =  pygame.image.load('textures\/colorRedWallBlack.png').convert()     settings.textures['5'] =  pygame.image.load('textures\/colorGreenWallBlack.png').convert()     settings.textures['&lt;'] =  pygame.image.load('textures\/robotBlack.png').convert()     ui['3'] = pygame.image.load(\"textures\/blue_uiBlack.png\")     ui['2'] = pygame.image.load(\"textures\/yellow_uiBlack.png\")     ui['4'] = pygame.image.load(\"textures\/red_uiBlack.png\")     ui['5'] = pygame.image.load(\"textures\/green_uiBlack.png\")<\/code><\/pre>\n<p>\u0414\u0430\u043b\u044c\u0448\u0435 \u044f \u0441\u0434\u0435\u043b\u0430\u043b \u043c\u0435\u043d\u044e \u0432 \u0432\u0438\u0434\u0435 \u043a\u043b\u0430\u0441\u0441\u0430, \u0447\u0442\u043e\u0431\u044b \u0443\u0434\u043e\u0431\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u043e\u043f\u0446\u0438\u0438 \u043a\u043e\u0433\u0434\u0430 \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u043d\u0443\u0436\u043d\u043e.<\/p>\n<pre><code class=\"python\">class Menu:     def __init__(self):         self.option_surface = []         self.callbacks = []         self.current_option_index = 0      def add_option(self, option, callback):         self.option_surface.append(f1.render(option, True, (255, 255, 255)))         self.callbacks.append(callback)      def switch(self, direction):         self.current_option_index = max(0, min(self.current_option_index + direction, len(self.option_surface) - 1))      def select(self):         self.callbacks[self.current_option_index]()      def draw(self, surf, x, y, option_y):         for i, option in enumerate(self.option_surface):             option_rect = option.get_rect()             option_rect.topleft = (x, y + i * option_y)             if i == self.current_option_index:                 pg.draw.rect(surf, (0, 100, 0), option_rect)             b = surf.blit(option, option_rect)             pos = pygame.mouse.get_pos()             if b.collidepoint(pos):                 self.current_option_index = i                 for event in pg.event.get():                     if pg.mouse.get_pressed()[0]:                         self.select()<\/code><\/pre>\n<p>\u0420\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f:<\/p>\n<pre><code class=\"python\">try:     with open(\"game\/settings\/settings.json\", 'r') as f:         sett = js.load(f) except:     with open(\"game\/settings\/settings.json\", 'w') as f:         sett = {             'FOV' : pi \/ 2,             'numRays' : 400,             'MAPSCALE' : 10,             'numL' : 1,             'mouse_sensivity' : 0.15         }         js.dump(sett, f)  numOfLvl = sett['numL'] textMap = levels.levelsList[str(numOfLvl)]  mouse_sensivity = sett['mouse_sensivity']<\/code><\/pre>\n<p>\u0418 \u0432 \u0437\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0438 \u043c\u0438\u043d\u0438 \u0444\u0438\u043b\u043e\u0441\u043e\u0444\u0441\u043a\u0443\u044e \u0438\u0441\u0442\u043e\u0440\u0438\u044e \u0441 \u0433\u043b\u0443\u0431\u043e\u043a\u0438\u043c \u0441\u043c\u044b\u0441\u043b\u043e\u043c \u0438 \u043d\u0435\u043e\u0436\u0438\u0434\u0430\u043d\u043d\u0443\u044e \u043a\u043e\u043d\u0446\u043e\u0432\u043a\u0443.<\/p>\n<h2>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h2>\n<p>\u0412\u043e\u0442 \u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u0438\u0433\u0440\u0430 \u0441 2.5D \u0438\u0437\u043c\u0435\u0440\u0435\u043d\u0438\u0435\u043c, \u0441\u043e\u0442\u043d\u044f\u043c\u0438 \u043b\u0443\u0447\u0435\u0439, \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0438\u043c FPS \u0438 \u043d\u0435\u0437\u0430\u043c\u044b\u0441\u043b\u043e\u0432\u0430\u0442\u044b\u043c \u0433\u0435\u0439\u043c\u043f\u043b\u0435\u0435\u043c, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043f\u043e\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043b\u043e\u0441\u044c \u0432\u0441\u0435\u0433\u043e 4 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438, 68 \u0442\u0435\u043a\u0441\u0442\u0443\u0440, \u0438 \u00a01018 \u0441\u0442\u0440\u043e\u0447\u0435\u043a \u043a\u043e\u0434\u0430. <\/p>\n<p>\u0422\u0430\u043a\u0436\u0435 \u0432\u044b \u0432\u0441\u0435\u0433\u0434\u0430 \u043c\u043e\u0436\u0435\u0442\u0435 \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u043f\u043e\u043b\u043d\u044b\u043c \u043a\u043e\u0434\u043e\u043c \u044d\u0442\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0438\u043b\u0438 <a href=\"https:\/\/github.com\/benvito\/raycasting-Game\" rel=\"noopener noreferrer nofollow\">\u0441\u043a\u0430\u0447\u0430\u0442\u044c \u0438\u0433\u0440\u0443 \u0443 \u043c\u0435\u043d\u044f \u043d\u0430 GitHub<\/a>.<\/p>\n<p>\u041d\u0430\u0434\u0435\u044e\u0441\u044c \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435\u0439 \u044f \u0432\u0430\u043c \u0447\u0435\u043c \u0442\u043e \u043f\u043e\u043c\u043e\u0433 \u0438 \u0432\u044b \u043d\u0430\u0448\u043b\u0438 \u0434\u0430\u043d\u043d\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u0432 \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u0441\u0442\u0435\u043f\u0435\u043d\u0438 \u043f\u043e\u043b\u0435\u0437\u043d\u043e\u0439. \u0421\u043f\u0430\u0441\u0438\u0431\u043e \u0437\u0430 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 &lt;3<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p> <!----> <!----><\/div>\n<p> <!----> <!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/749764\/\"> https:\/\/habr.com\/ru\/articles\/749764\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<h2>\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435<\/h2>\n<p>\u0412\u0441\u0435 \u043c\u044b \u043f\u043e\u043c\u043d\u0438\u043c \u0441\u0442\u0430\u0440\u044b\u0435 \u0438\u0433\u0440\u044b, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0432\u043f\u0435\u0440\u0432\u044b\u0435 \u043f\u043e\u044f\u0432\u0438\u043b\u043e\u0441\u044c \u0442\u0440\u0435\u0445\u043c\u0435\u0440\u043d\u043e\u0435 \u0438\u0437\u043c\u0435\u0440\u0435\u043d\u0438\u0435.<\/p>\n<p>\u041e\u0441\u043d\u043e\u0432\u043e\u043f\u043e\u043b\u043e\u0436\u043d\u0438\u043a\u043e\u043c 3\u0434 \u0438\u0433\u0440 \u0441\u0442\u0430\u043b\u0430 \u0438\u0433\u0440\u0430 <strong><em>Wolfenstein 3D,<\/em><\/strong> \u0432\u044b\u043f\u0443\u0449\u0435\u043d\u043d\u0430\u044f \u0432 1992 \u0433\u043e\u0434\u0443<\/p>\n<figure class=\"\">\n<div><figcaption>\u0418\u0433\u0440\u0430 Wolfenstein 3D (1992 \u0433\u043e\u0434)<\/figcaption><\/div>\n<\/figure>\n<p>\u0430 \u0437\u0430 \u043d\u0435\u0439 \u0438 <strong><em>Doom 1993<\/em><\/strong> \u0433\u043e\u0434\u0430.<\/p>\n<figure class=\"full-width\">\n<div><figcaption>\u0418\u0433\u0440\u0430 DOOM 1993 (1993)<\/figcaption><\/div>\n<\/figure>\n<p>\u042d\u0442\u0438 \u0434\u0432\u0435 \u0438\u0433\u0440\u044b \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0430 \u043e\u0434\u043d\u0430 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u044f: <em>\u00abid Software\u00bb<\/em><\/p>\n<p>\u041e\u043d\u0430 \u0441\u043e\u0437\u0434\u0430\u043b\u0430 \u0441\u0432\u043e\u0439 \u0434\u0432\u0438\u0436\u043e\u043a \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e \u0434\u043b\u044f \u044d\u0442\u043e\u0439 \u0438\u0433\u0440\u044b, \u0438 \u0432 \u0438\u0442\u043e\u0433\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0430\u0441\u044c 3\u0434 \u0438\u0433\u0440\u0430, \u0447\u0442\u043e \u0441\u0447\u0438\u0442\u0430\u043b\u043e\u0441\u044c \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u043c \u043d\u0430 \u0442\u0435 \u0432\u0440\u0435\u043c\u0435\u043d\u0430. <\/p>\n<p>\u041d\u043e \u0447\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0435\u0441\u043b\u0438 \u044f \u0441\u043a\u0430\u0436\u0443 \u0447\u0442\u043e \u044d\u0442\u043e \u043d\u0435 3\u0434 \u0438\u0433\u0440\u0430, \u0430 \u0432\u0441\u0435\u0433\u043e \u043b\u0438\u0448\u044c \u0441\u0438\u043c\u0443\u043b\u044f\u0446\u0438\u044f \u0438 \u0438\u0433\u0440\u0430 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0432\u043e\u0442 \u0442\u0430\u043a? <\/p>\n<figure class=\"full-width\">\n<div><figcaption>\u0418\u0433\u0440\u0430 Wolfenstein 3D \u0438\u0437\u043d\u0443\u0442\u0440\u0438<\/figcaption><\/div>\n<\/figure>\n<p>\u041d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u0437\u0434\u0435\u0441\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u044f <strong>Ray Casting<\/strong>, \u0442\u0440\u0435\u0442\u044c\u0435\u0433\u043e \u0438\u0437\u043c\u0435\u0440\u0435\u043d\u0438\u044f \u0442\u0443\u0442 \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442.<\/p>\n<p>\u0427\u0442\u043e \u0436\u0435 \u0442\u0430\u043a\u043e\u0435 \u044d\u0442\u043e\u0442 \u0441\u0430\u043c\u044b\u0439 RayCasting, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u0430\u0436\u0435 \u0432 \u043d\u0430\u0448\u0438 \u0432\u0440\u0435\u043c\u0435\u043d\u0430 \u0430\u043a\u0442\u0443\u0430\u043b\u0435\u043d, \u043d\u043e \u0443\u0436\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043d\u0435 \u0434\u043b\u044f \u0438\u0433\u0440, \u0430 \u0434\u043b\u044f \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0438 \u0442\u0440\u0430\u0441\u0441\u0438\u0440\u043e\u0432\u043a\u0438 \u043b\u0443\u0447\u0435\u0439 \u0432 \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0438\u0433\u0440\u0430\u0445.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0438\u0442\u044c \u043d\u0430 \u0440\u0443\u0441\u0441\u043a\u0438\u0439, \u0442\u043e:<\/p>\n<blockquote>\n<p><strong>\u041c\u0435\u0442\u043e\u0434 \u0431\u0440\u043e\u0441\u0430\u043d\u0438\u044f \u043b\u0443\u0447\u0435\u0439<em>(Ray Casting)<\/em><\/strong> &#8212; <em>\u043e\u0434\u0438\u043d \u0438\u0437 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433\u0430 \u0432 \u043a\u043e\u043c\u043f\u044c\u044e\u0442\u0435\u0440\u043d\u043e\u0439 \u0433\u0440\u0430\u0444\u0438\u043a\u0435, \u043f\u0440\u0438 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0441\u0446\u0435\u043d\u0430 \u0441\u0442\u0440\u043e\u0438\u0442\u0441\u044f \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0437\u0430\u043c\u0435\u0440\u043e\u0432 \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u044f \u043b\u0443\u0447\u0435\u0439 \u0441 \u0432\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c\u043e\u0439 \u043f\u043e\u0432\u0435\u0440\u0445\u043d\u043e\u0441\u0442\u044c\u044e.<\/em><\/p>\n<\/blockquote>\n<p><em>\u041c\u043d\u0435 \u0441\u0442\u0430\u043b\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e \u043d\u0430 \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u044d\u0442\u043e \u0441\u043b\u043e\u0436\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c.<\/em><\/p>\n<p>\u0418 \u044f \u043f\u0440\u0438\u043d\u044f\u043b\u0441\u044f \u0437\u0430 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0438 <strong>RayCasting<\/strong>.<\/p>\n<p>\u0411\u0443\u0434\u0443 \u0434\u0435\u043b\u0430\u0442\u044c \u0435\u0433\u043e \u043d\u0430 \u0441\u0432\u044f\u0437\u043a\u0435 <strong>python + pygame<\/strong><\/p>\n<p>Pygame \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0440\u0438\u0441\u043e\u0432\u0430\u0442\u044c \u043d\u0430 \u043f\u043b\u043e\u0441\u043a\u043e\u0441\u0442\u0438 \u043f\u0440\u043e\u0441\u0442\u044b\u0435 2D \u0444\u0438\u0433\u0443\u0440\u044b, \u0438 \u043f\u0443\u0442\u0435\u043c \u0442\u0430\u043d\u0446\u0430\u043c\u0438 \u0441 \u0431\u0443\u0431\u043d\u043e\u043c \u0432\u043e\u043a\u0440\u0443\u0433 \u043d\u0438\u0445 \u044f \u0438 \u0431\u0443\u0434\u0443 \u0434\u0435\u043b\u0430\u0442\u044c 3D \u0438\u043b\u043b\u044e\u0437\u0438\u044e<\/p>\n<h2>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f Ray Casting<\/h2>\n<p>\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0443\u044e \u043a\u0430\u0440\u0442\u0443 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432, \u0447\u0442\u043e\u0431\u044b \u0440\u0430\u0437\u0434\u0435\u043b\u044f\u0442\u044c \u043f\u0440\u0438 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0435 \u0433\u0434\u0435 \u0431\u043b\u043e\u043a \u0430 \u0433\u0434\u0435 \u043f\u0443\u0441\u0442\u043e\u0435 \u043c\u0435\u0441\u0442\u043e.<\/p>\n<figure class=\"\">\n<div><figcaption>\u041a\u0430\u0440\u0442\u0430 \u0438 \u0438\u0433\u0440\u043e\u043a \u043d\u0430 \u043d\u0435\u0439 <em>(\u043f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c)<\/em><br \/><strong>&#171;.&#187;<\/strong> &#8212; \u043f\u0443\u0441\u0442\u043e\u0435 \u043c\u0435\u0441\u0442\u043e, \u0433\u0434\u0435 \u043c\u043e\u0436\u0435\u0442 \u0445\u043e\u0434\u0438\u0442\u044c \u0438\u0433\u0440\u043e\u043a<br \/><strong>&#171;1&#187;<\/strong> &#8212; \u0431\u043b\u043e\u043a<\/figcaption><\/div>\n<\/figure>\n<p>\u0420\u0438\u0441\u0443\u0435\u043c \u043a\u0430\u0440\u0442\u0443 \u0432 2D, \u0438 \u0438\u0433\u0440\u043e\u043a\u0430 \u0441 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c\u044e \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0438 \u0440\u0430\u0441\u0447\u0435\u0442\u043e\u043c \u0442\u043e\u0447\u043a\u0438 \u0432\u0437\u0433\u043b\u044f\u0434\u0430.<\/p>\n<pre><code class=\"python\">player.delta = delta_time() player.move(enableMoving)  display.fill((0, 0, 0))  pg.draw.circle(display, pg.Color(\"yellow\"), (player.x, player.y), 0)  drawing.world(player)<\/code><\/pre>\n<pre><code class=\"python\">class Drawing:     def __init__(self, surf, surf_map):         self.surf = surf         self.surf_map = surf_map         self.font = pg.font.SysFont('Arial', 25, bold=True)               def world(self, player):         rayCasting(self.surf, player) <\/code><\/pre>\n<pre><code class=\"python\">def rayCasting(display, player):     inBlockPos = {'left': player.x - player.x \/\/ blockSize * blockSize,                   'right': blockSize - (player.x - player.x \/\/ blockSize * blockSize),                   'top': player.y - player.y \/\/ blockSize * blockSize,                   'bottom': blockSize - (player.y - player.y \/\/ blockSize * blockSize)}      for ray in range(numRays):         cur_angle = player.angle - halfFOV + deltaRays * ray         cos_a, sin_a = cos(cur_angle), sin(cur_angle)         vl, hl = 0, 0<\/code><\/pre>\n<p>\u0414\u0432\u0438\u0436\u0435\u043d\u0438\u0435 \u0431\u0443\u0434\u0435\u0442 \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u043f\u0443\u0442\u0435\u043c \u0441\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043a\u043e\u0441\u0438\u043d\u0443\u0441\u0430 \u0443\u0433\u043b\u0430 \u0437\u0440\u0435\u043d\u0438\u044f \u043f\u043e \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u0438 \u0438 \u0441\u0438\u043d\u0443\u0441\u0430 \u0443\u0433\u043b\u0430 \u0437\u0440\u0435\u043d\u0438\u044f \u043f\u043e \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u0438<\/p>\n<pre><code class=\"python\">class Player:    def init(self)     self.x = 0     self.y = 0     self.angle = 0     self.delta = 0     self.speed = 100     self.mouse_sense = settings.mouse_sensivity    def move(self, active):     self.rect.center = self.x, self.y     key = pygame.key.get_pressed()     key2 = pygame.key.get_pressed()     cos_a, sin_a = cos(self.angle), sin(self.angle)      if key2[pygame.K_LSHIFT]:         self.speed += 5         if self.speed >= 200:             self.speed = 200     else:         self.speed = 100      if key[pygame.K_w]:         dx = cos_a * self.delta * self.speed         dy = sin_a * self.delta * self.speed     if key[pygame.K_s]:         dx = cos_a * self.delta * -self.speed         dy = sin_a * self.delta * -self.speed     if key[pygame.K_a]:         dx = sin_a * self.delta * self.speed         dy = cos_a * self.delta * -self.speed     if key[pygame.K_d]:         dx = sin_a * self.delta * -self.speed         dy = cos_a * self.delta * self.speed<\/code><\/pre>\n<figure class=\"full-width\">\n<div><figcaption>\u0412\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0440\u0430\u0441\u0447\u0435\u0442\u0430 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f \u0438\u0433\u0440\u043e\u043a\u0430<\/figcaption><\/div>\n<\/figure>\n<p>\u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0442\u0430\u043a\u043e\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442:<\/p>\n<figure class=\"full-width\">\n<div><figcaption>\u041f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0438\u0433\u0440\u044b<\/figcaption><\/div>\n<\/figure>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043d\u0430\u0448\u0443 \u043a\u0430\u0440\u0442\u0443 \u0432 \u0432\u0438\u0434\u0435 \u0441\u0435\u0442\u043a\u0438. \u0418 \u0432\u043e \u0432\u0441\u0435\u043c \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043a\u0435 \u0443\u0433\u043b\u0430 \u043e\u0431\u0437\u043e\u0440\u0430 \u0431\u0440\u043e\u0441\u0430\u0442\u044c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043b\u0443\u0447\u0435\u0439, \u0447\u0435\u043c \u0438\u0445 \u0431\u043e\u043b\u044c\u0448\u0435, \u0442\u0435\u043c \u043b\u0443\u0447\u0448\u0435 \u0431\u0443\u0434\u0435\u0442 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0430, \u043d\u043e \u043c\u0435\u043d\u044c\u0448\u0435 \u043a\u0430\u0434\u0440\u043e\u0432 \u0432 \u0441\u0435\u043a\u0443\u043d\u0434\u0443.<\/p>\n<p>\u041a\u0430\u0436\u0434\u044b\u0439 \u043b\u0443\u0447 \u0434\u043e\u043b\u0436\u0435\u043d \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u044c \u043f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u0435 \u0441 \u043a\u0430\u0436\u0434\u043e\u0439 \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0439 \u0438 \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u043e\u0439 \u043b\u0438\u043d\u0438\u0435\u0439 \u0441\u0435\u0442\u043a\u0438. \u041a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u043d \u043d\u0430\u0445\u043e\u0434\u0438\u0442 \u0441\u0442\u043e\u043b\u043a\u043d\u043e\u0432\u0435\u043d\u0438\u0435 \u0441 \u0431\u043b\u043e\u043a\u043e\u043c, \u043e\u043d \u0440\u0438\u0441\u0443\u0435\u0442 \u0435\u0433\u043e \u043d\u0443\u0436\u043d\u044b\u0445 \u0440\u0430\u0437\u043c\u0435\u0440\u043e\u0432 \u0438 \u043f\u0440\u0435\u043a\u0440\u0430\u0449\u0430\u0435\u0442 \u0441\u0432\u043e\u0435 \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u0435, \u0434\u0430\u043b\u0435\u0435 \u0446\u0438\u043a\u043b \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u0442 \u043a \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c\u0443 \u043b\u0443\u0447\u0443.<\/p>\n<figure class=\"full-width\">\n<div><figcaption>\u041f\u0435\u0440\u0435\u0441\u0435\u0447\u0435\u043d\u0438\u0435 \u043b\u0443\u0447\u0430 \u0438 \u043b\u0438\u043d\u0438\u0439 \u043d\u0430 \u0441\u0435\u0442\u043a\u0435<\/figcaption><\/div>\n<\/figure>\n<p>\u0422\u0430\u043a \u0436\u0435 \u043d\u0443\u0436\u043d\u043e \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u0430\u0442\u044c \u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0434\u043e \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0445 \u0438 \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u044b\u0445 \u043b\u0438\u043d\u0438\u0439 \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u043f\u0435\u0440\u0435\u0441\u0435\u043a\u0441\u044f \u043b\u0443\u0447.<\/p>\n<p>\u0412\u0441\u043f\u043e\u043c\u0438\u043d\u0430\u0435\u043c \u0448\u043a\u043e\u043b\u044c\u043d\u0443\u044e \u0442\u0440\u0438\u0433\u043e\u043d\u043e\u043c\u0435\u0442\u0440\u0438\u044e \u0438 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u044d\u0442\u043e \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0445 \u043b\u0438\u043d\u0438\u0439<\/p>\n<figure class=\"full-width\">\n<div><figcaption>\u0420\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0434\u043e \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0445 \u0438 \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u044b\u0445 \u043b\u0438\u043d\u0438\u0439 \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u043f\u0435\u0440\u0435\u0441\u0435\u043a\u0441\u044f \u043b\u0443\u0447<\/figcaption><\/div>\n<\/figure>\n<p>\u041d\u0430\u043c \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u0430 \u0441\u0442\u043e\u0440\u043e\u043d\u0430 <strong>k \u2013 \u044d\u0442\u043e \u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0438\u0433\u0440\u043e\u043a\u0430 \u0434\u043e \u0431\u043b\u043e\u043a\u0430<\/strong><\/p>\n<p><strong>a \u2013 \u044d\u0442\u043e\u00a0\u0443\u0433\u043e\u043b \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043b\u0443\u0447\u0430<\/strong><\/p>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0434\u043b\u0438\u043d\u0443, \u0442\u0430\u043a \u043a\u0430\u043a \u043c\u044b \u0437\u043d\u0430\u0435\u043c \u0440\u0430\u0437\u043c\u0435\u0440 \u043d\u0430\u0448\u0435\u0433\u043e \u0431\u043b\u043e\u043a\u0430 \u0441\u0435\u0442\u043a\u0438.<\/p>\n<p>\u0418 \u043a\u043e\u0433\u0434\u0430 \u043b\u0443\u0447 \u0432\u0440\u0435\u0436\u0435\u0442\u0441\u044f \u0432 \u0441\u0442\u0435\u043d\u0443 \u0446\u0438\u043a\u043b \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c\u0441\u044f.<\/p>\n<p>\u041f\u043e\u0442\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u043c \u044d\u0442\u043e \u043a\u043e \u0432\u0441\u0435\u043c \u043e\u0441\u044f\u043c \u0441 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0438\u043c\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f\u043c\u0438<\/p>\n<p>\u0414\u043b\u044f \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u044b\u0445 \u043b\u0438\u043d\u0438\u0439 \u0442\u043e\u0436\u0435 \u0441\u0430\u043c\u043e\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0441 \u0441\u0438\u043d\u0443\u0441\u043e\u043c.<\/p>\n<p>\u0412 \u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043b\u0443\u0447\u0430 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u043e\u0435 \u0438\u043b\u0438 \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0435 \u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u0435, \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u0431\u043b\u0438\u0436\u0435<\/p>\n<p>\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043f\u0430\u0440\u0443 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0432\u044b\u0441\u043e\u0442\u044b, \u0433\u043b\u0443\u0431\u0438\u043d\u044b, \u0440\u0430\u0437\u043c\u0435\u0440\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u044b\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0438\u0437 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u0444\u043e\u0440\u043c\u0443\u043b<\/p>\n<pre><code class=\"python\">def rayCasting(display, player):   inBlockPos = {'left': player.x - player.x \/\/ blockSize * blockSize,                 'right': blockSize - (player.x - player.x \/\/ blockSize * blockSize),                 'top': player.y - player.y \/\/ blockSize * blockSize,                 'bottom': blockSize - (player.y - player.y \/\/ blockSize * blockSize)}    for ray in range(numRays):       cur_angle = player.angle - halfFOV + deltaRays * ray       cos_a, sin_a = cos(cur_angle), sin(cur_angle)       vl, hl = 0, 0        #\u0412\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u0438       for k in range(mapWidth):           if cos_a > 0:               vl = inBlockPos['right'] \/ cos_a + blockSize \/ cos_a * k + 1           elif cos_a &lt; 0:               vl = inBlockPos['left'] \/ -cos_a + blockSize \/ -cos_a * k + 1            xw, yw = vl * cos_a + player.x, vl * sin_a + player.y           fixed = xw \/\/ blockSize * blockSize, yw \/\/ blockSize * blockSize           if fixed in blockMap:               textureV = blockMapTextures[fixed]               break        #\u0413\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u0438       for k in range(mapHeight):           if sin_a > 0:               hl = inBlockPos['bottom'] \/ sin_a + blockSize \/ sin_a * k + 1           elif sin_a &lt; 0:               hl = inBlockPos['top'] \/ -sin_a + blockSize \/ -sin_a * k + 1            xh, yh = hl * cos_a + player.x, hl * sin_a + player.y           fixed = xh \/\/ blockSize * blockSize, yh \/\/ blockSize * blockSize           if fixed in blockMap:               textureH = blockMapTextures[fixed]               break        ray_size = min(vl, hl) * depthCoef       toX, toY = ray_size * cos(cur_angle) + player.x, ray_size * sin(cur_angle) + player.y       pg.draw.line(display, pg.Color(\"yellow\"), (player.x, player.y), (toX, toY))<\/code><\/pre>\n<p>\u0420\u0438\u0441\u0443\u0435\u043c \u043f\u0440\u044f\u043c\u043e\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u0438 \u043f\u043e \u0446\u0435\u043d\u0442\u0440\u0443 \u044d\u043a\u0440\u0430\u043d\u0430, \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043f\u043e \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u0438 \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u0432\u0438\u0441\u0435\u0442\u044c \u043e\u0442 \u043d\u043e\u043c\u0435\u0440\u0430 \u043b\u0443\u0447\u0430, \u0430 \u0432\u044b\u0441\u043e\u0442\u0430 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0432\u043d\u0430 \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u044e \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u0433\u043e \u043a\u043e\u044d\u0444\u0444\u0438\u0446\u0438\u0435\u043d\u0442\u0430 \u043d\u0430 \u0434\u043b\u0438\u043d\u0443 \u043b\u0443\u0447\u0430.<\/p>\n<pre><code class=\"python\">#def rayCasting  ray_size += cos(player.angle - cur_angle) height_c = coef \/ (ray_size + 0.0001) c = 255 \/ (1 + ray_size ** 2 * 0.0000005) color = (c, c, c) block = pg.draw.rect(display, color, (ray * scale, half_height - height_c \/\/ 2, scale, height_c))<\/code><\/pre>\n<p>\u0418 \u0432\u043e\u0442 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u0443\u0436\u0435 \u043a\u0430\u043a\u0430\u044f-\u043d\u0438\u043a\u0430\u043a\u0430\u044f \u0438\u043b\u043b\u044e\u0437\u0438\u044f 3D \u0438\u0437\u043c\u0435\u0440\u0435\u043d\u0438\u044f.<\/p>\n<figure class=\"full-width\">\n<div><figcaption>\u0418\u043b\u043b\u044e\u0437\u0438\u044f 3D \u0438\u0437\u043c\u0435\u0440\u0435\u043d\u0438\u044f<\/figcaption><\/div>\n<\/figure>\n<h2>\u0422\u0435\u043a\u0441\u0442\u0443\u0440\u044b<\/h2>\n<p>1 \u0431\u043b\u043e\u043a \u0438\u043c\u0435\u0435\u0442 4 \u0441\u0442\u043e\u0440\u043e\u043d\u044b \u0438 \u043a\u0430\u0436\u0434\u0443\u044e \u0431\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u043e\u043a\u0440\u044b\u0442\u044c \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u043e\u0439.<\/p>\n<p>\u041a\u0430\u0436\u0434\u0443\u044e \u0441\u0442\u043e\u0440\u043e\u043d\u0443 \u043c\u044b \u0440\u0430\u0437\u0434\u0435\u043b\u044f\u0435\u043c \u043d\u0430 \u043f\u043e\u043b\u043e\u0441\u043a\u0438 \u0441 \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u043e\u0439 \u0448\u0438\u0440\u0438\u043d\u043e\u0439, \u0433\u043b\u0430\u0432\u043d\u043e\u0435 \u0447\u0442\u043e\u0431\u044b \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043b\u0443\u0447\u0435\u0439 \u043f\u0430\u0434\u0430\u044e\u0449\u0438\u0445 \u043d\u0430 \u0431\u043b\u043e\u043a \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u043b\u043e \u0441 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u043f\u043e\u043b\u043e\u0441\u043e\u043a \u043d\u0430 \u0441\u0442\u043e\u0440\u043e\u043d\u0435, \u0438 \u0434\u0435\u043b\u0438\u043c \u043d\u0430 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u044d\u0442\u0438\u0445 \u043f\u043e\u043b\u043e\u0441\u043e\u043a \u043d\u0430\u0448\u0443 \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u0443 \u0438 \u043f\u043e\u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0435\u043c \u043f\u043e\u043b\u043e\u0441\u043a\u0443 \u0438\u0437 \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u044b \u043d\u0430 \u043f\u043e\u043b\u043e\u0441\u043a\u0443 \u043d\u0430 \u0431\u043b\u043e\u043a\u0435.<\/p>\n<figure class=\"full-width\">\n<div><figcaption>\u041d\u0430\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u043e\u0441\u043e\u043a \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u044b \u043d\u0430 \u0431\u043b\u043e\u043a<\/figcaption><\/div>\n<\/figure>\n<p>\u0422\u0430\u043a \u0448\u0438\u0440\u0438\u043d\u0430 \u0431\u0443\u0434\u0435\u0442 \u0432\u0430\u0440\u044c\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0443\u0434\u0430\u043b\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u0441\u0442\u043e\u0440\u043e\u043d\u044b \u0431\u043b\u043e\u043a\u0430. \u0410 \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u043e\u0441\u043a\u0438 \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u0443\u0442\u0435\u043c \u0443\u043c\u043d\u043e\u0436\u0435\u043d\u0438\u044f \u043e\u0442\u0441\u0442\u0443\u043f\u0430 \u043d\u0430 \u0440\u0430\u0437\u043c\u0435\u0440 \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u044b.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u043b\u0443\u0447 \u043f\u0430\u0434\u0430\u0435\u0442 \u043d\u0430 \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c \u0442\u043e \u043e\u0442\u0441\u0442\u0443\u043f \u0432\u044b\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u043c \u043e\u0442 \u0432\u0435\u0440\u0445\u043d\u0435\u0439 \u0442\u043e\u0447\u043a\u0438, \u0435\u0441\u043b\u0438 \u043d\u0430 \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c \u0442\u043e \u043e\u0442 \u043b\u0435\u0432\u043e\u0439 \u0442\u043e\u0447\u043a\u0438.<\/p>\n<figure class=\"full-width\">\n<div><figcaption>\u0420\u0430\u0441\u0447\u0435\u0442 \u043e\u0442\u0441\u0442\u0443\u043f\u0430<\/figcaption><\/div>\n<\/figure>\n<pre><code class=\"python\">#def rayCasting  if hl > vl:     ray_size = vl     mr = yw     textNum = textureV else:     ray_size = hl     mr = xh     textNum = textureH  mr = int(mr) % blockSize  textures[textNum].set_alpha(c) wallLine = textures[textNum].subsurface(mr * textureScale, 0, textureScale, textureSize) wallLine = pg.transform.scale(wallLine, (scale, int(height_c))).convert_alpha() display.blit(wallLine, (ray * scale, half_height - height_c \/\/ 2))<\/code><\/pre>\n<p>\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0435\u0449\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0442\u0435\u043a\u0441\u0442\u0443\u0440 \u043d\u0430 \u043e\u0434\u043d\u043e\u0439 \u043a\u0430\u0440\u0442\u0435 \u043f\u0443\u0442\u0435\u043c \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043d\u0430 \u043a\u0430\u0440\u0442\u0443 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0445 \u0437\u043d\u0430\u043a\u043e\u0432, \u043a\u0430\u0436\u0434\u043e\u043c\u0443 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u0441\u0432\u043e\u044f \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u0430.<\/p>\n<figure class=\"full-width\">\n<div><figcaption>\u0421\u043f\u0438\u0441\u043e\u043a \u043c\u043e\u0438\u0445 \u0437\u043d\u0430\u043a\u043e\u0432 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0443\u0440\u043e\u0432\u043d\u0435\u0439<\/figcaption><\/div>\n<\/figure>\n<p>\u0412\u043e\u0442 \u043f\u0440\u0438\u043c\u0435\u0440 \u043a\u0430\u043a \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 2-\u043e\u0439 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u0432 \u0438\u0433\u0440\u0435 \u0432 \u0432\u0438\u0434\u0435 \u043a\u043e\u0434\u0430:<\/p>\n<pre><code class=\"python\">textMaplvl2 = [             \"111111111111111111111111\",             \"1111................1111\",             \"11.........1....11...111\",             \"11....151..1....31...111\",             \"1111............331...11\",             \"11111.....115..........1\",             \"1111.....11111....1113.1\",             \"115.......111......333.1\",             \"15....11.......11......1\",             \"11....11.......11..11111\",             \"111...................51\",             \"111........1......115551\",             \"11111...11111...11111111\",             \"11111%&lt;@1111111111111111\", ]<\/code><\/pre>\n<p>\u0412 \u0438\u0442\u043e\u0433\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0430\u0434\u0435\u043a\u0432\u0430\u0442\u043d\u043e\u0435 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0442\u0435\u043a\u0441\u0442\u0443\u0440:<\/p>\n<figure class=\"full-width\"><\/figure>\n<h2>\u041a\u043e\u043b\u043b\u0438\u0437\u0438\u044f<\/h2>\n<p>\u0413\u0434\u0435 \u0436\u0435 \u0442\u0430\u043a\u043e\u0435 \u0432\u0438\u0434\u0430\u043d\u043e \u0447\u0442\u043e \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442\u044c \u0447\u0435\u0440\u0435\u0437 \u0431\u043b\u043e\u043a\u0438\u2026   <\/p>\n<p>\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043a\u043e\u043b\u043b\u0438\u0437\u0438\u044e. \u041a \u043a\u0430\u0436\u0434\u043e\u0439 \u043f\u043e\u0437\u0438\u0446\u0438\u044f \u0431\u043b\u043e\u043a\u0430 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0442\u0430\u043a \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u043c\u044b\u0439 \u043a\u043e\u043b\u043b\u0430\u0439\u0434\u0435\u0440 \u0438 \u0442\u0430\u043a\u043e\u0439 \u0436\u0435 \u043a\u043e\u043b\u043b\u0430\u0439\u0434\u0435\u0440 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0438\u0433\u0440\u043e\u043a\u0443. \u0415\u0441\u043b\u0438 \u043e\u043d \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442 \u0438\u0434\u0442\u0438 \u0442\u0430\u043a \u043a\u0430\u043a \u0448\u0435\u043b \u0438 \u0442\u0430\u043a\u0438\u043c\u0438 \u0442\u0435\u043c\u043f\u0430\u043c\u0438 \u043d\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c \u043a\u0430\u0434\u0440\u0435 \u043f\u043e \u043f\u0440\u0435\u0434\u0441\u043a\u0430\u0437\u0430\u043d\u0438\u044e \u0437\u0430\u0439\u0434\u0435\u0442 \u0432 \u0431\u043b\u043e\u043a, \u0442\u043e \u043c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u0437\u0430\u043d\u0443\u043b\u044f\u0435\u043c \u0443\u0441\u043a\u043e\u0440\u0435\u043d\u0438\u0435 \u043f\u043e \u043d\u0443\u0436\u043d\u043e\u0439 \u043e\u0441\u0438.<\/p>\n<figure class=\"full-width\">\n<div><figcaption>\u0421\u0442\u043e\u043b\u043a\u043d\u043e\u0432\u0435\u043d\u0438\u0435 \u0431\u043b\u043e\u043a\u0430 \u0438 \u0438\u0433\u0440\u043e\u043a\u0430<\/figcaption><\/div>\n<\/figure>\n<p>\u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0447\u0443\u0442\u044c \u0434\u043e\u043f\u0438\u0448\u0435\u043c \u043a\u043b\u0430\u0441\u0441 <strong>Player<\/strong>. \u042f \u0440\u0435\u0448\u0438\u043b \u0435\u0449\u0435 \u0441\u0440\u0430\u0437\u0443 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043a\u0430\u043c\u0435\u0440\u043e\u0439 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u044b\u0448\u0438. \u0412\u043e\u0442 \u043a\u0430\u043a \u043f\u043e \u0438\u0442\u043e\u0433\u0443 \u0441\u0442\u0430\u043b \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u044d\u0442\u043e\u0442 \u043a\u043b\u0430\u0441\u0441:<\/p>\n<pre><code class=\"python\">class Player:     def __init__(self):         self.x = 0         self.y = 0          self.angle = 0         self.delta = 0         self.speed = 100         self.mouse_sense = settings.mouse_sensivity          #collision         self.side = 50         self.rect = pygame.Rect(*(self.x, self.y), self.side, self.side)      def detect_collision_wall(self, dx, dy):         next_rect =<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-350658","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/350658","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=350658"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/350658\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=350658"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=350658"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=350658"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}