2021年 8月 24日
マップの作成はできたので、今度は国の境界線表示を試みる。
まずベタに考えると、1つのマスにつき 6方向に対する枠線の情報を持つとなると、マップの大きさ × 6倍のデータを持ち、かつ表示毎事にそれだけの判定と表示をしなければいけなくなる。
これではデータの量もさることながら、表示スピードは期待できない。
次に 1マスにつき左上 3方向に対する枠線のデータを持つ方法を考えた。
この方法だと表示が重なる部分を省ける。
合わせて 1つのデータを 2進数の集まりとして考え、1つのデータで ON OFF のデータを複数持つように考えた。
どういう事かと言うと、2進数だとケタ毎の数は 1、2、4、8、16、32となるので、例えば 1番目と 2番目が ONの場合はデータ数は 3となる。
要するにビット演算で ON OFF情報を持つようにする。
例えば 2番目と 4番目と 5番目が ONなら、2 + 8+ 16 = 26となる。
これを ANDで判定する、例えば 4番目があるかどうか判定するには if data & 8 =1 となる、無い場合は 0になる。
さて、この方法で 1マス 3方向の枠情報を持つやり方を考えたけど、これだとマップの外周表示に、それぞれ別の表示ルーチンを持たないといけない、あるいは最下段の下の段にマップより 1マス多いデータを用意しないといけない、めんどくさい。
そんな感じで色々考えたけど、最終的に 1つのデータで 6方向の枠情報を持つ方法にした。
閃いたのは、あらかじめ画像データで 6方向の枠線の全組み合わせを描いて置く事。
組み合わせは 1 + 2 + 4 + 8 + 16 + 32で 64通りとなる。
これは上から順に 2進数の表記にもなってる訳だ。
この方が表示は高速になるはず。
最初は手書きで描いてみたけど、流石に間違いも発生するので、プログラムで自動作成する事にした。
基になる画像を用意して
////////// HEX 枠6方向64種類生成 ////////// ox=33 : oy=34 screen 0,ox*10,oy*7 buffer 1 : picload "hw3_6line_h.bmp" ; 枠線 gsel 0 : gmode 2 color 0,0,0 : boxf : color 255,255,255 repeat 64 pos cnt\10*ox,cnt/10*oy ; 表示座標 if cnt&1 : gcopy 1,0*ox,0,ox,oy ; 右上 if cnt&2 : gcopy 1,1*ox,0,ox,oy ; 右 if cnt&4 : gcopy 1,2*ox,0,ox,oy ; 右下 if cnt&8 : gcopy 1,3*ox,0,ox,oy ; 左下 if cnt&16 : gcopy 1,4*ox,0,ox,oy ; 左 if cnt&32 : gcopy 1,5*ox,0,ox,oy ; 左上 loop bmpsave "hex_wak5h.bmp"
次のような画像になる
*画像はワードプレスで .bmp画像が使え無いし、拡大して .jpgにしてます。
こうすると実際に使う場合は、HEXの隣接を調べて枠線の 1、2、4、8、16、32をそのまま足し算すれば枠線のデータになる訳です。
#deffunc waku_set ; 国土境界の枠線データ dim hwd,mb ; HEXの外周枠情報 repeat mb : hwd(cnt)=0 : loop repeat hyb : cnt2=cnt repeat hxb : mn=cnt2*hxb+cnt if cnt=hxb-1 and cnt2\2=1 : continue ; 奇数列の右端は無し n1=map(mn) : if n1<=0 : continue ; 国土では無い repeat 6,1 hm2 mn,cnt if hm2p=-1 : continue ; 地形無し n2=map(hm2p) if n1=n2 : continue ; 同じ国土 if cnt=1 : hwd(mn)+=1 ; 右上 if cnt=2 : hwd(mn)+=2 ; 右 if cnt=3 : hwd(mn)+=4 ; 右下 if cnt=4 : hwd(mn)+=8 ; 左下 if cnt=5 : hwd(mn)+=16 ; 左 if cnt=6 : hwd(mn)+=32 ; 左上 loop loop loop return
表示する時は、データをそのまま画像 No.にすれば良いです。
; HEX枠表示 celload fi+"hex_yk_33_34i.png",1 celdiv 1,33,34 repeat hyb : cnt2=cnt ; y repeat hxb : mn=cnt2*hxb+cnt ; x if hwd(mn)<=0 : continue pos cnt*30+(cnt2\2)*15+hxp,cnt2*26+hyp celput 1,hwd(mn) ; 国土境界の枠線 loop loop