言語切り替え

『ふしぎなポケット』叩くたびに増えるビスケット

ポケットをたたくたび、Webサイト上のクッキーが増えます。

これはなに?

童謡『ふしぎなポケット』の歌詞『ポケットのなかにはビスケットがひとつ ポケットをたたくとビスケットはふたつ』をobnizを使って実現してみました。 ポケットをたたくたび、Webサイト上のクッキーが増えます。

用意するもの

手順

以下の表や図のように配線します。

obniz 加速度センサー KXR94-2050
0 Vcc (1)
1 GND (3)
2 X軸入力 (6)
3 Y軸入力 (7)
4 Z軸入力 (8)
5 Enable (2)
6 Self Test (5)

obnizに電源を繋ぎ、画像の向きの状態で上着等のポケットに入れます。

ブラウザやobnizのコンソールから実行して上着のポケットをたたくと、画面上のビスケットが増えます。 ポケットと自分の体の間に隙間を作って、一気にその隙間をなくすようにたたくとうまく反応します。

プログラム

<!-- HTML Example -->
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://obniz.io/js/jquery-3.2.1.min.js"></script>
<script src="https://unpkg.com/obniz@2.0.2/obniz.js" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" integrity="sha384-9gVQ4dYFwwWSjIDZnLEWnxCjeSWFphJiwGPXr1jddIhOegiu1FwO5qRGvFXOdJZ4" crossorigin="anonymous">
<style>
body {
	background-image: url("https://yahoo.jp/box/4m1j_d");
	background-position: center center;
	background-repeat: no-repeat;
	background-size: cover;
}
p.original {
	text-align: center;
}
</style>
<title>ふしぎなポケット</title>
</head>
<body>
<div id="bis-images">
 <p class="original"><img src="" width="16%" height="16%"></p>
</div>
<script>
	
  $(function(){
	  
	  //ビスケット画像のURL
	const bis0URL = "https://yahoo.jp/box/Q1_f_h";
	const bis1URL = "https://yahoo.jp/box/gI6mbV";
	const bis2URL = "https://yahoo.jp/box/vbmFHZ";
	const bis3URL = "https://yahoo.jp/box/ZgtLl7";
	const bis4URL = "https://yahoo.jp/box/vlxDc2";
	
	const bisImages = [bis0URL, bis1URL, bis2URL, bis3URL, bis4URL];
	  
	$(".original").find("img").attr('src',bis1URL);
	  
	  const WIN_WIDTH = $(window).width();
	  const WIN_HEIGHT = $(window).height();
	  const IMG_WIDTH = 1024;
	  const IMG_HEIGHT = 768;
	  
	  const ARR_LIMIT_NUM = 20;
	  const PAUSE_MILL = 800;
	
	  let reacting = false;
	  
	  //1,8ピン側を上にしてZ軸プラスからマイナスの方向へ叩く前提です
	  //この閾値は適宜調整してください
	  const Z_HIT_THRESHOLD = 0.2;
	  
	  let hitCount = 0;
	  let prevFilteredVal = {x: 0, y: 0, z: 0};
	  let rawAccelX = [];
	  let rawAccelY = [];
	  let rawAccelZ = [];
	  
	  let obniz = new Obniz("OBNIZ_ID_HERE");
	    
	  obniz.onconnect = async function(){
        let accel = obniz.wired("KXR94-2050", { vcc:0, gnd:1, x:2, y:3, z:4, enable:5, self_test:6});	
              
		obniz.repeat(async () => {
		   if(reacting){
			  return;
		  }
			
		  let accelValues = await accel.getWait();
			
		  //フィルタの適用と配列の制御
		  let filteredX = await applyFilter(rawAccelX, accelValues.x);
		  let filteredY = await applyFilter(rawAccelY, accelValues.y);
		  let filteredZ = await applyFilter(rawAccelZ, accelValues.z);
			
		  console.log("fZ: "+filteredZ);
			
		  
		  //前ループとの差分で振動を判断
          if((filteredZ - prevFilteredVal.z) > Z_HIT_THRESHOLD){
			  
			reacting = true;
			console.log("hit");
			await addBiscuit();
			await obniz.wait(PAUSE_MILL);  
			reacting = false;
			  
          }
			
		  //前回のループの値として保存
		  prevFilteredVal = {x: filteredX, y: filteredY, z: filteredZ};
		}, 100);
		  
                
	  }

	  
	  function arrangeArray(arr, val){
		arr.push(val);
		if(arr.length > ARR_LIMIT_NUM){
	      arr.shift();
		}
	  }
	  
	  //フィルタ
	  async function applyFilter(arr, val){
		const FILTER_PARAM = 0.8;
		const ACCEL_SPAN = 0.1;
		
		let lowpassVal = 0;
		let highpassVal = 0;
		
		await arrangeArray(arr, val);
		
		for(let i=0; i<arr.length; i++){
	  	  lowpassVal = FILTER_PARAM * lowpassVal + (1 - FILTER_PARAM) * arr[i];
	  	  highpassVal = arr[i] - lowpassVal;
		}
		
		return highpassVal;
	  }
	  
	  async function addBiscuit(){
		  
		let img = bisImages[Math.floor(Math.random()*bisImages.length)];
		
		await $("#bis-images").append('<p class="added'+hitCount+'"><img src='+img+' width="16%" height="16%"></p>');
		
		let leftPos = Math.floor(Math.random() * (WIN_WIDTH - 160));
		let topPos = Math.floor(Math.random() * (WIN_HEIGHT - 80));
		
		await $(".added"+hitCount).css({'width':IMG_WIDTH, 'height':IMG_HEIGHT});
		await $(".added"+hitCount).css({'position':'absolute'});
		await $(".added"+hitCount).css({'left':leftPos+'px', 'top':topPos+'px'});
		
		await hitCount++;
	  }
	  
  });

</script>
</body>
</html>

関連記事