前回まででいろいろ出来るようになったので、( ていうか F なので )
ここまでの内容で飛ばしたモノを、いくつか紹介します。
HSPで繰り返しといえば、ほぼ確実に使用するのはrepeat命令ですが、
C/C++、Javaなどの、製品も作れる本格的なプログラミング言語では、
主に別の繰り返しを使用します。
一番簡単なのは、whileです。
HSPでも使用できます。
// while を使ってみる // 単純な繰り返し i = 0 while ( i < 6 ) // repeat 6 と同じことをします mes " "+ i +" 回目の繰り返し。repeat と同じ効果です。" i ++ // i = i + 1 wend randomize question = rnd(100) pos 10, 200 : input number, 120, 25 // 条件付きの繰り返し while ( number != question ) wait 1 wend end
※答えはデバッグウィンドウで確認できます^^
while ( 条件 ) で、条件が成立する限り繰り返します。
指定回数の繰り返しを行うには、i のように、回数を数えておく変数が必要です。(カウンタ変数)
while の変化系として、do というモノもあります。while とほぼ同じです。
ただし、do の方は条件が成立するまで繰り返すので、条件が逆になります。
しかも、条件を書く位置が、始めではなく終端、untilの方です。( 後判定 )
さっきのサンプルをdo - untilに直すと、こんな感じです。
// do - until を使ってみる // 単純な繰り返し i = 0 do mes " "+ i +" 回目の繰り返し。repeat とほぼ同じ効果です。" i ++ // i = i + 1 until ( i > 5 ) // repeat 6 と同じようなことをします randomize question = rnd(100) pos 10, 200 : input number, 120, 25 // 条件付きの繰り返し do wait 1 until ( number == question ) end
条件に関係なく、最低でも一回は実行されます。この点、whileとは違います。
実行後、条件を見て、成立していなければ( 偽なら )もう一度繰り返します。
キー入力待ちループとして優秀です。
for文というものもあります。
これは、回数の繰り返しに特化した文です。
// for文 // 書式 ; for カウンタ変数, 初期値, 終値, 増分=1 ; /* スクリプト */ ; next // repeat的なループ for i, 0, 3 mes " "+ i +" 回目の繰り返し" next mes "抜けた直後の i は "+ i +" です。つまり終値と等しい。" mes // 減数ループ( 仮称 ) for i, 3, -1, -1 // i += 増分なので、i += -1 される mes " i = "+ i next // 仮の無限ループ? for bKeydA, 0, 1, 0 // i += 0 なので、絶対に終了しない getkey bKeydA, 'A' // [A] キーに反応 wait 1 next stop
なにげに getkey という新しい命令が登場しています。
stick同様キーボードの状態を調べる命令ですが、一度に一つしか調べられません。その代わり、すべてのキーに対応しています。
getkey 変数, 仮想キーコード
という書式です。仮想キーコードというのは、キーに割り当てられた定数( 整数値 )です。
ABCやタブスペースなどの文字を入力するキーは、ASCII文字コードと同じです。( 詳しくは↓ )
ASCII文字コードは、シングルクォーテーション( ' )で文字を括って、'X' のようにして簡単に取得できます。
暗記する必要はありません。
※キーコードとして使う場合は大文字アルファベットを使います。
※全角文字( 仮名や漢字 )は '' で取得できません。
※[Shift]や[Ctrl]などの特殊なキーは、「キーコードチェッカー」で調べてください。
+参照:getkey命令の F1 ヘルプ。これは便利。
キーが押されている場合は、変数に真が、
押されていなければ偽が代入されます。
とまぁ、ループの話をしていたことを忘れたかもしれませんが、戻ってきてください。
ここまでで、while、do、for の三種類のループ文を紹介しましたが、
勘のいい人なら思ったことでしょう。
「breakできないの?」、と。先に言ってしまうと、出来ます。
この話だけでやたら長いですが、最後におまけです。
while と wend、
do と until、
for と next、
の対応を間違えた場合や、これらの外に_breakがあったりすると、こんな感じのエラーが出ます。
※実行できませんでした
今回は for 文のどこかに異常があったようです。
がんばって探しましょう。
ラベルを扱う命令として、goto と gosub を紹介しましたが、実を言うともうちょっとあります。
あまり使わないかもしれませんが……。
randomize objmode 2 pos 10, 10 : input nCmdType, 120, 25 pos 10, 40 : button gosub "実行", *Execute stop *Execute if ( nCmdType < 0 || nCmdType > 5 ) { dialog "コマンドは 0 〜 5 にしてください。", 1, "Error" return } // nCmdType の数値によって分岐する on nCmdType gosub *Zero, *One, *Two, *Three, *Four, *Five return *Zero mes "ゼロってます" redraw return *One mes "何故1から始まらないのか疑問である。" return *Two logmes "2が選択されました" assert nCmdType == 2 return *Three color 255, 255, 255 : boxf : color return *Four color rnd(256), rnd(256), rnd(256) return *Five redraw 2 return
on命令です。書き方が特殊なので注意。
これは、p1 の数値によってジャンプ先が変更されます。
switchとジャンプ命令が合体したようなものですが、基本的にswitchの方が見やすいかと思います。
これと似たような名前に、onkeyなどの命令がありますが、それらは中級編で紹介します。
ただし、こんなことするくらいならラベル型の配列変数を使った方がいいです。
※サンプル略。
もう一つ、exgotoという命令もありますが、わかりにくい上に利用価値がないので、覚えるだけ時間の無駄です。
colorなどと同様、色を変更する命令には syscolor というモノもあります。
これは、Windows に設定されている色、システムカラーを使用するものです。
システムカラーは、ユーザーが独自に変更できます。( あまり変えている人はいませんが…… )
そのため、一覧は自分で作る必要があります。
// システムカラーを一覧にする #const HEIGHT_ONELINE (480 / 31) // 一行あたりの高さ font msgothic, 13 // システムカラーは31種類( たぶん ) repeat 31 py = cnt * HEIGHT_ONELINE // この行の y 座標 syscolor cnt boxf 30, py, 300, py + HEIGHT_ONELINE r = ginfo_r g = ginfo_g b = ginfo_b color pos 5, py : mes strf("%2d", cnt) // 行番号 pos 320, py : mes "RGB = ("+ strf("%3d, ", r) + strf("%3d, ", g) + strf("%3d", b) +")" loop stop
ツールっぽい画面の背景色に 15 を使いますが、それ以外はほぼ使いません。
strf() 関数は、文字列を書式化して返す関数です。
書式というのは、上の例では"%3d"などです。
%?? というのが書式で、この部分にもう一つのパラメータの値が入ります。
%d なら整数値、%f なら実数値、%x なら16進数の整数です。
% とアルファベットの間の数値は、桁数指定で、この数値より少ない桁なら前に空白が入ります。
例えば、strf("[%3d]", 34) なら、スペースが一つ入って "[ 34]" になります。
括弧でくくるときや、桁数をそろえたいときに便利です。
普通の % は、%% とします。フォーマット指定子(%??)と見分けるためです。
HSP3.2以降では、strf()はフォーマットを複数書けるようになっています。
世の中便利なモンですねぇ……。
// HSP3.2以降でしか動かない r = 17 g = 234 b = 25 mes strf("RGB = (%3d, %3d, %3d)", r, g, b) stop
ちなみに、strf()は string + format の略です。
C言語でおなじみ sprintf() のHSPバージョンですね。(謎)
ウィンドウは、screen命令以外でも作成できます。
その方法も紹介しておきましょう。
// 枠なしウィンドウを作成する #const wID_Main 0 *main gosub *Initialize gosub *SetWindow gsel wID_Main, 1 stop *Initialize randomize gsel 0, -1 return *SetWindow bgscr wID_Main, ginfo_dispx, ginfo_dispy, 2, 0, 0 button "終了", *OnBtn_End return *OnBtn_End end
bgscr命令です。
これで作成したウィンドウには、タイトルバーがありません。
「子ウィンドウ」というものを作成するときに使いますが、ほとんど必要はないでしょう。
もう一つあります。
// 低クオリティー・スタンプ #const IDW_MAIN 0 #const IDW_STAMP 1 *main gosub *init // Initialize (初期化) の略 gsel IDW_MAIN, 1 // メインループ *mainlp getkey bLClick, 1 // 左クリック (右利きの) // 左クリックされたとき if ( bLClick ) { pos mousex - 8, mousey - 8 gcopy IDW_STAMP, 0, 0, 32, 32 } await 64 goto *mainlp //######## サブルーチン群 ######## *init gsel 0, -1 gosub *SetWindow return *SetWindow buffer IDW_STAMP, 32, 32 repeat 16 hsvcolor (192 / 16) * cnt, 255, 255 boxf cnt, cnt, 32 - cnt, 32 - cnt loop return
※怒らないでね。
新しく出てきた命令を2つだけ紹介します。
まず一つ目は、bufferです。
これは、screen や bgscr に非常に似ていますが、
決定的な違いがあります。
ウィンドウではありません。
仮想ウィンドウといいます。今流行の「仮想」、ヴァーチャルです。
ウィンドウだと思って操作してもあまり問題ありませんが、ウィンドウではないので表示することはできません。
しかし、サンプルのように画像を保存するだけなら十分なので、結構便利です。
また、bufferをbgscrに変更すると、何が描画されているのか見れます。
……と、よく考えたらこれってレイアウト編だよな? という違和感がたっぷりですが、このままいきます。
続いて、gcopy です。
これは、graphics copy、画像をコピーする命令です。
ウィンドウ(または仮想ウィンドウ)の画像を、別のウィンドウ(または(略))にコピーします。
表示位置はカレントポジションからです。
詳しくは中級編で紹介する予定……です。たぶん。きっと。おそらく。
さて、以上を持ちまして初級編を終了させていただきます。
後半が初級っぽくなかったあたり申し訳ない気持ちで一杯です……。
では、中級編でまた会いましょう!
by 上大