×

[PR]この広告は3ヶ月以上更新がないため表示されています。
ホームページを更新後24時間以内に表示されなくなります。

カウントダウンタイマー


*ここに掲載している「カウントダウンタイマー」のソースコードを、以下にアップロードしています。ご自由にお使いください。
Microsoft Small Basic Program Listing(Program Listing : SSD540)

デジタル時計で「1秒ずつ更新するタイマーイベント」を使いましたので、応用としてカウントダウンタイマーを作ってみようと思います。
カウントしたい時間をテキストボックスに入力して、ボタンをクリックしたら1秒ずつカウントダウンし、0になったらタイマーを終了させる、というプログラムになりそうです。
一時停止ボタンも付けたいですね。
タイマーイベントをどう作るかが問題です。
入力した時間が1秒より大きければ、時間を1秒減らす。
入力した時間が0秒ならば、タイマーを停止。
というIf構文も使わなければならないでしょう。

……難しいことは後回しにして、外見を作ってみます。

GraphicsWindow.BackgroundColor = "AliceBlue"
GraphicsWindow.Title = "Timer"
GraphicsWindow.Width = 250
GraphicsWindow.Height = 50

byou = Controls.AddTextBox(60, 10)
hun =  Controls.AddTextBox(10, 10)
Controls.SetSize(byou, 40, 20)
Controls.SetSize(hun, 40, 20)
GraphicsWindow.DrawText(52, 10, ":")

botan = Controls.AddButton("|>", 115, 10)
Controls.ButtonClicked = OnClick

pause = Controls.AddButton("Pause", 160, 10)

これで、こんなのができました。

タイマー


「分」と「秒」を入力するためのテキストボックスと、カウントダウンをスタートさせるための「|>」ボタン、一時停止のための「Pause」ボタンです。
カウントダウンをスタートするためのサブルーチン名は「OnClick」、と、とりあえず決めてみました。
……ところでボタンが複数ある時って、どうやってボタンを指定すればいいんでしょ。
よくわからないので、知らないフリをして先に進みます。

次に、デジタル時計からそのまま、「1秒ずつ更新」の部分をコピペして「OnClick」を作ります。

Sub OnClick
  Timer.Interval = 1000
  Timer.Tick = countdownevent
EndSub

サブルーチン「countdownevent」で、テキストボックスから取得した分&秒を1秒減らすプログラムを書けば動きそうです。
また、0秒になったらプログラムを終了させることと、Pauseボタンを押したらタイマーイベントが一時停止する記述も必要になります。

まず、「テキストボックスから取得した分&秒を1秒減らす」の部分を考えましょう。
ややこしくなるので、まずは「分」がゼロ、「秒」だけテキストボックスに入力されている、と仮定しておきます。
たとえば「byouというテキストボックスに入力した時間」を「byoutime」としたら、

byoutime = Controls.GetTextBoxText(byou)
byoutime = byoutime - 1
Controls.SetTextBoxText(byou, byoutime)

1行目で、テキストボックスの数値を取得し「byoutime」という変数の名前にします。
2行目は数学としてはおかしいけど、プログラミング的には正しい表記の仕方です。
「byoutimeから1を引いた値を、新たなbyoutimeに設定する」という意味です。
3行目では、byoutimeを再びテキストボックス「byou」に書き込みます。
これはあくまでも、byoutimeが1より大きい時のみです。だから条件「byoutime > 0」ということになります。

「入力した時間」が「分」と「秒」のふたつだったらどうするか。
分けて色々計算するとややこしくなりそうです(実際にやったらめんどくさいことになりました……できるんだろうけど)。
ふたつを合わせて、秒に変換してカウントダウンしてみましょう。

byouhyouji = Controls.GetTextBoxText(byou)
hunhyouji = Controls.GetTextBoxText(hun)
totaltime = hunhyouji * 60 + byouhyouji
totaltime = totaltime - 1

ここでは、「hunhyouji * 60 + byouhyouji」で、分を秒に換算し、トータル何秒かを計算しました。
たとえば「4分12秒」だったら「4×60+12」で、totaltimeが「252」秒ですね。
上を実行したら、1を引いて「totaltime=251」ということになります。
しかし、この251秒を「○分×秒」の形式に直したい。
「totaltimeを60で割った商が○分、余りが×秒」のはずですから、以下のようにしてみましょう。

byouhyouji = Controls.GetTextBoxText(byou)
hunhyouji = Controls.GetTextBoxText(hun)
totaltime = hunhyouji * 60 + byouhyouji
totaltime = totaltime - 1
huntime = Math.Floor(totaltime / 60)
byoutime = Math.Remainder(totaltime, 60)
Controls.SetTextBoxText(byou, byoutime)
Controls.SetTextBoxText(hun, huntime)

Math.Floor」は、指定された値より小さいか等しい整数値を取得します。
Math.Remainder(A, B)」は、最初の値を2番目の値で割った余りを返します。
上を実行すれば、「4 : 11」と表示されるはずです。
以上が、条件「byoutime > 0」でのタイマーイベントになります。

  byouhyouji = Controls.GetTextBoxText(byou)
  hunhyouji = Controls.GetTextBoxText(hun)
  totaltime = hunhyouji * 60 + byouhyouji
If totaltime > 0 then
  totaltime = totaltime - 1
  huntime = Math.Floor(totaltime / 60)
  byoutime = Math.Remainder(totaltime, 60)
  Controls.SetTextBoxText(byou, byoutime)
  Controls.SetTextBoxText(hun, huntime)
EndIf

If構文を使うとこうですね。
totaltime = 0の時は簡単です。終了したことを表示するだけです。

If totaltime = 0 then
  Controls.SetTextBoxText(byou, 0)
  Controls.SetTextBoxText(hun, 0)
  Sound.PlayChime()
  Timer.Pause()
EndIf

このように表記して、タイマーをストップする、「Timer.Pause()」を追加して終了です。
上では終了時にチャイム音を鳴らす「Sound.PlayChime()」も入れてみました。
ぶっちゃけ、音を鳴らさないなら「Timer.Pause()」がなくてもプログラムは停止したように見えます。
しかし、チャイム音を鳴らす場合は「Timer.Pause()」を入れ忘れると、タイマーが動き続けてチャイム音連打状態となりますから注意。

最後に、「Pauseボタンを押したらタイマーイベントが一時停止する」動作ですが……
最後にクリックされたボタンを取得する「Controls.LastClickedButton」を使ってみました。

If Controls.LastClickedButton = pause then
  Timer.Pause()
EndIf

「最後にクリックされたボタンがpauseであったら、タイマーを一時停止」という文章です。

ということで、ひとまずこれで動くはず。

GraphicsWindow.BackgroundColor = "AliceBlue"
GraphicsWindow.Title = "Timer"
GraphicsWindow.Width = 250
GraphicsWindow.Height = 50

byou = Controls.AddTextBox(60, 10)
hun =  Controls.AddTextBox(10, 10)
Controls.SetSize(byou, 40, 20)
Controls.SetSize(hun, 40, 20)
GraphicsWindow.DrawText(52, 10, ":")

botan = Controls.AddButton("|>", 115, 10)
Controls.ButtonClicked = OnClick

pause = Controls.AddButton("Pause", 160, 10)

Sub OnClick
  Timer.Interval = 1000
  Timer.Tick = countdownevent
EndSub

Sub countdownevent
  byouhyouji = Controls.GetTextBoxText(byou)
  hunhyouji = Controls.GetTextBoxText(hun)
  totaltime = hunhyouji * 60 + byouhyouji
  If totaltime > 0 then
    totaltime = totaltime - 1
    huntime = Math.Floor(totaltime / 60)
    byoutime = Math.Remainder(totaltime, 60)
    Controls.SetTextBoxText(byou, byoutime)
    Controls.SetTextBoxText(hun, huntime)
  EndIf
  If totaltime = 0 then
    Controls.SetTextBoxText(byou, 0)
    Controls.SetTextBoxText(hun, 0)
    Sound.PlayChime()
    Timer.Pause()
  EndIf
  If Controls.LastClickedButton = pause then
    Timer.Pause()
  EndIf
EndSub

やったー動いた!
……となりましたが、ひとつ問題が起きました。
Pauseボタンを押すと、1秒カウントダウンしてから一時停止します。
「totaltime > 0」の条件を満たしてから一時停止しているようです。
一時停止の文章の場所を変更すれば良いのかな?

GraphicsWindow.BackgroundColor = "AliceBlue"
GraphicsWindow.Title = "Timer"
GraphicsWindow.Width = 250
GraphicsWindow.Height = 50

byou = Controls.AddTextBox(60, 10)
hun =  Controls.AddTextBox(10, 10)
Controls.SetSize(byou, 40, 20)
Controls.SetSize(hun, 40, 20)
GraphicsWindow.DrawText(52, 10, ":")

botan = Controls.AddButton("|>", 115, 10)
Controls.ButtonClicked = OnClick

pause = Controls.AddButton("Pause", 160, 10)

Sub OnClick
  Timer.Interval = 1000
  Timer.Tick = countdownevent
    If Controls.LastClickedButton = pause then
      Timer.Pause()
    EndIf
EndSub

Sub countdownevent
  byouhyouji = Controls.GetTextBoxText(byou)
  hunhyouji = Controls.GetTextBoxText(hun)
  totaltime = hunhyouji * 60 + byouhyouji
  If totaltime > 0 then
    totaltime = totaltime - 1
    huntime = Math.Floor(totaltime / 60)
    byoutime = Math.Remainder(totaltime, 60)
    Controls.SetTextBoxText(byou, byoutime)
    Controls.SetTextBoxText(hun, huntime)
  EndIf
  If totaltime = 0 then
    Controls.SetTextBoxText(byou, 0)
    Controls.SetTextBoxText(hun, 0)
    Sound.PlayChime()
    Timer.Pause()
  EndIf
EndSub

サブルーチン「OnClick」の中に移動してみたところ(太字部分)、上手く動くようになりました。
一時停止すると、きちんとタイマーが止まります。
ちなみにポーズ解除は「|>」ボタンになります。
ボタン一個で、カウントダウンスタート、一時停止、一時停止解除も出来るのかな?
……そういうのは他の言語でやった方が楽なのか。



●おまけ●

「ボタン一個で、カウントダウンスタート、一時停止、一時停止解除も出来るのか」について。
Small Basicでこれをやりたいのなら、ちょっとした工夫が必要です。

botan = Controls.AddButton("|>", 115, 10)
pause = Controls.AddButton("■", 115, 10)

こうすると、全く同じ場所に2つのボタンが表示されますね。
ですが、
「タイマー開始前と、タイマー終了後は『botan』ボタンを表示して『pause』ボタンを非表示」
「タイマー起動中は『botan』ボタンを非表示にして『pause』ボタンを表示」
という風にすれば、常にどちらかが表示されることになる上、位置が同じなのでボタンが1つに見えます。w

ボタンの表示、非表示は、

Controls.ShowControl(botan)……『botan』ボタンを表示
Controls.HideControl(botan)……『botan』ボタンを非表示

です。
ということで、一見、ボタンが1つに見えるタイマーは以下の通り。

GraphicsWindow.BackgroundColor = "AliceBlue"
GraphicsWindow.Title = "Timer"
GraphicsWindow.Width = 250
GraphicsWindow.Height = 50

byou = Controls.AddTextBox(60, 10)
hun =  Controls.AddTextBox(10, 10)
Controls.SetSize(byou, 40, 20)
Controls.SetSize(hun, 40, 20)
GraphicsWindow.DrawText(52, 10, ":")

botan = Controls.AddButton("|>", 115, 10)
pause = Controls.AddButton("■", 115, 10)
Controls.ButtonClicked = OnClick

Controls.HideControl(pause)

Sub OnClick
  Timer.Interval = 1000
  Timer.Tick = countdownevent
  If Controls.LastClickedButton = pause Then
    Controls.ShowControl(botan)
    Controls.HideControl(pause)
    Timer.Pause()
  EndIf
EndSub

Sub countdownevent
  byouhyouji = Controls.GetTextBoxText(byou)
  hunhyouji = Controls.GetTextBoxText(hun)
  totaltime = hunhyouji * 60 + byouhyouji
  If totaltime > 0 Then
    Controls.HideControl(botan)
    Controls.ShowControl(pause)
    totaltime = totaltime - 1
    huntime = Math.Floor(totaltime / 60)
    byoutime = Math.Remainder(totaltime, 60)
    Controls.SetTextBoxText(byou, byoutime)
    Controls.SetTextBoxText(hun, huntime)
  EndIf
  If totaltime = 0 Then
    Controls.HideControl(pause)
    Controls.ShowControl(botan)
    Controls.SetTextBoxText(byou, 0)
    Controls.SetTextBoxText(hun, 0)
    Sound.PlayChime()
    Timer.Pause()
  EndIf
EndSub

次:簡単ペイントツール


▲TOPへ戻る