クソアプリ Advent Calendar 2019 7日目の記事です。
はじめに
僕はジャンケンが弱い。1対1の心理戦では尚更だ。
しかし悲しいことに、世の中ジャンケンで決めることは多い。
テレビのチャンネル権、給食で余ったデザート、どちらが風呂掃除をするか・・・
人生においてここぞという決め事はいつもジャンケンで負けてきた。
このままでは負けっぱなしの人生だ。
次にこの手を出そうと頭で考えると負けてしまう・・・
自動でジャンケンしてくれるロボットアームがあったらいいのに・・・
そこで僕は自動で手を出してくれるアプリを作ることにした。
※ AIとか機械学習で勝率をあげるとかそういう技術レベルの高いことはやっていません。あらかじめご了承ください。
作ったもの
振ってジャンケン!
https://okmr-d.github.io/shake-janken/
スマホやタブレットを振ることで、ジャンケンの手をランダムで出してくれるWebアプリです。
これでもう次にどの手を出すか迷う必要はありません。
手の上にタブレットを置けばまるで自分の手のよう。相手にも違和感を与えることなく真剣勝負ができます。
ジャンケンする友達がいなくても大丈夫。スマホ片手に一人でもジャンケンができます。暇つぶしにはもってこいです。
端末の加速度センサーを利用するため、対応しているスマホやタブレットでご覧ください。ホーム画面に追加することで全画面で遊べます。
【注意事項】
・端末を振る際は落として壊さないよう十分ご注意ください。壊れても責任は負いかねます。
・本当に大事な場面でこのアプリを使うことは推奨しません。使って負けても責任は負いかねます。
工夫したこと
背景を透過した
この画像を背景に使うことで、人によっては端末が透けて見えます。
振ったことをわかりやすくした
振った時に同じ手が連続で出た場合、画面に変化がないとうまく振れなかったように感じてしまうため、振ったタイミングに一瞬だけ背景色を変えるようにしています。
技術解説
デバイスが振られたことを検知する
Webブラウザでシェイクジェスチャーを検知するには、 DeviceMotionEvent を利用してデバイスの加速度情報を取得し、計算して判定します。
const threshold = 5 // 判定のしきい値
const last = { x: null, y: null, z: null } // 前の時点のデータ
const deviceMotionHandler = (event) => {
// X、Y、Z 上のデバイスの加速度を重力度込みで与えるオブジェクト(m/s2)
const current = event.accelerationIncludingGravity
// 初回だけ
if (last.x === null && last.y === null && last.z === null) {
last.x = current.x
last.y = current.y
last.z = current.z
return
}
// 現時点の座標と前の時点の座標の差分
const deltaX = Math.abs(last.x - current.x)
const deltaY = Math.abs(last.y - current.y)
const deltaZ = Math.abs(last.z - current.z)
// シェイク判定(差分がしきい値を超えた)
if (deltaX > threshold || deltaY > threshold || deltaZ > threshold) {
// シェイクされた!!!
}
// 現時点の座標を更新する
last.x = current.x
last.y = current.y
last.z = current.z
}
window.addEventListener('devicemotion', deviceMotionHandler, false)
iOS 12 だとユーザーの設定変更が必要だったり、 iOS 13 からはパーミションの取得が必要だったりするので、別記事にまとめてあります。
→ iOS13+のSafariでdevicemotionやdeviceorientationイベントの許可を取得する方法
クソースコード
おわりに
世の役に立たないクソアプリを作るはずが、ジャンケン弱者を救う役立つアプリを生み出してしまいました。
クソアプリ Advent Calendar 今年も大人気ですね。明日も楽しみです。
よろしければ去年の作品もご覧ください。
→ 「通知止まらんwww」を体験できるアプリを作った