〜 グラフィック 〜
セリフ毎に速度を変えて文章を表示

現在の歌詞箇所がわかりやすいように、予め表示させた歌詞を別の文字色に塗り替えていくというのを
カラオケ等でよく見かけますが、この現象を実現させてみましょう。
色変え処理自体は同じ位置に異なる色で再描画するだけと単純ですが、
最初から最後までのウェイトが一定間隔ではない場合、セリフと色変えタイミングの同期取りは難しいです。
そこで、ココではHSP2の「ワード毎のウェイト時間を設定するサンプル」と、
ココでは、HSP3の「文字毎のウェイト時間を設定するサンプル」を載せています。
内部で、一文字毎に処理する必要があるため、文字の判別モジュールwordchkを流用しています。
wordchk命令・関数についての説明は、コチラをご覧ください。
また、HSP2では、変数の要素数取得の為、モジュールgetdiminfoを使用しています。
getdiminfo命令・関数についての説明は、コチラをご覧ください。
等幅フォントの場合は、mes命令やprint命令の描画位置と重ねて表示可能ですが、
標準フォント等のプロポーショナルフォントだと、描画位置がズレてしまいますので注意が必要です。
サンプルのように、ウェイト時間を指定しない変数を指定し、timemes命令を実行すれば
通常のmes命令による表示同様に一括して表示させることができますので、
プロポーショナルフォントで重ねたい場合は、一旦全部を表示させた後に重ねて表示させるようにしましょう。
	

getdiminfo 変数, 次元
変数指定変数、指定次元のサイズがstatにセットされる。
次元1次元目を0として、取得する次元を0〜3のいずれかで指定する。

wordchk 対象変数, 位置
対象変数判別したい文字列の入った変数を指定する。
statに-1(範囲外)、0(半角)、1(全角)のいずれかがセットされる。
位置指定変数の位置をバイト単位で指定する。

timemes 対象変数, ウェイト情報
対象変数ウェイトを設けて表示する文字列型変数を指定する。
尚、内部でgetdiminfo命令、wordchk命令をtimemes命令より先に定義すること。
ウェイト情報 ウェイト時間(10ミリ秒単位)を設定した配列を指定する。
尚、指定は配列要素3つで1セットとする。(5ワード分指定したい場合は、3×5で要素数15)
要素1つ目:ワードの文字数
要素2つ目:ワード内の文字間ウェイト
要素3つ目:1つのワード終了時のウェイト

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#module
#deffunc getdiminfo val, int
	mref pval, 1024 : mref dnum, 1
	mref stt, 64
	stt = dnum + 2
	stt = pval.stt
	if (pval & $FFFF = 2) && (dnum = 0) : stt = stt * 4
	return

#deffunc wordchk val, int
	mref txt, 24 : mref ichi, 1
	mref stt, 64
	peek chk, txt, ichi
	if chk = 0 : stt = -1 : return
	if (chk > 128 & (chk < 160)) | (chk > 223) : stt = 1 : else : stt = 0
	return

#deffunc timemes val, val
	mref string, 24 : mref speed, 49
	mref bmscr, 67
	strlen len, string
	cx = csrx : cx.1 = cx : cy = csry
	getdiminfo speed, 0 : spnum = stat
	count = 0, 0
	repeat len
		wordchk string, cnt
		strmid tmps, string, cnt, stat + 1
		// 改行1バイト
		if stat = 0 & (chk = 13) {
			peek chk, string, cnt + 1
			cx = cx.1 : cy += bmscr.32 // 文字の高さ分増やす
			continue cnt + (chk = 10) + 1
		}
		pos cx, cy : mes tmps
		cx += bmscr.32 / (2 - stat) // 文字幅(高さ÷2)を取得しカレントポジションの変更
		memset tmps, , 4
		if count + 2 < spnum & (count.1 <= 0) {
			count.1 = speed.count
			count++
		}
		if count.1 > 0 {
			count.1--
			wait speed.count
			if count.1 <= 0 {
			  count++
			  wait speed.count
			  count++
			}
		}
		continue cnt + stat + 1
	loop
	pos cx.1, cy + bmscr.32
	return
#global

	sdim txt, 200
	txt = {"
			    ゆっくりテキストを表示させるテスト。
			    ワード単位に設定できるので、
			    文字単位よりウェイト設定数が少なくできますし、
			    設定の仕方によっては、文字単位も可能ですから、
			    柔軟に対応できるかもしれません。
			  "}
	dim dummy, 1
	dim time, 96
	time.0  = 4, 20, 20 // ゆっくり
	time.3  = 4,  5, 40 // テキスト
	time.6  = 1,  5, 20 // を
	time.9  = 5,  1, 20 // 表示させる
	time.12 = 3,  5, 40 // テスト
	time.15 = 1, 60, 99 // 。
	time.18 = 5,  1, 20 // ワード単位
	time.21 = 1,  5, 40 // に
	time.24 = 5,  1, 40 // 設定できる
	time.27 = 2,  5, 20 // ので
	time.30 = 1, 40, 20 // 、
	time.33 = 6,  1, 40 // 文字単位より
	time.36 = 1,  5, 20 // も
	time.39 = 7,  1, 40 // ウェイト設定数
	time.42 = 1,  5, 20 // が
	time.45 = 7,  1, 40 // 少なくできます
	time.48 = 2, 40, 20 // し、
	time.51 = 5,  1, 40 // 設定の仕方
	time.54 = 1,  5, 20 // に
	time.57 = 4,  5, 20 // よっては
	time.60 = 1, 40, 20 // 、
	time.63 = 4,  1, 20 // 文字単位
	time.66 = 1,  5, 20 // も
	time.69 = 2,  5, 20 // 可能
	time.72 = 4,  5, 20 // ですから
	time.75 = 1, 40, 20 // 、
	time.78 = 2,  5, 20 // 柔軟
	time.81 = 1,  5, 20 // に
	time.84 = 5,  1, 40 // 対応できる
	time.87 = 2,  5, 20 // かも
	time.90 = 5,  1, 40 // しれません
	time.93 = 1, 60, 99 // 。
	pos 50, 50 : timemes txt, dummy // 徐々にではなく、ウェイトを掛けず一括表示する
	color 255
	pos 50, 50 : timemes txt, time  // 文字毎にウェイトを掛けて、徐々に表示させる
	color
	mes "- 完 -"
	stop

結果 = wordchk(対象変数, 位置)
結果-1(範囲外)、0(半角)、1(全角)のいずれかがセットされる。
対象変数判別したい文字列の入った変数を指定する。
位置指定変数の位置をバイト単位で指定する。

timemes 対象変数, ウェイト情報
対象変数ウェイトを設けて表示する文字列型変数を指定する。
ウェイト情報 ウェイト時間(10ミリ秒単位)を設定した配列を指定する。
ウェイト情報の配列要素と表示する文字位置はそれぞれ対応しており、
例えば対象変数の3文字目は、配列要素の3番目である。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#module
#defcfunc wordchk var s, int ichi
	if ichi < 0 : return -1
	chk = peek(s, ichi)
	if (chk > 128 & chk < 160) | chk > 223 : return 1
	if chk = 0 : return -1 : else : return 0

#deffunc timemes var string, array speed, local cx, local cy, local tmps, local count, local bmscr
	mref bmscr, 67
	cx = ginfo_cx : cx.1 = cx : cy = ginfo_cy
	repeat strlen(string)
		tmps = strmid(string, cnt, wordchk(string, cnt) + 1)
		// 改行1バイト
		if wordchk(string, cnt) = 0 & chk = 13 {
			chk = peek(string, cnt + 1)
			cx = cx.1 : cy += bmscr.32 // 文字の高さ分増やす
			  continue cnt + (chk = 10) + 1
		}
		pos cx, cy : mes tmps
		cx += bmscr.32 / (2 - wordchk(string, cnt)) // 文字幅(高さ÷2)を取得しカレントポジションの変更
		memset tmps, , 4
		if count < length(speed) : wait speed.count
		count++
		continue cnt + wordchk(string, cnt) + 1
	loop
	pos cx.1, cy + bmscr.32
	return
#global

	sdim txt, 200
	txt = {"
			    ゆっくりテキストを表示させるテスト。
			    文字毎にウェイトを設定できるので、
			    細かな制御が出来るものの、
			    その都度、間を設定するのは面倒だし、
			    設定後の再編集(メンテ)もやりにくいことこの上ない・・・。
			  "}
	dim time, 95
	time.0  = 60, 20,  5, 20,  5,  5,  5,  5, 20,  5,  5,  5,  5, 10,  5,  5, 20, 60
	time.18 =  5,  5,  5, 20,  5,  5,  5,  5, 20,  5,  5,  5,  5,  5,  5, 20, 40
	time.35 =  5,  5,  5,  5,  5, 20,  5,  5,  5,  5,  5, 20, 40
	time.48 =  5,  5, 40, 40, 40, 20,  5,  5,  5,  5,  5,  5,  5,  5,  5, 20, 40
	time.66 =  5,  5,  5, 20,  5,  5, 20, 60,  0,  0, 20, 60, 20,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5,  5, 60, 60, 60, 60, 60
	pos 50, 50 : timemes txt, dummy // 徐々にではなく、ウェイトを掛けず一括表示する
	color 255
	pos 50, 50 : timemes txt, time  // 文字毎にウェイトを掛けて、徐々に表示させる
	color
	mes "- 完 -"