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

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

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

HTML5の<canvas>要素用のタグです。CanvasはHTML5から導入された、二次元の図形描写が可能な要素です。

JavaScript

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

Q&A

解決済

1回答

500閲覧

CANVASで描いた正方形の輪郭を認識させたい

OG.

総合スコア7

canvas

HTML5の<canvas>要素用のタグです。CanvasはHTML5から導入された、二次元の図形描写が可能な要素です。

JavaScript

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

0グッド

1クリップ

投稿2020/06/29 02:11

前提・実現したいこと

正方形の座標

ここに質問の内容を詳しく書いてください。
2Dグラフィック制作を目的としたJavascriptのCANVAS APIの学習を行っており、正方形と正方形の指定した座標が乗ったときに上に乗ったように制止するプログラムを記述したいと考えています。
自分なりの範囲で調べたりは行ったのですが、衝突検出した際にものを乗せる等のイベントの記述(消す等があったが)があまり見受けられなかったのでご質問しました。
参考になるサイト等が万が一ございましたら、またアドバイス等ありましたらご助力頂ければ幸いです。

発生している問題・エラーメッセージ

CANVASで正方形をランダムで生成し、上から下に落とし、地面に乗せるプログラムまでは実装済み。

エラーメッセージ

該当のソースコード

Javascript

1<!DOCTYPE HTML> 2<HTML> 3<HEAD> 4<TITLE>test</TITLE> 5<META charset="utf-8"> 6</HEAD> 7<BODY> 8<CANVAS id ="view_1" height= "600" width = "800"></CANVAS> 9<div> 10 <button id="startAnimation">START!</button> 11 <button id="stopAnimation">STOP</button> 12</div> 13<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> 14<script type="text/javascript"> 15 let canvas = $("#view_1"); 16 let ctx = canvas.get(0).getContext("2d"); 17 18 let canvasWidth = canvas.width(); 19 let canvasHeight = canvas.height(); 20 21 $(window).resize(resizeCanvas); 22 23 function resizeCanvas(){ 24 canvas.attr("width", $(window).get(0).innnerWidth); 25 canvas.attr("height", $(window).get(0).innnerHeight); 26 canvasWidth = canvas.width(); 27 canvasHeight = canvas.height(); 28 }; 29 30 resizeCanvas(); 31 32 let playAnimation = true; 33 34 let startButton = $("#startAnimation"); 35 let stopButton = $("#stopAnimation"); 36 37 startButton.hide(); 38 startButton.click(function() { 39 $(this).hide(); 40 stopButton.show(); 41 42 playAnimation = true; 43 animate(); 44 }); 45 46 stopButton.click(function(){ 47 $(this).hide(); 48 startButton.show(); 49 50 playAnimation = false; 51 animate(); 52 }); 53 54let Shape = function(x, y,width,height,gravity){ 55 this.x = x; 56 this.y = y; 57 this.width = width; 58 this.height = height; 59 this.gravity = gravity; 60}; 61 62let shapes = new Array(); 63 64for (let squere = 0; squere < 20; squere++){ 65 let x = Math.random() * 500; 66 let y = Math.random() * 500; //500 * 500px 内のどこかに生成 67 let width = height = 20; //20pxの正方形 68 let gravity = 5; 69 shapes.push(new Shape(x, y, width, height, gravity)); 70}; 71 72 function animate(){ 73 ctx.clearRect(0, 0, canvasHeight, canvasWidth); 74 ctx.fillStyle = "rgb(124, 219, 255)"; 75 let shapesLength = shapes.length; 76 77 78 for(let i = 0; i < shapesLength; i++){ 79 let tmpShape = shapes[i]; 80 if(tmpShape.y + tmpShape.height > canvasHeight){ 81 tmpShape.y = canvasHeight - tmpShape.height; 82 } 83 84 ctx.fillRect(tmpShape.x, tmpShape.y, tmpShape.width, tmpShape.height); 85 tmpShape.y += tmpShape.gravity; //重力 86 }; 87 if(playAnimation===true){ 88 setTimeout(animate, 150); 89 }; 90 }; 91 92 93 94 animate(); 95 96</script> 97</BODY> 98</HTML> 99

試したこと

if(tmpShape.y + tmpShape.height > canvasHeight){
tmpShape.y = canvasHeight - tmpShape.height;
}
以降に更にif文で分岐させて、
(x,y)~(x + width, y)の範囲と(x, y + height)~(x + width, y + height)の範囲が一致した際にtmpShape.gravity = 0;

にするのが良いのかなとは考えているのですが、良い記述が思いつかず

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

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

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

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

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

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

guest

回答1

0

ベストアンサー

CANVAS APIの学習

google検索:「javascript collision detection」すると、MDN 2D 衝突検出 が出てきます。

MDNのページでは2種類のサンプルコードが示されていますので、ご質問の「試したこと」に示されるコードを見直すヒントになると思います(矩形ですと、1になりそうです)。

  1. 矩形の判定 … 「座標軸に沿ったバウンディングボックス」
  2. 円形の判定 … 「円形衝突」

ご質問のコード内で抽象化している Shape に衝突判定メソッドを実装すると大量の判定も楽できるかもしれません。
また、アニメーション表現の応用として Canvas API でシューティングゲームを作るテーマの 過去の質問&回答 もヒントになるかと思います。

追記)
現在、Canvas の下辺に到達したら停止するコードになっていますが、
更に、他のShape との衝突を判定して停止させる必要があります。

Codepen 動くサンプル

投稿2020/06/29 03:28

編集2020/07/01 22:11
AkitoshiManabe

総合スコア5432

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

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

OG.

2020/07/01 08:42

解答ありがとうございます。提示して頂いたページで試行錯誤したのですが、直接物体を指定した場合の流れは何となくの流れは理解できたのですが、 位置を個々で指定ではなく、乱数化した物体の場合はどうやって記述したらよいか案が出せずに居ます。 (おっしゃっていただいた衝突判定メソッドを乱数化したものに指定する) 理解が追い付かず申し訳ございませんが、もう少しだけご助力頂けたら幸いです。
AkitoshiManabe

2020/07/01 22:39 編集

> 衝突判定メソッドを乱数化したものに指定する 乱数を使う意図が読めないのですが(雪のように落ちるなど、動作のアレンジになるのでしょうか)、先ずは、等速で落ちる際の「個々の衝突時、停止して積み重なる動作」を考えましょう。 回答欄に追記しています。
OG.

2020/07/02 09:12

追記のものを参考にさせて頂き無事実装まで至りました。 ご丁寧に回答いただきありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問