高度なグラフィクス操作
この章では、HSP3から追加された、少し高度な描画処理を行う命令を紹介します。
まずは、ウィンドウ内スクロールを行う上で役に立つ描画基点を変更する命令から。
groll X座標, Y座標
X座標基点とするX座標を指定する。
Y座標基点とするY座標を指定する。
GraphicsROLLを元にしたgroll命令は、表示ウィンドウよりも大きな画像を表示する際に利用するもので、 gcopy命令やgzoom命令のコピー元座標パラメータを変更させてスクロールさせるやり方と似てますが、 コピーを行うわけではないので、スクロールさせる為にコピー元画像をバッファで用意する作業は必要はなく、 また、ginfo命令、ginfo_vxマクロ、ginfo_vyマクロでスクロール取得することが可能となっているので、 gcopy命令等のコピーのように現在どれだけスクロールさせたかのスクロール量を保持する必要もありません。 ただし、スクロールさせられるのはウィンドウ内の描画内容だけであり、 配置したオブジェクトの位置はgroll命令でスクロールさせて位置変更することはできません。
 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
	// スクロール用の描画データを作成
	screen 0, 1200, 900, , , , 400, 300
	redraw 0
	x = 0, 0 : y = -1, 0
	repeat ginfo_sx + ginfo_sy
		hsvcolor cnt / 3, 255 - cnt / 192 * 20, cnt / 20 + 150
		x = x.0 + (cnt <  ginfo_sx), x.1 + (cnt >= ginfo_sy)
		y = y.0 + (cnt >= ginfo_sx), y.1 + (cnt <  ginfo_sy)
		line x, y, x.1, y.1
	loop
	color
	repeat 100
		pos cnt \ 6 * 200 + 50, cnt / 6 * 150 + 30 + (cnt \ 2 * 80) : mes "スクロールしてね"
	loop
	redraw 1
	// ドラッグ&ドロップ受付開始
	repeat
		p = mousex + ginfo_vx, mousey + ginfo_vy
		wait 1
		stick k, 256
		if k & 256 {
			groll p.0 - mousex, p.1 - mousey
			title "" + ginfo_vx + ", " + ginfo_vy
		}
	loop
続いて紹介する命令は、boxf命令のように矩形を任意の単色で塗りつぶす命令ですが、 ラジアン単位の任意の角度分だけ回転させることができるようになっています。 ラジアンについての簡単な説明は35章で説明しているので改めては説明しません。
grect X座標, Y座標, 角度, 横幅, 高さ
X座標矩形の中心X座標を指定する。
Y座標矩形の中心Y座標を指定する。
角度ラジアンを単位とする回転角度を指定する。
横幅矩形の横幅を指定する。
高さ矩形の高さを指定する。
GraphicsRECTangleを意味するgrect命令はboxf命令のように基点は左上座標ではなく矩形の中心座標なので、 左端座標は横長の矩形において、度数法における0度・180度の時に最小で、「X座標−(横幅÷2)」、 右端もまた0度・180度の時に最大となり、位置は「X座標+(横幅÷2)」です。 上端・下端の縦位置も同じ考えでいけますね。 その他の半透明や色加算・減算等のコピーモード、省略時のコピーサイズは通常のboxf命令と同じく gmode命令の設定が適用されるようになっています。 下記のサンプルでは、背景のドラッグ&ドロップによりスクロールさせることができますが、 grect命令による回転物をリアルタイムで表示して背景も再描画する必要があるために 先ほどのサンプルと似てはいるもののgroll命令でスクロールしていません。
 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
	buffer 1, 1600, 1200
	s = 100
	x = ginfo_winx / s : y = ginfo_winy / s
	repeat x * y
		color cnt \ x * (256 / x), 200 - cnt / x * (256 / x)
		boxf cnt \ x * s, cnt / x * s, (cnt \ x + 1) * s, (cnt / x + 1) * s
	loop
	gsel 0
	osize = 200, 200			// 物体サイズ
	opos  = ginfo_winx / 2, ginfo_winy / 2	// X位置, Y位置
	orad  = 0				// 回転角度
	omove = 5, 5 				// X移動量, Y移動量
	gosub *draw
	repeat
		p = mousex + vx, mousey + vy
		wait 2
		stick k, 256
		if (k & 256) ! 0 & (p.0 ! mousex + vx | p.1 ! mousey + vy) {
			vx = limit(p.0 - mousex, 0, 1600 - ginfo_winx)
			vy = limit(p.1 - mousey, 0, 1200 - ginfo_winy)
		}
		gosub *draw
	loop

*draw
	title "" + vx + ", " + vy
	redraw 0
	pos 0, 0 : gcopy 1, vx, vy, ginfo_winx, ginfo_winy
	grect opos.0 - vx, opos.1 - vy, 3.14 * orad / 180, osize.0, osize.1 // 回転させた矩形を描画
	redraw 1
	if omove.0 < 0 & opos.0 - vx + omove.0 - osize.0 / 2 < 0 : omove.0 = 5
	if omove.0 > 0 & opos.0 - vx + omove.0 + osize.0 / 2 > ginfo_winx : omove.0 = -5
	if omove.1 < 0 & opos.1 - vy + omove.1 - osize.1 / 2 < 0 : omove.1 = 5
	if omove.1 > 0 & opos.1 - vy + omove.1 + osize.1 / 2 > ginfo_winy : omove.1 = -5
	opos = opos.0 + omove.0, opos.1 + omove.1
	orad += 3
	return
お次はgcopy命令・gzoom命令に回転機能が加わった命令です。
grotate ウィンドウID, X座標, Y座標, 角度, 横幅, 高さ
ウィンドウIDコピー元画像が格納されたウィンドウIDを指定する。
X座標コピー元の基点となる左端座標を指定する。
Y座標コピー元の基点となる上端座標を指定する。
角度ラジアンを単位とする回転角度を指定する。
横幅gmode命令の横幅を指定サイズに変倍する。省略時に等倍コピー。
高さgmode命令の高さを指定サイズに変倍する。省略時に等倍コピー。
GraphicsROTATEを意味するgrotate命令の第5、第6パラメータの横幅と高さは、 コピー元データの横幅・高さではなく、gmode命令で指定したサイズから伸縮させたサイズとなります。 つまり、予めgmode命令で縦横共にサイズ100が指定されている場合、 grotate命令の横幅に200、高さに150を指定すると、 コピー元X座標から100ドット分を200に、コピー元Y座標から100ドット分を150に伸ばすのです。 コピーサイズが横幅200、高さ150であったとしても grotate命令の第5、第6パラメータに200、150と指定しないよう気をつけてください。 尚、gmode命令によるサイズやコピーモード情報が利用されるわけですが、 HSP3から追加されたモード7(ピクセルアルファブレンドコピー)には対応していません。 その他の半透明や色加算・減算コピーには対応しています。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
	buffer 1
	picload "sample/demo/sky_bg.jpg"
	win.0 = ginfo_winx, ginfo_winy
	buffer 2
	picload "sample/demo/logop.bmp"
	win.2 = ginfo_winx, ginfo_winy
	gsel 0
	gmode 2, win.2, win.3 // 黒色(0,0,0)を透過させてコピーサイズを回転体に指定する
	repeat
		rad = 3.14 * cnt / 180
		redraw 0
		pos 0, 0 : gcopy 1, , , win.0, win.1
		pos win.0 / 2, win.1 / 2 : grotate 2, , , rad // ウィンドウ中央に等倍コピー
		redraw 1
		wait 1
	loop
次に紹介するのは、ニン○ンドーDSiのライブカメラのように引っ張る機能の命令です。
gsquare ウィンドウID, 貼付先X情報, 貼付先Y情報, コピー元X情報, コピー元Y情報
ウィンドウIDコピー元画像が格納されたウィンドウIDを指定する。
貼付先X情報貼付先4座標を配列変数(0:左上X 1:右上X 2:右下X 3:左下X)に格納して指定する。
貼付先Y情報貼付先4座標を配列変数(0:左上Y 1:右上Y 2:右下Y 3:左下Y)に格納して指定する。
コピー元X情報コピー元4座標を配列変数(0:左上X 1:右上X 2:右下X 3:左下X)に格納して指定する。
コピー元Y情報コピー元4座標を配列変数(0:左上Y 1:右上Y 2:右下Y 3:左下Y)に格納して指定する。
gsquare命令はGraphicsSQUAREの名前通り、左上・右上・右下・左下の4点からなる矩形を操作するもので、 画像内にある任意の点を基準に引っ張るものではないために少々期待してるものと異なるかもしれませんが、 複数組み合わせることでクリックした点等のある一点を基準に伸縮させることも可能でしょう。 命令の使い方ですが、第2〜5パラメータは4要素を持つ数値型配列変数を指定する形となっており、 0番目に左上座標、1番目に右上座標、2番目に右下座標、3番目に左下座標情報を格納します。 2番目に左下、3番目に右下座標を指定する方が扱いやすかったのに、 何故か左上から時計回りに指定する形となっているためにプログラムで一括指定がしにくくなっています。 愚痴はさておき、画像の伸縮以外に、第1パラメータのウィンドウIDにマイナス値を指定することで フルカラーモードではカレントカラー、パレットモードではパレットコードカラーで塗り潰すこともできます。 画像コピーではなく、塗り潰しを行う場合は第3、4のコピー元座標情報を指定する必要はありません。 現時点のヘルプには「p1で指定した値−1がパレットコード」と書かれていますが、 p1はマイナスなので、使用されるパレットコードは「(p1+1)×−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
	buffer 1
	picload "sample/hspdx/testchr.bmp"
	gsel 0
	zoom = 4
	gpos = 200, 100
	cx = 256, 320, 320, 256
	cy = 64, 64, 128, 128
	px = gpos.0, zoom * (cx.1 - cx.0) + gpos.0, zoom * (cx.1 - cx.0) + gpos.0, gpos.0
	py = gpos.1, gpos.1, zoom * (cy.2 - cy.0) + gpos.1, zoom * (cy.2 - cy.0) + gpos.1
	gosub *draw
	repeat
		p = mousex, mousey
		wait 1
		stick k, 256
		if (k & 256) ! 0 {
			x = (zoom * (cx.1 - cx.0) / 2 + gpos.0 < mousex)   // 画像中心より右側か
			y = (zoom * (cy.2 - cy.0) / 2 + gpos.1 < mousey)   // 画像中心より下側か
			no = x + y * 2 + (x = 0 & y ! 0) - (x ! 0 & y ! 0) // 左上:0 右上:1 右下:2 左下:3
			px.no += mousex - p.0
			py.no += mousey - p.1
			gosub *draw
		}
	loop

*draw
	redraw 0
	color 255, 255, 255 : boxf
	gsquare 1, px, py, cx, cy // 伸縮させた画像を貼り付ける
	redraw 1
	return
最後に紹介するのは、Tipsで紹介しているような矩形をグラデーションで塗り潰す命令について。
gradf 左上X, 左上Y, 横幅, 縦幅, モード, 開始色, 終了色
左上X矩形左上のX座標を指定する。
左上Y矩形左上のY座標を指定する。
横幅塗り潰す横幅サイズを指定する。
縦幅塗り潰す縦幅サイズを指定する。
モードグラデーションする方向(0:横, 1:縦)を指定する。
開始色矩形左上の色をRGBカラーコードで指定する。
終了色矩形右下の色をRGBカラーコードで指定する。
HSP3.2で追加されたgradf命令は、パラメータ1と2の座標から、 パラメータ3と4のサイズ分をパラメータ5で指定したグラデーション方向で、 パラメータ6の色からパラメータ7の色で終わるように徐々に色を変えながら塗り潰します。 パラメータ1と2を省略するとウィンドウ左上(0,0)を指定したことになります。 パラメータ3と4はヘルプに矩形の右下座標と書いていますが、 座標ではなく、gcopy命令同様のサイズ指定となっていることを確認しました。 省略するとサイズ(0,0)ではなく、(ウィンドウ幅−左上基点X座標,ウィンドウ高さ−左上基点Y座標)です。 Tipsでは斜め方向のグラデーションにも対応させていましたが、 gradf命令は縦または横方向のどちらかのみしか対応してません。 省略すると0…即ち、縦縞となる横方向のグラデーションになります。 パラメータ5と6はRGBを1つにまとめたRGBカラーコードで指定しますので、 例えば紫(255,0,255)を指定する場合、通常の色輝度同様に0〜255の範囲で10進数指定すると、 「(255 << 16) + (0 << 8) + 255」のように面倒な書き方となりますが、 数値の頭に$または0xを付けた16進数で指定すると、 「$ff00ff」や「0xFF00FF」のようにスッキリとしていてわかりやすいのでコチラで書くほうが良いでしょう。 尚、省略するとカレントカラーを指定したことになります。 開始色と終了色が一緒の場合はboxf命令で塗り潰す方が高速ですので、 単色塗り潰しする場合はgradf命令ではなくboxf命令を使うようヘルプに記載されています。 しかし、場合によってはgradf命令の方が高速となる場合があります。 boxf命令で塗り潰す色を指定する場合はcolor命令も使用する必要があり、 処理時間を計測すると管理人の環境でboxf命令を使う方が平均20%程遅くなっていました。 また、処理的にも塗り潰しは背景であり、塗り潰した後に前景色を指定することを考えれば、 gradf命令で指定する方がパラメータ6と7で色指定をしていても、 カレントカラーに影響はなく、塗り潰し色とは別に前景色のまま保持することができますので便利です。
 1
 2
 3
 4
 5
	gradf  50, 100, 50, 300 // 「boxf 50, 100, 99, 399」と同じ
	gradf 150, 100, 50, 300, 0, 0xFF
	gradf 250, 100, 50, 300, 0, , 0xFF
	gradf 350, 100, 50, 300, 1, 0xFF
	gradf 450, 100, 50, 300, 1, , 0xFF