デジタル時計


・プログラムが簡単そう
・実用的

このふたつを満たすものといったら、デジタル時計でしょう。
Windowsパソコンを使っているのなら、たいてい、パソコン画面の右下に時計が表示されていますが、これはパソコン内部のごちゃごちゃしたシステム内に「時計」があり、それを画面右下で見せてくれているのです。 (「パソコン内部のごちゃごちゃしたシステム」については、専門的な話になると思われますので、ここでの説明は省きます……w)
同じように、パソコンの中の「時計」から時間を取得して表示すればいいんだろうなと、だいたい想像ができます。

しかもSmall Basicの場合は、Clockという便利な定型文があります。

Clock.Time

これでパソコン上の時計の時間を取得してくれます。
(もちろん、パソコンの時計がズレている場合はズレた時間を取得することになりますが)

ただし、取得しただけでは何の意味もないので、

GraphicsWindow.DrawText(0, 0, Clock.Time)

こういう風にすると、プログラムとして機能します。
「GraphicsWindow.DrawText」という文章のお約束として、「GraphicsWindow.DrawText(数字その1, 数字その2, 命令)」という風に入力しなければならないのですが……その説明は後にして、上の文章を記述して「実行」してみましょう。

時計1

ウィンドウを開き、座標(0,0)に時間を表示してくれました。
つまり、「命令」で書いたことを文章として描いてくれるプログラムだったのです。
数字その1は「表示する場所のx座標」で、数字その2は「表示する場所のy座標」でした。

さて、このプログラムの駄目な点は……

(1) ウィンドウがでかすぎる(ウィンドウサイズを指定しなかったから)
(2) プログラムを実行した瞬間の時間しか表示してくれない(本物のデジタル時計のように機能しない)

他にもありますが、致命的だなというのはこのふたつ。

(1)については、

GraphicsWindow.Width = 200
GraphicsWindow.Height = 30

例えばこれを書き足せば、幅200ピクセル、高さ30ピクセルのウィンドウを表示してくれます。
時間しか表示しないのなら、このサイズでも充分です。
(あまりにも幅が狭いと、自動的に幅が広げられてしまいます。最低でも200ピクセルくらいがお勧めです)

(2)は、「このプログラムを1秒ごとに更新する」ことで解決しそうです。
この時計は秒まで表示するので、1秒ごとに更新すれば、毎秒進むデジタル時計が再現できそうです。

これにはTimerオブジェクトを使います。

Timer.Interval = 1000
Timer.Tick = (実行したいイベント)

Timer.Interval = 1000」は、1000ミリ秒に1回、Timer.Tickで定めたイベントを実行するという意味です。
1000ミリ秒=1秒です。
ただし、

Timer.Interval = 1000
Timer.Tick = GraphicsWindow.DrawText(0, 0, Clock.Time)

こう書いても実行できません。「Timer.Tick = GraphicsWindow.DrawText(0, 0, Clock.Time)」の部分で、エラーが出ます。
Sub(サブルーチン)を使って、イベントを作り、そのイベントを実行、という手順が必要のようです。
サブルーチンというのは「プログラム内の一部の作業に名前を付けてまとめたもの」と思ってくださればOKです。
サブルーチンの書き方は、

Sub サブルーチンの名前
  サブルーチンで行う作業
EndSub

となります。
「サブルーチンの名前」は、自分で自由に決められますが、わかりやすいものにするのをお勧めします。
(下の文章はコピーして貼り付けするなどせずに、Small Basicでちゃんと文章を打ちましょう。すると、サブルーチンの中では勝手に文章の頭に空白が付きます。ここはサブルーチンの文章です、とわかりやすくしてくれているのです)

GraphicsWindow.Width = 200
GraphicsWindow.Height = 30
Timer.Interval = 1000
Timer.Tick = OnTick
Sub OnTick
  GraphicsWindow.DrawText(0, 0, Clock.Time)
EndSub

上では「OnTick」という名前のサブルーチンをTimer.Tickで実行します、と書いた後に、Sub以下でサブルーチン「OnTick」は「GraphicsWindow.DrawText(0, 0, Clock.Time)」です、と記述しました。
これなら実行できます。できますが……

時計2

文字が重なってしまいました。
どんどん上書きしているような感じになっているんですね。
これを解決するには、タイマーを実行する前に、前に書かれた文字を消去するようなプログラムを入れれば良いのでしょう。
方法として、

GraphicsWindow.Clear()

これを実行するとウィンドウの内容が全て消えます。
時計だけを表示しているなら、これを

Sub OnTick
  GraphicsWindow.Clear()
  GraphicsWindow.DrawText(0, 0, Clock.Time)
EndSub

こんな感じで、時計を書く前に入れれば良いのですが、この時計に日付や曜日など他のものも表示したいとか、枠線などで飾りを入れたい……という場合、それらも全部消えてしまうので、時計部分だけを消すのなら……

GraphicsWindow.BrushColor = "white"
GraphicsWindow.FillRectangle(0, 0, 55, 20)
GraphicsWindow.BrushColor = "black"

「ブラシに背景色(白色)を選んだ後に、時計が描かれている部分に、55×20ピクセルの白色の四角形を描いて時計を塗りつぶし消す」
というプログラムです。
最後に「GraphicsWindow.PenColor = "black"」で、ブラシの色を黒などに変更しないと、時計が白い色で表示されることになってしまう(つまり、何も表示されなくなる)ので注意。

Sub OnTick
  GraphicsWindow.BrushColor = "white"
  GraphicsWindow.FillRectangle(0, 0, 55, 20)
  GraphicsWindow.BrushColor = "black"
  GraphicsWindow.DrawText(0, 0, Clock.Time)
EndSub

「白く塗りつぶして前の文字を消す」なんていうのは、なんかゴリ押しな気もしますが、これでもOKなはず。

ということで、とりあえず、デジタル時計が完成しました。

GraphicsWindow.Width = 200
GraphicsWindow.Height = 30
Timer.Interval = 1000
Timer.Tick = OnTick
Sub OnTick
  GraphicsWindow.BrushColor = "white"
  GraphicsWindow.FillRectangle(0, 0, 55, 20)
  GraphicsWindow.BrushColor = "black"
  GraphicsWindow.DrawText(0, 0, Clock.Time)
EndSub

これを実行すると時計としては機能しますが、見た目はイマイチです。

時計3

文字の位置やサイズ、色を変える、日付なども加えてみる……と、ここからは趣味で色々変更してください。
以下は私が作ってみた一例。

tokeihaikei = "CornflowerBlue"
GraphicsWindow.BackgroundColor = tokeihaikei
GraphicsWindow.Title = "clock"
GraphicsWindow.Width = 300
GraphicsWindow.Height = 100
GraphicsWindow.PenColor = "white"
GraphicsWindow.DrawRectangle(5, 5, 290, 80)
GraphicsWindow.FontSize = "20"
GraphicsWindow.BrushColor = "white"
GraphicsWindow.DrawText(10, 10, Clock.Date)
GraphicsWindow.FontSize = "12"
GraphicsWindow.DrawText(10, 55, Clock.Weekday)

Timer.Interval = 1000
Timer.Tick = OnTick
Sub OnTick
  GraphicsWindow.BrushColor = tokeihaikei
  GraphicsWindow.FillRectangle(10, 40, 90, 13)
  GraphicsWindow.BrushColor = "white"
  GraphicsWindow.DrawText(10, 40, Clock.Time)
EndSub

時計4

ポイントを幾つか。

ウィンドウタイトルの追加

GraphicsWindow.Title = "clock"

で、ウィンドウタイトルに「clock」と表示されます。タイトルは""で囲うことを忘れないように。

日付と曜日を追加

GraphicsWindow.DrawText(10, 10, Clock.Date) で月日、
GraphicsWindow.DrawText(10, 55, Clock.Weekday) で曜日を表示しています。
GraphicsWindow.FontSizeで文字サイズの変更も行っています。

背景色

一行目の「tokeihaikei = "CornflowerBlue"」は、tokeihaikeiという変数にCornflowerBlueという色を設定しました、ということです。
そして二行目は「GraphicsWindow.BackgroundColor = tokeihaikei」で、背景色を決定しています。
なぜこうしたのかというと、うっかりミスをなくす為と、わかりやすさを重視したからです。

この例でもタイマーで、背景色塗りつぶし→時間を描画、としていますが、背景色=塗りつぶしの色ですね。
GraphicsWindow.BackgroundColorの色指定と、タイマー内のGraphicsWindow.BrushColorの色指定は同じ色でなければなりません。
もし、ある日突然気分が変わって、背景色を赤にしたくなったら、このふたつの色をredに変更することになりますが、
一行目で色を決めているので、「tokeihaikei = "Red"」と変更すればそれで修正終了となります。
この方がわかりやすいでしょう。



他にできそうなことは「毎時0分になったらチャイム音を鳴らす」なんてのもありますね。
これは「If...Then...」という構文を使えばできそうです。

If (条件) Then
(条件で実行すること)
Endif

ここでなら

If (分の値が0、かつ、秒の値が0) Then
(チャイム音を鳴らす)
Endif

です。秒の値も0にしないと、0分0秒から0分59秒までずっとチャイム音が鳴ってしまいます。

If Clock.Minute = 0 And Clock.Second = 0 Then
  Sound.PlayChime()
Endif

「Clock.Minute」で時計の分を取得、「Clock.Second」で時計の秒を取得します。
そして、Andを使い「Clock.Minute = 0 かつ Clock.Second = 0 」、それが0なら「Sound.PlayChime()」を実行、というプログラムです。
これを、タイマーイベントの中に記述します。

Timer.Tick = OnTick
Sub OnTick
  GraphicsWindow.BrushColor = tokeihaikei
  GraphicsWindow.FillRectangle(10, 40, 90, 13)
  GraphicsWindow.BrushColor = "white"
  GraphicsWindow.DrawText(10, 40, Clock.Time)
  If Clock.Minute = 0 And Clock.Second = 0 Then
    Sound.PlayChime()
  Endif
EndSub

これで、毎時0分になるとチャイム音が鳴るようになります。

次:デジタル時計・応用編


▲TOPへ戻る