グラフィカルなルーレットを作る
グラフィカルなルーレットです。
コンテンツ
今回やること
ボタンを押してブラウザ内のルーレットを回転させます。 もう一度押すとゆっくり止まって音がなります。
用意するもの
- 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のコンソールでプログラムを実行すると、画面にルーレットが表示されます。ボタンを押すとルーレットが回り始め、もう一度ボタンを押すとゆっくりルーレットが止まります。
完成したプログラム