{"id":286063,"date":"2017-05-09T20:10:04","date_gmt":"2017-05-09T16:10:04","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=286063"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=286063","title":{"rendered":"\u0414\u0435\u043b\u0430\u0435\u043c Space Invaders \u043d\u0430 Love2d \u0438 Lua"},"content":{"rendered":"<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/web\/92a\/03a\/066\/92a03a0667b54bf4aee39deb4ef5752d.png\"\/><\/p>\n<p>  \u0414\u043e\u0431\u0440\u044b\u0439 \u0434\u0435\u043d\u044c! \u0421\u0435\u0433\u043e\u0434\u043d\u044f \u0431\u0443\u0434\u0435\u043c \u0434\u0435\u043b\u0430\u0442\u044c \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u0443\u044e \u0438\u0433\u0440\u0443 Space Invaders \u043d\u0430 \u0434\u0432\u0438\u0436\u043a\u0435 <a href=\"https:\/\/love2d.org\/\">Love2d<\/a>. \u0414\u043b\u044f \u043b\u044e\u0431\u0438\u0442\u0435\u043b\u0435\u0439 \u00ab\u043a\u043e\u0434\u0430 \u0441\u0440\u0430\u0437\u0443\u00bb \u043e\u043a\u043e\u043d\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e \u0438\u0433\u0440\u044b \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043d\u0430 <a href=\"https:\/\/github.com\/vlfedotov\/small_games\/tree\/games\/space-invaders\">\u0433\u0438\u0442\u0445\u0430\u0431\u0435<\/a>. \u0422\u0435\u043c \u0436\u0435 \u043a\u043e\u043c\u0443 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0435\u043d \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438, \u0434\u043e\u0431\u0440\u043e \u043f\u043e\u0436\u0430\u043b\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0434 \u043a\u0430\u0442.<br \/>  <a name=\"habracut\"><\/a><br \/>  \u0417\u0434\u0435\u0441\u044c \u044f \u043d\u0435 \u0441\u043c\u043e\u0433\u0443 \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0432\u0441\u0435\u0433\u043e, \u0447\u0442\u043e \u0435\u0441\u0442\u044c \u0432 \u043e\u043a\u043e\u043d\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438, \u044d\u0442\u043e \u0438 \u043d\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e \u0438 \u0441\u0434\u0435\u043b\u0430\u0435\u0442 \u0441\u0442\u0430\u0442\u044c\u044e \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u043e\u0439. \u041c\u043e\u0433\u0443 \u0441\u043a\u0430\u0437\u0430\u0442\u044c, \u0447\u0442\u043e \u043a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u044f \u0440\u0430\u0437\u0431\u0435\u0440\u0443 \u0437\u0434\u0435\u0441\u044c, \u0438\u0433\u0440\u0430 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0440\u0430\u0437\u043d\u044b\u0435 \u0440\u0435\u0436\u0438\u043c\u044b (\u043f\u0430\u0443\u0437\u0430, \u043f\u0440\u043e\u0438\u0433\u0440\u044b\u0448, \u0432\u044b\u0438\u0433\u0440\u044b\u0448), \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0432\u043e\u0434\u0438\u0442\u044c \u043e\u0442\u043b\u0430\u0434\u043e\u0447\u043d\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e (\u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0438 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432, \u043f\u0430\u043c\u044f\u0442\u044c, \u043f\u0440.), \u0443 \u0418\u0433\u0440\u043e\u043a\u0430 \u0435\u0441\u0442\u044c \u0436\u0438\u0437\u043d\u0438 \u0438 \u0432\u0435\u0434\u0451\u0442\u0441\u044f \u0441\u0447\u0451\u0442, \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0442 \u0440\u0430\u0437\u043d\u044b\u0435 \u0443\u0440\u043e\u0432\u043d\u0438 \u0438\u0433\u0440\u044b (\u043d\u0435 \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u044c, \u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c). \u0412\u0441\u0451 \u044d\u0442\u043e \u043b\u0438\u0431\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432 \u043a\u043e\u0434\u0435, \u043b\u0438\u0431\u043e \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b.<\/p>\n<p>  \u0418\u0442\u0430\u043a, <b>\u043f\u043b\u0430\u043d \u0440\u0430\u0431\u043e\u0442\u044b:<\/b><\/p>\n<ul>\n<li><a href=\"#main\">\u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430<\/a><\/li>\n<li><a href=\"#player\">\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0438\u0433\u0440\u043e\u043a\u0430<\/a><\/li>\n<li><a href=\"#enemies\">\u0412\u0440\u0430\u0433\u043e\u0432<\/a><\/li>\n<li><a href=\"#walls\">\u0421\u0442\u0435\u043d\u044b \u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u043a\u043e\u043b\u043b\u0438\u0437\u0438\u0439<\/a><\/li>\n<li><a href=\"#bullets\">\u0423\u0447\u0438\u043c \u0438\u0433\u0440\u043e\u043a\u0430 \u0441\u0442\u0440\u0435\u043b\u044f\u0442\u044c<\/a><\/li>\n<li><a href=\"#graphics\">\u041f\u0440\u0438\u043a\u0440\u0435\u043f\u043b\u044f\u0435\u043c \u0433\u0440\u0430\u0444\u0438\u043a\u0443<\/a><\/li>\n<\/ul>\n<p>  <a name=\"main\"><\/a><\/p>\n<h3>\u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430<\/h3>\n<p>  \u0412 <em>main.lua<\/em> \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0432\u044b\u0437\u043e\u0432\u044b \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 love2d. \u041a\u0430\u0436\u0434\u044b\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0438\u043b\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u0432\u043f\u043e\u0441\u043b\u0435\u0434\u0441\u0442\u0432\u0438\u0438 \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u0440\u044f\u043c\u043e \u0438\u043b\u0438 \u043a\u043e\u0441\u0432\u0435\u043d\u043d\u043e \u0431\u044b\u0442\u044c \u0441\u0432\u044f\u0437\u0430\u043d\u044b \u0441 \u044d\u0442\u0438\u043c\u0438 \u043c\u0435\u0442\u043e\u0434\u0430\u043c\u0438, \u0438\u043d\u0430\u0447\u0435 \u043f\u0440\u043e\u0439\u0434\u0443\u0442 \u043d\u0435\u0437\u0430\u043c\u0435\u0447\u0435\u043d\u043d\u044b\u043c\u0438.<\/p>\n<pre><code class=\"lua\">function love.load() end  function love.keyreleased( key ) end  function love.draw() end  function love.update( dt ) end <\/code><\/pre>\n<p>  <a name=\"player\"><\/a><\/p>\n<h3>\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0438\u0433\u0440\u043e\u043a\u0430<\/h3>\n<p>  \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0432 \u043a\u043e\u0440\u0435\u043d\u044c \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0444\u0430\u0439\u043b <em>player.lua<\/em><\/p>\n<pre><code class=\"lua\"> local player = {}  player.position_x = 500 player.position_y = 550 player.speed_x = 300  player.width = 50 player.height = 50  function player.update( dt )     if love.keyboard.isDown( &quot;right&quot; ) and              player.position_x &lt; ( love.graphics.getWidth() - player.width ) then         player.position_x = player.position_x + ( player.speed_x * dt )     end     if love.keyboard.isDown( &quot;left&quot; )  and player.position_x &gt; 0 then         player.position_x = player.position_x - ( player.speed_x * dt )     end end  function player.draw()     love.graphics.rectangle(                        &quot;fill&quot;,                        player.position_x,                        player.position_y,                        player.width,                        player.height                  ) end  return player <\/code><\/pre>\n<p>  \u0410 \u0442\u0430\u043a\u0436\u0435 \u043e\u0431\u043d\u043e\u0432\u0438\u043c <em>main.lua<\/em><\/p>\n<pre><code class=\"lua\">local player = require 'player'  function love.draw()         player.draw() end  function love.update( dt )         player.update( dt ) end <\/code><\/pre>\n<p>  \u0415\u0441\u043b\u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0438\u0433\u0440\u0443, \u0442\u043e \u043c\u044b \u0443\u0432\u0438\u0434\u0438\u043c \u0447\u0451\u0440\u043d\u044b\u0439 \u044d\u043a\u0440\u0430\u043d \u0441 \u0431\u0435\u043b\u044b\u043c \u043a\u0432\u0430\u0434\u0440\u0430\u0442\u043e\u043c \u0441\u043d\u0438\u0437\u0443, \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u043c\u043e\u0436\u043d\u043e \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u043a\u043b\u0430\u0432\u0438\u0448\u0430\u043c\u0438 \u00ab\u0432\u043b\u0435\u0432\u043e\u00bb \u0438 \u00ab\u0432\u043f\u0440\u0430\u0432\u043e\u00bb. \u041f\u0440\u0438\u0447\u0451\u043c \u0432\u044b\u0439\u0442\u0438 \u0437\u0430 \u043f\u0440\u0435\u0434\u0435\u043b\u044b \u044d\u043a\u0440\u0430\u043d\u0430 \u043e\u043d \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0432 \u0441\u0438\u043b\u0443 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0439 \u0432 \u043a\u043e\u0434\u0435 \u0418\u0433\u0440\u043e\u043a\u0430:<\/p>\n<pre><code class=\"lua\">player.position.x &lt; ( love.graphics.getWidth() - player.width ) player.position.x &gt; 0 <\/code><\/pre>\n<p>  <a name=\"enemies\"><\/a><\/p>\n<h3>\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u0432\u0440\u0430\u0433\u043e\u0432<\/h3>\n<p>  \u0422\u0430\u043a \u043a\u0430\u043a \u0431\u043e\u0440\u043e\u0442\u044c\u0441\u044f \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u043f\u0440\u043e\u0442\u0438\u0432 \u0438\u043d\u043e\u0437\u0435\u043c\u043d\u044b\u0445 \u0437\u0430\u0445\u0432\u0430\u0442\u0447\u0438\u043a\u043e\u0432, \u0442\u043e \u0438 \u0444\u0430\u0439\u043b\u0438\u043a \u0441 \u043d\u0438\u043c\u0438 \u043d\u0430\u0437\u043e\u0432\u0451\u043c <em>invaders.lua<\/em>:<\/p>\n<pre><code class=\"lua\"> local invaders = {}  invaders.rows = 5 invaders.columns = 9  invaders.top_left_position_x = 50 invaders.top_left_position_y = 50  invaders.invader_width = 40 invaders.invader_height = 40  invaders.horizontal_distance = 20 invaders.vertical_distance = 30  invaders.current_speed_x = 50  invaders.current_level_invaders = {}  local initial_speed_x = 50 local initial_direction = 'right'  function invaders.new_invader( position_x, position_y )     return { position_x = position_x,                  position_y = position_y,                  width = invaders.invader_width,                  height = invaders.invader_height } end  function invaders.new_row( row_index )     local row = {}     for col_index=1, invaders.columns - (row_index % 2) do         local new_invader_position_x = invaders.top_left_position_x + invaders.invader_width * (row_index % 2) + (col_index - 1) * (invaders.invader_width + invaders.horizontal_distance)         local new_invader_position_y = invaders.top_left_position_y + (row_index - 1) * (invaders.invader_height + invaders.vertical_distance)         local new_invader = invaders.new_invader( new_invader_position_x, new_invader_position_y )         table.insert( row, new_invader )     end     return row end  function invaders.construct_level()     invaders.current_speed_x = initial_speed_x     for row_index=1, invaders.rows do         local invaders_row = invaders.new_row( row_index )         table.insert( invaders.current_level_invaders, invaders_row )     end end  function invaders.draw_invader( single_invader )     love.graphics.rectangle('line',                        single_invader.position_x,                        single_invader.position_y,                        single_invader.width,                        single_invader.height ) end  function invaders.draw()     for _, invader_row in pairs( invaders.current_level_invaders ) do         for _, invader in pairs( invader_row ) do             invaders.draw_invader( invader, is_miniboss )         end     end end  function invaders.update_invader( dt, single_invader )     single_invader.position_x = single_invader.position_x + invaders.current_speed_x * dt end  function invaders.update( dt )     local invaders_rows = 0     for _, invader_row in pairs( invaders.current_level_invaders ) do         invaders_rows = invaders_rows + 1     end     if invaders_rows == 0 then         invaders.no_more_invaders = true     else         for _, invader_row in pairs( invaders.current_level_invaders ) do             for _, invader in pairs( invader_row ) do                 invaders.update_invader( dt, invader )             end         end     end end  return invaders <\/code><\/pre>\n<p>  \u041e\u0431\u043d\u043e\u0432\u0438\u043c <em>main.lua<\/em><\/p>\n<pre><code class=\"lua\">... local invaders = require 'invaders'  function love.load()         invaders.construct_level() end  function love.draw()         ...         invaders.draw() end  function love.update( dt )         ...         invaders.update( dt ) end <\/code><\/pre>\n<p>  <em>love.load<\/em> \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u0441\u0430\u043c\u043e\u043c \u043d\u0430\u0447\u0430\u043b\u0435 \u0440\u0430\u0431\u043e\u0442\u044b \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u041e\u043d \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u043c\u0435\u0442\u043e\u0434 <em>invaders.construct_level<\/em>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 <em>invaders.current_level_invaders<\/em> \u0438 \u043d\u0430\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0435\u0451 \u043f\u043e \u0441\u0442\u0440\u043e\u043a\u0430\u043c \u0438 \u0441\u0442\u043e\u043b\u0431\u0446\u0430\u043c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u043c\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u0430\u043c\u0438 <em>invader<\/em> \u0441 \u0443\u0447\u0451\u0442\u043e\u043c \u0432\u044b\u0441\u043e\u0442\u044b \u0438 \u0448\u0438\u0440\u0438\u043d\u044b \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u043c\u043e\u0433\u043e \u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043c\u0435\u0436\u0434\u0443 \u043d\u0438\u043c\u0438 \u043f\u043e \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u0438 \u0438 \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u0438. \u041f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0443\u0441\u043b\u043e\u0436\u043d\u0438\u0442\u044c \u043c\u0435\u0442\u043e\u0434 <em>invaders.new_row<\/em>, \u0447\u0442\u043e\u0431\u044b \u0434\u043e\u0431\u0438\u0442\u044c\u0441\u044f \u0441\u043c\u0435\u0449\u0435\u043d\u0438\u044f \u0447\u0451\u0442\u043d\u044b\u0445 \u0438 \u043d\u0435\u0447\u0451\u0442\u043d\u044b\u0445 \u0440\u044f\u0434\u043e\u0432. \u0415\u0441\u043b\u0438 \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u0442\u0435\u043a\u0443\u0449\u0443\u044e \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e:<\/p>\n<pre><code class=\"lua\">for col_index=1, invaders.columns - (row_index % 2) do     local new_invader_position_x = invaders.top_left_position_x + invaders.invader_width * (row_index % 2) + (col_index - 1) * (invaders.invader_width + invaders.horizontal_distance) <\/code><\/pre>\n<p>  \u0432\u043e\u0442 \u0442\u0430\u043a\u043e\u0439:<\/p>\n<pre><code class=\"lua\">for col_index=1, invaders.columns do     local new_invader_position_x = invaders.top_left_position_x + (col_index - 1) * (invaders.invader_width + invaders.horizontal_distance) <\/code><\/pre>\n<p>  \u0442\u043e \u0443\u0431\u0435\u0440\u0451\u043c \u044d\u0442\u043e\u0442 \u044d\u0444\u0444\u0435\u043a\u0442 \u0438 \u0432\u0435\u0440\u043d\u0451\u043c \u043f\u0440\u044f\u043c\u043e\u0443\u0433\u043e\u043b\u044c\u043d\u043e\u0435 \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435. \u0421\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435 \u043d\u0430 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0430\u0445  <\/p>\n<table>\n<tr>\n<th>\u0422\u0435\u043a\u0443\u0449\u0438\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442<\/th>\n<th>\u041f\u0440\u044f\u043c\u043e\u0443\u0433\u043e\u043b\u044c\u043d\u044b\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442<\/th>\n<\/tr>\n<tr>\n<td><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/web\/1e7\/85e\/166\/1e785e16664545d8a3847a888da7fb32.png\"\/><\/td>\n<td><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/web\/17f\/9e6\/e92\/17f9e6e92dcc468e808b9ec4ddefc24f.png\"\/><\/td>\n<\/tr>\n<\/table>\n<p>  \u041e\u0431\u044a\u0435\u043a\u0442 <em>invader<\/em> \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0441\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430\u043c\u0438: position_x, position_y, width, height. \u0412\u0441\u0451 \u044d\u0442\u043e \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u0430, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043f\u043e\u0437\u0434\u043d\u0435\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043d\u0430 \u043a\u043e\u043b\u043b\u0438\u0437\u0438\u0438 \u0441 \u0432\u044b\u0441\u0442\u0440\u0435\u043b\u0430\u043c\u0438.<\/p>\n<p>  <em>love.draw<\/em> \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 <em>invaders.draw<\/em> \u0438 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0432\u0441\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u0432\u043e \u0432\u0441\u0435\u0445 \u0440\u044f\u0434\u0430\u0445 \u0442\u0430\u0431\u043b\u0438\u0446\u044b <em>invaders.current_level_invaders<\/em>.<\/p>\n<p>  <em>love.update<\/em>, \u0430 \u0441\u043b\u0435\u0434\u043e\u043c \u0438 <em>invaders.update<\/em> \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u044e\u0442 \u0442\u0435\u043a\u0443\u0449\u0443\u044e \u043f\u043e\u0437\u0438\u0446\u0438\u044e \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0437\u0430\u0445\u0432\u0430\u0442\u0447\u0438\u043a\u0430 \u0441 \u0443\u0447\u0451\u0442\u043e\u043c \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u043e\u043a\u0430 \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u043d\u0430 \u2014 \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u0430\u044f.<\/p>\n<p>  \u0417\u0430\u0445\u0432\u0430\u0442\u0447\u0438\u043a\u0438 \u0443\u0436\u0435 \u043d\u0430\u0447\u0430\u043b\u0438 \u0434\u0432\u0438\u0433\u0430\u0442\u044c\u0441\u044f, \u043d\u043e \u043f\u043e\u043a\u0430 \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u043f\u0440\u0430\u0432\u043e, \u0437\u0430 \u044d\u043a\u0440\u0430\u043d. \u042d\u0442\u043e \u043c\u044b \u0441\u0435\u0439\u0447\u0430\u0441 \u043f\u043e\u043f\u0440\u0430\u0432\u0438\u043c.<br \/>  <a name=\"walls\"><\/a><\/p>\n<h3>\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u0441\u0442\u0435\u043d\u044b \u0438 \u043a\u043e\u043b\u043b\u0438\u0437\u0438\u0438<\/h3>\n<p>  \u041d\u043e\u0432\u044b\u0439 \u0444\u0430\u0439\u043b <em>walls.lua<\/em><\/p>\n<pre><code class=\"lua\">local walls = {}  walls.wall_thickness = 1 walls.bottom_height_gap = 1\/5 * love.graphics.getHeight()  walls.current_level_walls = {}  function walls.new_wall( position_x, position_y, width, height )     return { position_x = position_x,              position_y = position_y,              width = width,              height = height } end  function walls.construct_level()     local left_wall = walls.new_wall( 0,                                       0,                                       walls.wall_thickness,                                       love.graphics.getHeight() - walls.bottom_height_gap                                 )     local right_wall = walls.new_wall( love.graphics.getWidth() - walls.wall_thickness,                                        0,                                        walls.wall_thickness,                                        love.graphics.getHeight() - walls.bottom_height_gap                                 )     local top_wall = walls.new_wall( 0,                                      0,                                      love.graphics.getWidth(),                                      walls.wall_thickness                                 )     local bottom_wall = walls.new_wall( 0,                                  love.graphics.getHeight() - walls.bottom_height_gap - walls.wall_thickness,                                 love.graphics.getWidth(),                                 walls.wall_thickness                                 )     walls.current_level_walls[&quot;left&quot;] = left_wall     walls.current_level_walls[&quot;right&quot;] = right_wall     walls.current_level_walls[&quot;top&quot;] = top_wall     walls.current_level_walls[&quot;bottom&quot;] = bottom_wall end  function walls.draw_wall(wall)     love.graphics.rectangle( 'line',                              wall.position_x,                              wall.position_y,                              wall.width,                              wall.height                         ) end  function walls.draw()     for _, wall in pairs( walls.current_level_walls ) do         walls.draw_wall( wall )     end end  return walls <\/code><\/pre>\n<p>  \u0418 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0432 <em>main.lua<\/em><\/p>\n<pre><code class=\"lua\">... local walls    = require 'walls'  function love.load()     ...     walls.construct_level() end  function love.draw()     ...     -- walls.draw() end <\/code><\/pre>\n<p>  \u0410\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e \u0441 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435\u043c \u0437\u0430\u0445\u0432\u0430\u0442\u0447\u0438\u043a\u043e\u0432, \u0437\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0441\u0442\u0435\u043d \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0432\u044b\u0437\u043e\u0432 <em>walls.construct_level<\/em>. \u0421\u0442\u0435\u043d\u044b \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u044b \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0445\u0432\u0430\u0442\u0430 \u00ab\u0441\u0442\u043e\u043b\u043a\u043d\u043e\u0432\u0435\u043d\u0438\u0439\u00bb \u0441 \u043d\u0438\u043c\u0438 \u0437\u0430\u0445\u0432\u0430\u0442\u0447\u0438\u043a\u043e\u0432 \u0438 \u0432\u044b\u0441\u0442\u0440\u0435\u043b\u043e\u0432, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u0438\u0445 \u043d\u0430\u043c \u0431\u0435\u0437 \u043d\u0430\u0434\u043e\u0431\u043d\u043e\u0441\u0442\u0438. \u041d\u043e \u044d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u0446\u0435\u043b\u0435\u0439 \u043e\u0442\u043b\u0430\u0434\u043a\u0438, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0443 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 Walls \u0438\u043c\u0435\u0435\u0442\u0441\u044f \u043c\u0435\u0442\u043e\u0434 draw, \u0432\u044b\u0437\u043e\u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e \u0438\u0437 <em>main.lua -&gt; love.draw<\/em>, \u043d\u043e \u043f\u043e\u043a\u0430 \u043e\u0442\u043b\u0430\u0434\u043a\u0430 \u043d\u0435 \u043d\u0443\u0436\u043d\u0430 \u2014 \u043e\u043d (\u0432\u044b\u0437\u043e\u0432) \u0437\u0430\u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d.<\/p>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u043a\u043e\u043b\u043b\u0438\u0437\u0438\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u044b\u043b \u043c\u043d\u043e\u0439 \u043f\u043e\u0437\u0430\u0438\u043c\u0441\u0442\u0432\u043e\u0432\u0430\u043d <a href=\"https:\/\/github.com\/noooway\/love2d_arkanoid_tutorial\/wiki\">\u043e\u0442\u0441\u044e\u0434\u0430<\/a>. \u0418\u0442\u0430\u043a, <em>collisions.lua<\/em><\/p>\n<pre><code class=\"lua\">local collisions = {}  function collisions.check_rectangles_overlap( a, b )     local overlap = false     if not( a.x + a.width &lt; b.x or b.x + b.width &lt; a.x or             a.y + a.height &lt; b.y or b.y + b.height &lt; a.y ) then         overlap = true     end     return overlap end  function collisions.invaders_walls_collision( invaders, walls )     local overlap, wall     if invaders.current_speed_x &gt; 0 then         wall, wall_type = walls.current_level_walls['right'], 'right'     else         wall, wall_type = walls.current_level_walls['left'], 'left'     end          local a = { x = wall.position_x,                 y = wall.position_y,                 width = wall.width,                 height = wall.height }     for _, invader_row in pairs( invaders.current_level_invaders ) do         for _, invader in pairs( invader_row ) do             local b = { x = invader.position_x,                         y = invader.position_y,                         width = invader.width,                         height = invader.height }             overlap = collisions.check_rectangles_overlap( a, b )             if overlap then                 if wall_type == invaders.allow_overlap_direction then                     invaders.current_speed_x = -invaders.current_speed_x                      if invaders.allow_overlap_direction == 'right' then                         invaders.allow_overlap_direction = 'left'                     else                         invaders.allow_overlap_direction = 'right'                     end                     invaders.descend_by_row()                 end             end         end     end end  function collisions.resolve_collisions( invaders, walls )     collisions.invaders_walls_collision( invaders, walls ) end  return collisions <\/code><\/pre>\n<p>  \u0414\u043e\u0431\u0430\u0432\u0438\u043c \u043f\u0430\u0440\u0443 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u0432 <em>invaders.lua<\/em><\/p>\n<pre><code class=\"lua\">invaders.allow_overlap_direction = 'right'  function invaders.descend_by_row_invader( single_invader )     single_invader.position_y = single_invader.position_y + invaders.vertical_distance \/ 2 end  function invaders.descend_by_row()     for _, invader_row in pairs( invaders.current_level_invaders ) do         for _, invader in pairs( invader_row ) do             invaders.descend_by_row_invader( invader )         end     end end <\/code><\/pre>\n<p>  \u0418 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u043d\u0430 \u043a\u043e\u043b\u043b\u0438\u0437\u0438\u0438 \u0432 <em>main.lua<\/em><\/p>\n<pre><code class=\"lua\">local collisions = require 'collisions'  function love.update( dt )     ...     collisions.resolve_collisions( invaders, walls ) end <\/code><\/pre>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u0437\u0430\u0445\u0432\u0430\u0442\u0447\u0438\u043a\u0438 \u043d\u0430\u0442\u044b\u043a\u0430\u044e\u0442\u0441\u044f \u043d\u0430 \u0441\u0442\u0435\u043d\u0443 <em>collisions.invaders_walls_collision<\/em> \u0438 \u0441\u043f\u0443\u0441\u043a\u0430\u044e\u0442\u0441\u044f \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043f\u043e\u043d\u0438\u0436\u0435, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043c\u0435\u043d\u044f\u044e\u0442 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043d\u0430 \u043f\u0440\u043e\u0442\u0438\u0432\u043e\u043f\u043e\u043b\u043e\u0436\u043d\u0443\u044e.<\/p>\n<p>  \u041f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u0432\u0432\u0435\u0441\u0442\u0438 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u0443\u044e \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u043d\u0430 \u0440\u0430\u0432\u0435\u043d\u0441\u0442\u0432\u043e \u0442\u0438\u043f\u0430 \u0442\u043e\u0439 \u0441\u0442\u0435\u043d\u044b, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043d\u0430\u0442\u043a\u043d\u0443\u043b\u0438\u0441\u044c \u0437\u0430\u0445\u0432\u0430\u0442\u0447\u0438\u043a\u0438, \u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u0439 \u0442\u0438\u043f:<\/p>\n<pre><code class=\"lua\">if overlap then     if wall_type == invaders.allow_overlap_direction then     ... <\/code><\/pre>\n<p>  \u0438\u0437-\u0437\u0430 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u043d\u0430 \u0441\u0442\u0435\u043d\u0443 \u043d\u0430\u0442\u044b\u043a\u0430\u044e\u0442\u0441\u044f \u0441\u0440\u0430\u0437\u0443 \u0432\u0441\u0435 \u0437\u0430\u0445\u0432\u0430\u0442\u0447\u0438\u043a\u0438 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u0438\u0437 \u043a\u0440\u0430\u0439\u043d\u0435\u0433\u043e \u0441\u0442\u043e\u043b\u0431\u0446\u0430 \u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u043a\u043e\u043b\u043b\u0438\u0437\u0438\u0439 \u0443\u0441\u043f\u0435\u0432\u0430\u0435\u0442 \u00ab\u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e\u00bb \u043e\u0442\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0438 \u0441\u043d\u0438\u0437\u0438\u0442\u044c \u043d\u0430 \u043e\u0434\u0438\u043d \u0440\u044f\u0434 \u0432\u0435\u0441\u044c \u043a\u043e\u043b\u043b\u0435\u043a\u0442\u0438\u0432, \u043f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c, \u0437\u0430\u0445\u0432\u0430\u0442\u0447\u0438\u043a\u0438 \u0440\u0430\u0437\u0432\u0435\u0440\u043d\u0443\u0442\u0441\u044f \u0438 \u0432\u044b\u0439\u0434\u0443\u0442 \u0438\u0437 \u0441\u043e\u043f\u0440\u0438\u043a\u043e\u0441\u043d\u043e\u0432\u0435\u043d\u0438\u0439, \u0432 \u0438\u0442\u043e\u0433\u0435 \u0430\u0440\u043c\u0430\u0434\u0430 \u0441\u043f\u0443\u0441\u043a\u0430\u043b\u0430\u0441\u044c \u0441\u0440\u0430\u0437\u0443 \u043d\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u044f\u0434\u043e\u0432. \u0422\u0443\u0442 \u043b\u0438\u0431\u043e \u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043a\u0430\u043a\u043e\u0439-\u043d\u0438\u0431\u0443\u0434\u044c \u0431\u043b\u043e\u043a \u043f\u0440\u0438 \u0432\u043e\u0437\u043d\u0438\u043a\u043d\u043e\u0432\u0435\u043d\u0438\u0438 \u043e\u0434\u043d\u043e\u0439 \u043a\u043e\u043b\u043b\u0438\u0437\u0438\u0438 \u043d\u0430 \u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0438\u0435 \u043a\u043e\u043b\u043b\u0438\u0437\u0438\u0438, \u043b\u0438\u0431\u043e \u0440\u0430\u0441\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u0437\u0430\u0445\u0432\u0430\u0442\u0447\u0438\u043a\u043e\u0432 \u043d\u0435 \u0442\u043e\u0447\u043d\u043e \u043e\u0434\u0438\u043d \u043f\u043e\u0434 \u0434\u0440\u0443\u0433\u0438\u043c, \u043b\u0438\u0431\u043e \u0442\u0430\u043a \u043a\u0430\u043a \u0441\u0434\u0435\u043b\u0430\u043d\u043e, \u043b\u0438\u0431\u043e \u043a\u0430\u043a-\u0442\u043e \u0435\u0449\u0451.<\/p>\n<p>  <a name=\"bullets\"><\/a><\/p>\n<h3>\u041f\u043e\u0440\u0430 \u0438\u0433\u0440\u043e\u043a\u0443 \u043d\u0430\u0443\u0447\u0438\u0442\u044c\u0441\u044f \u0441\u0442\u0440\u0435\u043b\u044f\u0442\u044c<\/h3>\n<p>  \u041d\u043e\u0432\u044b\u0439 \u0444\u0430\u0439\u043b\u0438\u043a \u0438 \u043a\u043b\u0430\u0441\u0441 <em>bullets.lua<\/em><\/p>\n<pre><code class=\"lua\">local bullets = {}  bullets.current_speed_y = -200 bullets.width = 2 bullets.height = 10  bullets.current_level_bullets = {}  function bullets.destroy_bullet( bullet_i )     bullets.current_level_bullets[bullet_i] = nil end  function bullets.new_bullet(position_x, position_y)     return { position_x = position_x,              position_y = position_y,              width = bullets.width,              height = bullets.height } end  function bullets.fire( player )     local position_x = player.position_x + player.width \/ 2     local position_y = player.position_y     local new_bullet = bullets.new_bullet( position_x, position_y )     table.insert(bullets.current_level_bullets, new_bullet) end  function bullets.draw_bullet( bullet )     love.graphics.rectangle( 'fill',                              bullet.position_x,                              bullet.position_y,                              bullet.width,                              bullet.height                         ) end  function bullets.draw()     for _, bullet in pairs(bullets.current_level_bullets) do         bullets.draw_bullet( bullet )     end end  function bullets.update_bullet( dt, bullet )     bullet.position_y = bullet.position_y + bullets.current_speed_y * dt end  function bullets.update( dt )     for _, bullet in pairs(bullets.current_level_bullets) do         bullets.update_bullet( dt, bullet )     end end  return bullets <\/code><\/pre>\n<p>  \u0417\u0434\u0435\u0441\u044c \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u043c\u0435\u0442\u043e\u0434 \u2014 <em>bullets.fire<\/em>. \u041c\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u0451\u043c \u0432 \u043d\u0435\u0433\u043e \u0418\u0433\u0440\u043e\u043a\u0430, \u0442.\u043a. \u0445\u043e\u0442\u0438\u043c, \u0447\u0442\u043e\u0431\u044b \u043f\u0443\u043b\u044f \u0432\u044b\u043b\u0435\u0442\u0430\u043b\u0430 \u00ab\u0438\u0437 \u043d\u0435\u0433\u043e\u00bb, \u0430 \u0437\u043d\u0430\u0447\u0438\u0442 \u043d\u0430\u043c \u043d\u0430\u0434\u043e \u0437\u043d\u0430\u0442\u044c \u0435\u0433\u043e \u043c\u0435\u0441\u0442\u043e\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435. \u0422.\u043a. \u043f\u0430\u0442\u0440\u043e\u043d \u0443 \u043d\u0430\u0441 \u043d\u0435 \u043e\u0434\u0438\u043d, \u0430 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u0430 \u0446\u0435\u043b\u0430\u044f \u043e\u0447\u0435\u0440\u0435\u0434\u044c, \u0442\u043e \u0445\u0440\u0430\u043d\u0438\u043c \u0435\u0451 \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 <em>bullets.current_level_bullets<\/em>, \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u0434\u043b\u044f \u043d\u0435\u0451 \u0438 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043f\u0430\u0442\u0440\u043e\u043d\u0430 \u043c\u0435\u0442\u043e\u0434\u044b <em>draw<\/em> \u0438 <em>update<\/em>. \u041c\u0435\u0442\u043e\u0434 <em>bullets.destroy_bullet<\/em> \u043d\u0443\u0436\u0435\u043d, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0438 \u0441\u043e\u043f\u0440\u0438\u043a\u043e\u0441\u043d\u043e\u0432\u0435\u043d\u0438\u0438 \u0441 \u0437\u0430\u0445\u0432\u0430\u0442\u0447\u0438\u043a\u043e\u043c \u0438\u043b\u0438 \u043f\u043e\u0442\u043e\u043b\u043a\u043e\u043c \u0443\u0434\u0430\u043b\u044f\u0442\u044c \u043b\u0438\u0448\u043d\u0438\u0435 \u043f\u0430\u0442\u0440\u043e\u043d\u044b \u0438\u0437 \u043f\u0430\u043c\u044f\u0442\u0438.<\/p>\n<p>  \u0414\u043e\u0431\u0430\u0432\u0438\u043c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u043a\u043e\u043b\u043b\u0438\u0437\u0438\u0439 \u043f\u0443\u043b\u044f-\u0437\u0430\u0445\u0432\u0430\u0442\u0447\u0438\u043a \u0438 \u043f\u0443\u043b\u044f-\u043f\u043e\u0442\u043e\u043b\u043e\u043a.<\/p>\n<p>  <em>collisions.lua<\/em>  <\/p>\n<pre><code class=\"lua\">function collisions.invaders_bullets_collision( invaders, bullets )     local overlap          for b_i, bullet in pairs( bullets.current_level_bullets) do         local a = { x = bullet.position_x,                     y = bullet.position_y,                     width = bullet.width,                     height = bullet.height }                  for i_i, invader_row in pairs( invaders.current_level_invaders ) do             for i_j, invader in pairs( invader_row ) do                 local b = { x = invader.position_x,                             y = invader.position_y,                             width = invader.width,                             height = invader.height }                 overlap = collisions.check_rectangles_overlap( a, b )                 if overlap then                     invaders.destroy_invader( i_i, i_j )                     bullets.destroy_bullet( b_i )                 end             end         end     end end  function collisions.bullets_walls_collision( bullets, walls )     local overlap     local wall = walls.current_level_walls['top']          local a = { x = wall.position_x,                 y = wall.position_y,                 width = wall.width,                 height = wall.height }          for b_i, bullet in pairs( bullets.current_level_bullets) do         local b = { x = bullet.position_x,                     y = bullet.position_y,                     width = bullet.width,                     height = bullet.height }              overlap = collisions.check_rectangles_overlap( a, b )         if overlap then             bullets.destroy_bullet( b_i )         end     end end  function collisions.resolve_collisions( invaders, walls, bullets )     ...     collisions.invaders_bullets_collision( invaders, bullets )     collisions.bullets_walls_collision( bullets, walls ) end <\/code><\/pre>\n<p>  \u041a \u0437\u0430\u0445\u0432\u0430\u0442\u0447\u0438\u043a\u0430\u043c \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043c\u0435\u0442\u043e\u0434 \u0434\u043b\u044f \u0435\u0433\u043e \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0435\u043d\u0438\u044f, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043d\u0430 \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u0437\u0430\u0445\u0432\u0430\u0442\u0447\u0438\u043a\u043e\u0432 \u0432 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u043c \u0440\u044f\u0434\u0443 \u0432 \u043e\u0431\u0449\u0435\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 \u0437\u0430\u0445\u0432\u0430\u0442\u0447\u0438\u043a\u043e\u0432 \u2014 \u0435\u0441\u043b\u0438 \u043d\u0438\u043a\u043e\u0433\u043e \u043d\u0435 \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c, \u0442\u043e \u0438 \u0441\u0430\u043c \u0440\u044f\u0434 \u0443\u0434\u0430\u043b\u044f\u0435\u043c. \u0410 \u0442\u0430\u043a\u0436\u0435 \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u043c \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0432\u0441\u0435\u0439 \u0430\u0440\u043c\u0430\u0434\u044b \u043f\u0440\u0438 \u0443\u0431\u0438\u0439\u0441\u0442\u0432\u0435.<\/p>\n<p>  <em>invaders.lua<\/em>  <\/p>\n<pre><code class=\"lua\">... invaders.speed_x_increase_on_destroying = 10  function invaders.destroy_invader( row, invader )     invaders.current_level_invaders[row][invader] = nil     local invaders_row_count = 0     for _, invader in pairs( invaders.current_level_invaders[row] ) do         invaders_row_count = invaders_row_count + 1     end     if invaders_row_count == 0 then         invaders.current_level_invaders[row] = nil     end     if invaders.allow_overlap_direction == 'right' then         invaders.current_speed_x = invaders.current_speed_x + invaders.speed_x_increase_on_destroying     else         invaders.current_speed_x = invaders.current_speed_x - invaders.speed_x_increase_on_destroying     end  end ... <\/code><\/pre>\n<p>  \u0418 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c <em>mail.lua<\/em>: \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043d\u043e\u0432\u044b\u0439 \u043a\u043b\u0430\u0441\u0441, \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u0435\u0433\u043e \u0432 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u043a\u043e\u043b\u043b\u0438\u0437\u0438\u0439, \u0438 \u0432\u0435\u0448\u0430\u0435\u043c \u0432\u044b\u0437\u043e\u0432 \u0441\u0442\u0440\u0435\u043b\u044c\u0431\u044b \u043d\u0430 \u043a\u043b\u0430\u0432\u0438\u0448\u0443 Space. <\/p>\n<pre><code class=\"lua\">... local bullets    = require 'bullets'  function love.keyreleased( key )     if key == 'space' then         bullets.fire( player )     end end  function love.draw()     ...     bullets.draw() end  function love.update( dt )     ...     collisions.resolve_collisions( invaders, walls, bullets )     bullets.update( dt ) end <\/code><\/pre>\n<p>  \u0414\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0430\u044f \u0440\u0430\u0431\u043e\u0442\u0430 \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442 \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0433\u043e \u043a\u043e\u0434\u0430, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0442\u043e, \u0447\u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u043d\u0430 \u0434\u0430\u043d\u043d\u043e\u043c \u044d\u0442\u0430\u043f\u0435 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u043a\u0430\u043a <a href=\"https:\/\/github.com\/vlfedotov\/small_games\/commit\/21868d59adb3ea4dc358f2fecf0cc05548153410\">\u0432\u0435\u0440\u0441\u0438\u044e 0.5<\/a>.<\/p>\n<p>  <b>NB<\/b> \u041a\u043e\u0434 \u0432 \u0433\u0438\u0442\u0435 \u043e\u0442\u043b\u0438\u0447\u0430\u0435\u0442\u0441\u044f \u043e\u0442 \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u043d\u043d\u043e\u0433\u043e \u0437\u0434\u0435\u0441\u044c. \u0418\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0430\u0441\u044c \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 <a href=\"https:\/\/github.com\/vrld\/hump\">hump<\/a> \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0432\u0435\u043a\u0442\u043e\u0440\u0430\u043c\u0438. \u041d\u043e \u043f\u043e\u0442\u043e\u043c \u0441\u0442\u0430\u043b\u043e \u044f\u0441\u043d\u043e, \u0447\u0442\u043e \u0432\u043f\u043e\u043b\u043d\u0435 \u043c\u043e\u0436\u043d\u043e \u043e\u0431\u043e\u0439\u0442\u0438\u0441\u044c \u0438 \u0431\u0435\u0437 \u043d\u0435\u0451, \u0438 \u0432 \u043e\u043a\u043e\u043d\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u0440\u0435\u0434\u0430\u043a\u0446\u0438\u0438 \u0432\u044b\u043f\u0438\u043b\u0438\u043b \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443. \u041a\u043e\u0434 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u043e \u0440\u0430\u0431\u043e\u0447\u0438\u0439 \u0438 \u0437\u0434\u0435\u0441\u044c \u0438 \u0442\u0430\u043c, \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043a\u043e\u0434\u0430 \u0441 \u0433\u0438\u0442\u0445\u0430\u0431\u0430 \u043f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u043f\u0440\u043e\u0438\u043d\u0438\u0446\u0438\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0430\u0431\u043c\u043e\u0434\u0443\u043b\u0438:<\/p>\n<pre><code class=\"bash\">git submodule update --init <\/code><\/pre>\n<p>  <a name=\"graphics\"><\/a><\/p>\n<h3>\u041d\u0430\u0432\u0435\u0448\u0438\u0432\u0430\u0435\u043c \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u044b<\/h3>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/web\/be4\/392\/9c1\/be43929c136d4c08955a23d847cf6dda.png\"\/><br \/>  \u042d\u0442\u043e \u0442\u0440\u0438 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0445 \u0432\u0440\u0430\u0433\u0430, \u043f\u043b\u044e\u0441 \u043e\u0434\u0438\u043d \u043c\u0438\u043d\u0438\u0431\u043e\u0441\u0441, \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0437\u0434\u0435\u0441\u044c \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u043e \u043d\u0435 \u0431\u0443\u0434\u0435\u0442, \u043d\u043e \u043e\u043d \u0435\u0441\u0442\u044c \u0432 \u043e\u043a\u043e\u043d\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0439 <a href=\"https:\/\/github.com\/vlfedotov\/small_games\/tree\/games\/space-invaders\">\u0432\u0435\u0440\u0441\u0438\u0438<\/a>. \u0418 \u0441\u0430\u043c \u0438\u0433\u0440\u043e\u043a-\u0442\u0430\u043d\u043a.<\/p>\n<p>  \u0422\u0435\u043a\u0441\u0442\u0443\u0440\u044b \u0434\u043b\u044f \u0438\u0433\u0440\u044b \u043b\u044e\u0431\u0435\u0437\u043d\u043e \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u0438\u043b\u0430 <a href=\"https:\/\/www.artstation.com\/artist\/annnushkkka\">annnushkkka<\/a>.<\/p>\n<p>  \u0412\u0441\u0435 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0438 \u0431\u0443\u0434\u0443\u0442 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u0432 \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0435 <em>images<\/em> \u0432 \u043a\u043e\u0440\u043d\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430. \u041c\u0435\u043d\u044f\u0435\u043c \u0418\u0433\u0440\u043e\u043a\u0430 \u0432 <em>player.lua<\/em><\/p>\n<pre><code class=\"lua\">... player.image = love.graphics.newImage('images\/Hero.png')  -- from https:\/\/love2d.org\/forums\/viewtopic.php?t=79756 function getImageScaleForNewDimensions( image, newWidth, newHeight )     local currentWidth, currentHeight = image:getDimensions()     return ( newWidth \/ currentWidth ), ( newHeight \/ currentHeight ) end local scaleX, scaleY = getImageScaleForNewDimensions( player.image, player.width, player.height )  function player.draw()  -- \u043c\u0435\u043d\u044f\u0435\u043c \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e     love.graphics.draw(player.image,                        player.position_x,                        player.position_y, rotation, scaleX, scaleY ) end ... <\/code><\/pre>\n<p>  \u0424\u043d\u043a\u0446\u0438\u044f getImageScaleForNewDimensions, \u043f\u043e\u0434\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u043d\u0430\u044f \u0432\u043e\u0442 <a href=\"https:\/\/love2d.org\/forums\/viewtopic.php?t=79756\">\u043e\u0442\u0441\u044e\u0434\u0430<\/a>, \u043f\u043e\u0434\u0433\u043e\u043d\u044f\u0435\u0442 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0443 \u043f\u043e\u0434 \u0442\u0435 \u0440\u0430\u0437\u043c\u0435\u0440\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u0443\u043a\u0430\u0437\u0430\u043b\u0438 \u0432 <em>player.width, player.height<\/em>. \u041e\u043d\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0438 \u0437\u0434\u0435\u0441\u044c \u0438 \u0434\u043b\u044f \u0432\u0440\u0430\u0433\u043e\u0432, \u0432\u043f\u043e\u0441\u043b\u0435\u0434\u0441\u0442\u0432\u0438\u0438 \u0432\u044b\u043d\u0435\u0441\u0435\u043c \u0435\u0451 \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u043c\u043e\u0434\u0443\u043b\u044c <em>utils.lua<\/em>. \u0424\u0443\u043d\u043a\u0446\u0438\u044e <em>player.draw<\/em> \u0437\u0430\u043c\u0435\u043d\u044f\u0435\u043c.<\/p>\n<p>  \u041f\u0440\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u0431\u044b\u0432\u0448\u0438\u0439 \u0438\u0433\u0440\u043e\u043a-\u043a\u0432\u0430\u0434\u0440\u0430\u0442 \u0442\u0435\u043f\u0435\u0440\u044c \u2014 \u0442\u0430\u043d\u043a!<\/p>\n<p>  \u041c\u0435\u043d\u044f\u0435\u043c \u0432\u0440\u0430\u0433\u043e\u0432 <em>invaders.lua<\/em><\/p>\n<pre><code class=\"lua\">... invaders.images = {love.graphics.newImage('images\/bad_1.png'),                    love.graphics.newImage('images\/bad_2.png'),                    love.graphics.newImage('images\/bad_3.png')             }  -- from https:\/\/love2d.org\/forums\/viewtopic.php?t=79756 function getImageScaleForNewDimensions( image, newWidth, newHeight )     local currentWidth, currentHeight = image:getDimensions()     return ( newWidth \/ currentWidth ), ( newHeight \/ currentHeight ) end local scaleX, scaleY = getImageScaleForNewDimensions( invaders.images[1], invaders.invader_width,     invaders.invader_height )  function invaders.new_invader(position_x, position_y ) -- \u043c\u0435\u043d\u044f\u0435\u043c     local invader_image_no = math.random(1, #invaders.images)     invader_image = invaders.images[invader_image_no]     return ({position_x = position_x,              position_y = position_y,              width = invaders.invader_width,              height = invaders.invader_height,              image = invader_image}) end  function invaders.draw_invader( single_invader ) -- \u043c\u0435\u043d\u044f\u0435\u043c     love.graphics.draw(single_invader.image,                        single_invader.position_x,                        single_invader.position_y, rotation, scaleX, scaleY ) end <\/code><\/pre>\n<p>  \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0438 \u0432\u0440\u0430\u0433\u043e\u0432 \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 \u0438 \u043f\u043e\u0434\u0433\u043e\u043d\u044f\u0435\u043c \u0440\u0430\u0437\u043c\u0435\u0440\u044b \u0447\u0435\u0440\u0435\u0437 getImageScaleForNewDimensions. \u041f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u043d\u043e\u0432\u043e\u0433\u043e \u0437\u0430\u0445\u0432\u0430\u0442\u0447\u0438\u043a\u0430 \u0435\u043c\u0443 \u0432 \u0430\u0442\u0440\u0438\u0431\u0443\u0442 image \u043f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0440\u0430\u043d\u0434\u043e\u043c\u043d\u0430\u044f \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0430 \u0438\u0437 \u043d\u0430\u0448\u0435\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u043a\u0430\u0440\u0442\u0438\u043d\u043e\u043a. \u0418 \u043c\u0435\u043d\u044f\u0435\u043c \u0441\u0430\u043c \u043c\u0435\u0442\u043e\u0434 \u043e\u0442\u0440\u0438\u0441\u043e\u0432\u043a\u0438.<\/p>\n<p>  \u0412\u043e\u0442 \u0447\u0442\u043e \u0432\u044b\u0448\u043b\u043e:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/web\/399\/282\/0aa\/3992820aa7eb489695770c7f7383096f.png\"\/><\/p>\n<p>  \u0415\u0441\u043b\u0438 \u043f\u043e\u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0438\u0433\u0440\u0443 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0437, \u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0443\u0432\u0438\u0434\u0435\u0442\u044c, \u0447\u0442\u043e \u0440\u0430\u043d\u0434\u043e\u043c\u043d\u0430\u044f \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0446\u0438\u044f \u0432\u0440\u0430\u0433\u043e\u0432 \u043a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u0430\u044f. \u0427\u0442\u043e\u0431\u044b \u044d\u0442\u043e\u0433\u043e \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u043d\u0430\u0434\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c <em>math.randomseed<\/em> \u043f\u0435\u0440\u0435\u0434 \u043d\u0430\u0447\u0430\u043b\u043e\u043c \u0438\u0433\u0440\u044b. \u0425\u043e\u0440\u043e\u0448\u043e \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c, \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u044f \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430 os.time. \u0414\u043e\u0431\u0430\u0432\u0438\u043c \u044d\u0442\u043e \u0432 <em>main.lua<\/em><\/p>\n<pre><code class=\"lua\">function love.load()     ...     math.randomseed( os.time() )     ... end <\/code><\/pre>\n<p>  \u0422\u0435\u043f\u0435\u0440\u044c \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u043f\u043e\u0447\u0442\u0438 \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u0430\u044f \u0438\u0433\u0440\u0430, <a href=\"https:\/\/github.com\/vlfedotov\/small_games\/commit\/7d282a061cb77e07e05e91eb3ae8966bfa6808f8\">\u0432\u0435\u0440\u0441\u0438\u044f 0.75<\/a>. \u0420\u0430\u0437\u043e\u0431\u0440\u0430\u043b\u0438 \u0432\u0441\u0451, \u0447\u0442\u043e \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043b\u0438.<\/p>\n<p>  \u0411\u0443\u0434\u0443 \u0440\u0430\u0434 \u043e\u0442\u0437\u044b\u0432\u0430\u043c, \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f\u043c, \u043f\u043e\u0434\u0441\u043a\u0430\u0437\u043a\u0430\u043c!<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:\/\/habrahabr.ru\/post\/328264\/\"> https:\/\/habrahabr.ru\/post\/328264\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/web\/92a\/03a\/066\/92a03a0667b54bf4aee39deb4ef5752d.png\"\/><\/p>\n<p>  \u0414\u043e\u0431\u0440\u044b\u0439 \u0434\u0435\u043d\u044c! \u0421\u0435\u0433\u043e\u0434\u043d\u044f \u0431\u0443\u0434\u0435\u043c \u0434\u0435\u043b\u0430\u0442\u044c \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u0443\u044e \u0438\u0433\u0440\u0443 Space Invaders \u043d\u0430 \u0434\u0432\u0438\u0436\u043a\u0435 <a href=\"https:\/\/love2d.org\/\">Love2d<\/a>. \u0414\u043b\u044f \u043b\u044e\u0431\u0438\u0442\u0435\u043b\u0435\u0439 \u00ab\u043a\u043e\u0434\u0430 \u0441\u0440\u0430\u0437\u0443\u00bb \u043e\u043a\u043e\u043d\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e \u0438\u0433\u0440\u044b \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043d\u0430 <a href=\"https:\/\/github.com\/vlfedotov\/small_games\/tree\/games\/space-invaders\">\u0433\u0438\u0442\u0445\u0430\u0431\u0435<\/a>. \u0422\u0435\u043c \u0436\u0435 \u043a\u043e\u043c\u0443 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0435\u043d \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438, \u0434\u043e\u0431\u0440\u043e \u043f\u043e\u0436\u0430\u043b\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0434 \u043a\u0430\u0442.  <\/p>\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-286063","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/286063","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=286063"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/286063\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=286063"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=286063"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=286063"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}