;
	;	HSP キャラクタ表示サンプル3
	;	( HSP ver2.2e以上で動作します )
	;
 
	randomize				; 乱数を不定にする
	wx=640:wy=384				; ウインドゥのサイズ
	screen 0,wx,wy,1			; Windowをパレットモードで初期化
 
	buffer 3,,,1				; 仮想画面をパレットモードで初期化
	picload "testchr.bmp"			; 仮想画面にキャラクタデータをロード
	chrsx=64:chrsy=64			; キャラクタのサイズを指定
	chrx=0:chry=64				; キャラクタのデータがある左上の座標
 
	;
	;  複数をキャラクタを動かす(背景付き)
	;
	;	sprite2.asに背景をつけたバージョンです。
	;	背景は10×6ブロックに、マップデータで指定したチップが配置されます。
	;	マップデータはmapという文字列型変数に記憶されます。ここに、文字列の
	;	形で「0」から「4」を書いておくと、それが背景チップの番号になるように
	;	なっています。高速化のために、スクリーンID4にメイン画面と同じ大きさで
	;	仮想画面を作成し、一旦そこにマップデータ通りの背景を描画して、
	;	メインループでは、背景クリアの代わりにID4から背景をコピーすることで
	;	画面クリアを行なっています。こうすることで、背景クリアのたびにマップ
	;	データを参照する必要がなくなり、処理が速くなります。
	;
	mapx=10:mapy=6				; マップのX,Yサイズ
	alloc map,1000				; マップデータの領域を確保
	map  = "3330000000"			; Y=0のマップデータ
	map += "3000000000"			; Y=1のマップデータ
	map += "3004440000"			; Y=2のマップデータ
	map += "0000000000"			; Y=3のマップデータ
	map += "1000000011"			; Y=4のマップデータ
	map += "1100001111"			; Y=5のマップデータ
	buffer 4,wx,wy,1			; ID4に仮想画面を作成
	palcopy 3				; ID3のパレットをコピーしてくる
	gosub *map_draw				; 背景マップを作成
 
	;
	;    配列変数への初期設定
	;
	kazu=12					; 同時に表示するキャラクタの数
	dim x,kazu				; キャラクタの数だけ変数xの配列変数を確保
	dim y,kazu				; キャラクタの数だけ変数yの配列変数を確保
	dim px,kazu				; キャラクタの数だけ変数pxの配列変数を確保
 
	ax=0:ay=0:apx=0				; dup命令で使用する変数を宣言(ダミー)
 
	repeat kazu				; キャラクタの数だけループさせる
	dup ax,x.cnt				; 変数axをx.cntの代用にする
	dup ay,y.cnt				; 変数ayをy.cntの代用にする
	dup apx,px.cnt				; 変数apxをpx.cntの代用にする
	rnd ax,50:ax=ax*10+50			; X座標を乱数で設定する
	rnd ay,30:ay=ay*9+20			; Y座標を乱数で設定する
	rnd apx,4:apx++				; 動くドット数を乱数で設定する
	loop					; ループ終了
 
*chrmove
	;	メインループ(複数のリンゴが左から右へと移動する)
	;	   1. redraw命令で画面の書き換えスイッチをoffにします。
	;	   2. 背景となるマップデータを描画します。
	;	   3. 表示したい絵を描画します。全体の個数だけループさせて、
	;             ここでもdup命令による代用で、配列変数x,y,pxを変数ax,ay,apx
	;	      として使用しています。
	;	   4. 表示したい絵をすべて描画し終わったら、再びredraw命令で
	;	      画面の書き換えスイッチをonにします。2〜3までの結果は、
	;	      書き換えスイッチがoffになっている間は画面に反映されません。
	;	      (内部的には更新されています)最後に、redraw 1を行なうことで、
	;	      いままでの更新が画面上にも反映されます。こうすることにより、
	;	      画面のちらつきがなくなり、きれいに動きます。また、何より
	;	      速度が2〜3倍以上速くなります。リアルタイムにキャラクタが
	;	      動くソフトなどを作る際には重要なテクニックです。
	;
	gsel 0					; 描画先をID0に
	redraw 2				; 書き換えスイッチOFF
	gmode 1,wx,wy				; 透明なし高速コピーモード設定
	pos 0,0:gcopy 4,0,0			; ID4の全画面をコピー
	repeat kazu				; キャラクタの数だけループさせる
	dup ax,x.cnt				; 変数axをx.cntの代用にする
	dup ay,y.cnt				; 変数ayをy.cntの代用にする
	dup apx,px.cnt				; 変数apxをpx.cntの代用にする
	pos ax,ay				; カレントポジションを変数ax,ayの場所に設定
	a=0:gosub *chr_draw			; 重ねあわせキャラ表示
	ax+=apx					; X座標を変数apxのぶんだけ右に動かす
	if ax>540 : ax=0			; X座標が右端まできていたら、0に戻す
	loop					; ループ終了
 
	redraw 1				; 最後に書き換えスイッチON
	await 20				; 必ずウエイトを入れる
 
	goto *chrmove				; 無限にループさせる
 
*map_draw
	;	マップ描画ルーチン
	;
	a=0
	gmode 1,chrsx,chrsy				; 高速モードでコピー指定
	yy=0:i=0					; 画面左上から順番に描画する
	repeat mapy
	xx=0
	repeat mapx
	peek a,map,i:i+					; マップデータ読み出し
	pos xx,yy					; 変数xx,yyが描画先の座標になる
	a-='0'						; 1桁数字の文字を0〜9の数値に変換
	gcopy 3,a*chrsx,0				; チップをコピー
	xx+=chrsx					; 1つ右にずらす
	loop
	yy+=chrsy					; 1つ下にずらす
	loop
	return
 
*chr_draw
	;	重ねあわせキャラクタ描画ルーチン
	;	( カレントポジションに変数aのキャラNo.を表示する)
	;
	gmode 2,chrsx,chrsy			; 重ねあわせモードとコピーサイズの設定
	gcopy 3,a*chrsx+chrx,chry		; 重ねあわせコピーを実行
	return					; サブルーチン終了
 
back