跳转至

检测视觉线索

对机器人来说,生命值相对容易检查,因为它只是一个数字,但某些游戏元素必须以不同方式传达给机器人。例如,当状态疾病或增益效果影响角色时,你最容易的判断方式就是寻找屏幕上的状态指示器,机器人也是如此。

当读取内存不够时,你可以通过钩住游戏图形引擎并等待游戏渲染特定模型来检测某些事件。(请回顾第一百七十五页「把跳转钩子和 VF 钩子应用到 Direct3D」和第一百九十四页「创建 Direct3D 透视」,复习 Direct3D 钩子。)模型绘制时你可以排队一个帧绘制后执行的反应,像这样:

// 下面是 drawIndexedPrimitive 钩子
void onDrawIndexedPrimitive(...) {
    if (numVertices == EVENT_VERT && primCount == 
EVENT_PRIM) {
        // 做出反应,最好在绘制完成后
    }
}

使用与第 9 章透视代码相同的模型指纹识别技巧,这段代码检测特定模型何时绘制到屏幕并相应做出反应。不过,这段代码会在每一帧都对事件做出反应,这可能让游戏无法玩。你可能想要一些内部冷却来避免重复触发反应。当指示器模型持续绘制(即不闪烁)时,你实际上可以跨帧跟踪它,确定它何时出现和消失。以下代码片段还处理跟踪:

bool eventActive = false;
bool eventActiveLastFrame = false;
// 下面是 drawIndexedPrimitive 钩子
void onDrawIndexedPrimitive(...) {
    if (numVertices == EVENT_VERT && primCount == 
EVENT_PRIM)
}
// 下面是 endScene 钩子
void onDrawFrame(...) {
    if (eventActive) {
        if (!eventActiveLastFrame) {
            // 对事件模型出现做出反应
        }
        eventActiveLastFrame = true;
    } else {
        if (eventActiveLastFrame) {
            // 对事件模型消失做出反应
        }
        eventActiveLastFrame = false;
    }
    eventActive = false;
}

onDrawIndexedPrimitive() 函数仍然检查某个模型是否被绘制,但现在两个布尔值跟踪模型是在这一帧还是上一帧被绘制。然后,当帧完全绘制后,机器人可以检查这些变量,对模型出现或消失做出反应。

这种方法非常适合检测只在角色受到眩晕、移动减速、定身、中毒等影响时出现的视觉状态指示器。你也可以用它检测 MOBA 和 RTS 游戏中的敌人出现和消失,因为这些游戏只绘制明确在友方单位或玩家视野范围内的敌人。