diff options
author | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:42:52 -0500 |
---|---|---|
committer | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:42:52 -0500 |
commit | 074785cea106179cb3305637055ab0a009ca74f2 (patch) | |
tree | e6ae371cccd642aa2b67f39752a2cdf1fd4eb040 /files/ru/games/tutorials/2d_breakout_game_pure_javascript | |
parent | da78a9e329e272dedb2400b79a3bdeebff387d47 (diff) | |
download | translated-content-074785cea106179cb3305637055ab0a009ca74f2.tar.gz translated-content-074785cea106179cb3305637055ab0a009ca74f2.tar.bz2 translated-content-074785cea106179cb3305637055ab0a009ca74f2.zip |
initial commit
Diffstat (limited to 'files/ru/games/tutorials/2d_breakout_game_pure_javascript')
11 files changed, 1156 insertions, 0 deletions
diff --git a/files/ru/games/tutorials/2d_breakout_game_pure_javascript/bounce_off_the_walls/index.html b/files/ru/games/tutorials/2d_breakout_game_pure_javascript/bounce_off_the_walls/index.html new file mode 100644 index 0000000000..1e5796777e --- /dev/null +++ b/files/ru/games/tutorials/2d_breakout_game_pure_javascript/bounce_off_the_walls/index.html @@ -0,0 +1,109 @@ +--- +title: Отскок от стен +slug: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Bounce_off_the_walls +tags: + - Анимация + - Графика + - Игры + - Начинающим + - Обучение + - Примеры + - столкновения +translation_of: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Bounce_off_the_walls +--- +<div>{{GamesSidebar}}</div> + +<div>{{IncludeSubnav("/en-US/docs/Games")}}</div> + +<p>{{PreviousNext("Games/Tutorials/2D_Breakout_game_pure_JavaScript/Переместить_мяч", "Games/Tutorials/2D_Breakout_game_pure_JavaScript/Paddle_and_keyboard_controls")}}</p> + +<div class="summary"> +<p>Это 3-й этап из 10 <a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/Breakout_game_from_scratch">Gamedev Canvas tutorial</a>. Вы можете найти исходный код как он должен выглядеть после завершения этого урока в <a href="https://github.com/end3r/Gamedev-Canvas-workshop/blob/gh-pages/lesson03.html">Gamedev-Canvas-workshop/lesson3.html</a>.</p> +</div> + +<p>Приятно наблюдать за нашим мяч, но он быстро исчезает с экрана, удовольствие длится недолго! Чтобы продлить, мы реализуем некоторое очень простое обнаружение столкновений (о которых будет рассказано <a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/Breakout_game_from_scratch/Collision_detection">далее</a> более подробно), чтобы сделать отскок мяча от четырех краев холста.</p> + +<h2 id="Простое_обнаружение_столкновений">Простое обнаружение столкновений</h2> + +<p>Для обнаружения столкновения мы будем проверять - касается ли мяч стены, и если это так, изменим направление его движения в нужную сторону.</p> + +<p>Чтобы сделать расчеты проще, давайте определим переменную <code>ballRadius</code>, что задаст радиус нарисованного круга и будет использоваться для вычислений. Добавьте это в ваш код, где-то ниже существующих переменных:</p> + +<pre class="brush: js">var ballRadius = 10;</pre> + +<p>Теперь обновите строку, которая рисует шарик, внутри функции <code>drawBall() </code>:</p> + +<pre class="brush: js">ctx.arc(x, y, ballRadius, 0, Math.PI*2);</pre> + +<h3 id="Отскакивание_от_верхней_и_нижней_стены">Отскакивание от верхней и нижней стены</h3> + +<p>Есть четыре стены, от которых мяч будет отскакивать — давайте сначала сосредоточимся на верхней. При каждом кадре нужно проверять, коснулся ли мяч верхней границы — если да, то будет обратное движение мяча, поэтому он начнет двигаться в противоположном направлении и остановится в пределах видимой границы. Вспомнив, что система координат начинается с левого верхнего угла, мы можем придумать что-то вроде этого:</p> + +<pre class="brush: js">if(y + dy < 0) { + dy = -dy; +}</pre> + +<p>Если значение <code>y</code> положения шара ниже нуля, изменить направление движения по оси <font face="consolas, Liberation Mono, courier, monospace"><span style="background-color: rgba(220, 220, 220, 0.5);">y</span></font> установив его с тем же значением но с другим знаком. Если мяч движется вверх со скоростью 2 пикселя на кадр, теперь он будет двигаться "вверх" со скоростью -2 пикселя, что на самом деле означает движение вниз со скоростью 2 пикселя.</p> + +<p>Приведенный выше код описывает отражение только от верхней границы, так что теперь давайте думать о нижнем крае:</p> + +<pre class="brush: js">if(y + dy > canvas.height) { + dy = -dy; +}</pre> + +<p>Если положение мяча по оси <code>y</code> больше, чем высота полотна (помните, что мы рассчитываем значения <code>y</code> от верхнего левого, чтобы верхний край начинался с 0, а нижний край — 480 пикселей, высота нашего <code><canvas></code>), затем после отскока от нижней кромки обратное движение по оси <code>y</code>.</p> + +<p>Мы можем объединить эти две конструкции в одну, чтобы уменьшить код:</p> + +<pre class="brush: js">if(y + dy > canvas.height || y + dy < 0) { + dy = -dy; +}</pre> + +<p>Если одно из двух утверждений верно, тогда направление мяча меняется.</p> + +<h3 id="Отскоки_влево_и_вправо">Отскоки влево и вправо</h3> + +<p>Мы сделали отражение от верхней и нижней границ, нельзя забывать и про боковины. Задача очень похожа на самом деле, все, что вам нужно сделать, это повторить конструкцию заменив Y на X:</p> + +<pre class="brush: js">if(x + dx > canvas.width || x + dx < 0) { + dx = -dx; +} + +if(y + dy > canvas.height || y + dy < 0) { + dy = -dy; +}</pre> + +<p>На этом этапе вы должны вставить этот блок кода в функцию Draw (), непосредственно перед закрывающей фигурной скобкой.</p> + +<h3 id="Мяч_продолжает_исчезать_в_стене!">Мяч продолжает исчезать в стене!</h3> + +<p>Проверьте сейчас свой код, и вы будете впечатлены — теперь мяч, отскакивает от всех четерёх краёв нашего <code><canvas></code>! Однако есть некоторая проблема - когда мяч попадает в любую стену, он немного заходит за границы <code><canvas></code> перед отскоком:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/10432/ball-in-wall.png" style="display: block; height: 320px; margin: 0px auto; width: 480px;"></p> + +<p>Это происходит потому, что мы проверяем касание стены и центра мяча, а не его края. Мяч должен отскакивать сразу после касания, а не когда он уже на половину в стене, так что давайте корректировать наш код включив в него небольшое выражение. Обновите последний код добавив к нему:</p> + +<pre class="brush: js">if(x + dx > canvas.width-ballRadius || x + dx < ballRadius) { + dx = -dx; +} +if(y + dy > canvas.height-ballRadius || y + dy < ballRadius) { + dy = -dy; +}</pre> + +<p>Когда расстояние между центром шара и краем стены равно радиусу шарика, шарик изменит направление движения. Вычитая радиус при отскоке от одной стены и добавляя при отскоке от другой, мы получили простое обнаружение столкновений. Шарик отскакивает от стен как надо.</p> + +<h2 id="Сравните_ваш_код">Сравните ваш код</h2> + +<p>Давайте еще раз провериим готовый код для этой части, и код, что у вас есть, и играйте:</p> + +<p>{{JSFiddleEmbed("https://jsfiddle.net/end3r/redj37dc/","","370")}}</p> + +<div class="note"> +<p><strong>Упражнение: </strong>попробуйте изменить цвет шарика на случайный цвет каждый раз, когда он попадает в стену.</p> +</div> + +<h2 id="Следующий_шаг">Следующий шаг</h2> + +<p>Теперь мы добрались до стадии, где наш мяч одновременно двигается и остаётся на игровом поле. В четвертой главе мы рассмотрим реализацию управления — см. <a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/Breakout_game_from_scratch/Paddle_and_keyboard_controls">Paddle and keyboard controls</a>.</p> + +<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_pure_JavaScript/Move_the_ball", "Games/Workflows/2D_Breakout_game_pure_JavaScript/Paddle_and_keyboard_controls")}}</p> diff --git a/files/ru/games/tutorials/2d_breakout_game_pure_javascript/game_over/index.html b/files/ru/games/tutorials/2d_breakout_game_pure_javascript/game_over/index.html new file mode 100644 index 0000000000..bb944fae5d --- /dev/null +++ b/files/ru/games/tutorials/2d_breakout_game_pure_javascript/game_over/index.html @@ -0,0 +1,95 @@ +--- +title: Game over +slug: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Game_over +tags: + - Canvas + - JavaScript + - game over + - Начинающий +translation_of: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Game_over +--- +<div>{{GamesSidebar}}</div> + +<div>{{IncludeSubnav("/en-US/docs/Games")}}</div> + +<p>{{PreviousNext("Games/Tutorials/2D_Breakout_game_pure_JavaScript/Paddle_and_keyboard_controls", "Games/Tutorials/2D_Breakout_game_pure_JavaScript/Создаем_зону_кирпичей")}}</p> + +<div class="summary"> +<p>Это - 5-й шаг из 10 из <a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/Breakout_game_from_scratch">Gamedev Canvas tutorial</a>. Вы можете найти исходный код к этому уроку в <a href="https://github.com/end3r/Gamedev-Canvas-workshop/blob/gh-pages/lesson05.html">Gamedev-Canvas-workshop/lesson5.html</a>.</p> +</div> + +<p><span class="seoSummary">Конечно интересно наблюдать за отражающимся мячом и двигать биту, но кроме этого игра ничего не делает и не имеет никакого прогресса или конечной цели. Было бы хорошо с точки зрения геймплея иметь возможность проигрыша. Логика проигрыша в потере мяча. Если вы пропустите мяч и дадите ему добраться до нижнего края экрана, то на этом игра закончится.</span></p> + +<h2 id="Реализация_окончания_игры">Реализация окончания игры</h2> + +<p>Давайте попытаемся реализовать "Конец Игры" в нашей игре. Вот часть кода от третьего урока, где мы заставили шар отталкиваться от стен:</p> + +<pre class="brush: js">if(x + dx > canvas.width-ballRadius || x + dx < ballRadius) { + dx = -dx; +} + +if(y + dy > canvas.height-ballRadius || y + dy < ballRadius) { + dy = -dy; +}</pre> + +<p>Вместо того, чтобы позволить шару отталкиваться от всех четырех стен, давайте позволим отталкиваться только от трех стен — левую, верхнюю и правую. Удар об нижнюю стенку закончит игру. Мы отредактируем второй блок if, таким образом, что if else вызовит "Конец Игры" , когда шар столкнется с нижней стенкой холста. Сохраните документ, взгляните на выводящееся сообщение перезагрузите игру путем презагрузки страницы.</p> + +<p>Во-первых, измените код, где вы изначально вызывали <code>setInterval()</code></p> + + + +<pre><code>setInterval(draw, 10);</code> +</pre> + +<p>на следующий:</p> + +<pre><code>var interval = setInterval(draw, 10);</code> +</pre> + + + +<p>Затем замените второй оператор if следующим:</p> + +<pre class="brush: js">if(y + dy < ballRadius) { + dy = -dy; +} else if(y + dy > canvas.height-ballRadius) { + alert("GAME OVER"); + document.location.reload(); + clearInterval(interval); // Needed for Chrome to end game +}</pre> + + + +<h2 id="Отбить_шар">Отбить шар</h2> + +<p>Последняя вещь, которую нyжно сделать на этом уроке состоит в том, чтобы создать некоторое обнаружение столкновений между шаром и битой, таким образом, шар оттолкнется от биты и возвратиться в область игры. Самая простая вещь состоит в том, чтобы проверить, является ли центр шара между левыми и правыми краями биты. Обновите последний бит кода, который Вы изменили:</p> + +<pre class="brush: js">if(y + dy < ballRadius) { + dy = -dy; +} else if(y + dy > canvas.height-ballRadius) { + if(x > paddleX && x < paddleX + paddleWidth) { + dy = -dy; + } + else { + alert("GAME OVER"); + document.location.reload(); + } +}</pre> + +<p>Если мяч направляется к нижнему краю Canvas, мы должны проверить, касается ли он биты. Если да, то шар возвращается прочь точно так же, как Вы ожидали бы; если не тогда игра заканчивется.</p> + +<h2 id="Сравните_свой_код">Сравните свой код</h2> + +<p>Вот рабочий код для Вас, чтобы сравнить Ваш с:</p> + +<p>{{JSFiddleEmbed("https://jsfiddle.net/raymondjplante/L61c9y50/","","395")}}</p> + +<div class="note"> +<p><strong>Упражнение: заставить мяч двигаться быстрее, когда он попадает в биту.</strong></p> +</div> + +<h2 id="Следующие_шаги">Следующие шаги</h2> + +<p>Все идет хорошо и наша игра начинает чувствовать себя намного более достойно. Вы уже можете проиграть! Но все еще не хватает чего-то. Перейдем к шестой главе — <a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/Breakout_game_from_scratch/Build_the_brick_field">Build the brick field</a> — и создадим некоторые кирпичи для шара, чтобы их уничтожить.</p> + +<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_pure_JavaScript/Paddle_and_keyboard_controls", "Games/Workflows/2D_Breakout_game_pure_JavaScript/Build_the_brick_field")}}</p> diff --git a/files/ru/games/tutorials/2d_breakout_game_pure_javascript/index.html b/files/ru/games/tutorials/2d_breakout_game_pure_javascript/index.html new file mode 100644 index 0000000000..2a30bbadb5 --- /dev/null +++ b/files/ru/games/tutorials/2d_breakout_game_pure_javascript/index.html @@ -0,0 +1,59 @@ +--- +title: 2D игра на чистом JavaScript +slug: Games/Tutorials/2D_Breakout_game_pure_JavaScript +tags: + - 2D + - Canvas + - JavaScript + - TopicStub + - Игры + - Начинающий + - Руководство +translation_of: Games/Tutorials/2D_Breakout_game_pure_JavaScript +--- +<div>{{GamesSidebar}}</div> + +<div>{{IncludeSubnav("/en-US/docs/Games")}}</div> + +<p>{{Next("Games/Tutorials/2D_Breakout_game_pure_JavaScript/Создание_Canvas_и_рисование_на_нём")}}</p> + +<p class="summary">В этом пошаговом руководстве мы создадим простую игру <strong>MDN Breakout,</strong> написанную на чистом JavaScript и отрендеренную на HTML5 {{htmlelement("canvas")}}.</p> + +<p>К каждому шагу прилагаются редактируемые live-примеры, с которыми можно поиграть, чтобы увидеть, как должна выглядеть игра на промежуточных этапах. Вы изучите основы использования элемента {{htmlelement("canvas")}} для реализации таких фундаментальных игровых механик, как рендеринг и перемещение изображений, обнаружение столкновений, механизмы управления, а также состояния выигрыша и проигрыша.</p> + +<p>Для извлечения максимальной пользы из этой серии статей необходимо иметь средние (или хотя бы базовые) знания языка <a href="/en-US/Learn/Getting_started_with_the_web/JavaScript_basics">JavaScript</a>. После прохождения этого урока вы сможете создавать собственные простые браузерные игры.</p> + +<p><img alt="Gameplay screen from the game MDN Breakout where you can use your paddle to bounce the ball and destroy the brick field, with keeping the score and lives." src="https://mdn.mozillademos.org/files/10383/mdn-breakout-gameplay.png" style="display: block; height: 320px; margin: 0px auto; width: 480px;"></p> + +<h2 id="Детали_к_урокам">Детали к урокам</h2> + +<p>Все уроки и версии игры <a href="http://breakout.enclavegames.com/lesson10.html">MDN Breakout </a>доступны в <a href="https://github.com/end3r/Canvas-gamedev-workshop">GitHub</a>:</p> + +<ol> + <li><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_pure_JavaScript/Create_the_Canvas_and_draw_on_it">Создание Canvas и рисование на нем</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_pure_JavaScript/Move_the_ball">Движение мяча</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_pure_JavaScript/Bounce_off_the_walls">Реакция при столкновении со стеной</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_pure_JavaScript/Paddle_and_keyboard_controls">Управление</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_pure_JavaScript/Game_over">Конец игры</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_pure_JavaScript/Build_the_brick_field">Построение поля кирпичей</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_pure_JavaScript/Collision_detection">Реакция при столкновении</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_pure_JavaScript/Track_the_score_and_win">Счет и выигрыш</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_pure_JavaScript/Mouse_controls">Контроль мышью</a></li> + <li><a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_Breakout_game_pure_JavaScript/Finishing_up">Заключение</a></li> +</ol> + +<p>Лучший способ получить надежные знания в области разработки браузерных игр — это начать с чистого JavaScript. Затем можно выбрать любой фреймворк для использования в своих проектах. Фреймворки — это инструменты, созданные на языке JavaScript; поэтому, даже если вы планируете работать с ними, нелишним будет сначала изучить сам язык, чтобы понимать, что именно происходит внутри. Фреймворки ускоряют разработку и помогают справиться со скучными частями игры, но если что-то работает не так, как ожидалось, всегда можно попытаться отладить код или написать собственное решение на чистом JavaScript.</p> + +<div class="note"> +<p><strong>Примечание.</strong> Если вам интересно узнать о разработке двухмерных игр с помощью игровой библиотеки, ознакомьтесь с альтернативной серией статей <a href="/en-US/docs/Games/Workflows/2D_breakout_game_Phaser">2D игра Breakout с использованием Phaser</a>.</p> +</div> + +<div class="note"> +<p><span style="font-size: 14px;"><strong>Примечание.</strong></span> Эту серию статей можно использовать как материал для практических занятий по разработке игр. Также можно воспользоваться набором инструментов <a href="https://github.com/end3r/Gamedev-Canvas-Content-Kit">Gamedev Canvas Content Kit</a>, основанном на этом уроке, если нужно сделать доклад о разработке игр в целом.</p> +</div> + +<h2 id="Следующий_шаг">Следующий шаг</h2> + +<p>Ладно, давайте начнем! Перейдите к первой главе — <a href="/en-US/docs/Games/Workflows/2D_Breakout_game_pure_JavaScript/Create_the_Canvas_and_draw_on_it">Создание Canvas и рисование на нем</a>.</p> + +<p>{{Next("Games/Workflows/2D_Breakout_game_pure_JavaScript/Create_the_Canvas_and_draw_on_it")}} </p> diff --git a/files/ru/games/tutorials/2d_breakout_game_pure_javascript/paddle_and_keyboard_controls/index.html b/files/ru/games/tutorials/2d_breakout_game_pure_javascript/paddle_and_keyboard_controls/index.html new file mode 100644 index 0000000000..ad4caeefa1 --- /dev/null +++ b/files/ru/games/tutorials/2d_breakout_game_pure_javascript/paddle_and_keyboard_controls/index.html @@ -0,0 +1,124 @@ +--- +title: Ракетка и управление клавиатурой +slug: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Paddle_and_keyboard_controls +translation_of: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Paddle_and_keyboard_controls +--- +<div>{{GamesSidebar}}</div> + +<div>{{IncludeSubnav("/en-US/docs/Games")}}</div> + +<p>{{PreviousNext("Games/Tutorials/2D_Breakout_game_pure_JavaScript/Bounce_off_the_walls", "Games/Tutorials/2D_Breakout_game_pure_JavaScript/Game_over")}}</p> + +<div class="summary"> +<p>Это 4-й этап из 10 <a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/Breakout_game_from_scratch">Gamedev Canvas tutorial</a>. Вы можете найти исходный код как он должен выглядеть после завершения этого урока в <a href="https://github.com/end3r/Gamedev-Canvas-workshop/blob/gh-pages/lesson04.html">Gamedev-Canvas-workshop/lesson4.html</a>.</p> + +<p>Мяч беспрепятственно отражается от стен, и вы можете смотреть на него бесконечно, но в настоящее время нет интерактивности. Это не игра, если вы не можете управлять мячом. Давайте добавим взаимодействие с игрой: управление ракеткой.</p> +</div> + +<h2 id="Определение_ракетки_чтобы_ударить_по_мячу">Определение ракетки, чтобы ударить по мячу</h2> + +<p>Итак, нам нужна ракетка, чтобы ударить по мячу - давайте определим несколько переменных для этого. Добавьте следующие переменные в верхней части кода, рядом с вашими другими переменными:</p> + +<pre class="brush: js">var paddleHeight = 10; +var paddleWidth = 75; +var paddleX = (canvas.width-paddleWidth)/2;</pre> + +<p>Здесь мы определяем высоту и ширину ракетки, и его начальную точку на оси X, для дальнейшего использования в расчетах. Давайте создадим функцию, которая будет рисовать ракетку на экране. Добавьте следующий блок после функции <code>drawBall()</code>:</p> + +<pre class="brush: js">function drawPaddle() { + ctx.beginPath(); + ctx.rect(paddleX, canvas.height-paddleHeight, paddleWidth, paddleHeight); + ctx.fillStyle = "#0095DD"; + ctx.fill(); + ctx.closePath(); +}</pre> + +<h2 id="Позволяем_пользователю_управлять_ракеткой">Позволяем пользователю управлять ракеткой</h2> + +<p>Мы можем отобразить ракетку там, где мы хотим, но она должна реагировать на действия пользователя — настало время реализовать управление с помощью кнопок. Нам понадобится:</p> + +<ul> + <li>Две переменные для хранения информации о том, левая или правая кнопка управления нажата.</li> + <li>Два слушателя для событий <code>keydown</code> и <code>keyup</code> — мы хотим запустить некоторый код для обработки движения ракетки при нажатии кнопок.</li> + <li>Две функции обработки события <code>keydown</code> и <code>keyup</code> код, который будет выполняться при нажатии кнопок.</li> + <li>Возможность перемещения ракетки влево и вправо</li> +</ul> + +<p>Нажатые кнопки могут быть определены и инициализированы булевыми переменными. Добавьте эти строки рядом с остальными вашими переменными:</p> + +<pre class="brush: js">var rightPressed = false; +var leftPressed = false;</pre> + +<p>Значением по умолчанию для обоих является <code>false</code>, так как изначально кнопки не нажаты. Для прослушивания нажатий клавиш, мы создадим два обработчика событий. Добавьте следующие строки чуть выше функции <code>setInterval()</code> в нижней части JavaScript:</p> + +<pre class="brush: js">document.addEventListener("keydown", keyDownHandler, false); +document.addEventListener("keyup", keyUpHandler, false);</pre> + +<p>Когда <code>keydown</code> событие вызывается любой клавишей клавиатуры (нажатием клавиши), функция <code>keyDownHandler()</code> будет выполняться. Та же картина верна для второго обработчика: <code>keyup</code> событие запустит функцию <code>keyUpHandler ()</code> (когда будет отпущена). Добавьте следующий блок в ваш код ниже <code>addEventListener()</code>:</p> + +<pre class="brush: js">function keyDownHandler(e) { + if(e.keyCode == 39) { + rightPressed = true; + } + else if(e.keyCode == 37) { + leftPressed = true; + } +} + +function keyUpHandler(e) { + if(e.keyCode == 39) { + rightPressed = false; + } + else if(e.keyCode == 37) { + leftPressed = false; + } +}</pre> + +<p>Когда мы нажимаем клавишу, эта информация хранится в переменной. Соответствующая переменная в каждом конкретном случае устанавливается в <code>true</code>. Когда клавиша отпущена, переменная устанавливается обратно в <code>false</code>.</p> + +<p>Обе функции принимают параметр, представленный переменной <code>e</code>. Из нее вы можете получить полезную информацию: <code>key</code> содержит информацию о нажатой клавише. Например, код 37 — это клавиша стрелка влево и 39 — стрелка вправо. Если стрелка влево нажата, то переменная <code>leftPressed</code> имеет значение <code>true</code>, когда кнопка отпущена, то переменная leftPressed имеет значение false. Та же схема со стрелкой вправо и переменной rightPressed.</p> + +<h3 id="Логика_перемещения_ракетки">Логика перемещения ракетки</h3> + +<p>Теперь у нас есть переменные для хранения информации о нажатых клавишах, обработчики событий и соответствующие функции. Теперь мы допишем код, чтобы перемещать ракетку на экране. Внутри функции <code>draw()</code>, мы будем проверять, нажата левая или правая клавиша, когда каждый кадр отображается. Наш код будет выглядеть следующим образом:</p> + +<pre class="brush: js">if(rightPressed) { + paddleX += 7; +} +else if(leftPressed) { + paddleX -= 7; +}</pre> + +<p>Если нажата стрелка влево, то ракетка будет двигаться на 7 пикселей влево, а если нажата стрелка вправо то на 7 пикселей вправо. Все хорошо, но, если держать клавишу слишком долго, ракетка уходит за границы холста. Улучшим ситуацию, будем перемещать ракетку только в пределах холста, изменив код следующим образом:</p> + +<pre class="brush: js">if(rightPressed && paddleX < canvas.width-paddleWidth) { + paddleX += 7; +} +else if(leftPressed && paddleX > 0) { + paddleX -= 7; +}</pre> + +<p>Позиция <code>paddleX</code> будет двигаться от 0 на левой стороне холста и <code>canvas.width-paddleWidth</code> на правой стороне. Это будет работать именно так, как нам нужно.</p> + +<p>Добавьте вышеприведенный блок кода в функцию <code>draw()</code> в самый конец, чуть выше закрывающей фигурной скобки.</p> + +<p>Единственное, что осталось сделать сейчас, это вызвать <code>drawPaddle()</code> функцию внутри функции <code>draw()</code>, чтобы нарисовать ракетку на экране. Добавьте следующую строку внутрь функции <code>draw()</code>, чуть ниже строки, которая вызывает <code>drawBall()</code>:</p> + +<pre class="brush: js">drawPaddle(); +</pre> + +<h2 id="Сравните_ваш_код"><span style="background-color: #ffffff; color: #222222; display: inline !important; float: none; font-family: arial,helvetica,sans-serif; font-size: 20px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 24px; text-align: start; text-indent: 0px; text-transform: none; white-space: pre-wrap;">Сравните ваш код</span></h2> + +<p>Вот работающий код для вас, чтобы сравнить со своим:</p> + +<p>{{JSFiddleEmbed("https://jsfiddle.net/end3r/tgn3zscj/","","320")}}</p> + +<div class="note"> +<p><span style="font-size: 14px;"><strong>Упражнение</strong></span>: Сделайте скорость движения ракетки быстрее или медленнее, или измените ее размер.</p> +</div> + +<h2 id="Следующий_шаг">Следующий шаг</h2> + +<p>Теперь у нас есть что-то похожее на игру. Беда только в том, что пока вы можете лишь бесконечно бить мяч ракеткой. Это все изменится в пятой главе, <a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/Breakout_game_from_scratch/Game_over">Game over</a>, когда мы начнем добавлять конечное состояние для нашей игры.</p> + +<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_pure_JavaScript/Bounce_off_the_walls", "Games/Workflows/2D_Breakout_game_pure_JavaScript/Game_over")}}</p> diff --git a/files/ru/games/tutorials/2d_breakout_game_pure_javascript/track_the_score_and_win/index.html b/files/ru/games/tutorials/2d_breakout_game_pure_javascript/track_the_score_and_win/index.html new file mode 100644 index 0000000000..f9993a8b31 --- /dev/null +++ b/files/ru/games/tutorials/2d_breakout_game_pure_javascript/track_the_score_and_win/index.html @@ -0,0 +1,100 @@ +--- +title: Счет и выигрыш +slug: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Track_the_score_and_win +tags: + - JavaScript + - Игры + - Начинающий + - Учебник + - счет +translation_of: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Track_the_score_and_win +--- +<div>{{GamesSidebar}}</div> + +<div>{{IncludeSubnav("/en-US/docs/Games")}}</div> + +<p>{{PreviousNext("Games/Tutorials/2D_Breakout_game_pure_JavaScript/Обнаружение_столкновений", "Games/Tutorials/2D_Breakout_game_pure_JavaScript/Управление_мышью")}}</p> + +<div class="summary"> +<p>Это 8й шаг из 10 в <a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/Breakout_game_from_scratch">Gamedev Canvas tutorial</a>. Вы можете найти исходный код для этого урока по ссылке <a href="https://github.com/end3r/Gamedev-Canvas-workshop/blob/gh-pages/lesson08.html">Gamedev-Canvas-workshop/lesson8.html</a>.</p> +</div> + +<p><span class="seoSummary">Уничтожение кирпичей действительно классно, но, чтобы быть еще более удивительным, игра должна присуждать очки за каждый кирпич, в который попадает игрок, и подсчитывать общий балл.</span></p> + +<h2 id="Подсчет_очков">Подсчет очков</h2> + +<p>Если вы можете увидеть свои очки на протяжении всей игры, вы можете произвести впечатление на своих друзей. Вам нужна переменная для записи очков. Добавьте следующие данные в свой JavaScript, после остальных переменных:</p> + +<pre class="brush: js">var score = 0;</pre> + +<p>Вам также нужна функция <code>drawScore()</code> для создания и обновления отображения оценки. Добавьте после функции <code>collisionDetection()</code> следующий код:</p> + +<pre class="brush: js">function drawScore() { + ctx.font = "16px Arial"; + ctx.fillStyle = "#0095DD"; + ctx.fillText("Score: "+score, 8, 20); +}</pre> + +<p>Рисование текста на канве аналогично рисованию фигур. Определение шрифта выглядит точно так же, как и в CSS - вы можете установить размер и тип шрифта в {{domxref("CanvasRenderingContext2D.font","font()")}} методе. Затем используйте {{domxref("CanvasRenderingContext2D.fillStyle()","fillStyle()")}} для установки цвета шрифта и {{domxref("CanvasRenderingContext2D.fillText","fillText()")}} для установки фактического текста, который будет помещен на канву, и где он будет размещен. Первым параметром является сам текст - приведенный выше код показывает текущее количество точек, а два последних параметра - это координаты, в которых текст будет помещен на канву.</p> + +<p>Чтобы начислять баллы каждый раз при ударе кирпича, добавьте строку в функцию <code>collisionDetection()</code>, чтобы увеличить значение переменной оценки каждый раз при обнаружении столкновения. Добавьте в код следующую выделенную строку:</p> + +<pre class="brush: js; highlight:[9]">function collisionDetection() { + for(var c=0; c<brickColumnCount; c++) { + for(var r=0; r<brickRowCount; r++) { + var b = bricks[c][r]; + if(b.status == 1) { + if(x > b.x && x < b.x+brickWidth && y > b.y && y < b.y+brickHeight) { + dy = -dy; + b.status = 0; + score++; + } + } + } + } +}</pre> + +<p>Вызов <code>drawScore()</code>из функции <code>draw()</code> позволяет обновить счет с каждым новым фреймом - добавьте следующую строку внутри <code>draw()</code>, чуть ниже вызова <code>drawPaddle()</code>:</p> + +<pre class="brush: js">drawScore();</pre> + +<h2 id="Отображение_сообщения_о_победе_когда_все_кирпичи_были_уничтожены">Отображение сообщения о победе, когда все кирпичи были уничтожены</h2> + +<p>В конце концов, это главная цель игры, поэтому вы должны отобразить сообщение о победе, если все доступные кирпичи уничтожены. Добавьте следующий код в свою функцию <code>collisionDetection()</code> :</p> + +<pre class="brush: js; highlight:[10,11,12,13]">function collisionDetection() { + for(var c=0; c<brickColumnCount; c++) { + for(var r=0; r<brickRowCount; r++) { + var b = bricks[c][r]; + if(b.status == 1) { + if(x > b.x && x < b.x+brickWidth && y > b.y && y < b.y+brickHeight) { + dy = -dy; + b.status = 0; + score++; + if(score == brickRowCount*brickColumnCount) { + alert("YOU WIN, CONGRATULATIONS!"); + document.location.reload(); + } + } + } + } + } +}</pre> + +<p>Благодаря этому, игроки могут выиграть игру, когда они уничтожают все кирпичи, что очень важно, когда дело доходит до игр. Функция <code>document.location.reload()</code> перезагружает страницу и снова запускает игру после нажатия кнопки оповещения.</p> + +<h2 id="Сравните_ваш_код">Сравните ваш код</h2> + +<p>Вот работающий код для вас, чтобы сравнить со своим:</p> + +<p>{{JSFiddleEmbed("https://jsfiddle.net/yumetodo/2m74vr9r/1/","","395")}}</p> + +<div class="note"> +<p><strong>Упражнение: добавьте больше очков за каждый разбитый кирпич, выведите количество набранных очков в конце игры</strong>.</p> +</div> + +<h2 id="Следующие_шаги">Следующие шаги</h2> + +<p>На данный момент игра выглядит довольно хорошо. В следующем уроке Вы расширите привлекательность игры, добавив <a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/Breakout_game_from_scratch/Mouse_controls">Mouse controls</a>.</p> + +<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_pure_JavaScript/Collision_detection", "Games/Workflows/2D_Breakout_game_pure_JavaScript/Mouse_controls")}}</p> diff --git a/files/ru/games/tutorials/2d_breakout_game_pure_javascript/заключение/index.html b/files/ru/games/tutorials/2d_breakout_game_pure_javascript/заключение/index.html new file mode 100644 index 0000000000..d8f40896e1 --- /dev/null +++ b/files/ru/games/tutorials/2d_breakout_game_pure_javascript/заключение/index.html @@ -0,0 +1,103 @@ +--- +title: Заключение +slug: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Заключение +tags: + - Игры + - Канва + - Начинающий + - жизни +translation_of: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Finishing_up +--- +<div>{{GamesSidebar}}</div> + +<div>{{IncludeSubnav("/en-US/docs/Games")}}</div> + +<p>{{Previous("Games/Tutorials/2D_Breakout_game_pure_JavaScript/Управление_мышью")}}</p> + +<div class="summary"> +<p>Это 10-й и заключительный шаг в <a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/Breakout_game_from_scratch">Gamedev Canvas tutorial</a>. Вы можете найти исходный код, как он должен выглядеть, после завершения этого урока в <a href="https://github.com/end3r/Gamedev-Canvas-workshop/blob/gh-pages/lesson10.html">Gamedev-Canvas-workshop/lesson10.html</a>.</p> +</div> + +<p><span class="seoSummary">В любой игре, которую мы пишем, всегда есть место для улучшений. Например, мы можем предложить игроку несколько жизней. Они могут сделать несколько ошибок и все равно закончить игру. Мы также можем улучшить отрисовку кода.</span></p> + +<h2 id="Предоставление_игроку_нескольких_жизней">Предоставление игроку нескольких жизней</h2> + +<p>Реализация довольно проста. Давайте сначала добавим переменную для хранения количества жизней в том же месте, где мы объявляли другие наши переменные:</p> + +<pre class="brush: js">var lives = 3;</pre> + +<p>Отрисовка счетчика жизни выглядит почти так же, как и счетчика баллов - добавьте в код следующую функцию под функцией <code>drawScore()</code> :</p> + +<pre class="brush: js">function drawLives() { + ctx.font = "16px Arial"; + ctx.fillStyle = "#0095DD"; + ctx.fillText("Lives: "+lives, canvas.width-65, 20); +}</pre> + +<p>Вместо того, чтобы немедленно закончить игру, мы уменьшим количество жизней, пока они больше не будут доступны. Мы также можем сбросить позиции мяча и биты, когда игрок начинает игру со следующей жизнью. Итак, в функции <code>draw()</code> замените следующие три строки:</p> + +<pre class="brush: js">alert("GAME OVER"); +document.location.reload(); +clearInterval(interval); // Needed for Chrome to end game</pre> + +<p>Давайте добавим немного более сложную логику к ней, как показано ниже:</p> + +<pre class="brush: js">lives--; +if(!lives) { + alert("GAME OVER"); + document.location.reload(); +} +else { + x = canvas.width/2; + y = canvas.height-30; + dx = 2; + dy = -2; + paddleX = (canvas.width-paddleWidth)/2; +}</pre> + +<p>Теперь, когда мяч попадает в нижний край экрана, мы вычитаем одну жизнь из переменной <code>lives</code>. Если жизней не осталось, игра проиграна, если осталось еще несколько жизней, то положение мяча и биты сбрасываются вместе с движением мяча.</p> + +<h3 id="Визуализация_дисплея_жизней">Визуализация дисплея жизней</h3> + +<p>Теперь вам нужно добавить вызов <code>drawLives()</code> внутри функции <code>draw()</code> и добавить его под вызовом <code>drawScore()</code>.</p> + +<pre class="brush: js">drawLives(); +</pre> + +<h2 id="Улучшение_рендеринга_с_requestAnimationFrame">Улучшение рендеринга с requestAnimationFrame()</h2> + +<p>Теперь давайте работать над чем-то, что не связано с игровой механикой, но с тем, как она рендерится. {{domxref("window.requestAnimationFrame", "requestAnimationFrame")}} поможет браузеру рендерить игру лучше, чем фиксированная частота кадров, которую в настоящее время мы реализовали, используя {{domxref("windowTimers.setInterval()", "setInterval()")}}. Замените следующую строку:</p> + +<pre class="brush: js">setInterval(draw, 10);</pre> + +<p>на:</p> + +<pre class="brush: js">draw();</pre> + +<p>и удалите каждый экземпляр:</p> + +<pre>clearInterval(interval); // Needed for Chrome to end game</pre> + +<p>Затем в самом низу функции <code>draw()</code> (непосредственно перед закрывающей фигурной скобкой) добавьте следующую строку, которая заставляет функцию <code>draw()</code> вызывать себя снова и снова:</p> + +<pre class="brush: js">requestAnimationFrame(draw);</pre> + +<p>Функция <code>draw()</code> теперь выполняется снова и снова в цикле <code>requestAnimationFrame()</code>, но вместо фиксированной частоты кадров в 10 миллисекунд, мы возвращаем управление частотой кадров обратно в браузер. Соответственно он будет синхронизировать частоту кадров и отображать фигуры только при необходимости. Это обеспечивает более эффективный и плавный цикл анимации, чем более старый метод <code>setInterval().</code></p> + +<h2 id="Сравните_свой_код">Сравните свой код</h2> + +<p>Вот и все-финальная версия игры готова!</p> + +<p>{{JSFiddleEmbed("https://jsfiddle.net/yumetodo/3becw9fy/1/","","395")}}</p> + +<div class="note"> +<p><strong>Упражнение: измените количество жизней и угол отскока мяча от биты.</strong></p> +</div> + +<h2 id="Игра_закончена_-_на_данный_момент!">Игра закончена - на данный момент!</h2> + +<p>Вы закончили все уроки — поздравляем! К этому моменту вы должны знать основы манипулирования canvas и логику простых 2D-игр. Сейчас самое время изучить некоторые фреймворки и продолжить разработку игр. Вы можете проверить аналог этой серии, <a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/2D_breakout_game_Phaser">2D breakout game using Phaser</a> или <a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/HTML5_Gamedev_Phaser_Device_Orientation">Cyber Orb built in Phaser</a> учебник. Вы также можете просмотреть раздел <a href="https://developer.mozilla.org/en/docs/Games">Games section on MDN</a> для вдохновения и увеличения знаний.</p> + +<p>Вы также можете вернуться на <a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/Breakout_game_from_scratch">this tutorial series' index page</a> учебника. Получайте удовольствие от написания кода!</p> + +<p>{{Previous("Games/Workflows/2D_Breakout_game_pure_JavaScript/Mouse_controls")}}</p> diff --git a/files/ru/games/tutorials/2d_breakout_game_pure_javascript/обнаружение_столкновений/index.html b/files/ru/games/tutorials/2d_breakout_game_pure_javascript/обнаружение_столкновений/index.html new file mode 100644 index 0000000000..576f17e7cc --- /dev/null +++ b/files/ru/games/tutorials/2d_breakout_game_pure_javascript/обнаружение_столкновений/index.html @@ -0,0 +1,128 @@ +--- +title: Обнаружение столкновений +slug: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Обнаружение_столкновений +translation_of: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Collision_detection +--- +<div>{{GamesSidebar}}</div> + +<div>{{IncludeSubnav("/en-US/docs/Games")}}</div> + +<p>{{PreviousNext("Games/Tutorials/2D_Breakout_game_pure_JavaScript/Создаем_зону_кирпичей", "Games/Tutorials/2D_Breakout_game_pure_JavaScript/Track_the_score_and_win")}}</p> + +<div class="summary"> +<p>Это 7 шаг из 10 в <a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/Breakout_game_from_scratch">Gamedev Canvas tutorial</a>. Вы можете найти исходный код, как он будет выглядеть после завершения этого урока, тут <a href="https://github.com/end3r/Gamedev-Canvas-workshop/blob/gh-pages/lesson07.html">Gamedev-Canvas-workshop/lesson7.html</a>.</p> + +<p>У нас уже есть кирпичи, появляющиеся на экране, но игра все еще не так интересна, ведь мяч проходит сквозь них. Нам нужно подумать о добавлении обнаружения столкновений, чтобы он мог отскакивать от кирпичей и ломать их.</p> +</div> + +<p>Конечно, это наше решение, как реализовать это, но может быть сложно рассчитать, касается ли шар прямоугольника или нет, потому что в Canvas нет вспомогательных функций для этого. В этом уроке мы сделаем это самым простым способом. Мы проверим, сталкивается ли центр мяча с любым из данных кирпичей. Это не идеальное решение на все случаи жизни, и есть намного более сложные и эффективные способы обнаружения столкновений, но это научит вас основным понятиям.</p> + +<h2 id="Функция_обнаружения_столкновения">Функция обнаружения столкновения</h2> + +<p>Мы хотим создать функцию обнаружения столкновений, которая будет перебирать все кирпичи и сравнивать позицию каждого кирпича с координатами шара при каждой отрисовке кадра. Для лучшей читаемости кода определим переменную <code>b</code>, чтобы хранить объект кирпича в цикле обнаружения столкновения:</p> + +<pre class="brush: js">function collisionDetection() { + for(var c=0; c<brickColumnCount; c++) { + for(var r=0; r<brickRowCount; r++) { + var b = bricks[c][r]; + // calculations + } + } +}</pre> + +<p>Если центр шара находится внутри координат одного из наших кирпичей, мы изменим направление шара. Для того, чтобы центр шара находился внутри кирпича, все четыре из следующих утверждений должны быть верны:</p> + +<ul> + <li>Координата X шара больше, чем координата X кирпича.</li> + <li>Координата X шара меньше, чем X-координата кирпича плюс его ширина.</li> + <li>Координата Y шара больше, чем Y-координата кирпича.</li> + <li>Координата Y шара меньше, чем Y-координата кирпича плюс его высота.</li> +</ul> + +<p>Давайте напишем это в коде:</p> + +<pre class="brush: js">function collisionDetection() { + for(var c=0; c<brickColumnCount; c++) { + for(var r=0; r<brickRowCount; r++) { + var b = bricks[c][r]; + if(x > b.x && x < b.x+brickWidth && y > b.y && y < b.y+brickHeight) { + dy = -dy; + } + } + } +}</pre> + +<p>Добавьте вышеприведенный блок к вашему коду под <code>keyUpHandler() </code>функцией .</p> + +<h2 id="Удаление_кирпичей_после_их_попадания">Удаление кирпичей после их попадания</h2> + +<p>Вышеприведенный код будет работать, как и задумано, и мяч изменит свое направление. Проблема в том, что кирпичи остаются на своих местах. Мы должны придумать, как избавляться от тех, в которые мы уже попали мячом. Мы можем сделать это, добавив дополнительный параметр кирпичам, определяющий, будет ли кирпич отрисовываться на экране или нет. В той части кода, где мы инициализируем кирпичи, добавим свойство <code>status</code> к каждому кирпичному объекту. Обновите следующую часть кода, как показано ниже:</p> + +<pre class="brush: js; highlight:[5]">var bricks = []; +for(var c=0; c<brickColumnCount; c++) { + bricks[c] = []; + for(var r=0; r<brickRowCount; r++) { + bricks[c][r] = { x: 0, y: 0, status: 1 }; + } +}</pre> + +<p>Теперь мы будем проверять значение свойства <code>status</code> каждого кирпича в функции <code>drawBricks()</code> перед его рисованием - если <code>status</code> равен <code>1</code> , нарисуем его, а если равен <code>0</code> , то значит в него попал мяч и он не должен больше отрисовываться. Отредактируйте <code>drawBricks()</code> следующим образом:</p> + +<pre class="brush: js; highlight:[4,5,6,7,8,9,10,11,12,13,14]">function drawBricks() { + for(var c=0; c<brickColumnCount; c++) { + for(var r=0; r<brickRowCount; r++) { + if(bricks[c][r].status == 1) { + var brickX = (c*(brickWidth+brickPadding))+brickOffsetLeft; + var brickY = (r*(brickHeight+brickPadding))+brickOffsetTop; + bricks[c][r].x = brickX; + bricks[c][r].y = brickY; + ctx.beginPath(); + ctx.rect(brickX, brickY, brickWidth, brickHeight); + ctx.fillStyle = "#0095DD"; + ctx.fill(); + ctx.closePath(); + } + } + } +}</pre> + +<h2 id="Отслеживание_и_обновление_состояния_в_функции_обнаружения_столкновений">Отслеживание и обновление состояния в функции обнаружения столкновений</h2> + +<p>Теперь нам нужно задействовать свойство <code>status</code> кирпича в функции <code>collisionDetection()</code> : если кирпич активен (его статус равен <code>1</code> ), мы проверяем, было ли столкновение; если да, мы устанавливаем статус данного кирпича равным <code>0</code>, чтобы он не был нарисован на экране. Отредактируйте функцию <code>collisionDetection()</code>, как показано ниже:</p> + +<pre class="brush: js; highlight:[5,6,7,8,9,10]">function collisionDetection() { + for(var c=0; c<brickColumnCount; c++) { + for(var r=0; r<brickRowCount; r++) { + var b = bricks[c][r]; + if(b.status == 1) { + if(x > b.x && x < b.x+brickWidth && y > b.y && y < b.y+brickHeight) { + dy = -dy; + b.status = 0; + } + } + } + } +}</pre> + +<h2 id="Активация_нашего_обнаружения_столкновений">Активация нашего обнаружения столкновений</h2> + +<p>Последнее, что нужно сделать, это добавить вызов функции <code>collisionDetection()</code> в нашу основную функцию <code>draw()</code> . Добавьте следующую строку в функцию <code>draw()</code> , чуть ниже <code>drawPaddle()</code> :</p> + +<pre class="brush: js">collisionDetection(); +</pre> + +<h2 id="Сравните_свой_код">Сравните свой код</h2> + +<p>Обнаружение столкновения шара теперь выполняется на каждом кадре и для каждого кирпича. Теперь мы можем ломать кирпичи! : -</p> + +<p>{{JSFiddleEmbed("https://jsfiddle.net/yumetodo/mkwtxgc3/3/","","395")}}</p> + +<div class="note"> +<p><strong>Упражнение</strong> : измените цвет шара, когда он ударит по кирпичу.</p> +</div> + +<h2 id="Следующие_шаги">Следующие шаги</h2> + +<p>Мы уверенно движемся вперёд! Поехали! В восьмой главе мы будем учиться <a href="https://translate.googleusercontent.com/translate_c?act=url&depth=1&hl=ru&ie=UTF8&prev=_t&rurl=translate.google.com&sl=en&sp=nmt4&tl=ru&u=https://developer.mozilla.org/en-US/docs/Games/Workflows/Breakout_game_from_scratch/Track_the_score_and_win&xid=25657,15700022,15700124,15700149,15700168,15700186,15700190,15700201,15700205&usg=ALkJrhhN9U9TuRM07dQaU3Oyqz2-F5ctig">отслеживать счет и выигрывать</a> .</p> + +<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_pure_JavaScript/Build_the_brick_field", "Games/Workflows/2D_Breakout_game_pure_JavaScript/Track_the_score_and_win")}}</p> diff --git a/files/ru/games/tutorials/2d_breakout_game_pure_javascript/переместить_мяч/index.html b/files/ru/games/tutorials/2d_breakout_game_pure_javascript/переместить_мяч/index.html new file mode 100644 index 0000000000..f6d26cfc52 --- /dev/null +++ b/files/ru/games/tutorials/2d_breakout_game_pure_javascript/переместить_мяч/index.html @@ -0,0 +1,146 @@ +--- +title: Переместить мяч +slug: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Переместить_мяч +tags: + - 2D + - Canvas + - Игры + - Обучение + - Цикл + - передвижение + - пишем игру на javascript +translation_of: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Move_the_ball +--- +<div>{{GamesSidebar}}</div> + +<div>{{IncludeSubnav("/en-US/docs/Games")}}</div> + +<p>{{PreviousNext("Games/Tutorials/2D_Breakout_game_pure_JavaScript/Создание_Canvas_и_рисование_на_нём", "Games/Tutorials/2D_Breakout_game_pure_JavaScript/Bounce_off_the_walls")}}</p> + +<div class="summary"> +<p>Это <strong>2й шаг</strong> из 10 <a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/Breakout_game_from_scratch">Gamedev Canvas tutorial</a>. Вы можете найти исходный код для данного урока по ссылке <a href="https://github.com/end3r/Gamedev-Canvas-workshop/blob/gh-pages/lesson02.html">Gamedev-Canvas-workshop/lesson2.html</a>.</p> +</div> + +<p><span class="seoSummary">Из предыдущей статьи Вы уже знаете, как нарисовать мяч, а сейчас давайте заставим его двигаться. Технически, мы будем рисовать мяч на экране, стирать его и рисовать заново на немного другой позиции каждый раз, чтобы создать эффект движения - точно так же, как это работает в фильмах.</span></p> + +<h2 id="Определяем_цикл_рисования">Определяем цикл рисования</h2> + +<p>Чтобы canvas постоянно обновлялся, необходимо определить функцию отрисовки, которая будет циклически запускаться с разными параметрами, чтобы изменять позицию элемента. Функцию можно циклически запускать с помощью JavaScript временной функции, такой как {{domxref("WindowTimers.setInterval()", "setInterval()")}} или {{domxref("window.requestAnimationFrame()", "requestAnimationFrame()")}}.</p> + +<p>Удалите весь JavaScript код, который сейчас хранился в Вашем HTML файле, за исключением первых двух строк, и добавьте следующий код после них. Функция <code>draw()</code> будет исполняться внутри функции <code>setInterval</code> каждые 10 мс:</p> + +<pre class="brush: js">function draw() { + // код отрисовки +} +setInterval(draw, 10);</pre> + +<p>Благодаря бесконечности функции <code>setInterval</code> функция <code>draw()</code> будет выполняться каждые 10 мс бесконечно или же пока мы не остановим её. Теперь давайте нарисуем мяч - добавьте в свой код функцию <code>draw()</code>:</p> + +<pre class="brush: js">ctx.beginPath(); +ctx.arc(50, 50, 10, 0, Math.PI*2); +ctx.fillStyle = "#0095DD"; +ctx.fill(); +ctx.closePath(); +</pre> + +<p>Попробуйте сейчас Ваш обновлённый код - каждый раз мяч будет перерисовываться.</p> + +<h2 id="Перемещение">Перемещение</h2> + +<p>Вы не можете определить, перерисовывается ли мяч в конкретный момент, так как его позиция не меняется. Давайте исправим это. Прежде всего, в позиции (50,50) определим стартовую точку в нижней центральной части Canvas в переменной <code>x</code> и <code>y</code>, и потом используем их для определения текущего положения мяча.</p> + +<p>Для начала добавьте следующие две строки до функции <code>draw()</code>, чтобы определить переменные <code>x</code> и <code>y</code>:</p> + +<pre class="brush: js">var x = canvas.width/2; +var y = canvas.height-30; +</pre> + +<p>Далее обновите функцию <code>draw()</code>, чтобы использовать переменные x и y в методе {{domxref("CanvasRenderingContext2D.arc()","arc()")}}, как показано на подсвеченной линии:</p> + +<pre class="brush: js; highlight:[3]">function draw() { + ctx.beginPath(); + ctx.arc(x, y, 10, 0, Math.PI*2); + ctx.fillStyle = "#0095DD"; + ctx.fill(); + ctx.closePath(); +} +</pre> + +<p>Теперь важная часть: мы хотим добавлять небольшое значение к переменным <code>x</code> и <code>y</code> после каждой итерации, чтобы заставить мяч двигаться. Давайте определим эти небольшие значения в переменных <code>dx</code> и <code>dy</code> и установим их 2 и -2 соответственно. Добавьте следующий код после определения переменных x и y:</p> + +<pre class="brush: js">var dx = 2; +var dy = -2; +</pre> + +<p>И последнее, необходимо обновить переменные <code>x</code> и <code>y</code> на значение <code>dx</code> и <code>dy</code> каждую итерацию, чтобы мяч отрисовывался каждый раз на новой позиции. Добавьте ещё две строки кода в функции <code>draw()</code>:</p> + +<pre class="brush: js; highlight:[7,8]">function draw() { + ctx.beginPath(); + ctx.arc(x, y, 10, 0, Math.PI*2); + ctx.fillStyle = "#0095DD"; + ctx.fill(); + ctx.closePath(); + x += dx; + y += dy; +}</pre> + +<p>Сохраните Ваш код и откройте страницу в браузере. Всё работает хорошо, вот только мяч оставляет позади след:</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/10430/ball-trail.png" style="display: block; height: 320px; margin: 0px auto; width: 480px;"></p> + +<h2 id="Очищение_объекта_после_каждого_кадра">Очищение объекта после каждого кадра</h2> + +<p>Мяч оставляет след, потому что мы рисуем круг на каждой итерации без удаления предыдущей отрисованной фигуры. Не переживайте, потому что существует метод для очистки canvas элемента: {{domxref("CanvasRenderingContext2D.clearRect()","clearRect()")}}. Этот метод принимает четыре параметра: x и y координаты верхнего левого угла прямоугольника, x и y координаты нижнего правого угла прямоугольника. Вся площадь, покрытая прямоугольником, будет очищена от любого содержимого, которое когда-либо было там отрисовано.</p> + +<p>Добавьте следующую подсвеченную строку в функцию <code>draw()</code>:</p> + +<pre class="brush: js; highlight:[2]">function draw() { + ctx.clearRect(0, 0, canvas.width, canvas.height); + ctx.beginPath(); + ctx.arc(x, y, 10, 0, Math.PI*2); + ctx.fillStyle = "#0095DD"; + ctx.fill(); + ctx.closePath(); + x += dx; + y += dy; +} +</pre> + +<p>Сохраните Ваш код и попробуйте снова, и на этот раз Вы увидите, что мяч перемещается без следов. Каждые 10 мс canvas очищается, голубой круг (наш мяч) отрисовывается на заданной позиции, переменные <code>x</code> и <code>y</code> каждую итерацию обновляются.</p> + +<h2 id="Рефакторинг">Рефакторинг</h2> + +<p>Мы будем добавлять каждый раз всё больше команд в функцию <code>draw()</code>, поэтому было бы неплохо содержать наш код настолько простым и понятным, на сколько это возможно. Давайте вынесем команды перемещения мяча в отдельную функцию.</p> + +<p>Замените существующую функцию draw() следующими двумя функциями:</p> + +<pre class="brush: js">function drawBall() { + ctx.beginPath(); + ctx.arc(x, y, 10, 0, Math.PI*2); + ctx.fillStyle = "#0095DD"; + ctx.fill(); + ctx.closePath(); +} + +function draw() { + ctx.clearRect(0, 0, canvas.width, canvas.height); + drawBall(); + x += dx; + y += dy; +}</pre> + +<h2 id="Сравните_Ваш_код">Сравните Ваш код</h2> + +<p>Вы можете проверить итоговый код для этого урока с помощью демо, а так же поэкспериментировать с ним, изменяя те или иные параметры:</p> + +<p>{{JSFiddleEmbed("https://jsfiddle.net/end3r/3x5foxb1/","","395")}}</p> + +<div class="summary"> +<p>Упражнение: попробуйте изменить скорость перемещения мяча, или направление перемещения.</p> +</div> + +<h2 id="Следующие_шаги">Следующие шаги</h2> + +<p>Мы нарисовали мяч и заставили его двигаться, но он продолжает пропадать на краю canvas. В третьей части мы рассмотрим, как заставить его <a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/Breakout_game_from_scratch/Bounce_off_the_walls">отскакивать от стен</a>.</p> + +<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_pure_JavaScript/Create_the_Canvas_and_draw_on_it", "Games/Workflows/2D_Breakout_game_pure_JavaScript/Bounce_off_the_walls")}}</p> diff --git a/files/ru/games/tutorials/2d_breakout_game_pure_javascript/создаем_зону_кирпичей/index.html b/files/ru/games/tutorials/2d_breakout_game_pure_javascript/создаем_зону_кирпичей/index.html new file mode 100644 index 0000000000..91c7ea5405 --- /dev/null +++ b/files/ru/games/tutorials/2d_breakout_game_pure_javascript/создаем_зону_кирпичей/index.html @@ -0,0 +1,119 @@ +--- +title: Создаем зону кирпичей +slug: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Создаем_зону_кирпичей +translation_of: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Build_the_brick_field +--- +<div>{{GamesSidebar}}</div> + +<div>{{IncludeSubnav("/en-US/docs/Games")}}</div> + +<p>{{PreviousNext("Games/Tutorials/2D_Breakout_game_pure_JavaScript/Game_over", "Games/Tutorials/2D_Breakout_game_pure_JavaScript/Collision_detection")}}</p> + +<div class="summary"> +<p>Это 6 шаг из 10 в <a href="/en-US/docs/Games/Workflows/Breakout_game_from_scratch">Gamedev Canvas tutorial</a>. Вы можете найти исходный код, как он будет выглядеть после завершения этого урока, тут - <a href="https://github.com/end3r/Gamedev-Canvas-workshop/blob/gh-pages/lesson06.html">Gamedev-Canvas-workshop/lesson6.html</a>.</p> +</div> + +<p>После изменения механики игрового процесса мы теперь можем проиграть - это здорово, так как это означает, что игра, наконец, больше похожа на игру. Тем не менее, он быстро станет скучным, если все, что вы делаете, это отскок шара от стен и биты. То, что действительно нужно для прорыва - это кирпичи, которые нужно уничтожить мячом, и это то, что мы сейчас создадим!</p> + +<h2 id="Настройка_переменных_кирпича">Настройка переменных кирпича</h2> + +<p>Общая цель этого урока - сделать несколько строк кода для кирпичей, используя вложенный цикл, который работает через двумерный массив. Однако сначала нам нужно настроить некоторые переменные для определения информации о таких кирпичах, как их ширина и высота, строки и столбцы и т. Д. Добавьте следующие строки в свой код под переменными, которые вы ранее объявили в своей программе.</p> + +<pre class="brush: js">var brickRowCount = 3; +var brickColumnCount = 5; +var brickWidth = 75; +var brickHeight = 20; +var brickPadding = 10; +var brickOffsetTop = 30; +var brickOffsetLeft = 30;</pre> + + + +<p>Здесь мы определили количество строк и столбцов кирпичей, их ширину и высоту, прокладку между кирпичами, чтобы они не касались друг друга и верхнее и левое смещение, чтобы они не начинали рисоваться прямо от края Холста.</p> + +<p>Мы будем держать все наши кирпичи в двумерном массиве. Он будет содержать кирпичные столбцы (c), которые, в свою очередь, будут содержать кирпичные ряды (r), которые, в свою очередь, будут содержать объект, содержащий положение <code>x</code> и <code>y</code>чтобы рисовать каждый кирпич на экране. Добавьте следующие значения ниже ваших переменных:</p> + + + +<pre class="brush: js">var bricks = []; +for(var c=0; c<brickColumnCount; c++) { + bricks[c] = []; + for(var r=0; r<brickRowCount; r++) { + bricks[c][r] = { x: 0, y: 0 }; + } +}</pre> + +<p>Вышеприведенный код будет прокручивать строки и столбцы и создавать новые кирпичи. Обратите внимание, что кирпичные объекты также будут использоваться для целей обнаружения столкновений позже.</p> + +<h2 id="Механизм_отрисовки_кирпичей">Механизм отрисовки кирпичей</h2> + +<p>Теперь давайте создадим функцию, чтобы перебрать все кирпичи в массиве и нарисовать их на экране. Наш код может выглядеть так:</p> + +<pre class="brush: js">function drawBricks() { + for(var c=0; c<brickColumnCount; c++) { + for(var r=0; r<brickRowCount; r++) { + bricks[c][r].x = 0; + bricks[c][r].y = 0; + ctx.beginPath(); + ctx.rect(0, 0, brickWidth, brickHeight); + ctx.fillStyle = "#0095DD"; + ctx.fill(); + ctx.closePath(); + } + } +}</pre> + +<p>Опять же, мы зацикливаем строки и столбцы, чтобы установить положение <code>x</code> и <code>y</code>каждого кирпича, и мы также <code>brickWidth</code> кирпич на кирпичной <code>brickWidth</code> Canvas -<code>brickWidth</code> - с каждой итерацией цикла. Проблема в том, что мы рисуем их все в одном месте, в координатах <code>(0,0)</code> . Нам нужно включить некоторые вычисления, которые будут определять положение <code>x</code> и <code>y</code> каждого кирпича для каждой итерации цикла:</p> + +<pre class="brush: js">var brickX = (c*(brickWidth+brickPadding))+brickOffsetLeft; +var brickY = (r*(brickHeight+brickPadding))+brickOffsetTop;</pre> + + + +<p>Каждая позиция <code>brickX</code> разрабатывается как <code>brickWidth</code> + <code>brickPadding</code> , умноженная на номер столбца, <code>c</code> , плюс <code>brickOffsetLeft</code> ; логика для brickY идентична, за исключением того, что она использует значения для номера строки, <code>r</code>, <code>brickHeight</code> и <code>brickOffsetTop</code> . Теперь каждый отдельный кирпич может быть помещен в правильное место и столбец места, с отступом между каждым кирпичом, нарисованным на смещение от левого и верхнего краев холста.</p> + +<p>Окончательная версия функции <code>drawBricks()</code> после назначения <code>brickX</code> и <code>brickY</code> в качестве координат вместо <code>(0,0)</code> каждый раз будет выглядеть следующим образом: добавьте это в свой код ниже функции <code>drawPaddle()</code> :</p> + + + +<pre class="brush: js"> for(var c=0; c<brickColumnCount; c++) { + for(var r=0; r<brickRowCount; r++) { + var brickX = (c*(brickWidth+brickPadding))+brickOffsetLeft; + var brickY = (r*(brickHeight+brickPadding))+brickOffsetTop; + bricks[c][r].x = brickX; + bricks[c][r].y = brickY; + ctx.beginPath(); + ctx.rect(brickX, brickY, brickWidth, brickHeight); + ctx.fillStyle = "#0095DD"; + ctx.fill(); + ctx.closePath(); + } + } +}</pre> + +<h2 id="Сама_отрисовка_кирпичей">Сама отрисовка кирпичей</h2> + +<p>Последнее, что нужно сделать в этом уроке, - добавить вызов <code>drawBricks()</code> где-нибудь в функции <code>draw()</code> , предпочтительно в начале, между очисткой холста и рисованием шара. Добавьте следующее выше <code>drawBall()</code> :</p> + +<pre class="brush: js">drawBricks(); +</pre> + +<h2 id="Сравните_свой_код">Сравните свой код</h2> + + + +<p>На этом этапе игра снова стала интереснее:</p> + + + +<p>{{JSFiddleEmbed("https://jsfiddle.net/yumetodo/t1zqmzLp/","","395")}}</p> + +<div class="note"> +<p>Упражнение: попробуйте изменить количество кирпичей в строке или столбце или их позиции.</p> +</div> + +<h2 id="Следующие_шаги">Следующие шаги</h2> + +<p>Итак, теперь у нас есть кирпичи! Но мяч вообще не взаимодействует с ними - мы изменим это, поскольку мы переходим в седьмую главу: <a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/Breakout_game_from_scratch/Collision_detection">Collision detection</a>.</p> + +<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_pure_JavaScript/Game_over", "Games/Workflows/2D_Breakout_game_pure_JavaScript/Collision_detection")}}</p> diff --git a/files/ru/games/tutorials/2d_breakout_game_pure_javascript/создание_canvas_и_рисование_на_нём/index.html b/files/ru/games/tutorials/2d_breakout_game_pure_javascript/создание_canvas_и_рисование_на_нём/index.html new file mode 100644 index 0000000000..84f23b0e2a --- /dev/null +++ b/files/ru/games/tutorials/2d_breakout_game_pure_javascript/создание_canvas_и_рисование_на_нём/index.html @@ -0,0 +1,115 @@ +--- +title: Создание Canvas и рисование на нём +slug: >- + Games/Tutorials/2D_Breakout_game_pure_JavaScript/Создание_Canvas_и_рисование_на_нём +tags: + - JavaScript + - Игры + - разработка игр + - создание игр +translation_of: >- + Games/Tutorials/2D_Breakout_game_pure_JavaScript/Create_the_Canvas_and_draw_on_it +--- +<div>{{GamesSidebar}}</div> + +<div>{{IncludeSubnav("/ru/docs/Games")}}</div> + +<p>{{PreviousNext("Games/Tutorials/2D_Breakout_game_pure_JavaScript", "Games/Tutorials/2D_Breakout_game_pure_JavaScript/Переместить_мяч")}}</p> + +<div class="summary"> +<p>Это <strong>1й шаг</strong> из 10 <a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/Breakout_game_from_scratch">Gamedev Canvas tutorial</a>. Вы можете найти исходный код для этого урока по ссылке <a href="https://github.com/end3r/Gamedev-Canvas-workshop/blob/gh-pages/lesson01.html">Gamedev-Canvas-workshop/lesson1.html</a>.</p> +</div> + +<p>Прежде чем мы сможем начать писать функциональные возможности игры, нам необходимо создать базовую структуру для рендеринга игры внутри. Это можно сделать с помощью HTML и элемента {{htmlelement ("canvas")}}.</p> + +<h2 id="HTML_игры">HTML игры</h2> + +<p>Структура HTML документа довольно проста, так как игра будет полностью визуализироваться в {{htmlelement("canvas")}} элементе. Используя Ваш любимый текстовый редактор, создайте новый HTML документ, сохраните его как <code>index.html</code> в любом удобном месте, и скопируйте в него этот код:</p> + +<pre class="brush: html"><!DOCTYPE html> +<html> +<head> + <meta charset="utf-8" /> + <title>Gamedev Canvas Workshop</title> + <style> + * { padding: 0; margin: 0; } + canvas { background: #eee; display: block; margin: 0 auto; } + </style> +</head> +<body> + +<canvas id="myCanvas" width="480" height="320"></canvas> + +<script> + // JavaScript код будем писать здесь +</script> + +</body> +</html> +</pre> + +<p>Мы определили <code>charset</code>, {{htmlelement("title")}} и некий базовый CSS в заголовке. Тело документа содержит элементы {{htmlelement("canvas")}} и {{htmlelement("script")}} — мы будем визуализировать игру внутри первого и писать JavaScript код, который управляет игрой, во втором. Элемент {{htmlelement("canvas")}} имеет <code>id</code> равный <code>myCanvas</code>, который позволяет однозначно отыскать элемент. Так же этот элемент имеет ширину 480 пикселей и высоту 320 пикселей. Весь JavaScript код мы будем писать между открывающим тегом <code><script></code> и закрывающим тегом <code></script></code>.</p> + +<h2 id="Основы_Canvas">Основы Canvas</h2> + +<p>Чтобы иметь возможность визуализировать игру в {{htmlelement("canvas")}} элементе, сначала мы должны сослаться на этот элемент в коде JavaScript. Добавьте следующий код после открывающего тега <code><script></code>.</p> + +<pre class="brush: js">var canvas = document.getElementById("myCanvas"); +var ctx = canvas.getContext("2d");</pre> + +<p>Таким образом, мы храним ссылку на {{htmlelement("canvas")}} элемент в переменной <code>canvas</code>. Далее мы создаём переменную <code>ctx</code> для хранения 2D визуализации контекста — метод, который используется для отрисовки в Canvas.</p> + +<p>Давайте рассмотрим пример отрисовки красного квадрата на canvas. Добавьте этот код ниже предыдущего кода на JavaScript и загрузите <code>index.html</code> в браузере, чтобы посмотреть результат.</p> + +<pre class="brush: js">ctx.beginPath(); +ctx.rect(20, 40, 50, 50); +ctx.fillStyle = "#FF0000"; +ctx.fill(); +ctx.closePath();</pre> + +<p>Все инструкции располагаются между методами {{domxref("CanvasRenderingContext2D.beginPath()","beginPath()")}} и {{domxref("CanvasRenderingContext2D.closePath()","closePath()")}}. Мы определяем прямоугольник, используя {{domxref("CanvasRenderingContext2D.rect()","rect()")}}: первые два параметра определяют координаты верхнего левого угла прямоугольника на canvas, в то время, как два других параметра определяют ширину и высоту прямоугольника. В нашем случае прямоугольник нарисован на расстоянии 20 пикселей слева и 40 пикселей сверху, 50 пикселей в ширину и 50 пикселей в высоту, что делает его квадратом. Свойство {{domxref("CanvasRenderingContext2D.fillStyle","fillStyle")}} хранит цвет, который будет использован методом {{domxref("CanvasRenderingContext2D.fill()","fill()")}} для отрисовки нашего квадрата.</p> + +<p>Мы не ограничены только прямоугольниками - ниже часть кода для отрисовки зелёного круга. Попробуйте добавить этот код вконец Вашего кода JavaScript, сохраните и обновите страницу в браузере:</p> + +<pre class="brush: js">ctx.beginPath(); +ctx.arc(240, 160, 20, 0, Math.PI*2, false); +ctx.fillStyle = "green"; +ctx.fill(); +ctx.closePath();</pre> + +<p>Как видите, мы снова используем методы {{domxref("CanvasRenderingContext2D.beginPath()","beginPath()")}} и {{domxref("CanvasRenderingContext2D.closePath()","closePath()")}}. Между ними наиболее важная часть кода - метод {{domxref("CanvasRenderingContext2D.arc()","arc()")}}. Он принимает шесть параметров:</p> + +<ul> + <li><code>x</code> и <code>y</code> координаты центра круга</li> + <li>радиус</li> + <li>начальный и конечный угол отрисовки круга (в радианах)</li> + <li>направление отрисовки: (<code>false</code> - по часовой стрелке, по умолчанию, или <code>true</code> - против часовой стрелки). Последний параметр не обязательный.</li> +</ul> + +<p>Свойство {{domxref("CanvasRenderingContext2D.fillStyle","fillStyle")}} выглядит не так, как прежде. Это потому что, как и в CSS, цвет может быть задан в шестнадцатиричном формате, названием цвета, функцией <code>rgba()</code> , или же любым другим методом для цвета.</p> + +<p>Вместо {{domxref("CanvasRenderingContext2D.fill()","fill()")}} и заполнения фигур цветом, можно использовать {{domxref("CanvasRenderingContext2D.stroke()","stroke()")}}, чтобы окрасить только внешнюю обводку фигуры. Попробуйте добавить этот код к Вашему коду JavaScript:</p> + +<pre class="brush: js">ctx.beginPath(); +ctx.rect(160, 10, 100, 40); +ctx.strokeStyle = "rgba(0, 0, 255, 0.5)"; +ctx.stroke(); +ctx.closePath();</pre> + +<p>Код выше отрисовывает пустой прямоугольник с синей обводкой. Благодаря функции альфа-канала <code>rgba()</code> , голубой цвет полупрозрачный.</p> + +<h2 id="Сравните_Ваш_код">Сравните Ваш код</h2> + +<p>Здесь полный исходный код для первого урока, посмотреть онлайн можно на JSFiddle:</p> + +<p>{{JSFiddleEmbed("https://jsfiddle.net/end3r/x62h15e2/","","395")}}</p> + +<div class="note"> +<p><strong>Упражнение</strong>: попробуйте изменить цвет и размер созданных фигур.</p> +</div> + +<h2 id="Следующие_шаги">Следующие шаги</h2> + +<p>Сейчас мы создали базовый HTML и немного узнали о canvas, давайте на следующем шаге изучим, как <a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/Breakout_game_from_scratch/Move_the_ball">Двигать мяч в нашей игре</a>.</p> + +<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_pure_JavaScript", "Games/Workflows/2D_Breakout_game_pure_JavaScript/Move_the_ball")}}</p> diff --git a/files/ru/games/tutorials/2d_breakout_game_pure_javascript/управление_мышью/index.html b/files/ru/games/tutorials/2d_breakout_game_pure_javascript/управление_мышью/index.html new file mode 100644 index 0000000000..b3ab4efaca --- /dev/null +++ b/files/ru/games/tutorials/2d_breakout_game_pure_javascript/управление_мышью/index.html @@ -0,0 +1,58 @@ +--- +title: Управление мышью +slug: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Управление_мышью +tags: + - Игры + - Начинающий + - канвас + - мышь +translation_of: Games/Tutorials/2D_Breakout_game_pure_JavaScript/Mouse_controls +--- +<div>{{GamesSidebar}}</div> + +<div>{{IncludeSubnav("/en-US/docs/Games")}}</div> + +<p>{{PreviousNext("Games/Tutorials/2D_Breakout_game_pure_JavaScript/Track_the_score_and_win", "Games/Tutorials/2D_Breakout_game_pure_JavaScript/Заключение")}}</p> + +<div class="summary"> +<p>Это 9-й шаг из 10 в <a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/Breakout_game_from_scratch">Gamedev Canvas tutorial</a>. Вы можете найти исходный код к этому уроку в <a href="https://github.com/end3r/Gamedev-Canvas-workshop/blob/gh-pages/lesson09.html">Gamedev-Canvas-workshop/lesson9.html</a>.</p> +</div> + +<p><span class="seoSummary">Сама игра на самом деле закончена, так что давайте отполируем её. Мы уже добавили элементы управления клавиатуру, но мы могли бы легко добавить элемент управления мышь.</span></p> + +<h2 id="Отслеживание_движений_мыши">Отслеживание движений мыши</h2> + +<p>Отслеживание движений мыши еще проще, чем прослушивание нажатий клавиш. Все, что нам нужно, это следить за событиями {{event("mousemove")}}. Добавьте следующую строку в том же месте, как и для других событий, чуть ниже <code>keyup event</code>:</p> + +<pre class="brush: js">document.addEventListener("mousemove", mouseMoveHandler, false);</pre> + +<h2 id="Привязка_движения_ракетки_к_движению_мыши">Привязка движения ракетки к движению мыши</h2> + +<p>Мы можем обновить положение ракетки на основе координат указателя - следующая функция обработчика сделает именно это. Добавьте в код следующую функцию под предыдущей добавленной строкой:</p> + +<pre class="brush: js">function mouseMoveHandler(e) { + var relativeX = e.clientX - canvas.offsetLeft; + if(relativeX > 0 && relativeX < canvas.width) { + paddleX = relativeX - paddleWidth/2; + } +}</pre> + +<p>В этой функции мы сначала разрабатываем значение <code>relativeX</code>, которое равно горизонтальному положению мыши в окне браузера (<code>e.clientX</code>) минус расстояние между левым краем canvas и левым краем окна браузера (<code>canvas.offsetLeft</code>) - фактически это равно расстоянию между левым краем canvas и указателем мыши. Если относительный указатель позиции X больше нуля и меньше, чем ширина Canvas, указатель находится в пределах границы Canvas, и <code>paddleX</code> установки (крепится на левый край ракетки) - устанавливается на <code>relativeX</code> значение минус половина ширины ракетки, так что движение будет по отношению к середине ракетки.</p> + +<p>Ракетка теперь будет следовать за положением курсора мыши, но так как мы ограничиваем движение размером Canvas, он не исчезнет полностью с обеих сторон.</p> + +<h2 id="Сравните_свой_код">Сравните свой код</h2> + +<p>Это последнее состояние кода для сравнения:</p> + +<p>{{JSFiddleEmbed("https://jsfiddle.net/yumetodo/1L9ep9r2/1/","","395")}}</p> + +<div class="summary"> +<p>Упражнение: отрегулируйте границы движения ракетки так, что вся ракетка будет видна на обоих краях Canvas, а не только на его половину.</p> +</div> + +<h2 id="Следующий_шаг">Следующий шаг</h2> + +<p>Теперь у нас есть полная игра, мы закончим нашу серию уроков с еще несколькими небольшими хитростями — <a href="https://developer.mozilla.org/en-US/docs/Games/Workflows/Breakout_game_from_scratch/Finishing_up">Finishing up</a>.</p> + +<p>{{PreviousNext("Games/Workflows/2D_Breakout_game_pure_JavaScript/Track_the_score_and_win", "Games/Workflows/2D_Breakout_game_pure_JavaScript/Finishing_up")}}</p> |