HSP3 プログラミングの基礎W | |
「プログラミングの基礎W」では、プログラム作成で使えるような処理を命令や関数(サブルーチン)として考えていく。
(1) 日付と時間
例えば、ゲームのハイスコアや会員管理アプリケーションの会員登録日など、日付や時間とともに記録しなければならないケースが起こる。あるいは、制限時間内に何かをするというプログラムの場合にも時間が必要になる。
ここでは、現在の日付と時間についてプログラムを作成していく。
◎ 現在の日付
日付や時間を返却する関数である。日付に関するパラメータは次の通りである。
gettime(パラメータ)
0 西暦年 1 月 2 曜日(日=0, 月=1, 火=2, 水=3, 木,=4 金=5, 土=6 3 日
現在の日付を表示する。
sdim day, 2, 7 day = "日", "月", "火", "水", "木", "金", "土" date = "" + gettime(0) + "年" + gettime(1) + "月" + gettime(3) + "日" mes date + "(" + day(gettime(2)) + ")" stop
現在の西暦年、月、日、曜日が表示される。
◆ 日付取得関数(date_now)作成
次に、現在の日付(文字列)を返却する関数(モジュール)として作成する。
#module
#defcfunc date_now
;
;date_now()
; 返却値=str 現在日付(yyyy年mm月dd日(曜)形式の文字列)
;
sdim day, 1, 7
day = "日", "月", "火", "水", "木", "金", "土"
date = "" + gettime(0) + "年" + gettime(1) + "月" + gettime(3) + "日"
return date + "(" + day(gettime(2)) + ")"
#global
mes date_now()
stop
現在の西暦年、月、日、曜日が表示される。
日付を返却する関数として作成したので、「mes "今日は、" + date_now() + "です。"」のように使うこともできる。
曜日あり/なしを選択できるようにする。関数のパラメータとして、0は曜日なし、1は曜日ありとする。
#module #defcfunc date_now int flag ; ;date_now(flag) ; flag=0:曜日なし、1:曜日あり ; 返却値=str 現在日付(yyyy年mm月dd日(曜)形式の文字列) ; sdim day, 1, 7 day = "日", "月", "火", "水", "木", "金", "土" date = "" + gettime(0) + "年" + gettime(1) + "月" + gettime(3) + "日" if flag = 0 : return date return date + "(" + day(gettime(2)) + ")" #global mes date_now() ;mes date_now(0)と同じ stop
現在の西暦年、月、日が表示される。下から2行目を「mes date_now(1)」に変更すると曜日ありで表示される。
date_now関数で値(パラメータ)を受け取る変数が必要になる。パラメータは0か1だけなので、int(整数)型とし、変数flagで受け取るようにしている(2行目太字部分)。変数名は別のものでも良い。
◎ 別ファイルの読み込み
作成したdate_now関数を利用するとき、利用するプログラムに#module〜#globalの部分をコピーする必要がある。毎回、コピーする作業は面倒である。そこで、date_now関数のプログラムを別のプログラムファイルとして保存しておき、必要なプログラムに読み込むようにすることができる。
この命令が記述された位置にファイル名で指定したプログラムを読み込む。
#include ファイル名
別のファイルとして保存したdate_now関数を利用する。
#include "utility.hsp" ;この位置にファイルを読み込む
mes date_now()
stop
次の#module〜#globalの部分は別ファイルutility.hspとして、サンプルと同じフォルダに保存しておく。
#module
#defcfunc date_now int flag
;
;date_now(flag)
; flag=0:曜日なし、1:曜日あり
; 返却値=str 現在日付(yyyy年mm月dd日(曜)形式の文字列)
;
sdim day, 1, 7
day = "日", "月", "火", "水", "木", "金", "土"
date = "" + gettime(0) + "年" + gettime(1) + "月" + gettime(3) + "日"
if flag = 0 : return date
return date + "(" + day(gettime(2)) + ")"
#global
現在の西暦年、月、日、曜日が表示される。
◎ 現在の時間
日付や時間を返却する関数である。時間に関するパラメータは次の通りである。
gettime(パラメータ)
4 時 5 分 6 秒 7 ミリ秒
値を書式で指定した文字列に変換して返却する関数である。書式はC言語のprinfと同じだが、%d(整数)、%f(実数)、%x(16進数)、%c(文字コード)だけである。
strf (書式, 値)
現在の時間を表示する。
time = strf("%02d:", gettime(4)) + strf("%02d:", gettime(5)) + strf("%02d", gettime(6)) mes time stop
現在の時間が表示される。
strf命令(関数)の書式"%02d"は、値を2けたの整数にする指定である。02の0は指定したけた数に満たないときに0をつける指示である。したがって、0時〜9時までは00〜09という2けたになる。
◆ 時間取得関数(time_now)作成
次に、現在の時間(文字列)を返却する関数(モジュール)として作成する。
#module
#defcfunc time_now
;
;time_now()
; 返却値=str 現在時間(hh:mm:ss形式の文字列)
;
time = strf("%02d:", gettime(4)) + strf("%02d:", gettime(5)) + strf("%02d", gettime(6))
return time
#global
mes time_now()
stop
現在の時間が表示される。
デジタル時計を作成する。
繰り返しを利用して1秒間隔で表示するとデジタル時計になるが、mes命令では文字列表示後に改行してしまう。表示位置を指定するには、pos命令を使う。
#module #defcfunc time_now ; ;time_now() ; 返却値=str 現在時間(hh:mm:ss形式の文字列) ; time = strf("%02d:", gettime(4)) + strf("%02d:", gettime(5)) + strf("%02d", gettime(6)) return time #global repeat redraw 0 color 255, 255, 255 ;白色 boxf ;ウィンドウ全体(白色)塗りつぶし color 0, 0, 0 ;黒色 pos 0, 0 ;座標指定(0,0) mes time_now() ;現在時間表示 redraw 1 wait 100 ;1秒間ウェイト loop stop
デジタル時計のように現在の時間が表示される。
mes命令で表示した文字列のX方向(Y方向)のサイズが格納されるシステム変数である。
ginfo_mesx ginfo_mesy
boxf命令でウィンドウ全体を消去(白色塗りつぶし)しているが、時間表示の部分だけを消去するように変更する。
#module #defcfunc time_now ; ;time_now() ; 返却値=str 現在時間(hh:mm:ss形式の文字列) ; time = strf("%02d:", gettime(4)) + strf("%02d:", gettime(5)) + strf("%02d", gettime(6)) return time #global repeat redraw 0 color 200, 200, 200 ;薄い灰色 boxf 0, 0, ginfo_mesx, ginfo_mesy ;部分消去 color 0, 0, 0 pos 0, 0 mes time_now() redraw 1 wait 100 loop stop
時間の背景だけが薄いグレーになる。
白色ではわかりにくいので灰色で塗りつぶすようにしている。mes命令で表示した文字列のサイズがシステム変数ginfo_mesxとginfo_mesyに格納されているので、その値を使って時間を表示した部分だけを消去している。
※ time_now関数のプログラムをファイルutility.hspに追加しておく。
◆ 経過時間取得関数(time_sec)作成
時間の経過を計算する処理を作成する。処理の開始時間をnow1に、現在の時間をnow2に格納しておけば、now2-now1で経過時間が計算できる。例えば、now1=12:34:56、now2=13:26:54のとき、now2-now1は秒、分、時のそれぞれの部分にわけて計算する必要がある。
now1=12:34:56を午前0時からの経過秒数に変換すると12*60*60 + 34*60 + 56=45296秒となる。同じようにして、now2は48414秒となる。したがって、経過時間はnow2-now1=48414-45296=3118秒となる。時間を秒数に変換した方がいろいろな計算をするとき便利である。
変数の開始位置(先頭からの文字数)から文字数分の文字列を取り出して返却する関数である。開始位置は0から数える。開始位置に負数を指定すると変数の末尾からの指定になる。
strmid(変数, 開始位置, 文字数)
hh:mm:ss形式の時間文字列を午前0時からの経過秒数に変換する関数time_secを作成する。
#module #defcfunc time_now time = strf("%02d:", gettime(4)) + strf("%02d:", gettime(5)) + strf("%02d", gettime(6)) return time #defcfunc time_sec str jikan jj = jikan sec = int(strmid(jj, 0, 2)) * 3600 + int(strmid(jj, 3, 2)) * 60 + int(strmid(jj, -1, 2)) return sec #global now1 = time_now() mes "start = " + now1 ;開始時間表示 repeat redraw 0 color 255, 255, 255 boxf 0, 16 color 0, 0, 0 pos 0, 16 mes time_now() ;現在時間表示 mes time_sec(time_now()) - time_sec(now1) ;経過時間表示 redraw 1 wait 100 loop stop
開始時間、現在時間、経過秒数の順に表示される。
次のように、strmid命令(関数)で時間の文字列から時、分、秒の文字列を取り出している。取り出した値が文字列なので、int( )で整数に変換している。秒を取り出す関数はstrmid(jj, 6, 2)と書いても良い。
開始位置 0 1 2 3 4 5 6 7 変数の値 h h : m m : s s 関数 strmid(jj, 0, 2) strmid(jj, 3, 2) strmid(jj, -1, 2) 時間 分 秒
秒数をhh:mm:ss形式の時間文字列に変換する関数time_sec2を作成せよ。
2006 © Hiroshi Masuda |