Delay 2000
//做脚本首要的工作就是根据需要的功能建立一个框架。按实际的需要的判断和动作做一个清单,这个时候不需要很详细,只需要考虑要点。
//例如本例中的框架结构和考虑的要点应该如下:
//判断1、找怪(解:通过小地图上的红点和蓝点的距离确定怪的方位,并按照地图比例换算到大地图的坐标)找怪过程中
//还同时检测游戏结束与否的标志
//动作1、如果找到怪根据上面得到的坐标点击打怪,进入判断2
//          如果没有找到怪,人物移动再判断1(因此可以在此处插入人物移动子程序)
//          如果检测到游戏结束则停止脚本
//判断2、是否打到了怪。(解:通过检测怪物血条)
//动作2、检测到了怪物血条则继续,检测不到回到判断2
//判断3、在打怪过程中是否需要补血(通过检测人物血条)
//动作3、如果缺血则按1键补血,否则没有动作程序往下走
//判断4、打怪是否结束(仍然通过怪物血条)
//动作4、没有怪物血条表示打怪结束,程序回到判断1,重新找怪
//          还有怪物血条,打怪持续中,回到判断3持续检测血量以免人物被打死
//整个任务的主框架就是这么简单。有了主框架以后就可以考虑每一步骤的实现方法,也就是考虑用哪些点和颜色来进行判断。
//通过前面的练习应该大家也会有一些心得,我这里就不一一累述,只讲一些特殊的地方和一些技巧。
//这里比较特殊的是人物血条的判断。因为是半圆型的血条,如果要考虑自己设定补血百分比的话,就需要用到一些三角函数的知识。
//具体可参考程序里面的说明。
//同时我的程序里面还增加了一些保证稳定的程序段,比如点怪的时候一下没有点到怎么办,可以增加一个判断,
//多少秒没有检测到怪物血条则跳出等待怪物血条的循环,重新寻找怪物。这样的判断不需要在大框架考虑,
//而是主要程序成型以后在需要的地方增加。以保证程序主框架的简洁和完整。
//虽然高级版本的按键精灵提供了多线程的功能,但是不建议随意的使用。在程序主结构清晰,单线循环完全可以满足要求的情况下
//尽量不要使用多线。这保证了程序主线的连贯性,逻辑上也更清晰,容易对程序进行跟踪和解读,实际上也避免发生各种意外的冲突。
//--------------------------------------------------------------
//获得游戏窗口句柄和位置尺寸等信息以便使用后台操作
Plugin hw=Window.mousepoint()
Plugin clintrect=Window.GetClientRect(hw)
rect=split(clintrect,"|",-1,1)
xoffset=cint(rect(0))
yoffset=cint(rect(1))
xwinsize=cint(rect(2))
ywinsize=cint(rect(3))
//系统和窗口初始化完毕------------------------------------------
//
//以下语句判断是否获得的是游戏窗口(游戏窗口尺寸是550x400)
If xwinsize<>550 or ywinsize<>400
    VBSCall messagebox("请将鼠标放在游戏窗口内启动脚本。")
    Goto end
EndIf 
//
//以下程序段用于参数设置
//补血百分比,这个比例在应用的时候用户根据具体情况调整,可保证安全的前提下达到最少加血次数
UserVar fillredscale=14 补血百分比
//参数设置完毕--------------------------------------------------
//
//以下程序段用于定义关键点(所有点位均以游戏窗口左上角为基准零点)
//之所以把一些关键点位都集中在一起定义是为了方便以后修改
//
//1、血条关键点及颜色(因为是半圆形血条,所以用圆心和半径来定义血条,用角度来分来确定补血百分比,其中xcenter,ycenter为圆心,r为半径
xcenter=49: ycenter=46: colorred="0000FF": r=32
//通过下面的公式来计算对应补血百分比所要检测的点的位置(其中的ang代表补血百分比所代表的弧度,因为sin,cos函数都是用弧度来计算的)
ang=(3.1415926*fillredscale/100)
xred=cint(xcenter-r*sin(ang))
yred=cint(ycenter+r*cos(ang))
//
//2、怪物血条基准点和颜色(用怪物血条边框的黑色来判断怪是否打死)
xbar=209: ybar=25: colorbar="000000"
//
//3、小地图范围和怪物颜色(1和2分别为左上角和右下角点)
xmap1=420 :ymap1=20 :xmap2=530 :ymap2=100: coloranimy="0000CC": colorme="009900"
xmapcenter=475: ymapcenter=60
//
//4、人物头发的黑色可以用来判断游戏是否结束
xhead=47: yhead=33: colorhead="000000"
//
//定义基本点完毕------------------------------------------------
//
//****************************************************************
//
//挂机程序正式开始
Rem start
//先将鼠标移动到窗口右下角位置以免影响取色
MoveTo xoffset+xwinsize/2,yoffset+ywinsize/2
//建立两个变量分别记录血瓶数量和打怪个数
redbt=50: killanimy=0
//记录程序运行时间
timestart=now
//
Rem 寻找敌人
//在小地图上搜索敌人并转换为大地图的坐标
////用中心向外的找色方式,以确保找到的怪距离自己最近,范围向内收缩两个像素点,为了避免怪物太靠边,找到了但点不到的情况
Plugin ret=BkgndColor.FindCenterColor(hw,xmap1+2,ymap1+2,xmap2-2,ymap2-2,coloranimy)
If ret="-1|-1"
    //小地图没有找到怪则调用人物移动子命令,并重新寻找敌人
    Gosub 人物移动
Else 
    //找到了怪则拆分出坐标值
    zuobiao=split(ret,"|",-1,1)
    x1=zuobiao(0)
    y1=zuobiao(1)
    //小地图和大地图像素比例为1:5 ,根据这个比例,把小地图上怪和人的位差换算到大地图上,从而得到怪的坐标点
    xanimy=xwinsize/2+7+(x1-xmapcenter)*5
    //上面公式中加了一个7,是因为在调试中发现大地图上人物的头的中心并不在整个窗口中心,而要往右偏7个像素点左右
    yanimy=ywinsize/2+(y1-ymapcenter)*5
    Gosub 战斗
EndIf 
//此处判断一下游戏是否结束,可用左上角人物头像的头发颜色来判断
Plugin color1=BkgndColor.GetPixelColor(hw,xhead,yhead)
If color1<>clng("&H" & colorhead)