戻る

z-indexを使用したキャラの当たり判定
簡単な当たり判定のサンプル

サンプル
ひよこの座標
大豆の座標
ひよこの中心座標
大豆の中心座標


<div class="layer layer2" id="hiyoko" style="width:100px;height:100px;">
    <img id="img" src="i3/nawmin_sample6.png" style="width:100px;height:100px;">
</div>
ひよこのdivタグです。
「nawmin_sample6.png」は、ひよこの画像ファイルIDです。

<div class="layer layer3" id="daizu" style="width:50px;height:50px;">
    <img src="nawmin_sample8.png" style="width:50px;height:50px;">
</div>
大豆のdivタグです。
「nawmin_sample8.png」は、大豆の画像ファイルIDです。

大豆の座標<div id="daizu_pos"></div>
大豆の座標位置情報を表示するエリアです。

[CSS]
copy
.container{
	position: sticky;
}
.layer{
	width: 200px;
	height: 200px;
	position: absolute;
}
.layer1{
	top: 0px;
	left: 0px;
}
.layer2{
	top: 100px;
	left: 90px;
	z-index:1;
}
.layer3{
	top: 140px;
	left: 20px;
}
「.layer2」はひよこのレイヤーです。
「.layer3」は大豆のレイヤーです。

[javascript]
copy
//大豆の座標配列
const aryX=[20,120,50];
const aryY=[140,0,50];
let index=0;
//大豆の座標位置を表示
currentDaizuPosition();
let score=0;
let x=90;//キャラクターのx座標位置(初期値はキャラの初期座標位置)
let y=100;//キャラクターのy座標位置(初期値はキャラの初期座標位置)
currentHiyokoPosition();
const b1 = document.getElementById("btn1");//左方向ボタン
const b2 = document.getElementById("btn2");//右方向ボタン
const b3 = document.getElementById("btn3");//上方向ボタン
const b4 = document.getElementById("btn4");//下方向ボタン
const leftPosition=0;//枠の左側の位置
const rightPosition=200-100;//枠の幅- 画像の幅
const upPosition=0;//枠の上
const downPosition=200-100;//枠の高さ- 画像の高さ
let moveDistance=10;//移動距離
//左へ
b1.addEventListener("click", () => 
{
	moveCharacterImage(0);
});
//右へ
b2.addEventListener("click", () => 
{
	moveCharacterImage(1);
});
//上へ
b3.addEventListener("click", () => 
{
	moveCharacterImage(2);
});
//下へ
b4.addEventListener("click", () => 
{
	moveCharacterImage(3);
})
//ひよこの移動処理
//direction:
//0:左へ移動
//1:右へ移動
//2:上へ移動
//3:下へ移動
function moveCharacterImage(direction)
{
	const obj = document.getElementById("hiyoko");
	const img = document.getElementById("img");
	if(direction==0)//左
	{
		//パスは環境にあわせて変更してください
		img.src="nawmin_sample6.png";
		x-=moveDistance;
		if(x < leftPosition)
		{
			x=-10;//微調整
		}
		obj.style.left = x +'px';
		if(x<0)x=0;
	}
	else if(direction==1)//右
	{
		//パスは環境にあわせて変更してください
		img.src="nawmin_sample9.png";
		x+=moveDistance;
		if(x > rightPosition)
		{
			x=rightPosition+5;//微調整
		}
		obj.style.left = x +'px';
		if(x>rightPosition)x=rightPosition;
	}
	else if(direction==2)//上
	{
		//パスは環境にあわせて変更してください
		img.src="nawmin_sample10.png";
		y-=moveDistance;
		if(y>upPosition)
		{
			y=upPosition-5;//微調整
		}
		obj.style.top = y +'px';
		if(y<0)y=0;
	}
	else if(direction==3)//下
	{
		//パスは環境にあわせて変更してください
		img.src="nawmin_sample10.png";
		y+=moveDistance;
		if(y>downPosition)
		{
			y=downPosition;//微調整
		}
		obj.style.top = y +'px';
		if(y>downPosition)y=downPosition;
	}
	//大豆のあたり判定
	judgeFeed();
	currentHiyokoPosition();
}
//大豆のあたり判定
function judgeFeed()
{
	let result = 0;
	result = judgeHiyoko();
	if(result == 1)
	{
		//次の配列インデックスを準備します
		index++;
		if(index==aryX.length)index=0;
		//大豆の位置を反映
		const daizu = document.getElementById("daizu");
		daizu.style.top = aryY[index] +'px';
		daizu.style.left = aryX[index] +'px';
		//スコアを加算した結果を反映
		score++;
		const point = document.getElementById("score");
		point.textContent = score;
		//大豆の座標位置を表示
		currentDaizuPosition();
	}
}
//ひよこ判定
function judgeHiyoko()
{
	let result =0;
	//ひよこのx/y座標
	let x1=x+100/2;
	let y1=y+100/2;
	//大豆のx/y座標
	let x2=aryX[index]+50/2;
	let y2=aryY[index]+50/2;
	//ひよこと大豆のx座標の差分の絶対値
	let xx=Math.abs(x1-x2);
	//ひよこと大豆のy座標の差分の絶対値
	let yy=Math.abs(y1-y2);
	//絶対値の累乗(xとy)を計算
	let xy=Math.pow(xx,2) + Math.pow(yy,2);
	//ルート計算
	let r=Math.sqrt(xy);
	//if(r<=75)//ピッタリ接触(ひよこの半分:50 + 大豆の半分:25)
	if(r<=30)//微調整
	{
		result =1;//あたり
	}
	return result;
}
//大豆の座標位置を表示
function currentDaizuPosition()
{
	//x座標 y座標
	const pos = document.getElementById("daizu_pos");
	pos.textContent = "x:"+aryX[index]+" y:"+aryY[index];
	//中心座標
	const posCenter = document.getElementById("daizu_center_pos");
	posCenter.textContent = "x:"+(aryX[index]+25)+" y:"+(aryY[index]+25);
}
//ひよこの座標位置を表示
function currentHiyokoPosition()
{
	const pos = document.getElementById("hiyoko_pos");
	//x座標 y座標
	pos.textContent = "x:"+x+" y:"+y;
	//中心座標
	const posCenter = document.getElementById("hiyoko_center_pos");
	posCenter.textContent = "x:"+(x+50)+" y:"+(y+50);
}
ひよこが大豆にぶつかったらスコアが加算されるサンプルです。
ひよこと大豆の中心座標の距離を三平方の定理で距離を計算します。
そのため、ひよこと大豆、それぞれのx中心座標とy中心座標を取得して
1:ひよこと大豆のx座標の差分
2:ひよこと大豆のy座標の差分
を求めます。
1と2の計算結果は距離を知りたいため絶対値にします。
1(x差分)と2(y差分)をそれぞれ累乗した結果を加算します。
上記のたし算をした結果をルートにすることで、三平方の定理の斜線の長さを求められます。
この計算結果がひよこの半分の長さと大豆の半分の長さと一致している場合は衝突したと考えれます。
この判定方法が
if(r<=75)//ピッタリ接触(ひよこの半分:50 + 大豆の半分:25)
という判定方法です。
しかし、画像には透過色の余白があるため、視覚的に有効なあたり判定にするため
この判定処理では下記の判定方法にしています。
if(r<=30)//微調整



[謝辞]
「イラスト:農民イラスト」さんの画像を使用させていただいております。
ありがとうございます。
[URL]イラスト:農民イラスト
URL[https://nawmin.stores.jp][クリックすると開きます])


戻る
back

Character collision detection using z-index
A simple example of collision detection

sample
chick coordinate
soybean coordinate
chick center coordinate
soybean center coordinate


<div class="layer layer2" id="hiyoko" style="width:100px;height:100px;">
    <img id="img" src="i3/nawmin_sample6.png" style="width:100px;height:100px;">
</div>
This is the div tag for the chick.
"nawmin_sample6.png" is the image file ID for the chick.

<div class="layer layer3" id="daizu" style="width:50px;height:50px;">
    <img src="nawmin_sample8.png" style="width:50px;height:50px;">
</div>
This is the div tag for soybeans.
"nawmin_sample8.png" is the image file ID for soybeans.

Soybean coordinates <div id="daizu_pos"></div>
This is the area that displays the coordinate location information for soybeans.

[CSS]
copy
.container{
	position: sticky;
}
.layer{
	width: 200px;
	height: 200px;
	position: absolute;
}
.layer1{
	top: 0px;
	left: 0px;
}
.layer2{
	top: 100px;
	left: 90px;
	z-index:1;
}
.layer3{
	top: 140px;
	left: 20px;
}
".layer2" is the chick layer.
".layer3" is the soybean layer.

[javascript]
copy
//Soybean coordinate array
const aryX=[20,120,50];
const aryY=[140,0,50];
let index=0;
//Display the coordinates of soybeans
currentDaizuPosition();
let score=0;
let x=90;//Character's x coordinate position (initial value is the character's initial coordinate position)
let y=100;//Character's y coordinate position (initial value is the character's initial coordinate position)
currentHiyokoPosition();
const b1 = document.getElementById("btn1");//Left Arrow Button
const b2 = document.getElementById("btn2");//Right button
const b3 = document.getElementById("btn3");//Up button
const b4 = document.getElementById("btn4");//Down button
const leftPosition=0;//Left position of frame
const rightPosition=200-100;//Width of frame - width of image
const upPosition=0;//Top of frame
const downPosition=200-100;//Height of frame - height of image
let moveDistance=10;//Movement distance
//To the left
b1.addEventListener("click", () => 
{
	moveCharacterImage(0);
});
//right
b2.addEventListener("click", () => 
{
	moveCharacterImage(1);
});
//up
b3.addEventListener("click", () => 
{
	moveCharacterImage(2);
});
//down
b4.addEventListener("click", () => 
{
	moveCharacterImage(3);
})
//Chick movement process
//direction:
//0: Move left
//1: Move right
//2: Move up
//3: Move down
function moveCharacterImage(direction)
{
	const obj = document.getElementById("hiyoko");
	const img = document.getElementById("img");
	if(direction==0)//left
	{
		//Please change the path according to your environment.
		img.src="nawmin_sample6.png";
		x-=moveDistance;
		if(x < leftPosition)
		{
			x=-10;//Fine adjustment
		}
		obj.style.left = x +'px';
		if(x<0)x=0;
	}
	else if(direction==1)//right
	{
		//Please change the path according to your environment.
		img.src="nawmin_sample9.png";
		x+=moveDistance;
		if(x > rightPosition)
		{
			x=rightPosition+5;//Fine adjustment
		}
		obj.style.left = x +'px';
		if(x>rightPosition)x=rightPosition;
	}
	else if(direction==2)//up
	{
		//Please change the path according to your environment.
		img.src="nawmin_sample10.png";
		y-=moveDistance;
		if(y>upPosition)
		{
			y=upPosition-5;//Fine adjustment
		}
		obj.style.top = y +'px';
		if(y<0)y=0;
	}
	else if(direction==3)//down
	{
		//Please change the path according to your environment.
		img.src="nawmin_sample10.png";
		y+=moveDistance;
		if(y>downPosition)
		{
			y=downPosition;//Fine adjustment
		}
		obj.style.top = y +'px';
		if(y>downPosition)y=downPosition;
	}
	//Soybean hit detection
	judgeFeed();
	currentHiyokoPosition();
}
//Soybean hit detection
function judgeFeed()
{
	let result =0;
	result judgeHiyoko();
	if(result == 1)
	{
		//Prepare the next array index
		index++;
		if(index==aryX.length)index=0;
		//Reflects the position of soybeans
		const daizu = document.getElementById("daizu");
		daizu.style.top = aryY[index] +'px';
		daizu.style.left = aryX[index] +'px';
		//Reflect the result of adding the score
		score++;
		const point = document.getElementById("score");
		point.textContent = score;
		//Display the coordinates of soybeans
		currentDaizuPosition();
	}
}
//judge chick
function judgeHiyoko()
{
	let result =0;
	//chick x/y coordinate
	let x1=x+100/2;
	let y1=y+100/2;
	//soybean x/y coordinate
	let x2=aryX[index]+50/2;
	let y2=aryY[index]+50/2;
	//chick and soybean absolute value of the difference in x coordinates
	let xx=Math.abs(x1-x2);
	//chick and soybean value of the difference in y coordinates
	let yy=Math.abs(y1-y2);
	//absolute value power(x and y) calculate
	let xy=Math.pow(xx,2) + Math.pow(yy,2);
	//root calculation
	let r=Math.sqrt(xy);
	//if(r<=75)//just the right contact(chick half:50 + soyabean half:25)
	if(r<=30)//fine adjustment
	{
		result =1;//hit
	}
	return result;
}
//Display the coordinates of soybeans
function currentDaizuPosition()
{
	//x coordinate y coordinate
	const pos = document.getElementById("daizu_pos");
	pos.textContent = "x:"+aryX[index]+" y:"+aryY[index];
	//center coordinate
	const posCenter = document.getElementById("daizu_center_pos");
	posCenter.textContent = "x:"+(aryX[index]+25)+" y:"+(aryY[index]+25);
}
//Display the coordinates of chick
function currentHiyokoPosition()
{
	const pos = document.getElementById("hiyoko_pos");
	//x coordinate y coordinate
	pos.textContent = "x:"+x+" y:"+y;
	//center coordinate
	const posCenter = document.getElementById("hiyoko_center_pos");
	posCenter.textContent = "x:"+(x+50)+" y:"+(y+50);
}
This is a sample where a score is added if the chick collides with the soybean.
The distance between the center coordinates of the chick and the soybean is calculated using Pythagoras' theorem.
To do this, obtain the x and y center coordinates of the chick and the soybean, and calculate
1: the difference between the x coordinates of the chick and the soybean
2: the difference between the y coordinates of the chick and the soybean

The results of 1 and 2 are absolute values ​​because we want to know the distance.
The results of raising 1 (x difference) and 2 (y difference) to their respective powers are added.
The length of the diagonal line in Pythagoras' theorem can be found by taking the result of the above addition as the root.
If this calculation result matches the half length of the chick and the half length of the soybean, it is considered that a collision has occurred.
This determination method is called
if(r<=75)//exact contact (half of the chick: 50 + half of the soybean: 25)
However, since the image has a transparent margin, in order to make the hit determination visually valid,
the following judgment method is used in this judgment process.
if(r<=30) // Fine-tuning


[Acknowledgements]
images used are from "illustration by nawmin.com"
Thank you very much.
[URL]illustration by nawmin.com
URL[https://nawmin.stores.jp][click to open the homepage])


back



著作権情報
ホームページおよプリ等に掲載されている情報等については、いかなる保障もいたしません。
ホームページおよびアプリ等を通じて入手したいかなる情報も複製、販売、出版または使用させたり、
または公開したりすることはできません。
当方は、ホームペーよびアプリ利用したいかなる理由によっての障害等が発生しても、
その結果ホームページおよびアプリ等を利用された本人または他の第三者が被った損害について
一切の責任を負わないものとします。