2022年 2月 11日
 
 
 最後にキー入力の座標計算をする。

座標の計算そのものは HEXの x座標 mkxに lxを足すだけでできた。
訂正 : 以下の式が必要でした。
if mkx>=(hxb+schk) : mkx-=(hxb+schk)
赤枠の部分です。

つまりこの場合、横の HEX数 hxb=37、海の余白 schk=2で、全長さ 39ですけど、マップの左端座標は 0なので 1週すると 0が 39になります。
ですので mkx(マウス座標)に lx(スクロール座標)を足した座標が 39オーバーなら 39引きます。
 これでも動いてるように見えたのは、マップデータが 1次元配列だったために 39のズレが、トータルで y座標が 1個ズレるような感じの事になったからです。
 
 
 カーソルの座標は mx,my
そこから HEXの座標 mkx,mkyを算出する。
mkn=-1 ; hex座標 mx=mousex : my=mousey ; カーソル位置 ; HEX座標(mkn) mkx=(mx-hxp-2-(mky\2)*(hkx/2))/hkx mkx+=lx if mkx>=(hxb+schk) : mkx-=(hxb+schk) mky=(my-hyp-3)/hky mkn=mky*hxb+mkx ; HEX座標 if mkn>=hxb*hyb : mkn=-1 ; オーバー
 見ての通り mkx+=lxで mkxに lx(スクロール座標)を足してる、変更はそれだけだった(訂正しました)
y座標はスクロールせず固定なので変更無し。
 最終的に算出する HEXの座標は mknになる、いつもながら縦横を 1次元配列で扱っているため。
 
 
 さて問題なのは、むしろキー入力の処理。
何が問題かと言うと「押して放す操作」と「押したままドラッグしてスクロールさせる操作」を判定しないといけない。
でも、これは前に 1MAP防衛シューティングの時にやったので、今回はそのソースを元にして割りと簡単にできた。
 プログラムは 1度思考錯誤して作成すると割と使いまわすだけで済む、なんかプログラム用語では「同じ車輪を 2度発明するな」とかなんとかいう言葉があった。
 
 
 考え方としては「押してる」状態の処理と「押してない」状態の処理を分けて処理する事。
状態(モード)を kf(キーフラグ)で管理する事。
kfフラグにより、押した kf=1、そこから放した kf=2のように処理できる(このソースでは kf=2はスクロールモードになってる)
	kf=0	; キーフラグ
	kln1=0	; 押した国
	kln2=0	; 攻め込む国
	repeat
	 mkn=-1 ; hex座標
	 k=0 : mx=0 : my=0 ; 入力リセット
	 repeat 1
	  if kwc>0 : kwc- : break ; ウエイト
	  mx=mousex : my=mousey ; カーソル位置
	  stick k,256 ; マウスボタン、スマホクリック
	 loop
; 押してる
	 repeat 1
	  if k!256 : break
	  if kf=0 : kf=1 : kepx=mx : kepy=my : keplx=lx
	  if kf=1 : if kepx-mx>8 or mx-kepx>8 : kf=2 ; スクロールモード
	  if kf=2 { ; スクロール
	   lx=keplx+(kepx-mx)/20;hkx
	    if lx<0 : lx=lx+hxb+schk
	    if lx>=hxb+schk : lx=lx-(hxb+schk)
	  }
	 loop
; 押してない
	 repeat 1
	  if k=256 : break ; 放してない
	  if kf=0  : break ; 一度も押してない
	  if kf=2 : kf=0 : break ; スクロールモード
; 押して放した
	  kf=0 ; リセット
; HEX座標(mkn)
	  mkx=(mx-hxp-2-(mky\2)*(hkx/2))/hkx
	  mkx+=lx
	  mky=(my-hyp-3)/hky
	  mkn=mky*hxb+mkx ; HEX座標
	   if mkn>=hxb*hyb : mkn=-1 ; オーバー
	  if mkn<0 { ; 画面外
	   if kln1=0 : gosub *tarn_end
	   kln1=0 : kf=3 : break
	  }
	  if map(mkn)<1 : kln1=0 : break ; 領土外
	  ldn=map(mkn) ; 国No.
	  if kln1=ldn : kln1=0   : break ; 同じ国の場合リセット
	  if kln1=0   : kln1=ldn : break ; 国選択
	  if lpd(kln1)!pn1 and kln1!ldn : kln1=ldn : break ; 別の国を選択
	  repeat 1 ; 攻め込む
	   if kln1=0		: break ; 選択してない
	   if lpd(kln1)!pn1 : break ; 自国では無い
	   if lpd(ldn)=pn1	: break ; 自領なので攻め込まない
	   if ldcd(kln1)<2	: kln1=0 : break ; ダイスが2以上無い
	   f=0 : ldlg=kln1*ldlb
	   repeat ldlb ; 隣接国か
		if ldl(ldlg+cnt)=ldn : f=1 : break
	   loop
	   if f=0 : kln1=0 : break
	   kln2=ldn
	   gosub *battle ; 戦闘へ
	  loop
	  kln1=0
	  kln2=0
	 loop
	 if k=512 {
	  if kln1=0 : gosub *tarn_end : kf=3 : break ; ターンエンド
	  if kln1>0 : kln1=0
	 }
	 if mainf!5 or kf=3 : break
kf=0 の時押した座標を元にして、kf=1の処理で移動距離が 8ドット以上の時に kf=2にしてスクロール処理している。
lx=keplx+(kepx-mx)/20 でスクロールする HEX数(lx)を算出している。
 /20と言うのは移動量で、HEXの幅が30ドットなので、この数字を /30にすれば、なぞったドットと等速でスクロールする、/20は少し早めのスクロールになる。
 
 
 
 次に問題なのは CPUが自動操作している状態でのスクロール操作。
当然 CPUが行動している状態でもマップ画面をスクロールして確認したい。
 戦闘状態の時はスクロールしないとして、それ以外の時のスクロールをしたい。
 
 
 まずキー入力を一元化する。
#deffunc scr_key ; スクロール入力
	mx=mousex : my=mousey ; カーソル位置
	stick k,256 ; マウスボタン、スマホクリック
; 押してる
	repeat 1
	 if k!256 : break
	 if kf=0 : kf=1 : kepx=mx : kepy=my : keplx=lx
	 if kf=1 : if kepx-mx>8 or mx-kepx>8 : kf=2 ; スクロールモード
	 if kf=2 { ; スクロール
	  lx=keplx+(kepx-mx)/20;hkx
	   if lx<0 : lx=lx+hxb+schk
	   if lx>=hxb+schk : lx=lx-(hxb+schk)
	 }
	loop
	return
押して放す、つまりタップ操作は必要無いので、これだけで LXを算出すれば済む。
 一元化したのは 8ドットずらしたらスクロールのような値を一元管理するため、と言っても先のものと合わせて今の所 2ヶ所だけ。
 
 
 とりあえずターンエンド時のダイス増の時に受け付けるようにした。
#deffunc te_put int _te_putf; ターンエンド表示 te_putf=_te_putf bpwt1c=0 repeat scr_key ; スクロール入力 if kf>0 and k!256 : kf=0 : break ; 放した if bpwt1f=0 and k!0 : break if bpwt1f>0 and bpwt1c=bpwt1 : break bpwt1c+ redraw 0 n=0 : if tef=1 or te_putf=1 : n=1 map_put n redraw 1 await 1000/50 loop return
これはターンエンドの画面表示ルーチンだけど、ここにスクロールのキー操作を入れた。
なぜかと言うと await 1000/50 つまり FPS 20 で時間を待っているので、一番キー入力を受け付ける時間があるため。
 当然何かの処理中にキー入力をすると言うのは、ややこし過ぎる。
 
 
 実機にて確認。

きちんと動いている。
これでスクロールの実装はできた。
