aboutsummaryrefslogtreecommitdiff
path: root/files/ru/learn/javascript/objects/adding_bouncing_balls_features/index.html
blob: fe97392371e73938ede1be2754083d7627a69ae9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
---
title: Добавление функций в нашу демонстрацию отбойных шаров
slug: Learn/JavaScript/Объекты/Adding_bouncing_balls_features
translation_of: Learn/JavaScript/Objects/Adding_bouncing_balls_features
---
<div>{{LearnSidebar}}</div>

<div>{{PreviousMenuNext("Learn/JavaScript/Objects/Object_building_practice", "", "Learn/JavaScript/Objects")}}</div>

<p class="summary">В этом упражнении мы будем использовать проект прыгающих шаров из предыдущей статьи и добавим в него новые интересные возможности.</p>

<table class="learn-box standard-table">
 <tbody>
  <tr>
   <th scope="row">Требования:</th>
   <td>Перед тем как приступить к этому упражнению нужно выполнить задания из всех статей текущего модуля.</td>
  </tr>
  <tr>
   <th scope="row">Цель:</th>
   <td>Проверить насколько хорошо вы понимаете объекты и связанные с ними конструкции в языке Javascript. </td>
  </tr>
 </tbody>
</table>

<h2 id="Начало">Начало</h2>

<p>Для начала скопируйте файлы <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/bouncing-balls/index-finished.html">index-finished.html</a>, <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/bouncing-balls/style.css">style.css</a> и <a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/bouncing-balls/main-finished.js">main-finished.js</a> из предыдущей статьи в новую директорию на вашем компьютере.</p>

<p>Для выполнения упражнения вы можете использовать сайт <a class="external external-icon" href="http://jsbin.com/">JSBin</a> или <a class="external external-icon" href="https://thimble.mozilla.org/">Thimble</a>. Вы можете вставлять HTML, CSS и JavaScript код в один из этих онлайн-редакторов. Если ваш онлайн-редактор не поддерживает раздельные панели для редактирования JavaScript/CSS кода, то вы можете встроить код в HTML с помощью тегов <code>&lt;script&gt;</code>/<code>&lt;style&gt;</code>.</p>

<div class="note">
<p><strong>Примечание</strong>. Если у вас что-то не получается — попросите о помощи. Более подробная информация находится в секции {{anch("Assessment or further help")}} в конце этой страницы.</p>
</div>

<h2 id="Краткое_описание_проекта">Краткое описание проекта</h2>

<p>Наша веселая демонстрация шаров - это весело, но теперь мы хотим сделать ее немного более интерактивной, добавив контролируемый пользователем злой круг, который будет есть шары, если он их поймает. Мы также хотим проверить ваши навыки создания объектов, создав общий объект <code>Shape()</code>, который могут наследовать наши шары и злой круг. Наконец, мы хотим добавить счетчик очков, чтобы отслеживать количество оставшихся шаров для захвата.</p>

<p>Следующий скриншот дает вам представление о том, как должна выглядеть готовая программа:</p>

<p><img alt="" src="https://mdn.mozillademos.org/files/13875/bouncing-evil-circle.png" style="display: block; margin: 0 auto;"></p>

<ul>
</ul>

<p>Чтобы дать вам больше идеи, посмотрите на <a href="https://mdn.github.io/learning-area/javascript/oojs/assessment/">законченный пример</a> (не заглядывая в исходный код!)</p>

<h2 id="Шаги_по_завершению">Шаги по завершению</h2>

<p>В следующих разделах описывается, что вам нужно делать.</p>

<h3 id="Создание_наших_новых_объектов">Создание наших новых объектов</h3>

<p>Прежде всего, измените существующий конструктор <code>Ball()</code> так, чтобы он стал конструктором <code>Shape()</code> и добавил новый конструктор <code>Ball()</code>:</p>

<ol>
 <li>Конструктор <code>Shape()</code> должен определять свойства <code>x</code>, <code>y</code>, <code>velX</code> и <code>velY</code>,  так же, как и конструктор <code>Ball()</code>, но не свойства <code>color</code> и <code>size</code>.</li>
 <li>Он также должен определить новое свойство<code>exists</code>, которое используется для отслеживания наличия шаров в программе (не было съедено злым кругом). Это должно быть логическое (<code>true</code> / <code>false</code>).</li>
 <li>Конструктор <code>Ball()</code> должен наследовать свойства <code>x</code>, <code>y</code>, <code>velX</code>, <code>velY</code> и <code>exists</code> из конструктора <code>Shape()</code>.</li>
 <li>Он также должен определить свойство <code>color</code> и <code>size</code>, как это сделал оригинальный конструктор <code>Ball()</code>.</li>
 <li>Не забудьте установить <code>prototype</code> и <code>constructor</code> конструктора <code>Ball()</code> соответствующим образом.</li>
</ol>

<p>Определения меток шара <code>draw()</code>, <code>update()</code> и <code>collisionDetect()</code> должны быть такими же, как и раньше.</p>

<p>Вам также нужно добавить новый параметр в новый вызов конструктора <code>new Ball() ( ... )</code> - параметр <code>exists</code> должен быть 5-м параметром и ему должно быть присвоено значение <code>true</code>.</p>

<p>На этом этапе попробуйте перезагрузить код - он должен работать так же, как и раньше, с нашими перепроектированными объектами.</p>

<h3 id="Определение_EvilCircle">Определение EvilCircle()</h3>

<p>Теперь пришло время встретить плохого парня - <code>EvilCircle()</code>! Наша игра будет включать только один злой круг, но мы все еще будем определять его с помощью конструктора, который наследует от <code>Shape()</code>, чтобы дать вам некоторую практику. Возможно, вам захочется добавить еще один круг в приложение, которое может контролироваться другим игроком или иметь несколько злобных окружений, управляемых компьютером. Вы, вероятно, не собираетесь захватить мир одним злым кругом, но он будет делать для этой оценки.</p>

<p>Конструктор <code>EvilCircle()</code> должен наследовать <code>x</code>, <code>y</code>, <code>velX</code>, <code>velY</code> и <code>exists</code> из <code>Shape()</code>, но <code>velX</code> и <code>velY</code> должны всегда равняться 20.</p>

<p>Вы должны сделать что-то вроде <code>Shape.call(this, x, y, 20, 20, exists);</code></p>

<p>Он также должен определить свои собственные свойства следующим образом:</p>

<ul>
 <li><code>color</code><code>'white'</code></li>
 <li><code>size</code><code>10</code></li>
</ul>

<p>Опять же, не забудьте определить свои унаследованные свойства как параметры в конструкторе и правильно установить свойства <code>prototype</code> и <code>constructor</code>.</p>

<h3 id="Defining_EvilCircles_methods">Defining EvilCircle()'s methods</h3>

<p><code>EvilCircle()</code> должен иметь четыре метода, как описано ниже.</p>

<h4 id="draw"><code>draw()</code></h4>

<p>Этот метод имеет ту же цель, что и метод <code>draw()</code> метода <code>Ball()</code>: он рисует экземпляр объекта на холсте. Он будет работать очень схожим образом, поэтому вы можете начать с копирования определения <code>Ball.prototype.draw</code>. Затем вы должны внести следующие изменения:</p>

<ul>
 <li>Мы хотим, чтобы злой круг не был заполнен, а скорее имел внешнюю линию (удар). Вы можете добиться этого, обновив <code><a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/fillStyle">fillStyle</a></code> и <code><a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/fill">fill()</a></code> до <code><a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/strokeStyle">strokeStyle</a></code> и s<code><a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/stroke">stroke()</a></code>.</li>
 <li>Мы также хотим сделать ход немного толще, так что вы можете увидеть злой круг немного легче. Этого можно добиться, установив значение для <code><a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineWidth">lineWidth</a></code> где-нибудь после вызова <code><a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/beginPath">beginPath()</a></code> (3 будем делать).</li>
</ul>

<h4 id="checkBounds"><code>checkBounds()</code></h4>

<p>Этот метод будет делать то же самое, что и первая часть функции  <code>Ball()</code>'s <code>update()</code>, чтобы посмотреть, не исчезнет ли злой круг от края экрана и не прекратит это делать. Опять же, вы можете просто скопировать определение <code>Ball.prototype.update</code>, но есть несколько изменений, которые вы должны сделать:</p>

<ul>
 <li>Избавьтесь от последних двух строк - мы не хотим автоматически обновлять позицию злого круга на каждом кадре, потому что мы будем перемещать его каким-то другим способом, как вы увидите ниже.</li>
 <li>Внутри операторов <code>if()</code>, если тесты возвращают true, мы не хотим обновлять <code>velX</code> / <code>velY</code>; мы хотим вместо этого изменить значение <code>x</code> / <code>y</code>, так что злой круг возвращается на экран немного. Добавление или вычитание (по мере необходимости) свойства <code>size</code> злого круга имеет смысл.</li>
</ul>

<h4 id="setControls"><code>setControls()</code></h4>

<p>Этот метод добавит прослушиватель событий <code>onkeydown</code> к объекту <code>window</code>, чтобы при нажатии определенных клавиш клавиатуры мы могли перемещать злой круг вокруг. Следующий код должен быть помещен внутри определения метода:</p>

<pre class="brush: js">var _this = this;
window.onkeydown = function(e) {
    if (e.keyCode === 65) {
      _this.x -= _this.velX;
    } else if (e.keyCode === 68) {
      _this.x += _this.velX;
    } else if (e.keyCode === 87) {
      _this.y -= _this.velY;
    } else if (e.keyCode === 83) {
      _this.y += _this.velY;
    }
  }</pre>

<p>Поэтому, когда нажата клавиша, проконсультируется о свойствах <a href="https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode">keyCode</a> объекта события, чтобы увидеть, какая клавиша нажата. Если это один из четырех, представленных указанными ключевыми кодами, тогда злой круг будет перемещаться влево / вправо / вверх / вниз.</p>

<ul>
 <li>Для бонусного пункта сообщите нам, к каким ключам относятся указанные коды ключей.</li>
 <li>В другой бонусной точке вы можете сказать нам, почему нам пришлось установить <code>var _this = this</code>; в позиции, в которой он находится? Это как-то связано с функциональной областью.</li>
</ul>

<h4 id="collisionDetect"><code>collisionDetect()</code></h4>

<p>Этот метод будет действовать очень похоже на метод <code>collisionDetect()</code> в <code>Ball()</code>, поэтому вы можете использовать его в качестве основы для этого нового метода. Но есть несколько отличий:</p>

<ul>
 <li>В внешнем выражении <code>if</code> вам больше не нужно проверять, совпадает ли текущий мяч на итерации с шаром, который выполняет проверку, потому что он больше не является мячиком, это злой круг! Вместо этого вам нужно выполнить проверку, чтобы проверить, существует ли проверенный шар (с каким свойством вы могли бы это сделать?). Если этого не существует, он уже был съеден злым кругом, поэтому нет необходимости проверять его снова.</li>
 <li>Во внутреннем <code>if</code>-выражении вы больше не хотите, чтобы объекты меняли цвет при обнаружении столкновения - вместо этого вы хотите установить любые шары, которые сталкиваются с злым кругом, чтобы больше не существовать (опять же, как вы думаете, d сделать это?).</li>
</ul>

<h3 id="Приведение_злого_круга_в_программу">Приведение злого круга в программу</h3>

<p>Теперь мы определили злой круг, нам нужно на самом деле заставить его появиться на нашей сцене. Для этого вам нужно внести некоторые изменения в функцию <code>loop()</code>.</p>

<ul>
 <li>Прежде всего, создайте новый экземпляр объекта злого круга (указав необходимые параметры), затем вызовите его метод <code>setControls()</code>. Вам нужно только сделать эти две вещи один раз, а не на каждой итерации цикла.</li>
 <li>В точке, где вы прокручиваете каждый шар и вызываете функции <code>draw()</code>, <code>update()</code> и <code>collisionDetect()</code> для каждого из них, делайте так, чтобы эти функции вызывались только в том случае, если текущий шар существует.</li>
 <li>На каждой итерации цикла вызовите методы draw <code>draw()</code>, <code>checkBounds()</code> и <code>collisionDetect()</code> для злого шарика.</li>
</ul>

<h3 id="Реализация_счетчика_баллов">Реализация счетчика баллов</h3>

<p>Чтобы выполнить счетчик счетчиков, выполните следующие действия:</p>

<ol>
 <li>В своем HTML-файле добавьте элемент {{HTMLElement ("p")}} непосредственно под элементом {{HTMLElement ("h1")}}, содержащим текст «Ball count:».</li>
 <li>В вашем файле CSS добавьте следующее правило внизу:
  <pre class="brush: css">p {
  position: absolute;
  margin: 0;
  top: 35px;
  right: 5px;
  color: #aaa;
}</pre>
 </li>
 <li>В своем JavaScript сделайте следующие обновления:
  <ul>
   <li>Создайте переменную, которая хранит ссылку на абзац.</li>
   <li>Держите подсчет количества шаров на экране в некотором роде.</li>
   <li>Увеличьте количество и покажите обновленное количество шаров каждый раз, когда шар добавляется в сцену.</li>
   <li>Уменьшите счет и покажите обновленное количество мячей каждый раз, когда злой круг ест шарик (его не существует).</li>
  </ul>
 </li>
</ol>

<h2 id="Советы_и_подсказки">Советы и подсказки</h2>

<ul>
 <li>Эта оценка довольно сложная. Делайте каждый шаг медленно и осторожно.</li>
 <li>Может быть, идея сохранить отдельную копию демонстрации после того, как вы получите каждый этап работы, так что вы можете вернуться к ней, если позже окажетесь в беде.</li>
</ul>

<h2 id="Assessment">Assessment</h2>

<p>Если вы проводите эту оценку в рамках организованного курса, вы должны уметь отдать свою работу своему учителю / наставнику для маркировки. Если вы самообучаетесь, то вы можете получить руководство по маркировке довольно легко, задав <a href="https://discourse.mozilla.org/t/adding-features-to-our-bouncing-balls-demo-assessment/24689">тему обсуждения для этого упражнения</a> или в IRC-канале <a href="irc://irc.mozilla.org/mdn">#mdn</a> в <a href="https://wiki.mozilla.org/IRC">Mozilla IRC</a>. Сначала попробуйте упражнение - ничего не выиграть от обмана!</p>

<p>{{PreviousMenuNext("Learn/JavaScript/Objects/Object_building_practice", "", "Learn/JavaScript/Objects")}}</p>



<h2 id="In_this_module">In this module</h2>

<ul>
 <li><a href="/en-US/docs/Learn/JavaScript/Objects/Basics">Object basics</a></li>
 <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object-oriented_JS">Object-oriented JavaScript for beginners</a></li>
 <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object_prototypes">Object prototypes</a></li>
 <li><a href="/en-US/docs/Learn/JavaScript/Objects/Inheritance">Inheritance in JavaScript</a></li>
 <li><a href="/en-US/docs/Learn/JavaScript/Objects/JSON">Working with JSON data</a></li>
 <li><a href="/en-US/docs/Learn/JavaScript/Objects/Object_building_practice">Object building practice</a></li>
 <li><a href="/en-US/docs/Learn/JavaScript/Objects/Adding_bouncing_balls_features">Adding features to our bouncing balls demo</a></li>
</ul>



<div class="s3gt_translate_tooltip_mini_box" id="s3gt_translate_tooltip_mini" style="background: initial !important; border: initial !important; border-radius: initial !important; border-collapse: initial !important; direction: ltr !important; font-weight: initial !important; height: initial !important; letter-spacing: initial !important; max-width: initial !important; min-height: initial !important; margin: auto !important; outline: initial !important; padding: initial !important; position: absolute; text-align: initial !important; text-shadow: initial !important; width: initial !important; display: initial !important; color: inherit !important; font-size: 13px !important; font-family: X-LocaleSpecific, sans-serif, Tahoma, Helvetica !important; line-height: 13px !important; vertical-align: top !important; white-space: inherit !important; left: 112px; top: 698px; opacity: 0;">
<div class="s3gt_translate_tooltip_mini" id="s3gt_translate_tooltip_mini_logo" style="width: 12px; height: 12px; border-radius: 4px;" title="Перевести выделенный фрагмент"></div>

<div class="s3gt_translate_tooltip_mini" id="s3gt_translate_tooltip_mini_sound" style="width: 12px; height: 12px; border-radius: 4px;" title="Прослушать"></div>

<div class="s3gt_translate_tooltip_mini" id="s3gt_translate_tooltip_mini_copy" style="width: 12px; height: 12px; border-radius: 4px;" title="Скопировать текст в буфер обмена"></div>
</div>