draw脚本库

 

关于脚本库请参考文档:名字空间、脚本库

一、draw脚本库简介

draw脚本库基本功能是按预设的几何图形、渐开线轨迹遍历所有的坐标点。
移动到一个坐标点以后就会自动触发draw.move函数。

通过重写draw.move函数即可以使用draw类库实现很多常用的功能。
例如:绘图,扫描屏幕,在游戏中自动移动鼠标同时抓点搜怪(利用鼠标移动到怪物身上会导致颜色改变的原理)

二、创建draw脚本库

把下面的代码保存为draw.las文件,并且放到Fairy_Ape\import目录下。
也可以将draw.las放到模拟精灵主程序所在目录、或者需要使用draw脚本库的程序所在目录都可以。

-- 创建名字空间draw 添加参数_G以继承_G全局表中的所有对象
namespace("draw",_G )

 
--[[
************* 画线函数 **********
说明:
      可以修改这个函数决定在画线的时候做什么事
 
 
参数:
      x,y   当前坐标
 
 
返回值:
      返回true 表示继续,返回false表示停止
**********************************
]]
m
ove =   function(x,y)    
      error("使用draw类库以前必须重写draw.move函数",2);
end;
 
 
--[[
************* 画直线 *************
参数:
  x1,y1     起始坐标
  x2,y2     结束坐标
 
 
返回值:
      返回true 表示继续,返回false表示停止
**********************************
]]
l
ine = function(x1,y1,x2,y2)    
      local step = 1;
      local x,y = 1,1;
      if(math.abs(x2-x1) > math.abs(y2-y1) ) then
              if(x2<x1)then step = -1 end; --坐标如果是反过来的
              for x=x1,x2,step do
                      y = (y2 - y1) / (x2 - x1) * (x - x1) + y1
                      -- 当前y坐标 = ( 高度   / 宽度 ) * (部份宽度)   + 顶点
                      if(not move(x,y) ) then return false end;
              end;    
      else
              if(y2<y1)then step = -1 end; --坐标如果是反过来的
              for y=y1,y2,step do
                      x = (x2 - x1) / (y2 - y1) * (y - y1) + x1
                      -- 当前y坐标 = ( 宽度   / 高度 ) * (部份宽度)   + 顶点
                      if(not move(x,y) ) then return false end;
              end;
      end;
     
      return true;  
end;
 
 
--[[
************* 画矩形 **************
参数:
  x1,y1     左上角坐标
  x2,y2     右下角坐标
**********************************
]]
r
ect = function(x1,y1,x2,y2)
      if not line(x1,y1,x2,y1) then return false end;
      if not line(x2,y1,x2,y2) then return false end;
      if not line(x2,y2,x1,y2) then return false end;
      if not line(x1,y2,x1,y1) then return false end;
      return true;
end;
 
 
--[[
************* 画正弦曲线 **************
参数:
  x,y     宽高,参数可以忽略(默认为屏幕范围)
**********************************
]]
s
in =   function(x,y)
      local w = win.getScreen();
      local   y = 1;
      for x=1,w,1 do        
              y = 300 - math.sin(x/30) * 100;
              if(not move(x,y) ) then return false end;
      end;
     
      return true;
end;
 
 
--[[
************* 画渐开线 **************
参数:
  fx,fy     宽高,参数可以忽略(默认为屏幕范围)
**********************************
]]
i
nvolute =   function(fx,fy)
      if(not ( fx and fy) ) then
              fx,fy = win.getScreen();
      end;
     
      local x0,n,y0 = fx/2,1,fy/2;
     
      while( n<88 ) do
              x = x0+4*(   math.cos(n)+n*math.sin(n)   );
              y = y0+3*(   math.sin(n)-n*math.cos(n)   );
              if(not move(x,y) ) then return false end;
              n = n+0.2;
      end;
     
      local x1,n,y1 = fx/2,88,fy/2;
      while( n>1 ) do
              x = x1+4*(   math.cos(n)+n*math.sin(n)   );
              y = y1+3*(   math.sin(n)-n*math.cos(n)   );
              if(not move(x,y) ) then return false end;
              n = n-0.2
      end;
     
      return true;
end;
 
 
--[[
************* 画渐开线2 **************
参数:
  x,y     基圆圆心
  R         基圆半径
  n         渐开线周波数
**********************************
]]
i
nvolute2 = function(x,y,R,n)
      for a=0,2 * 360 * n,2       do
              x = x + R * (math.cos(a * math.pi / 360) + (a * math.pi / 360) * math.sin(a * math.pi / 360));
              y = y + R * (math.sin(a * math.pi / 360) - (a * math.pi / 360) * math.cos(a * math.pi / 360));
              if(not move(x,y) ) then return false end;
      end;
     
      return true;
end;
 
 
--[[
************* 画方形仿渐开线 **************
参数:
  step       步长
  n             起始正方形边长,指定中间忽略不扫描的正方形边长(默认等于20)
  x1,y1     扫描范围坐标,参数可省略(默认等于 1 X 1)
  x2,y2     扫描范围坐标2,参数可省略(默认等于屏幕大小)
**********************************
]]
r
ect_inv =   function(step,n,x1,y1,x2,y2)
      step = step or 1;
      step = math.abs(step);
      step = 0 - math.abs(step);
      n = n or 20;
     
      x1 = x1 or 1;
      y1 = y1 or 1;
 
 
      if(not ( x2 and y2) ) then
              x2,y2 = win.getScreen();
      end;
     
      local fx,fy = 1,1;
      if(x1<x2)then
              fx = x1;x1=x2;x2=fx;
      end;
      if(y1<y2)then
              fx = y1;y1=y2;y2=fx;
      end;
     
      fx = x1; fy = y1;
      x1 = fx/2;y1= fy/2;
     
      print(x1,y1,x2,y2,fx,fy);
     
      local x,y = 1,1;
      for x=x1-n/2,x2,step       do    
              y = (y2 - y1) / (x2 - x1) * (x - x1) + y1;
              if not rect( x,y,x1+(x1-x),y1+(y1-y) ) then return false end;
      end;
     
      return true;
end;
 
 
--[[
************* 画方形仿渐开线2 **********
参数:
      x,y   坐标
      m       扫描范围
      n       扫描速度,可省略(默认等于5)
      k       扫描密度,可省略(默认等于50)
示例:
      rect_inv2(322,384,300);
**********************************
]]
f
unction rect_inv2(x,y,m,n,k)    
      n = n or 5; --控制扫描速度
      k = k or 50; --控制扫描密度
      local l = 0; --控制扫描范围  
               
      local tx = {};
      local ty={};
      for i=1,5,1       do  
              table.insert(tx,x );
              table.insert(ty,y )    
      end;
     
      while(   --[[nStop()and]] l<m   ) do --让脚本在一定范围内扫描
             
              tx[1] = tx[1]-k; tx[2] = tx[2]+k;
              tx[3] = tx[3]+k; tx[4] = tx[4]-k;
              ty[1] = ty[1]-k; ty[2] = ty[2]-k;
              ty[3] = ty[3]+k; ty[4] = ty[4]+k;
     
              for i=tx[1],tx[2],n   do  
                      if(not move(i ,ty[1]) ) then return false end;
              end;
                                                                                                                 
              for i=ty[2],ty[3],n   do  
                      if(not move(tx[2] ,i) ) then return false end;
              end;
                                                                                                                           
              for i=tx[3],tx[4],0-n   do  
                      if(not move(i ,ty[3]) ) then return false end;
                      mouse.move(   i ,ty[3],true   ); delay(10);
              end;
                                                                                                                             
              for i=ty[4],ty[1],0-n   do  
                      if(not move(tx[4] ,i) ) then return false end;
              end;
      l = l+50
      end;
end;
 
 
 
 
--[[
************* 画多边形 **************
参数
  x,y         中心所在的屏幕坐标(像素)
  r             多边形外接圆半径(像素)
  n             多边形的边数
**********************************
]]
f
unction poly(x,y,r,n)
      local i;
      local theta=math.pi;
      local x1=x;
      local y1=y-r;
      local x2,y2;
      for i=1,n,1       do
              theta=theta - (2*math.pi/n);
              x2=x+r*math.sin(theta);
              y2=y+r*math.cos(theta);
              if not line(x1,y1,x2,y2) then return false end;
              x1=x2;
              y1=y2;
      end;
end;
 
 
--[[
************* 画椭圆 **************
  x,y                 中心所在的屏幕坐标(像素)
  a,b                 长轴和短轴的长度(像素)
  precision     边缘精细度
**********************************
]]
f
unction ellipse(x,y,a,b,precision)
      local i;
      local iMax=2*math.pi;
      local step=2*math.pi/(precision*math.sqrt(a*b)*4.5);
 
 
      for i=1,iMax,step       do  
              if(not move(x+a*math.cos(i),y+b*math.sin(i)) ) then return false end;
      end;
end;    

三、使用draw脚本库

使用 import("draw"); 运行draw.las并导入draw脚本库。

然后需要重写draw.move函数。以确定移动每个坐标点以后执行什么代码。
draw.move返回true表示继续画线,返回false表示停止。
我们可以使用win.doEvents();或者nStop();自动取得返回值,
这两个函数在用户按了全部停止热键(默认为Ctrl+Alt+L)以后都会返回false。

因为draw类库的扫描移动是一个循环过程,
如果在draw.move中没有使用win.doEvents();或者nStop();取得返回值。
那么用户无法中断draw类库的扫描。

import("draw"); --导入draw类库
 
 
--根据自已的需要重写move  函数,要找怪或者抓点都可以写在这个函数里面就行了
-- 注意返回true表示继续画线,返回false表示停止
draw.move =  function(x,y)  
    mouse.move(x,y,true);--鼠标移动到当前坐标点
    color("#FF0000"):toPos(x,y);--在屏幕上画一个点
    return nStop(); --这个比较通用
end;
 
--画直线
draw.line(23,100,23,300);
 
 
--画矩形
draw.rect(23,32,200,100);
 
-- 画正弦曲线
draw.sin()
 
 
-- 画渐开线
draw.involute();
 
 
-- 画方形仿渐开线,步进为5,中间忽略的正方形边长为50
draw.rect_inv(5,50);
 
 
--这是真正的渐开线,第三个参数指定基圆的半径
draw.involute2(1024/2,768/2,0.1,10);