スクロール移動



その時見えている範囲だけしか移動しなくてもいい場合は前回のでも大丈夫ですが、 マップが広くて全体を一度に表示しきれない時、スクロールを使う必要があります。
今回は背景をスクロールさせる改変です。

#const scy 300		;ウィンドウサイズy
#const osize 16		;自分の大きさ
#const tipsize 20	;1マスの大きさ
#const tipx 20		;マスの数x
#const tipy 15		;マスの数y
#const scx 300	;ウィンドウサイズx

	buffer 2,tipsize*tipx,scy	;背景画像用
	dim map,tipx,tipy	;マップデータ
	color : boxf
	repeat tipx	;ランダムでマップ作成
		c=cnt
		rnd high,5 : high++
		repeat high,1
			c2=tipy-cnt
			map.c.c2=1		;1で移動不可能場所
			color 255,255,255	;移動不可能場所は白
			boxf c*tipsize,c2*tipsize,c+1*tipsize-1,c2+1*tipsize-1
		loop
	loop

	screen 0,scx,scx

	jump=10		;ジャンプ力
	grab=2		;重力(高いほど重力低い)
	gcount=grab	;重力カウンター
	fallmax=15	;最高落下速度
	speed=2		;横移動スピード
	stps=winx-osize/2;スクロールを止める位置
	ox=stps		;マップ全体から見た自分の位置x
	oax=ox		;自分位置x
	oy=0		;自分位置y
	omx=0		;左右移動量
	omy=0		;上下移動量
	gos=0		;地上にいるか空中にいるか
	bsx=0		;背景スクロール数

	font "MS ゴシック",osize

*mainloop	;メインループ
	redraw 0
	gosub *drawback
	gosub *setown
	gosub *drawown
	redraw
	await 1
	goto *mainloop

*drawback	;背景描画
	pos 0,0 : gcopy 2,bsx,0,winx,winy
	return

*drawown	;自分描画
	color 255 : pos oax,oy : mes "●"
	return

*setown		;自分の処理
	olp=ox/tipsize		;移動前のマップ上の位置を保存(左)
	orp=ox+osize-1/tipsize	;右
	otp=oy/tipsize		;上
	obp=oy+osize-1/tipsize	;下

	obp2=oy+1+osize/tipsize
	if map.olp.obp2|map.orp.obp2 : gos=1 : else : gos=0	;地上にいるか空中にいるか

	stick key,5
	if key&1 : omx=-speed
	if key&4 : omx=speed
	if key&16 : if gos : omy=-jump

	gcount--
	if gos : gcount=0
	if gcount=0 {
		omy++		;下方向移動量+1
		gcount=grab	;カウンターを元に戻す
	}
	if omy>fallmax : omy=fallmax	;最高落下速度に達したらそこまで
	ox+omx : oy+omy	;移動

	if ox<0 : ox=0	;画面左端
	if ox>(tipx*tipsize-osize-1) : ox=tipx*tipsize-osize-1	;画面右端
	if oy<0 : oy=0	;画面上端

	if omx<0{
		olp2=ox/tipsize
		if olp2!=olp {
			otp2=oy/tipsize
			obp2=oy+osize-omy/tipsize
			if map.olp2.otp2|map.olp2.obp2 : ox=olp*tipsize
		}
	}
	if omx>0 {
		orp2=ox+osize/tipsize
		if orp2!=orp {
			otp2=oy/tipsize
			obp2=oy+osize-omy/tipsize
			if map.orp2.otp2|map.orp2.obp2 : ox=orp2*tipsize-osize-1
		}
	}
	omx=0	;横移動量を0に戻す

	if omy<0{
		otp2=oy/tipsize
		if otp2!=otp {
			olp2=ox/tipsize
			orp2=ox+osize/tipsize
			if map.olp2.otp2|map.orp2.otp2 : oy=otp*tipsize : omy=0
		}
	}
	if omy>0 {
		obp2=oy+osize/tipsize
		if obp2!=obp {
			olp2=ox/tipsize
			orp2=ox+osize/tipsize
			if map.olp2.obp2|map.orp2.obp2 : oy=obp2*tipsize-osize-1 : omy=0
		}
	}

	if ox<stps {
		oax=ox : bsx=0
	} else {
		if ox>(tipx*tipsize-stps-osize) {
			oax=ox-(tipx*tipsize-scx) : bsx=tipx*tipsize-scx
		} else {
			oax=stps : bsx=ox-stps
		}
	}
	return

スクロール方法は非常に簡単です。
大きなマップがあった場合、その中からウィンドウに表示する部分をずらしていけばいいのです。
このソースでスクロールピクセル数を管理している変数はbsxです。この変数の数値をgcopyのコピー始点x座標としています。
最後のif ox<stpsからが、スクロール数、表示位置を設定しています。 この部分が複雑になっているのは、自分がマップ上の左側にいる時、右側にいる時、スクロール中でそれぞれ表示位置の算出方法が異なるためです。
oxはマップ全体で考えたx座標なので、この位置に直接表示すると画面の外に出てしまいますので、oaxという変数にちゃんとした表示位置を設定するようにしています。


前へ 戻る 次へ