グラフィカルなルーレットを作る
グラフィカルなルーレットです。
コンテンツ
今回やること
ボタンを押してブラウザ内のルーレットを回転させます。 もう一度押すとゆっくり止まって音がなります。
用意するもの
- obniz Board
- obnizの電源 x1
- ボタン x1
- スピーカー x1
組み立て方
以下の表や図のように配線します。ボタンは左右どちらの向きで繋いでも問題ありません。
obniz | 部品 |
---|---|
0 | スピーカー signal |
1 | スピーカー GND |
6 | ボタン signal |
7 | ボタン GND |
プログラム
ボタンとスピーカーを繋いだピンの番号に応じて、プログラム内にてwiredの番号を変えます。
button = obniz.wired("Button", {signal:6 , gnd:7 }); speaker = obniz.wired("Speaker", {signal:0 , gnd: 1});
画像を回転させる
ルーレット画像を回転させます。
HTMLで画像を回転させる場合、cssのtransformを使います。 たとえば、90度回転させる場合、下記のように書きます。
document.getElementById("roulette").style = "transform:rotate(90deg);";
ゆっくり回転を開始したり止めたりしたいので、speed
という変数を作って1フレームあたりの回転角度を決めています。
let speed = 0; let deg = 0; function rotate(){ deg += speed; document.getElementById("roulette").style = "transform:rotate("+deg+"deg);"; } setInterval(rotate,10);
音を鳴らす
やはりルーレットの番号が変わったときに音を鳴らしたいですよね。 以下ように書くと、440Hz(ドの音)で10ms間音を鳴らすことができます。
speaker.play(440); await obniz.wait(10); speaker.stop();
ルーレットの番号が変わった時を知るには、先程のrotate
関数内にてdeg
の値を確認する必要があります。
if( Math.floor((deg + speed) / (360/7.0)) - Math.floor(deg / (360/7.0)) >= 1){ onRouletteChange(); }
これらを合わせると以下のようになります。
let speed = 0; let deg = 0; function rotate(){ //on change value if( Math.floor((deg + speed) / (360/7.0)) - Math.floor(deg / (360/7.0)) >= 1){ onRouletteChange(); } deg += speed; document.getElementById("roulette").style = "transform:rotate("+deg+"deg);"; } setInterval(rotate,10); async function onRouletteChange(){ if(!speaker){return;} speaker.play(440); await obniz.wait(10); speaker.stop(); }
ボタンを押したらスタートする
ボタンを押されたことを検知するために、buttonState
という変数を作り、そこに現在のボタンの値を入れておきます。
button.onchange = function(pressed){ buttonState = pressed; };
また、このプログラムでは、今どの状態かの把握のためにphase
変数を作っています。 このphase
が次のどれかになることで現在の状態を把握しています。
const PHASE_WAIT_FOR_START = 0; const PHASE_ROTATE = 1; const PHASE_STOPPING = 2; const PHASE_STOPPED = 3;
たとえば、phase
がPHASE_WAIT_FOR_START
のときにボタンが押されたら、次のPHASE_ROTATE
フェーズに行くようにします。
if(phase == PHASE_WAIT_FOR_START){ speed = 0; if(buttonState){ phase = PHASE_ROTATE; } }
ボタンが押されたら速度を上げるようにするにはこう書きます。
if(phase == PHASE_ROTATE){ speed = speed+0.5; }
逆に速度を落とすときはこうなります。ゆっくり止まって欲しいので、速度を上げるときより変化値を小さくしています。
if(phase == PHASE_STOPPING){ speed = speed-0.2; }
これらを組み合わせて実行してみましょう。
obnizに電源を繋いでブラウザやobnizのコンソールでプログラムを実行すると、画面にルーレットが表示されます。ボタンを押すとルーレットが回り始め、もう一度ボタンを押すとゆっくりルーレットが止まります。
完成したプログラム