信号機のシミュレーション

ビスケットでのプログラミングは他のプログラミング言語といろいろと違うために,これを作ろうと思ってもどのように作ればよいか,なかなか慣れないと難しいでしょう.

今回は,ご質問をいただいたので,そのプログラムを作ってみたいと思います.お題は信号機のシミュレーションです.

優しいものから考えて行きます.車用の信号で赤,青,黄色の3色があるというやつですね.

個人制作で,設定を押して,方眼紙のモードにします.実行速度も亀の一番遅いのにします.

まず絵を描きます.アニメーションを作るときに,それぞれの部品で変化しない部分に同じ色を使って描くことが重要です.同じ色を使うことで変化した部分が強調されるからです.同じ色で描くには,下絵の機能(お絵かきで右の絵をタップするとその絵で使われている色をとりだすことができる)をつかいます.ここでは,3つの信号機で,消えているときランプの色が他の2つで同じ色になるようにしています.

2016-10-20_02h41_13

では,例として赤が8秒,青が6秒,黄色が2秒で切り替わる信号機を考えます.このとき,8秒とか6秒といった時間を待つ方法が今のビスケットにはありませんので自分で作らなければなりません.一番簡単には8,7,6,...,0という数字の部品を作って,カウントダウンするメガネを作ります.

2016-10-20_02h46_082016-10-20_02h46_01

ここまで作ったところで,どこか間違えていないかをかならず確認しましょう.

2016-10-20_02h46_16

あとは簡単で,信号機と待つ秒数を一緒に並べたメガネを作るだけです.

2016-10-20_02h37_50

まず,最初のメガネは,青で0秒の時は,黄色で2秒待つに変わります. 次のメガネは,黄色で0秒の時は,赤で8秒待つに変わります.最後のメガネは,赤で0秒の時は,青で6秒待つに変わります.

ステージに信号機と最初の秒数(ここでは6秒)を置いて走らせると,ちゃんと動いたでしょうか.

作品はこちら

設定で,実行速度を亀にしています.今のバージョンでこの一番遅いモードでは0.9秒ごとにメガネが動作するので,そもそも1秒ずつではありません.そうだとしても,もっと変なのは,どうやら1ずつカウントが多いようです.

メガネの判定では,青で0のとき黄色2に変わるとなっていました.

実行速度の0.9秒というのは,メガネの左から右に変化するのに0.9秒かかる,と考えます.青が0の時に黄色の2に変わるときも,そこにも0.9秒かかってしまい,1回多くなります.正確には青が1の次の0.9秒後には黄色の2に変わると考えるべきなので,それぞれのメガネの左側は0ではなく1にすべきです.

それか,右側の6秒,2秒の数字を一つ減らした数にするというのでもよいです.

実は文字のプログラミングでも,0以上なのか0より大きいのか,といった判定で1つ多く(少なく)数えてしまうということが,よく出てきます.そして,とても間違えやすいです.間違えが潜んでいそうな場所です.

それでは次に,歩行者用の信号も作ってみましょう.歩行者用の信号機の難しい点は,黄色に相当する状態が絵じゃなくて点滅している,ということですね.

歩行者用信号の場合,青が付いている,赤が付いている,のほかに点滅を表すために,全部消えている,という絵を描く必要があります.ところが,信号機の内部状態としては青が付いているときと,点滅しているときに青が付いているのとは別物です.それを状態として区別しなければなりませんので,合計4つの絵を描きます.

2016-10-20_03h49_41

さて,先ほどは設定で一番遅い実行にしましたが,それだと信号機の点滅が遅すぎます.それで,一番早いうさぎの設定にします.

そうすると,信号機のカウントダウンが8くらいでは短すぎて,もっと大きな数が欲しくなります.先ほどの,10進法を使ったカウントダウンは長い時間が欲しい時に,その時間に比例した数の絵とメガネが必要になるため,考え方はわかりやすいですが,あまり便利ではありません.

そこで,2進法のカウンターを使います.

作り方は簡単で,1の生成器と,1+1→10の2つのメガネだけです.1の絵は重なっているのがわかりやすくするため,半透明の色を使います.0の絵は使いません.

2016-10-20_03h41_28

この2進法のカウンターを使った,車用の信号はこのようになります.

2016-10-20_04h01_33

先ほどと逆でカウンターの数が増えて行きます.左側には待つ数,右側には0(その待つ数を消す)になります.いま,桁を決めていないのですが,仮にこれが3桁目だとすると,青で4のとき黄色,黄色で2のとき赤,赤で6のとき青,に変わります.

信号機と1の生成器の位置関係はこのようにします.

2016-10-20_03h42_47

これで数がカウントアップされ,適当な数になったらその数を引いて次の絵に変わります.

さきほど,桁を指定していないといいましたが,生成器の位置を右にずらすことで,待つ数を2倍にできます.2進法のカウンターは考え方としては難しいですが,作るのは簡単ですし,こうやって簡単に2倍,4倍にできるのも便利です.

では,次に歩行者用信号を作ります.

まず,点滅している信号は

2016-10-20_04h01_09

のようにします.

あとは,車用の信号と同じように2進法でならべますが,黄色に相当する点滅が2種類の絵でつくられているため,どちらの絵でそのタイミングがきても良いように,それぞれの絵をメガネにしています.上の車用メガネと比べてみてください.

2016-10-20_04h01_21

車の信号と一緒に走らせてみます.車が青,歩行者が赤でスタートします.

2016-10-20_04h02_27

走らせてタイミングがずれないかどうか見ます.

先ほどと同じ0の問題があって,青の4の次が黄色の0となっているので,正確には青の時間が5,黄色が3,赤が7で,青と黄色の時間がちょっとだけ短いのですが,合計の周期が同じなのでずれが進行することはありません.

それと,2進法のカウンタは桁上がりでも1ステップ必要です.4桁目に1がくる(8のとき)のは3回桁上がりがあるので,3ステップ遅れます.つまり8かどうかの判定と4かどうかの判定は厳密には1ステップずれるはずです.

最終的に,縦横の交差点で,自動車用,歩行者用の信号を並べてみたのがこちらです.

2016-10-20_04h14_55

作品はこちら

とても忙しいですが,なんとか同期がとれて動いているようです.

押しボタンを押したら赤の時間を短くできる,という場合はどうしたらよいでしょうか.まず,先ほどのようにそれぞれの動きの周期を正確に一致させて,信号機ごとにカウンターを独立させる,というのはではダメそうです.

ボタンが押されるまでは,ずっと赤のまま.赤で一定以上の時間がたっていれば,ボタンを押してすぐに青に変わる.さっきも青になったばかりだったら,所定の時間を待つ.その辺の拡張は,次回にします.

シェアする

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

フォローする