午前?午後?

晴れなら海水浴、雨なら水族館

さて、いよいよお待ちかねの「条件判断」です。何がお待ちかねなのかというと、「HPが0ならゲームオーバー」「フラグが立ってたら別の話へ」「鍵を持っていたらお宝ゲット」「自機に弾が当たったらダメージ」など、「~なら~する」というものすべてがこれで実現できるからです。

こんな便利なものなのに、新しく必要な命令は、ifelseのたったの二つだけです。簡単にはこんな感じです。

	if (天気が良い){
		ビーチへ海水浴に行く
	} else {
		水族館へ行く
	}
	

つまるところ、ifの直後に条件を書き、条件に当てはまっている場合はその行の「{」から「}」までを実行し、条件に当てはまらない場合は「}」と同じ行のelseの後にある「{」から「}」までが実行されます。

実際は条件の部分には「条件式」という数式しか書くことが出来ません。条件式は以下の6種類があります。

また、以下の記号を使う事で、もっと複雑な条件を表すことも可能です。

例えば「耐久値が0かつ残機が0ならゲームオーバー」とか「疲れているか予定があるなら誘いを断る」などです。

……とまあ、やっぱり言葉で説明するよりソースコードを見た方がシンプルで解り易いので、完成品を見てしまいましょう。

	;ウインドウの準備
	title "デジタル時計"
	width 24/2*12,24
	font msgothic,24,16

*main

	;★午前、午後の表示を調節する
	hor=gettime(4)
	if hor<12 { time="AM" } else { time="PM" }
	if hor>12 { hor-=12 }
	time+=strf(" %02d:%02d:%02d",hor,gettime(5),gettime(6))

	;時刻を更新
	redraw 0
	color 0,0,0
	boxf 0,0,319,24
	color 255,255,255
	pos 0,0
	mes time
	redraw 1

	;繰り返し
	await 1000 ;★
	goto *main
	

AM、PMが表示されます

コメントを大部分削除して、見やすいようにまとめました。重要部分だけ抜き出します。

	;★午前、午後の表示を調節する
	hor=gettime(4)
	if hor<12 { time="AM" } else { time="PM" }
	if hor>12 { hor-=12 }
	time+=strf(" %02d:%02d:%02d",hor,gettime(5),gettime(6))
	

まず時刻の時の部分を代入したhorを12と比較して、12より小さい時は午前中としています。つまり、早朝0時から昼前11時までは午前中、それ以降を午後として処理します。次に、12よりも大きい数字、13時などは見栄えが悪いので、12を引いています。お昼の12時はPM、深夜であり早朝である夜中の24時、つまり0時はAMで処理しています。

今回はやることが変数の代入しかなかったので1行にまとめていますが、複数行にまたがって複数の命令を書いても全く問題ありません。また、if{}の中にまたifがあってもOKです。

重要な部分はここだけですが、あとの細かい部分も見て行きます。

文字列型変数、strf関数、await命令

そういえば今回は文字列型変数が新出でした。文字列型変数は数値型変数同様、文字列を代入できる変数です。また、文字をそこに足し合わせる、という意味で、+=も使用できます。ただし、文字列には足し算以外の計算は行えません。

それから、今回は新しい関数が登場しています。デジタル時計は、大抵2時3分などの時間でも「02:03」と表示されます。「2:3」だとちょっと格好悪いです。桁数を一定にして、足りない桁を0で補うための関数がstrfです。この関数は色々な書き方が出来るので詳細はF1で表示されるヘルプに譲りますが、今回のように%02dと書くと、パラメータの値を2桁の10進数として表示し、足りない桁を0で埋めます。もし、単に%を表示したいときは%%と書けばOKです。

そして今回、なぜかwait命令がawaitという別の命令に変更されています。こちらは1/1000=0.001(千分の1秒=1ミリ秒)単位で待ち時間を指定します。その理由を説明しましょう。

実はデバッグ中、しばらく眺めていた時、衝撃的な事件が起きました。30秒から急に32秒になってしまったのです。31秒が表示されなかったのです。いったい何が起きたのかと頭を抱えていたら、実は当然の事でした。というのも、画面を描書き換えたりする処理もあるのですから、1ループの時間は1秒のwait+処理時間になっています。つまり1秒よりほんのちょっとだけ長いのです。ほんのちょっとですが、それがずっと続けばいつかは1秒分飛ばしてしまうような出来事も発生するのです。まあほとんどの場合は気付きませんが…。

今回はたまたま気付いてしまって気になったので変更する事にしました。awaitの第一パラメータは、厳密には「前回awaitなど実行したときの時間から計って何ミリ秒待つか」を数値で指定します。これをループの中に置いておくと結局どうなるのかというと、「1ループの時間指定された時間とが同じになる」のです。今回の時計の例で言えば、1ループの時間が厳密に毎回1秒になり、ずれが発生しなくなります。

これはシューティングゲームなどでは非常に便利な機能です。敵数が増えるたびに遅くなるのでは、ゲームをプレイしている側からすると「重い」という感じになってしまします。でもawaitなら、敵の数や玉の数が変わっても同じ速さで動きますから、重くなったと感じることは無くなります。

さて、これで大体時計としての機能は完成しました。しかし、見た目がただの文字ではなんだかつまらないです。そこで、もっとデジタル度計っぽくするために、画像を使って時刻を表示してみましょう。

コラム:パラメータの省略

さてここで、redrawにカーソルを合わせて、キーボードのF1を押し、redraw命令のヘルプを表示してみてください。驚くべきことにパラメータが5つもあることになっています。どうも第2パラメータから第5パラメータでを使ってウインドウのどの部分の描画を停止、反映するのかを指定しなければいけないようです。

しかし、書かなくても問題なく動作します。これは、描かないと自動的にウインドウ全体が範囲に指定される(第2,3パラメータに0,0、第4パラメータにウインドウの幅、第5パラメータに高さ)仕組みになっているからです。パラメータを一部描かない事を「パラメータの省略」といいます。

パラメータには省略できるものとできないものがあるので注意してください。また、省略すると入力の手間が省けて楽ちんな上に解り易くていいことづくめのようにも見えますが、やりすぎると逆にわかりにくくなってしまう事もあるので注意してください。

目次へ戻る