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

このエントリーをはてなブックマークに追加

これは何?

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

用意するもの

  • obniz
  • obnizの電源
  • 加速度センサ(KXR94-2050)

手順

obnizに電源と加速度センサをobnizを繋ぎます。

  • (obniz) : (加速度センサ)
  • 0 : 1番 (Vdd)
  • 1 : 3番 (GND)
  • 2 : 6番 (X軸入力)
  • 3 : 7番 (Y軸入力)
  • 4 : 8番 (Z軸入力)
  • 5 : 2番 (Enable)
  • 6 : 5番 (Self Test)

画像の向きの状態で上着等のポケットに入れます。

Webページにアクセスして上着のポケットをたたくと、Webページ上のビスケットが増えます。
ポケットと自分の体の間に隙間を作って、一気にその隙間をなくすようにたたくとうまく反応します。

プログラム

Program

<!-- 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@1.14.1/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://lh6.googleusercontent.com/lTDHIc24ZcrYqXv5OtaN4pEVGnM0NF_2v-x2-REEjiknug58drWZYLVPj6g7lASsUscEdPboU0_z54oBRGQugZ7393USv4ixCghbW5VqknzX3clQJQ=w472");
		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://lh4.googleusercontent.com/pho0q0bY2mTszj0yTX3WINyiHQez58F2Xima3_FMnIbKV-0wUOSHf1sTbG6k0Ox_ADBCFBGm8FWZbE8MYriUmTRflweuyiOSv5wdf5C2YQTiovOPRy0=w572";
	const bis1URL = "https://lh6.googleusercontent.com/lX7BbW3nrEsF354j3dGjpwdTCkesuvCfVJJ-Sjeq8u-D4Dj6Uh_8B9dbjfB48ZxlhMGIsu4CHnDj8IR-7avirHw2aMtiMoGL5hQHgIeiPUuXfqCiSnY=w572";
	const bis2URL = "https://lh4.googleusercontent.com/-O8oYaNWpBRpwtGQTrtUZ-2VE2yRtmuxbA3V4hDQENNApqjagUYjS-o941WQzgZudazq1ado4xZqn9xIn6y53-fAh69QEbvGBX71I8BVtJG5ZjciZ49W=w572";
	const bis3URL = "https://lh5.googleusercontent.com/KWGEHLpHTH5WmHnXsHxBGcGauyfD9Xx4Li2_yMxflLqy1JOvf7uOYvpPrnTqKLe-HaYWPohPer9sPCRT2jlVaN6FfdJd6bUWp33zR4EEyeFPK8GCRw=w572";
	const bis4URL = "https://lh5.googleusercontent.com/UDR3LDN-6OJdDBliG-rO_kzRFYl6S98dEwbj2Ab5dLnpVqu9a9XKdHlc53gWssMP6cIxP1pMh6kbdXYf4WkPkCrJX8wIg1oAeLJ0I-4i2G1eXKjxOQc=w572";
	
	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 = 300;
	  
	  let react = true;
	  let noReactionCount = 0;
	  
	  //1,8ピン側を上にしてZ軸プラスからマイナスの方向へ叩く前提です
	  const Y_HIT_THRESHOLD = 0.18;
	  const Z_HIT_THRESHOLD = -0.158;
	  
	  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 function(){
			
		  let accelValues = await accel.getWait();
			
		  //RCフィルタの適用と配列の制御
		  let filteredX = applyRCFilter(rawAccelX, accelValues.x);
		  let filteredY = applyRCFilter(rawAccelY, accelValues.y);
		  let filteredZ = applyRCFilter(rawAccelZ, accelValues.z);
			
		  await obniz.wait(30);

		  //反応したループの次のループでは叩いたと検知しない
		  if(react){
		  
		  	//前ループとの差分で振動を判断
          	if((filteredZ - prevFilteredVal.z) < Z_HIT_THRESHOLD || filteredY - prevFilteredVal.y > Y_HIT_THRESHOLD){
			
				await addBiscuit();
				await obniz.wait(PAUSE_MILL);  
				react = false;
				  
          	}
			  
		  }else{
			  noReactionCount++;
			  
			  if(noReactionCount >= 1){
			  	react = true;
			  	noReactionCount = 0;
			  }
			  
		  }
			
		  //前回のループの値として保存
		  prevFilteredVal = {x: filteredX, y: filteredY, z: filteredZ};
                
	  	}, 200);
	  }

	  
	  function arrangeArray(arr, val){
		  arr.push(val);
		  if(arr.length > ARR_LIMIT_NUM){
			  arr.shift();
		  }
	  }
	  
	  //RCフィルタ
	  function applyRCFilter(arr, val){
		  const RC_PARAM = 0.8;
		  
		  arrangeArray(arr, val);
		  
		  return RC_PARAM * arr[arr.length-1] + (1 - RC_PARAM) * arr[arr.length-2];
	  }
	  
	  async function addBiscuit(){
		  
		  console.log("hit");
		  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>

今すぐ実行

HTMLがブラウザで開かれて実行されます。