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
213
214
215
216
217
218
219
220
221
222
223
|
---
title: バウンスボールのデモに機能を追加する
slug: Learn/JavaScript/Objects/Adding_bouncing_balls_features
tags:
- Assessment
- Beginner
- CodingScripting
- JavaScript
- Learn
- OOJS
- Object-Oriented
- Objects
- 'l10n:priority'
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">
<p>目的:</p>
</th>
<td>JavaScript オブジェクトとオブジェクト指向のインスタンス生成を理解しているかテストする。</td>
</tr>
</tbody>
</table>
<h2 id="Starting_point" name="Starting_point">出発点</h2>
<p>この評価をスタートするためには、私たちの最新記事からローカル PC の新しいディレクトリーに<a href="https://github.com/mdn/learning-area/blob/master/javascript/oojs/bouncing-balls/index-finished.html"> index-finished.htm</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-finshed.js</a> をコピーします。</p>
<p>または、あなたの評価のために、<a class="external external-icon" href="http://jsbin.com/">JSBin</a> や <a class="external external-icon" href="https://glitch.com/">Glitch</a> を使うことができます。これらのオンラインエディターに HTML、CSS や JavaScript を貼り付けることができます。もしあなたが使用しているオンラインエディタが、別々の JavaScript/CSS のパネルを持っていない場合は、HTML内の <code><script></code>/<code><style></code> 要素を使って、インラインで書くことができます。</p>
<div class="note">
<p><strong>注</strong>: もし行き詰った場合は、サポートを依頼してください。このページの下部にある{{anch("Assessment or further help", "評価とさらなる支援")}}セクションを参照してください。</p>
</div>
<h2 id="Hints_and_tips" name="Hints_and_tips">ヒントと tips</h2>
<p>始める前にいくつかの助言です。</p>
<ul>
<li>この評価はかなり難しいです。コーディングを始める前に評価全体を読み、各ステップをゆっくりと注意深く行ってください。</li>
<li>それぞれのステージを作業した後のデモを、別々のコピーとして保管しておけば、後で困ったときに参照することができます。</li>
</ul>
<h2 id="Project_brief" name="Project_brief">プロジェクト概要</h2>
<p>このバウンスボールのデモは面白いですが、ここではもう少しインタラクティブにするため、バウンスボールを捕まえたら食べてしまう、ユーザー制御された邪悪な円を追加します。また、<span style='background-color: transparent; color: #333333; display: inline !important; float: none; font-family: "Open Sans",arial,x-locale-body,sans-serif; font-size: 16px; font-style: normal; font-variant: normal; font-weight: 400; letter-spacing: normal; text-align: left; text-decoration: none; text-indent: 0px; text-transform: none; white-space: normal;'>バウンスボールや</span>邪悪な<span style='background-color: transparent; color: #333333; display: inline !important; float: none; font-family: "Open Sans",arial,x-locale-body,sans-serif; font-size: 16px; font-style: normal; font-variant: normal; font-weight: 400; letter-spacing: normal; text-align: left; text-decoration: none; text-indent: 0px; text-transform: none; white-space: normal;'>円が継承できる</span>一般的な <code>Shape()</code> オブジェクトを作ることで、<span style='background-color: transparent; color: #333333; display: inline !important; float: none; font-family: "Open Sans",arial,x-locale-body,sans-serif; font-size: 16px; font-style: normal; font-variant: normal; font-weight: 400; letter-spacing: normal; text-align: left; text-decoration: none; text-indent: 0px; text-transform: none; white-space: normal;'>あなたのオブジェクト構築スキルも</span>試してみましょう。最後に、残ったボールが数えられるスコアカウンターも追加してみましょう。</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="http://mdn.github.io/learning-area/javascript/oojs/assessment/">完成デモ</a>を見てみましょう。(ソースコードをチラ見しないように!)</p>
<h2 id="Steps_to_complete" name="Steps_to_complete">完成までの手順</h2>
<p>次のセクションでは、必要な操作について説明します。</p>
<h3 id="Creating_our_new_objects" name="Creating_our_new_objects">新しいオブジェクトを作る</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> コンストラクターが最初に行ったのと同じ方法で定義する必要がありますが、色とサイズのプロパティは指定しません。</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>Ball()</code> コンストラクターのように、<code>color</code> と <code>size</code> プロパティを定義する必要があります。</li>
<li><code>Ball()</code> コンストラクターの <code>prototype</code> と <code>constructor</code> を適切に設定してください。</li>
</ol>
<p>ボールの <code>draw()</code>、<code>update()</code>、と <code>collisionDetect()</code> メソッドの定義は、前とまったく同じである必要があります。</p>
<p>また、<code>new Ball() ( ... )</code> <span style='background-color: transparent; color: #333333; display: inline !important; float: none; font-family: "Open Sans",arial,x-locale-body,sans-serif; font-size: 16px; font-style: normal; font-variant: normal; font-weight: 400; letter-spacing: normal; text-align: left; text-decoration: none; text-indent: 0px; text-transform: none; white-space: normal;'>コンストラクターの呼び出し</span>に新しいパラメーターを追加する必要があります。<code>exists</code> パラメーターは 5番目のパラメーターにする必要があり、<code>true</code> の値を指定する必要があります。</p>
<p>この時点で、コードをリロードしてみてください。再設計されたオブジェクトで、前と全く同じように動作するはずです。</p>
<h3 id="Defining_EvilCircle" name="Defining_EvilCircle">EvilCircle() の定義</h3>
<p>さあ、悪者 <code>EvilCircle()</code> の出番です! 私たちのゲームに邪悪な円は1つしか登場しませんが、練習のためにあえて、<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>constractor</code> のプロパティを正しく設定することを忘れないでください。</p>
<h3 id="Defining_EvilCircles_methods" name="Defining_EvilCircles_methods">EvilCircle() のメソッドの定義</h3>
<p><code>EvilCircle()</code> には、以下に示す 4 つのメソッドがあります。</p>
<h4 id="draw" name="draw"><code>draw()</code></h4>
<p>このメソッドは、<code>Ball()</code> の <code>draw()</code> メソッドと同じく、キャンバス上にオブジェクトインスタンスを描画するという目的を持ちます。とても良く似た動作をするので、<code>Ball.prototype.draw</code> の定義をコピーすることから始めます。次に、以下の変更を行います。</p>
<ul>
<li>邪悪な円は塗りつぶしせず、枠線(ストローク)だけを持たせたいと思います。そのために、<code><a href="/ja/docs/Web/API/CanvasRenderingContext2D/fillStyle">fillStyle</a></code> と <code><a href="/ja/docs/Web/API/CanvasRenderingContext2D/fill">fill()</a></code> を <code><a href="/ja/docs/Web/API/CanvasRenderingContext2D/strokeStyle">strokeStyle</a></code> と <code><a href="/ja/docs/Web/API/CanvasRenderingContext2D/stroke">stroke()</a></code> に変更します。</li>
<li>また、線を少し太くすれば、邪悪な円が少し分かりやすくなります。これは、<code><a href="/ja/docs/Web/API/CanvasRenderingContext2D/beginPath">beginPath()</a></code> 呼び出しの後のどこかで <code><a href="/ja/docs/Web/API/CanvasRenderingContext2D/lineWidth">lineWidth</a></code> の値(3で十分でしょう)を設定することで実現できます 。</li>
</ul>
<h4 id="checkBounds" name="checkBounds"><code>checkBounds()</code></h4>
<p>このメソッドは、<code>Ball()</code>の <code>update()</code> 関数の最初の部分と同じ機能、すなわち、邪悪な円が画面の端から出そうになったら出ないようにする機能を持ちます。先ほどと同様に、<code>Ball.prototype.update</code> 定義をほぼコピーするだけでできますが、いくつか変更する必要があります。</p>
<ul>
<li>最後の 2行を削除します。後で見られるように、別の方法で邪悪な円を動かすので、フレーム毎に邪悪な円の位置を自動的に更新する必要はありません。</li>
<li>テストが true を返す場合、<code>if()</code> ステートメントの内部で<code>velX</code>/<code>velY</code> を更新したくありません。代わりに <code>x</code>/<code>y</code> の値を変更して、邪悪な円が画面上に少し跳ね返ってくるようにします。邪悪な円の size プロパティを(必要に応じて)増減させることは理にかなっています。</li>
</ul>
<h4 id="setControls" name="setControls"><code>setControls()</code></h4>
<p>このメソッドは、<code>onkeydown</code> イベントリスナーを <code>window</code> オブジェクトに追加し、特定のキーボードキーが押されたときに、邪悪な円を動かします。次のコードブロックは、メソッド定義の中に置く必要があります。</p>
<pre class="brush: js notranslate">let _this = this;
window.onkeydown = function(e) {
if (e.key === 'a') {
_this.x -= _this.velX;
} else if (e.key === 'd') {
_this.x += _this.velX;
} else if (e.key === 'w') {
_this.y -= _this.velY;
} else if (e.key === 's') {
_this.y += _this.velY;
}
}</pre>
<p>キーが押されると、イベントオブジェクトの <a href="/ja/docs/Web/API/KeyboardEvent/key">key</a> プロパティを調べて、どのキーが押されているかを確認します。押されたキーが、指定された4つのキーの 1 つである場合、邪悪な円は左/右/上/下に移動します。</p>
<p>おまけとして、<code>let _this = this;</code>をこの場所で設定しなければならない理由を教えてください。関数スコープと関係があります。</p>
<h4 id="collisionDetect" name="collisionDetect"><code>collisionDetect()</code></h4>
<p>このメソッドは <code>Ball()</code>の <code>collisionDetect()</code>メソッドと非常によく似た方法で動作するので、そのコピーをこの新しいメソッドの基礎として使用することができます。しかし、いくつかの違いがあります。</p>
<ul>
<li>外側の <code>if</code> ステートメントでは、反復処理中のボールが、チェックを行っているボールと同じであるかをチェックする必要はなくなりました。なぜなら、それは邪悪な円であって、ボールではないからです! その代わりに、チェックされているボールが存在するかどうかを確認(どのプロパティでこれを行うことができるでしょうか?)するテストを行う必要があります。存在しなければ、それはすでに邪悪な円によって食べられているので、再度チェックする必要はありません。</li>
<li>内部の <code>if</code> ステートメントでは、衝突が検出されたときにオブジェクトの色を変更する必要がなくなりました。その代わりに、邪悪な円と衝突するボールをもう存在しないように設定します(どうやって実行すると思いますか?)。</li>
</ul>
<h3 id="Bringing_the_evil_circle_into_the_program" name="Bringing_the_evil_circle_into_the_program">プログラムに邪悪な円を持ち込む</h3>
<p>さて、邪悪な円を定義したので、実際にそれをシーンに表示させる必要があります。そのためには、<code>loop()</code> 関数をいくつか変更する必要があります。</p>
<ul>
<li>まず、(必要なパラメーターを指定して)新しい邪悪な円オブジェクトインスタンスを作成し、その <code>setControls()</code> メソッドを呼び出します。これらの 2 つの処理は一度だけ実行すればよく、ループの繰り返し毎に行う必要はありません。</li>
<li>すべてのボールをループして、ボールが存在する場合にのみ、それぞれの <code>draw()</code>、<code>update()</code>、<code>collisionDetect()</code> が呼び出されるようにします。</li>
<li>ループの各繰り返しで、邪悪な円インスタンスの <code>draw()</code>、<code>checkBounds()</code>、および <code>collisionDetect()</code>メソッドを呼び出します。</li>
</ul>
<h3 id="Implementing_the_score_counter" name="Implementing_the_score_counter">スコアカウンターの実装</h3>
<p>スコアカウンターを実装するには、次の手順に従います。</p>
<ol>
<li>HTML ファイルの{{HTMLElement("h1")}}要素の直下に、"Ball count:" というテキストを含む{{HTMLElement( "p")}}要素を追加します。</li>
<li>あなたの CSS ファイルに、次のスタイルを追加します:
<pre class="brush: css notranslate">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="Assessment_or_further_help" name="Assessment_or_further_help">評価とさらなる支援</h2>
<p>If you would like your work assessed, or are stuck and want to ask for help:</p>
<ol>
<li>Put your work into an online shareable editor such as <a href="https://codepen.io/">CodePen</a>, <a href="https://jsfiddle.net/">jsFiddle</a>, or <a href="https://glitch.com/">Glitch</a>.</li>
<li>Write a post asking for assessment and/or help at the <a href="https://discourse.mozilla.org/c/mdn/learn">MDN Discourse forum Learning category</a>. Your post should include:
<ul>
<li>A descriptive title such as "Assessment wanted for Adding bouncing balls features".</li>
<li>Details of what you have already tried, and what you would like us to do, e.g. if you are stuck and need help, or want an assessment.</li>
<li>A link to the example you want assessed or need help with, in an online shareable editor (as mentioned in step 1 above). This is a good practice to get into — it's very hard to help someone with a coding problem if you can't see their code.</li>
<li>A link to the actual task or assessment page, so we can find the question you want help with.</li>
</ul>
</li>
</ol>
<p>{{PreviousMenuNext("Learn/JavaScript/Objects/Object_building_practice", "", "Learn/JavaScript/Objects")}}</p>
<h2 id="In_this_module" name="In_this_module">このモジュール</h2>
<ul>
<li><a href="/ja/docs/Learn/JavaScript/Objects/Basics">JavaScript オブジェクトの基本</a></li>
<li><a href="/ja/docs/Learn/JavaScript/Objects/Object-oriented_JS">初心者のためのオブジェクト指向 JavaScript</a></li>
<li><a href="/ja/docs/Learn/JavaScript/Objects/Object_prototypes">Object のプロトタイプ</a></li>
<li><a href="/ja/docs/Learn/JavaScript/Objects/Inheritance">JavaScript での継承</a></li>
<li><a href="/ja/docs/Learn/JavaScript/Objects/JSON">JSON データの操作</a></li>
<li><a href="/ja/docs/Learn/JavaScript/Objects/Object_building_practice">オブジェクト作成の練習</a></li>
<li><a href="/ja/docs/Learn/JavaScript/Objects/Adding_bouncing_balls_features">バウンスボールに機能を追加する</a></li>
</ul>
|