--- 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 ---
この評価では、前の記事のバウンスボールのデモを出発点として用い、いくつかの面白い機能を新たに追加してもらいます。
| 前提条件: | この評価を試みる前に、このモジュールのすべての記事を学習済みであること。 |
|---|---|
|
目的: |
JavaScript オブジェクトとオブジェクト指向のインスタンス生成を理解しているかテストする。 |
この評価をスタートするためには、私たちの最新記事からローカル PC の新しいディレクトリーに index-finished.htm、style.css、main-finshed.js をコピーします。
または、あなたの評価のために、JSBin や Glitch を使うことができます。これらのオンラインエディターに HTML、CSS や JavaScript を貼り付けることができます。もしあなたが使用しているオンラインエディタが、別々の JavaScript/CSS のパネルを持っていない場合は、HTML内の <script>/<style> 要素を使って、インラインで書くことができます。
注: もし行き詰った場合は、サポートを依頼してください。このページの下部にある{{anch("Assessment or further help", "評価とさらなる支援")}}セクションを参照してください。
始める前にいくつかの助言です。
このバウンスボールのデモは面白いですが、ここではもう少しインタラクティブにするため、バウンスボールを捕まえたら食べてしまう、ユーザー制御された邪悪な円を追加します。また、バウンスボールや邪悪な円が継承できる一般的な Shape() オブジェクトを作ることで、あなたのオブジェクト構築スキルも試してみましょう。最後に、残ったボールが数えられるスコアカウンターも追加してみましょう。
次のスクリーンショットでは、完成したプログラムがどのように見えるかのイメージを掴めるでしょう:

さらにヒントを差し上げます。完成デモを見てみましょう。(ソースコードをチラ見しないように!)
次のセクションでは、必要な操作について説明します。
まず初めに、既存の Ball() コンストラクターを Shape() コンストラクターに変更し、新しい Ball() コンストラクターを追加します:
Shape() コンストラクターは、x、y、velX、および、velY プロパティを、Ball() コンストラクターが最初に行ったのと同じ方法で定義する必要がありますが、色とサイズのプロパティは指定しません。exists を新しく定義する必要があります。これはブール値 (true/false) である必要があります。Ball() コンストラクターは、x、y、velX、velY、および exists プロパティを Shape() コンストラクターから継承する必要があります。Ball() コンストラクターのように、color と size プロパティを定義する必要があります。Ball() コンストラクターの prototype と constructor を適切に設定してください。ボールの draw()、update()、と collisionDetect() メソッドの定義は、前とまったく同じである必要があります。
また、new Ball() ( ... ) コンストラクターの呼び出しに新しいパラメーターを追加する必要があります。exists パラメーターは 5番目のパラメーターにする必要があり、true の値を指定する必要があります。
この時点で、コードをリロードしてみてください。再設計されたオブジェクトで、前と全く同じように動作するはずです。
さあ、悪者 EvilCircle() の出番です! 私たちのゲームに邪悪な円は1つしか登場しませんが、練習のためにあえて、Shape() から継承するコンストラクターを使用して定義します。後で、他のプレイヤーによって制御される円、あるいは、コンピューター制御の別の邪悪な円をいくつか加えたいと思うかもしれません。おそらく、あなたは単一の邪悪な円の世界を引き継いでいくつもりはないでしょうが、今回の評価のためにはこれで十分です。
EvilCircle() コンストラクターは、x, y, velX, velY と exists を Shape() から継承しますが、velX と velY は常に20です。
これは Shape.call(this, x, y, 20, 20, exists);のように呼び出します。
次のように、独自のプロパティも定義する必要があります:
color — 'white'size — 10ここでも、継承したプロパティをコンストラクターのパラメーターとして定義し、prototype と constractor のプロパティを正しく設定することを忘れないでください。
EvilCircle() には、以下に示す 4 つのメソッドがあります。
draw()このメソッドは、Ball() の draw() メソッドと同じく、キャンバス上にオブジェクトインスタンスを描画するという目的を持ちます。とても良く似た動作をするので、Ball.prototype.draw の定義をコピーすることから始めます。次に、以下の変更を行います。
fillStyle と fill() を strokeStyle と stroke() に変更します。beginPath() 呼び出しの後のどこかで lineWidth の値(3で十分でしょう)を設定することで実現できます 。checkBounds()このメソッドは、Ball()の update() 関数の最初の部分と同じ機能、すなわち、邪悪な円が画面の端から出そうになったら出ないようにする機能を持ちます。先ほどと同様に、Ball.prototype.update 定義をほぼコピーするだけでできますが、いくつか変更する必要があります。
if() ステートメントの内部でそのテストが true を返す場合、velX/velY を更新したくありません。代わりに x/y の値を変更して、邪悪な円が画面内に少し跳ね返ってくるようにしたいのです。邪悪な円の size プロパティを(適切に)加えたり減じたりすることは理にかなっています。setControls()このメソッドは、onkeydown イベントリスナーを window オブジェクトに追加し、特定のキーボードキーが押されたときに、邪悪な円を動かします。次のコードブロックは、メソッド定義の中に置く必要があります。
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;
}
}
キーが押されると、イベントオブジェクトの key プロパティを調べて、どのキーが押されているかを確認します。押されたキーが、指定された4つのキーの 1 つである場合、邪悪な円は左/右/上/下に移動します。
おまけとして、let _this = this;をこの場所で設定しなければならない理由を教えてください。関数スコープと関係があります。
collisionDetect()このメソッドは Ball()の collisionDetect()メソッドと非常によく似た方法で動作するので、そのコピーをこの新しいメソッドの基礎として使用することができます。しかし、いくつかの違いがあります。
if ステートメントでは、反復処理中のボールが、チェックを行っているボールと同じであるかをチェックする必要はなくなりました。なぜなら、それは邪悪な円であって、ボールではないからです! その代わりに、チェックされているボールが存在するかどうかを確認(どのプロパティでこれを行うことができるでしょうか?)するテストを行う必要があります。存在しなければ、それはすでに邪悪な円によって食べられているので、再度チェックする必要はありません。if ステートメントでは、衝突が検出されたときにオブジェクトの色を変更する必要がなくなりました。その代わりに、邪悪な円と衝突するボールをもう存在しないように設定します(どうやって実行すると思いますか?)。さて、邪悪な円を定義したので、実際にそれをシーンに表示させる必要があります。そのためには、loop() 関数をいくつか変更する必要があります。
setControls() メソッドを呼び出します。これらの 2 つの処理は一度だけ実行すればよく、ループの繰り返し毎に行う必要はありません。draw()、update()、collisionDetect() が呼び出されるようにします。draw()、checkBounds()、および collisionDetect()メソッドを呼び出します。スコアカウンターを実装するには、次の手順に従います。
p {
position: absolute;
margin: 0;
top: 35px;
right: 5px;
color: #aaa;
}
If you would like your work assessed, or are stuck and want to ask for help:
{{PreviousMenuNext("Learn/JavaScript/Objects/Object_building_practice", "", "Learn/JavaScript/Objects")}}