稲妻を描いてみた。
手前味噌ですが。sp.dllを使って稲妻を描けないかやってみた。
zigzag.lua
-- zigzag.lua do local int = math.floor local sin = math.sin local cos = math.cos local sqr = math.sqrt local pi = math.pi local dice = math.random -- 2点間の距離を計算する。 local distance = function(sp, ep) local res = {} for i, v in ipairs(sp) do res[i] = v - ep[i] end for i, v in ipairs(res) do res[i] = v * v end local ret = 0 for i, v in ipairs(res) do ret = ret + res[i] end return sqr(ret) end -- 2点間の中間点を計算する。 local middle = function(sp, ep) local res = {} for i, v in ipairs(sp) do res[i] = (v + ep[i])/2 end return res end function zigzag(res, param, max_depth, depth) param = param or 50 -- どれくらいよれるか、デフォルトは50% depth = depth or 0 -- 深さの指定がなければ0 -- これで最後なら、何もせずに終わる。 if depth == max_depth then return res end -- そうでなければ計算する。 local end_point = table.remove(res) -- このループでの終点を取得。 local start_point = res[#res] -- このループでの始点を取得。 -- 仮の中間点を作成 local middle_point = middle(start_point, end_point) -- 中間点と始点との距離を計算する。 local dis = distance(start_point, middle_point) -- 中間点をどれだけずらすか計算する。 local rad = dice()*pi*2 -- 角度 local length = dice(0, int(dis*param/2)) -- 中間点をずらす。 middle_point[1] = int(middle_point[1] + cos(rad)*length/100) middle_point[2] = int(middle_point[2] + sin(rad)*length/100) -- 後処理 res[1+#res] = middle_point if max_depth>depth then zigzag(res, param, max_depth, depth+1) end res[1+#res] = end_point if max_depth>depth then zigzag(res, param, max_depth, depth+1) end return res end end
system.lua
-- system.lua NL_dofile("zigzag.lua") NSExec("luasub zigzag") function NSCOM_zigzag() local ret = NSPopStrRef() NSPopComma() local x1 = NSPopInt() NSPopComma() local y1 = NSPopInt() NSPopComma() local x2 = NSPopInt() NSPopComma() local y2 = NSPopInt() NSPopComma() local param = NSPopInt() NSPopComma() local depth = NSPopInt() local res = zigzag({ {x1, y1}, {x2, y2} }, param, depth ) local str = "" for i, v in ipairs(res) do str = str .. "," str = str .. tostring(v[1]) str = str .. "," str = str .. tostring(v[2]) end NSSetStrValue(ret , str) end
zigzag命令が、NScripter側に作られる。
00.txt
*define deletemenu game *start lsp 0,":m>640,480,#FFFFFF;>640,480,#00FFFF",0,0 for %0=1 to 10 itoa $0,%0 zigzag $1,20,20,620,460,50,%0 exec_dll "sp.dll/fill,0,0,1,255,255,255" exec_dll "sp.dll/line,0,0,1,0,0,0"+$1 exec_dll "sp.dll/burst,0,0,1,20,20,2,2" repaint print 1 getscreenshot 640,480 savescreenshot "lightning"+$0+".bmp" next end
使い方
zigzag命令は下記の書式
zigzag $結果を受け取る文字列変数,(始点x),(始点y),(終点x),(終点y),(ぶれの大きさ),(折れ回数)
始点と終点の間をゴキゴキ折れながらつないでいく点の座標をまとめて文字列にして返します。
サンプルを見ればわかるとおり、作られた文字列は、sp.dllのline/polylineに渡すことができます。
ちなみに折れ回数が10を超えると、文字列が長すぎるエラーが出る可能性があります。
折れ回数は10にすると10回折れるのかと言えばそうではなく、2^10回折れるの意味になります。