DXlib用点線描画モジュールと使用サンプル(hgime3用に作ってたのでついでに)
ウィンドウモードならHSP命令のbutton等も使えると言うサンプル
DXlib命令の定義ファイルはNO.70321のURLから
DXlib.dllは最新版のVer3.14fだとzipファイルが壊れてるのか使えないので
旧バージョンのC#用(Ver3.14d)で動作確認
#include "DXlib.as"
#module
//複数ドットを使った点線の描画にDrawLineじゃ無くDrawPixelを使用するかのフラグ(DrawPixel使用時は線(DrawLine)の同一線上に点が置かれる)
// 0=1ドットの点線以外はDrawLineを使用 1=点線は全てDrawPixelを使用 2=点線は全てDrawLineを使用(これはおまけマイナス方向の斜めだと1ドットの点線だと繋がってしまう)
#deffunc DotLineFlag int f
dl_f=f
return
//点線描画にDrawLineを使ってる時に点の幅を設定
// 指定できるのは1以上
#deffunc DotLineWidth int w
dl_w=w
return
//点線を描画
// DotLine x1, y1, x2, y2, rgb, dot
// x1 , y1 : 描画する線の起点座標
// x2 , y2 : 描画する線の終点座標
// rgb : 描く線の色
// dot : 連続する点のドット数(0の場合DrawLineで線がかかれる)
#deffunc DotLine int x1,int y1,int x2,int y2,int rgb,int dot
if dl_w {}else{dl_w=1}
x = x1: y = y1
dx = x2 - x1
dy = y2 - y1
if (dx < 0){ addx = -1: dx*-1 } else {addx = 1}
if (dy < 0){ addy = -1: dy*-1 } else {addy = 1}
if (dot*(1+(dl_f=2)))>1 and (dl_f&1)=0 {//点が複数ドットかDrawLine使用設定
if dx>dy {//横方向の点線
doty=dot*2
adddot=dot*addx
addcntx=addx*doty
if dy {//横方向斜めの点線
addcnty=dy*doty
dotdy=dot*dy
addy*dx
cnty=dx/2
repeat cnty/dot
DrawLine x,y1+cnty/addy,x+adddot,y1+(cnty+dotdy)/addy,rgb,dl_w
x+addcntx
cnty+addcnty
loop
if (x2<x) = (adddot<0) {
adddot=limit(x2-x,-dot,dot)
DrawLine x,y1+cnty/addy,x+adddot,y1+(cnty+abs(adddot)*dy)/addy,rgb,dl_w
}
}else{//横の点線
repeat dx/doty
DrawLine x,y1,x+adddot,y1,rgb,dl_w
x+addcntx
loop
if (dx\doty) {
if addx>0 {DrawLine x,y1,limit(x+adddot,x1,x2),y1,rgb,dl_w}else{DrawLine limit(x+adddot,x2,x1),y1,x,y1,rgb,dl_w}
}
return
}
}else{//縦方向の点線
dotx=dot*2
adddot=dot*addy
addcnty=addy*dotx
if dx {//縦方向斜めの点線
addcntx=dx*dotx
dotdx=dot*dx
addx*dy
cntx=dy/2
repeat cntx/dot
DrawLine x1+cntx/addx,y,x1+(cntx+dotdx)/addx,y+adddot,rgb,dl_w
y+addcnty
cntx+addcntx
loop
if (y2<y) = (adddot<0) {
adddot=limit(y2-y,-dot,dot)
DrawLine x1+cntx/addx,y,x1+(cntx+abs(adddot)*dx)/addx,y+adddot,rgb,dl_w
}
}else{//縦の点線
repeat dy/dotx
DrawLine x1,y,x1,y+adddot,rgb,dl_w
y+addcnty
loop
if (dy\dotx) {if addy>0{DrawLine x1,y,x1,limit(y+adddot,y1,y2),rgb,dl_w}else{DrawLine x1,limit(y+adddot,y2,y1),x1,y,rgb,dl_w}}
return
}
}
}else{
if dot {//DrawPixelを使った点線
if dx>dy {
if dy {//横方向斜め点線
doty=dot*2 //次の点までのドット数
addy*dx //縦に段が変わる基準値(マイナスなら上に向かう基準値になる)
cnty=dx/2 //縦方向用カウンタ(cntyをaddyで割って縦の移動量を算出)初期値をdx/2にしてるのはDrawLineと同一ラインにするため
if dot=1 {
addcnty=dy*doty //次の点までの加算用縦カウント値
addcntx=addx*doty //次の点までの横移動量(マイナスなら左に向かう)
repeat (dx+1+(addx<0))/doty //描画点の総数分ループ((addx<0)にしてるのはDrawLineのバグか仕様か分からないがマイナス方向斜めが1ドット増えるので同じになるようにしてる)
DrawPixel x,y1+cnty/addy,rgb
x+addcntx //次の描画点座標進ませる
cnty+addcnty //次の描画点まで縦カウンタを進ませる
loop
}else{//複数ドットの点線
addcnty=dy*dot //複数ドット分の加算用縦カウント値(空白部分は含まない)
addcntx=addx*dot //複数ドット分の横移動量(空白部分は含まない)
repeat (dx+1+(addx<0))/doty
repeat dot //点一つ分のドット数分ループ
DrawPixel x,y1+cnty/addy,rgb
x+addx //横1ドット進ませる
cnty+dy //横1ドット分縦カウンタを進ませる
loop
x+addcntx //空白分横に進ませる
cnty+addcnty//空白分の縦カウンタを進ませる
loop
if (x2<x) = (addx<0) {//描画されてない点が残ってる
_cnt=abs(limit(x2-x,-dot,dot)) //残りのドット数を算出
repeat _cnt+(addx<0)*(_cnt<dot) //本当は(_cnt<=dot)にしないとDrawLineと同じにならないが最後だけ点の数が増えてしまうので・・・
DrawPixel x,y1+cnty/addy,rgb
x+addx
cnty+dy
loop
}
}
}else{//横点線
if dot=1 {
doty=dot*2
addcntx=addx*doty
repeat (dx+1)/doty
DrawPixel x,y1,rgb
x+addcntx
loop
return
}else{//複数ドットの点線
addcntx=addx*dot
repeat (dx+1+(addx<0))/(dot*2 )
repeat dot
DrawPixel x,y1,rgb
x+addx
loop
x+addcntx
loop
if (x2<x) = (addx<0) {
repeat abs(limit(x2-x,-dot,dot))
DrawPixel x,y1,rgb
x+addx
loop
}
}
}
}else{
if dx {//縦方向斜め点線
dotx=dot*2
addx*dy
cntx=dy/2
if dot=1 {
addcntx=dx*dotx
addcnty=addy*dotx
repeat (dy+1+(addy<0))/dotx
DrawPixel x1+cntx/addx,y,rgb
y+addcnty
cntx+addcntx
loop
}else{
addcntx=dx*dot
addcnty=addy*dot
repeat (dy+1+(addy<0))/dotx
repeat dot
DrawPixel x1+cntx/addx,y,rgb
y+addy
cntx+dx
loop
y+addcnty
cntx+addcntx
loop
if (y2<y) = (addy<0) {
_cnt=abs(limit(y2-y,-dot,dot))
repeat _cnt+(addy<0)*(_cnt<dot)
DrawPixel x1+cntx/addx,y,rgb
y+addy
cntx+dx
loop
}
}
}else{//縦点線
if dot=1 {
dotx=dot*2
addcnty=addy*dotx
repeat (dy+1)/dotx
DrawPixel x,y,rgb
y+addcnty
loop
}else{
addcnty=addy*dot
repeat (dy+1+(addy<0))/(dot*2 )
repeat dot
DrawPixel x1,y,rgb
y+addy
loop
y+addcnty
loop
if (y2<y) = (addy<0) {
repeat abs(limit(y2-y,-dot,dot))
DrawPixel x1,y,rgb
y+addy
loop
}
}
return
}
}
}else{//通常のライン
DrawLine x1, y1, x2, y2, rgb,dl_w
}
}
return
#global
//hspのウィンドウを使う
SetUserWindow hwnd
SetUserWindowMessageProcessDXLibFlag 0
onexit *exit
ChangeWindowMode 1
DxLib_Init
if ( stat == -1 ) : dialog "初期化エラー":end
pos 0,0
d=5
combox d,,"0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10"
w=1
combox w,,"0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10"
objsize 80,24
f=0
combox f,,"Pixel+Line\nDrawPixel\nDrawLine"
button gosub "比較LINE描画",*clin
SetFontSize 20
repeat
DotLineWidth w
DotLineFlag f
SetDrawScreen DX_SCREEN_BACK
GetColor 0,0,0
DrawBox 0,0,640,480,stat,1
GetColor 255,255,255
rgb=stat
DrawString 70,0,"ドット数",rgb
DrawString 70,24,"点の幅",rgb
DrawString 90,48,"描画命令",rgb
if cl {
DrawString 90,72,"ON",rgb
GetColor 0,255,0
DrawLine 320,240,mousex,mousey,stat,w //点線との比較用に同一線上に描画
}else{
DrawString 90,72,"OFF",rgb
}
GetColor 255,0,0
DotLine 320,240,mousex,mousey,stat,d
CheckHitKey KEY_INPUT_ESCAPE
if stat {break}//[Esc]で終了
ScreenFlip
ProcessMessage
if stat<0 {break}
if ginfo_act>=0 {await 0}else{await 16}//ウィンドウが全て隠れたり最小化するとScreenFlipは垂直同期を止めるのでウェイトがかからなくなる(面倒なので非アクティブになったらawait 16)
loop
*exit
DxLib_End
end
*clin
cl^1
return
複数ドットの点線の場合DrawLineで直線を引いた時と
段が変わる位置がずれる
これは、描画距離で段が変わる位置が決まってしまうので仕方ない
なので、全てDrawPixelで描画するモードも付けた
当然処理量は増える・・・