情報学部 菅沼ホーム JavaScript 目次 基礎技術目次 索引

衝突判定

  1. パスと点

      二つの物体の衝突判定を行う一つの方法は,「 2d コンテキストのプロパティとメソッド」における isPointInPath メソッドを利用する方法です.isPointInPath は既に描いたパス内に与えられた点が入っているか否かを判定します.この例では,矩形内に円の最も左側のが入ったか否かを判定しています.

      042 行目~ 049 行目で描画したパスを対象として,094 行目において,そのパス内に点 (x2-40, y2) が入ったか否かを判定します.051 行目~ 092 行目に示してあるように,パスの描き方は任意ですが,なぜか strokeRect や fillRect メソッドを使用すると正しく判定してくれません.
    001	<!DOCTYPE HTML>
    002	<HTML>
    003	<HEAD>
    004		<TITLE>衝突判定(パスと点)</TITLE>
    005		<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
    006		<META NAME=viewport CONTENT="width=device-width, initial-scale=1">
    007		<LINK REL="stylesheet" TYPE="text/css" HREF="../../master.css">
    008		<SCRIPT TYPE="text/javascript">
    009			canvas  = null;
    010			ctx     = null;
    011			timerID = -1;
    012			x1      = 0.0;   // 矩形の左上頂点の x 座標
    013			x2      = 0.0;   // 円の中心の x 座標
    014			y1      = 0.0;   // 矩形の左上頂点の y 座標
    015			y2      = 0.0;   // 円の中心の y 座標
    016			t       = 0.0;
    017			v       = 20.0;
    018			hit     = false;   // 衝突すると true に設定
    019	
    020			function start() {
    021				canvas = document.getElementById('canvas_e');
    022				canvas.width  = 600;   // キャンバス要素の幅
    023				canvas.height = 400;   // キャンバス要素の高さ
    024				ctx = canvas.getContext('2d');
    025				x1 = 0;
    026				x2 = canvas.width - 40;
    027				y1 = canvas.height / 2 - 40;
    028				y2 = canvas.height / 2 - 40;
    029				timerID = setInterval('draw()', 33);
    030			}
    031						// 描画
    032			function draw()
    033			{
    034				if (!hit) {
    035								// 移動
    036					t += 0.1;
    037					x1 = v * t;
    038					x2 = canvas.width - 40 - v * t;
    039								// 領域のクリア
    040					ctx.clearRect(0, 0, canvas.width, canvas.height);
    041								// 矩形の描画
    042					ctx.beginPath();
    043					ctx.fillStyle = "rgb(0, 255, 0)";
    044					ctx.moveTo(x1, y1);
    045					ctx.lineTo(x1+80, y1);
    046					ctx.lineTo(x1+80, y1+80);
    047					ctx.lineTo(x1, y1+80);
    048					ctx.closePath();
    049					ctx.fill();
    050								// 以下に示すいずれの方法でも良い
    051	//				ctx.beginPath();
    052	//				ctx.lineWidth = 5;
    053	//				ctx.strokeStyle = "rgb(0, 255, 0)";
    054	//				ctx.moveTo(x1, y1);
    055	//				ctx.lineTo(x1+80, y1);
    056	//				ctx.lineTo(x1+80, y1+80);
    057	//				ctx.lineTo(x1, y1+80);
    058	//				ctx.closePath();
    059	//				ctx.stroke();
    060	
    061	//				ctx.beginPath();
    062	//				ctx.fillStyle = "rgb(0, 255, 0)";
    063	//				ctx.rect(x1, y1, 80, 80);
    064	//				ctx.fill();
    065	
    066	//				ctx.beginPath();
    067	//				ctx.lineWidth = 5;
    068	//				ctx.strokeStyle = "rgb(0, 255, 0)";
    069	//				ctx.rect(x1, y1, 80, 80);
    070	//				ctx.stroke();
    071								// 円の場合も可能
    072	//				ctx.beginPath();
    073	//				ctx.fillStyle = "rgb(0, 255, 0)";
    074	//				ctx.arc(x1, y1, 40, 0, 2*Math.PI, false);
    075	//				ctx.fill();
    076	
    077	//				ctx.beginPath();
    078	//				ctx.lineWidth = 5;
    079	//				ctx.strokeStyle = "rgb(0, 255, 0)";
    080	//				ctx.arc(x1, y1, 40, 0, 2*Math.PI, false);
    081	//				ctx.stroke();
    082								// 以下のいずれの方法でも isPointInPath による衝突判定は不可能
    083	//				ctx.beginPath();
    084	//				ctx.lineWidth = 5;
    085	//				ctx.strokeStyle = "rgb(0, 255, 0)";
    086	//				ctx.strokeRect(x1, y1, 80, 80);
    087	//				ctx.stroke();
    088	
    089	//				ctx.beginPath();
    090	//				ctx.fillStyle = "rgb(0, 255, 0)";
    091	//				ctx.fillRect(x1, y1, 80, 80);
    092	//				ctx.fill();
    093								// 衝突判定(判定位置に注意)
    094					hit = ctx.isPointInPath(x2-40, y2);
    095								// 円の描画
    096					ctx.beginPath();
    097					ctx.fillStyle = "rgb(255, 0, 0)";
    098					ctx.arc(x2, y2, 40, 0, 2*Math.PI, false);
    099					ctx.fill();
    100				}
    101			}
    102		</SCRIPT>
    103	</HEAD>
    104	<BODY CLASS="white" STYLE="text-align: center" onLoad="start()">
    105		<H1>衝突判定(パスと点)</H1>
    106		<CANVAS ID="canvas_e" STYLE="background-color: #eeffee;" WIDTH="600" HEIGHT="400"></CANVAS>
    107	</BODY>
    108	</HTML>
    			

  2. パスと複数の点

      一般的には,一つの点だけで衝突判定を行っても正確な結果が得られません.この例では,円と円との衝突判定を行っています.ここでは,右図に示すように,赤色の円周上に 12 個の点を設定し,それらの点が緑色の円内に入るか否かの判定を行っています.多くの点を設定すれば,それだけ正確な衝突判定が可能になりますし,また,この考え方は任意の図形に対して適用可能です.
    01	<!DOCTYPE HTML>
    02	<HTML>
    03	<HEAD>
    04		<TITLE>衝突判定(パスと複数の点)</TITLE>
    05		<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
    06		<META NAME=viewport CONTENT="width=device-width, initial-scale=1">
    07		<LINK REL="stylesheet" TYPE="text/css" HREF="../../master.css">
    08		<SCRIPT TYPE="text/javascript">
    09			canvas  = null;
    10			ctx     = null;
    11			timerID = -1;
    12			x1      = 0.0;
    13			x2      = 0.0;
    14			y1      = 0.0;
    15			y2      = 0.0;
    16			t       = 0.0;
    17			v       = 20.0;
    18			hit     = false;
    19			x       = new Array (40, 40*Math.cos(Math.PI/6), 40*Math.cos(Math.PI/3),
    			                     0, 40*Math.cos(2*Math.PI/3), 40*Math.cos(5*Math.PI/6),
    			                     -40, 40*Math.cos(7*Math.PI/6), 40*Math.cos(4*Math.PI/3),
    			                     0, 40*Math.cos(5*Math.PI/3), 40*Math.cos(11*Math.PI/6));
    20			y       = new Array (0, 40*Math.sin(Math.PI/6), 40*Math.sin(Math.PI/3),
    			                     40, 40*Math.sin(2*Math.PI/3), 40*Math.sin(5*Math.PI/6),
    			                     0, 40*Math.sin(7*Math.PI/6), 40*Math.sin(4*Math.PI/3),
    			                     -40, 40*Math.sin(5*Math.PI/3), 40*Math.sin(11*Math.PI/6));
    21	
    22			function start() {
    23				canvas = document.getElementById('canvas_e');
    24				canvas.width  = 600;   // キャンバス要素の幅
    25				canvas.height = 400;   // キャンバス要素の高さ
    26				ctx = canvas.getContext('2d');
    27				x1  = 40;
    28				x2  = canvas.width - 40;
    29				y1  = canvas.height / 2;
    30				y2  = canvas.height / 2 - 40;
    31				timerID = setInterval('draw()', 33);
    32			}
    33						// 描画
    34			function draw()
    35			{
    36				if (!hit) {
    37								// 移動
    38					t += 0.1;
    39					x1 = 40 + v * t;
    40					x2 = canvas.width - 40 - v * t;
    41								// 領域のクリア
    42					ctx.clearRect(0, 0, canvas.width, canvas.height);
    43								// 円の描画
    44					ctx.beginPath();
    45					ctx.fillStyle = "rgb(0, 255, 0)";
    46					ctx.arc(x1, y1, 40, 0, 2*Math.PI, false);
    47					ctx.fill();
    48								// 衝突判定(判定位置に注意)
    49					for (let i1 = 0; i1 < 12; i1++) {
    50						hit = ctx.isPointInPath(x2+x[i1], y2+y[i1]);
    51						if (hit)
    52							break;
    53					}
    54								// 円の描画
    55					ctx.beginPath();
    56					ctx.fillStyle = "rgb(255, 0, 0)";
    57					ctx.arc(x2, y2, 40, 0, 2*Math.PI, false);
    58					ctx.fill();
    59				}
    60			}
    61		</SCRIPT>
    62	</HEAD>
    63	<BODY CLASS="white" STYLE="text-align: center" onLoad="start()">
    64		<H1>衝突判定(パスと複数点)</H1>
    65		<CANVAS ID="canvas_e" STYLE="background-color: #eeffee;" WIDTH="600" HEIGHT="400"></CANVAS>
    66	</BODY>
    67	</HTML>
    			
    19 行目~ 20 行目

      配列に,12 個の点の座標を設定しています.このような形で,配列の初期設定を行うことができます.

    49 行目~ 53 行目

      緑色の円と 12 個の各点との衝突判定を行っています.なお,break 文が実行されると,break 文が入っている最も内側のループの外に出て(ループの処理を中止して),そのループの次の文が実行されます.

  3. 距離

      最後に示す方法は,2 つの図形間の距離を計算し,その距離によって衝突を判定する方法です.この例に示すように,2 つの図形が円や点の場合は問題ありませんが,他の図形の場合は,図形の端点間の距離の最小値が,図形やその向きによって異なるため,簡単に衝突判定ができるとは限りません.
    <!DOCTYPE HTML>
    <HTML>
    <HEAD>
    	<TITLE>衝突判定(距離)</TITLE>
    	<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
    	<META NAME=viewport CONTENT="width=device-width, initial-scale=1">
    	<LINK REL="stylesheet" TYPE="text/css" HREF="../../master.css">
    	<SCRIPT TYPE="text/javascript">
    		canvas  = null;
    		ctx     = null;
    		timerID = -1;
    		x1      = 0.0;
    		x2      = 0.0;
    		y1      = 0.0;
    		y2      = 0.0;
    		t       = 0.0;
    		v       = 20.0;
    		hit     = false;
    
    		function start() {
    			canvas = document.getElementById('canvas_e');
    			canvas.width  = 600;   // キャンバス要素の幅
    			canvas.height = 400;   // キャンバス要素の高さ
    			ctx = canvas.getContext('2d');
    			x1  = 40.0;
    			x2  = canvas.width - 40;
    			y1  = canvas.height / 2;
    			y2  = canvas.height / 2 - 40;
    			timerID = setInterval('draw()', 33);
    		}
    					// 描画
    		function draw()
    		{
    			if (!hit) {
    							// 移動
    				t += 0.1;
    				x1 = 40 + v * t;
    				x2 = canvas.width - 40 - v * t;
    							// 描画
    				ctx.clearRect(0, 0, canvas.width, canvas.height);
    
    				ctx.beginPath();
    				ctx.fillStyle = "rgb(0, 255, 0)";
    				ctx.arc(x1, y1, 40, 0, 2*Math.PI, false);
    				ctx.fill();
    
    				ctx.beginPath();
    				ctx.fillStyle = "rgb(255, 0, 0)";
    				ctx.arc(x2, y2, 40, 0, 2*Math.PI, false);
    				ctx.fill();
    							// 衝突判定
    				let x = x1 - x2;
    				let y = y1 - y2;
    				if (Math.sqrt(x*x+y*y) <= 80)
    					hit = true;
    			}
    		}
    	</SCRIPT>
    </HEAD>
    <BODY CLASS="white" STYLE="text-align: center" onLoad="start()">
    	<H1>衝突判定(距離)</H1>
    	<CANVAS ID="canvas_e" STYLE="background-color: #eeffee;" WIDTH="600" HEIGHT="400"></CANVAS>
    </BODY>
    </HTML>
    			

  4. もう一つの例

      この例では,四方のランダムな位置からが出現し,中央の三角形に向かって進みます.三角形と衝突後,しばらくすると,次の円が別の位置から出現します.衝突判定を行う点は,三角形の頂点及び各辺に設定された 4 つの,合計 15 個です.プログラムとしては,先に述べた例のように,円に衝突判定を行う点を設定した方が簡単です.点の数が少ないため,衝突する位置によっては,三角形に多少めり込んだ位置で衝突判定が行われます.
    001	<!DOCTYPE HTML>
    002	<HTML>
    003	<HEAD>
    004		<TITLE>衝突判定</TITLE>
    005		<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
    006		<META NAME=viewport CONTENT="width=device-width, initial-scale=1">
    007		<LINK REL="stylesheet" TYPE="text/css" HREF="../../master.css">
    008		<SCRIPT TYPE="text/javascript">
    009			canvas  = null;
    010			ctx     = null;
    011			timerID = -1;
    012			x       = 0.0;   // 位置(x)
    013			y       = 0.0;   // 位置(y)
    014			dt      = 0.1;   // 時間刻み幅
    015			hit     = false;   // 命中中か否か
    016			ang     = 0.0;   // 時間
    017			let v   = 50;   // 速度
    018			let vx  = 0.0;   // 速度(x)
    019			let vy  = 0.0;   // 速度(y)
    020			r       = 20;   // 円の半径
    021			x1      = 0;   // 三角形の頂点
    022			y1      = 0;
    023			x2      = 0;
    024			y2      = 0;
    025			x3      = 0;
    026			y3      = 0;
    027			px      = new Array();   // 衝突判定位置
    028			py      = new Array();
    029			count   = 0;
    030	
    031			function start() {
    032				canvas = document.getElementById('canvas_e');
    033				canvas.width  = 600;   // キャンバス要素の幅
    034				canvas.height = 400;   // キャンバス要素の高さ
    035				ctx = canvas.getContext('2d');
    036						// 衝突判定位置
    037				let cx = canvas.width / 2;
    038				let cy = canvas.height / 2;
    039				x1     = cx;
    040				y1     = cy - 50.0 / Math.cos(Math.PI/6);
    041				x2     = cx - 50.0;
    042				y2     = cy + 50.0 * Math.tan(Math.PI/6);
    043				x3     = cx + 50.0;
    044				y3     = cy + 50.0 * Math.tan(Math.PI/6);
    045	
    046				let k = 0;
    047				px[k] = x1;
    048				py[k] = y1;
    049				k++;
    050				let sx = (x2 - x1) / 5;
    051				let sy = (y2 - y1) / 5;
    052				for (let i1 = 1; i1 < 5; i1++) {
    053					px[k] = x1 + i1 * sx;
    054					py[k] = y1 + i1 * sy;
    055					k++;
    056				}
    057				px[k] = x2;
    058				py[k] = y2;
    059				k++;
    060				sx = (x3 - x2) / 5;
    061				sy = (y3 - y2) / 5;
    062				for (let i1 = 1; i1 < 5; i1++) {
    063					px[k] = x2 + i1 * sx;
    064					py[k] = y2 + i1 * sy;
    065					k++;
    066				}
    067				px[k] = x3;
    068				py[k] = y3;
    069				k++;
    070				sx = (x1 - x3) / 5;
    071				sy = (y1 - y3) / 5;
    072				for (let i1 = 1; i1 < 5; i1++) {
    073					px[k] = x3 + i1 * sx;
    074					py[k] = y3 + i1 * sy;
    075					k++;
    076				}
    077						// 初期設定
    078				ini_set();
    079	
    080				timerID = setInterval('draw()', 33);
    081			}
    082						// 初期設定
    083			function ini_set()
    084			{
    085				let p = Math.random() * 2 * (canvas.width + canvas.height);
    086				if (p < canvas.width) {   // 上
    087					x = r + Math.random() * (canvas.width - 2 * r);
    088					y = r;
    089				}
    090				else if (p < canvas.width + canvas.height) {   // 右
    091					x = canvas.width - r;
    092					y = r + Math.random() * (canvas.height - 2 * r);
    093				}
    094				else if (p < 2 * canvas.width + canvas.height) {   // 下
    095					x = r + Math.random() * (canvas.width - 2 * r);
    096					y = canvas.height - r;
    097				}
    098				else {   // 左
    099					x = r;
    100					y = r + Math.random() * (canvas.height - 2 * r);
    101				}
    102				ang = Math.atan2(canvas.height/2-y, canvas.width/2-x);
    103				vx  = v * Math.cos(ang);
    104				vy  = v * Math.sin(ang);
    105			}
    106						// 描画
    107			function draw()
    108			{
    109				if (count == 0) {
    110								// 領域のクリア
    111					ctx.clearRect(0, 0, canvas.width, canvas.height);
    112								// 円の描画
    113					ctx.beginPath();
    114					ctx.fillStyle = "rgb(0, 255, 0)";
    115					ctx.arc(x, y, r, 0, 2*Math.PI, false);
    116					ctx.fill();
    117								// 衝突判定
    118					for (let i1 = 0; i1 < 15; i1++) {
    119						hit = ctx.isPointInPath(px[i1], py[i1]);
    120						if (hit)
    121							break;
    122					}
    123					if (hit)
    124						count = 1;
    125					else {
    126						x += vx * dt;
    127						y += vy * dt;
    128					}
    129								// 三角形の描画
    130					ctx.beginPath();
    131					ctx.fillStyle = "rgb(255, 0, 0)";
    132					ctx.moveTo(x1, y1);
    133					ctx.lineTo(x2, y2);
    134					ctx.lineTo(x3, y3);
    135					ctx.closePath();
    136					ctx.fill();
    137				}
    138				else {
    139					count++;
    140					if (count == 30) {
    141						count = 0;
    142						ini_set();
    143					}
    144				}
    145			}
    146		</SCRIPT>
    147	</HEAD>
    148	<BODY CLASS="white" STYLE="text-align: center" onLoad="start()">
    149		<H1>衝突判定(円と三角形)</H1>
    150		<CANVAS ID="canvas_e" STYLE="background-color: #eeffee;" WIDTH="600" HEIGHT="400"></CANVAS>
    151	</BODY>
    152	</HTML>
    			
    037 行目~ 044 行目

      三角形の 3 つの頂点(上,下左,下右)の座標を設定しています.

    046 行目~ 076 行目

      三角形上の衝突判定を行う点の座標を計算し,配列 px 及び py に設定しています.

    083 行目~ 105 行目

      初期設定を行う関数であり,出現位置,及び,進行方向をランダムに決めています.atan2 は,Math オブジェクトのメソッドであり,逆正接の計算,つまり,atan2(y, x) は,tan(a) = y/x となるような角度 a をラジアン単位で返します.従って,102 行目の計算により,すべての円は,キャンバスの中心に向かって移動することになります.

    109 行目

      この if 文によって,衝突していない場合は( count が 0 の場合は),110 行目~ 136 行目を実行します.118 行目~ 122 行目の衝突判定によって,衝突が判明した場合は変数 count を 1 に設定し,さもなければ,円の移動を続行します( 126,127 行目).

    138 行目

      count が 0 でない場合は,139 行目~ 143 行目を実行します.count を 1 だけ増加させ,その値が 30 になった場合は,count を 0 に設定し,初期設定を行う関数 ini_set によって,新しい円を出現させます.count が 30 になるまでは何も行いませんので,ほぼ 1 秒間( 33×30,079 行目),衝突した状態が表示されます.

      上と同じような例ですが,中央の形を多少複雑にし,かつ,衝突する図形を四角形に変更しています.様々な位置からの衝突を確認したい場合は,再読込を行ってください.
    <!DOCTYPE HTML>
    <HTML>
    <HEAD>
    	<TITLE>衝突判定</TITLE>
    	<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=utf-8">
    	<META NAME=viewport CONTENT="width=device-width, initial-scale=1">
    	<LINK REL="stylesheet" TYPE="text/css" HREF="../../master.css">
    	<SCRIPT TYPE="text/javascript">
    		canvas  = null;
    		ctx     = null;
    		timerID = -1;
    		x       = 0.0;   // 位置(x)
    		y       = 0.0;   // 位置(y)
    		dt      = 0.1;   // 時間刻み幅
    		hit     = false;   // 命中中か否か
    		ang     = 0.0;   // 時間
    		let v   = 50;   // 速度
    		let vx  = 0.0;   // 速度(x)
    		let vy  = 0.0;   // 速度(y)
    		r       = 20;   // 円の半径
    		x1      = 0;   // 三角形の頂点
    		y1      = 0;
    		x2      = 0;
    		y2      = 0;
    		x3      = 0;
    		y3      = 0;
    		px      = new Array();   // 衝突判定位置
    		py      = new Array();
    		count   = 0;
    
    		function start() {
    			canvas = document.getElementById('canvas_e');
    			canvas.width  = 600;   // キャンバス要素の幅
    			canvas.height = 400;   // キャンバス要素の高さ
    			ctx = canvas.getContext('2d');
    					// 衝突判定位置
    			let cx = canvas.width / 2;
    			let cy = canvas.height / 2;
    			x1     = cx;
    			y1     = cy - 50.0 / Math.cos(Math.PI/6);
    			x2     = cx - 50.0;
    			y2     = cy + 50.0 * Math.tan(Math.PI/6);
    			x3     = cx + 50.0;
    			y3     = cy + 50.0 * Math.tan(Math.PI/6);
    
    			let k = 0;
    			px[k] = x1;
    			py[k] = y1;
    			k++;
    			let sx = (x2 - x1) / 5;
    			let sy = (y2 - y1) / 5;
    			for (let i1 = 1; i1 < 5; i1++) {
    				px[k] = x1 + i1 * sx;
    				py[k] = y1 + i1 * sy;
    				k++;
    			}
    			px[k] = x2;
    			py[k] = y2;
    			k++;
    			sx = (x3 - x2) / 5;
    			sy = (y3 - y2) / 5;
    			for (let i1 = 1; i1 < 5; i1++) {
    				px[k] = x2 + i1 * sx;
    				py[k] = y2 + i1 * sy;
    				k++;
    			}
    			px[k] = x3;
    			py[k] = y3;
    			k++;
    			sx = (x1 - x3) / 5;
    			sy = (y1 - y3) / 5;
    			for (let i1 = 1; i1 < 5; i1++) {
    				px[k] = x3 + i1 * sx;
    				py[k] = y3 + i1 * sy;
    				k++;
    			}
    					// 初期設定
    			ini_set();
    
    			timerID = setInterval('draw()', 33);
    		}
    					// 初期設定
    		function ini_set()
    		{
    			let p = Math.random() * 2 * (canvas.width + canvas.height);
    			if (p < canvas.width) {   // 上
    				x = r + Math.random() * (canvas.width - 2 * r);
    				y = r;
    			}
    			else if (p < canvas.width + canvas.height) {   // 右
    				x = canvas.width - r;
    				y = r + Math.random() * (canvas.height - 2 * r);
    			}
    			else if (p < 2 * canvas.width + canvas.height) {   // 下
    				x = r + Math.random() * (canvas.width - 2 * r);
    				y = canvas.height - r;
    			}
    			else {   // 左
    				x = r;
    				y = r + Math.random() * (canvas.height - 2 * r);
    			}
    			ang = Math.atan2(canvas.height/2-y, canvas.width/2-x);
    			vx  = v * Math.cos(ang);
    			vy  = v * Math.sin(ang);
    		}
    					// 描画
    		function draw()
    		{
    			if (count == 0) {
    							// 領域のクリア
    				ctx.clearRect(0, 0, canvas.width, canvas.height);
    							// 円の描画
    				ctx.beginPath();
    				ctx.fillStyle = "rgb(0, 255, 0)";
    				ctx.arc(x, y, r, 0, 2*Math.PI, false);
    				ctx.fill();
    							// 衝突判定
    				for (let i1 = 0; i1 < 15; i1++) {
    					hit = ctx.isPointInPath(px[i1], py[i1]);
    					if (hit)
    						break;
    				}
    				if (hit)
    					count = 1;
    				else {
    					x += vx * dt;
    					y += vy * dt;
    				}
    							// 三角形の描画
    				ctx.beginPath();
    				ctx.fillStyle = "rgb(255, 0, 0)";
    				ctx.moveTo(x1, y1);
    				ctx.lineTo(x2, y2);
    				ctx.lineTo(x3, y3);
    				ctx.closePath();
    				ctx.fill();
    			}
    			else {
    				count++;
    				if (count == 30) {
    					count = 0;
    					ini_set();
    				}
    			}
    		}
    	</SCRIPT>
    </HEAD>
    <BODY CLASS="white" STYLE="text-align: center" onLoad="start()">
    	<H1>衝突判定(円と三角形)</H1>
    	<CANVAS ID="canvas_e" STYLE="background-color: #eeffee;" WIDTH="600" HEIGHT="400"></CANVAS>
    </BODY>
    </HTML>
    			

情報学部 菅沼ホーム JavaScript 目次 基礎技術目次 索引