質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.51%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

1回答

4612閲覧

Canvasで複数のクリック判定

meron-pan

総合スコア44

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2017/10/13 02:23

編集2017/10/13 04:52

###前提
Canvasでゲームの制作をしようとしています。Canvasを重ねてレイヤーとすることで複雑動きを可能にしようと思っていますが、クリックの判定処理についてアドバイスをいただきたいです。

JavaScript

1//Canvas1の下にCanvas2が存在する 2function button1(x, y, width, height){ 3 ctx1.rect(x, y, width, height); 4 ctx1.stroke(); 5 canvas1.addEventListener('click', function(e){ 6 var button = e.target.getBoundingClientRect(); 7 mouseX = e.clientX - button.left; 8 mouseY = e.clientY - button.top; 9          if(x < mouseX && mouseX < x + width){ 10 if(y < mouseY && mouseY < y + height){ 11              *ここに処理を書く 12          } 13//反応しない 14function button2(x, y, width, height){ 15 ctx2.rect(x, y, width, height); 16 ctx2.stroke(); 17 canvas2.addEventListener('click', function(e){ 18 var button = e.target.getBoundingClientRect(); 19 mouseX = e.clientX - button.left; 20 mouseY = e.clientY - button.top; 21          if(x < mouseX && mouseX < x + width){ 22 if(y < mouseY && mouseY < y + height){ 23              *ここに処理を書く 24          }

現在理解していることは、
①キャンバスのクリックされた相対座標の取得方法
②Canvasを重ねた場合、クリックイベントは一番上にあるキャンバスしか反応しない
③if関数を用いて、クリックの範囲を指定することで、ボタンやキャラクターなどにクリック判定を擬似的につけることができる。
④Canvasのイベントリスナーは一番上のCanvasしか反応しない。

ということです。
しかしながら、ボタンの実装とキャラクターの描画をそれぞれ別のレイヤーにかき分けた場合、反応するのは「一番上のCanvas」だけなので、ボタンがクリックに反応するようにすると、別レイヤーに描画したキャラクターをクリックしてもイベントが発火しなくなってしまいます。

###実現したいこと
こちらがしたいこととしては、ボタンもキャラクターもクリック判定を実装したいのですが、これはCanvasの技術的に不可能なことなのでしょうか?
自らの技術力を上げたいため、できればライブラリーを使用しないようにしたいです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

masaya_ohashi

2017/10/13 02:44

すべての当たり判定はマウス座標とキャラやボタンの座標を使ったif等の判定で行っていますか?
meron-pan

2017/10/13 03:44

他に、クリック判定を実装する方法が思いつかないので、if関数で事前に設けた四角形の範囲内にクリック時の相対座標が一致した場合にif内のコードを実行するようにと考えています。
masaya_ohashi

2017/10/13 04:10

コードの全体像が分かるコードを質問文に貼り付けてもらうほうが現状からどう変えるべきかというアドバイスをしやすいです。
meron-pan

2017/10/13 04:54

特にコードのトラブルではなく、アイデア段階での疑問です。なので特に、具体的な問題が発生してるのではないのです。
guest

回答1

0

ベストアンサー

一番上のCanvasのクリックイベントリスナーで、すべてのレイヤーのオブジェクトのクリック判定を行えばよいのではないでしょうか?

もちろんそのままやると、別のレイヤーに存在するオブジェクトが重なっているところをクリックしたときに、どちらのオブジェクトもクリックされたという判定になるので、もしそれを避けたいならば

  1. 一番上のレイヤーのクリック判定

↓もしどのオブジェクトもクリックされなかったら
2. 二番目のレイヤーのクリック判定
↓もしどのオブジェクトもクリックされなかったら
...

とすればいいと思います。

投稿2017/10/13 04:09

karamarimo

総合スコア2551

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

meron-pan

2017/10/13 05:03

一番上のクリックイベントリスナーで全ての判定を行うということは理解できるのですが、その下の判定をどのように行えばいいのかいまいち理解できませんので、もう少し詳しい説明をお手数ですがお願いできませんか?
karamarimo

2017/10/13 05:48

たとえば一番上のレイヤーの判定を行う前に変数を一つ用意します。 var someAreClicked = false; // どれかのオブジェクトがクリックされたか そのあと、たぶんオブジェクトの位置情報が配列かなんかに入ってるとして、 for (var i = 0; i < objects.length; i++) { if (クリック場所が objects[i] の中) { // クリックされたときの処理 someAreClicked = true; } } そして if (!someAreClicked) { // 次のレイヤーのクリック判定 }
karamarimo

2017/10/13 05:54

あ、すみません。質問文にコードが追加されているのにいま気づきました。 button2 関数内の canvas2.addEventListener を canvas1.addEventListener に変えればとりあえず動くのではないでしょうか?
meron-pan

2017/10/13 09:56

灯台下暗しというか全然気づきませんでした。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.51%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問