运行大话西游2游戏,模拟鼠标操作的话会发现游戏窗口里的光标跟系统光标不一致
而且每次的距离差都不一样,开着QQ在游戏窗口里ctrl+alt+a截图就可以看到两个光标的距离差了。
另外,游戏里的光标不是硬件光杯。
这里的方法是设定一个精确值,根据每次的移动鼠标的差值来调整游戏里的光标位置
首先要获取游戏里的光标的位置,有两种方法:
1、因为游戏里的光标不是硬件光标,所以图像是可以获取到的,可以用图像对比的方试获取到游戏里的光标位置,但是这个游戏里的光标是动态的,这里需要先固定光标。
游戏光标资源在gires.wdf这个文件,用a-wdf.exe解压出来之后,鼠标光标在0016号.was文件,改成一帧的tga再重新打包就可以了,进入游戏后发现光标不动了,可以用图像对比来找游戏光标位置了,需要注意的是游戏里还有一种手式的静态光标,需要两个都找一找,才不会漏。
这种方式不好,因为鼠标移到游戏窗口最右边的时候会发现光标找不到了,需要调整多次而且不稳定。
2、内存方式(我用这种方法)
这种方法相对比较简单,原来猜想里外光标位置不一致,游戏里应该会保存自己的光标位置才对,用CE搜到了。然后找基址,
最后定位在 x=[[5e123c]+0a8b4] ; y=[[5e123c]+0a8b8]
找到游戏光标位置之后就可以根据系统鼠标位置调整了,以下为代码
void SetDhxyCursorPos( POINT & pt ) { POINT GamePos; //游戏里的鼠标位置 POINT SysPos; //系统的鼠标位置 POINT DestPos; //目标鼠标位置 POINT LastPos; //调整的上一个位置 int ix,iy; ULONG uSleeped = 0; DebugPrintA( _T("目标点[%d,%d]"),pt.x,pt.y ); // // 初始化把鼠标移到目标点 // MovePos.x = DestPos.x = pt.x; MovePos.y = DestPos.y = pt.y; SetCursorPos( DestPos.x,DestPos.y ); Sleep( 100 ); // // 调整移偏了的鼠标 // do { // //获取大话西游光标位置 // while( TRUE ) { GamePos.x = 0; GamePos.y = 0; if( FALSE == GetDhxyCursorPos( GamePos ) ) { // // 光标偏到窗口外,无法获取 // 把鼠标调整回原点 // DebugPrintA( _T("找不到光标,调整回原点") ); } else { // break; } } GetCursorPos( &SysPos ); DebugPrintA( _T("游戏光标[%d,%d]"),GamePos.x,GamePos.y ); DebugPrintA( _T("系统光标[%d,%d]"),SysPos.x,SysPos.y ); // // 计算差值 // ix = (int)DestPos.x - (int)GamePos.x; iy = (int)DestPos.y - (int)GamePos.y; DebugPrintA( _T("差值[%d,%d]"),ix,iy ); // // 精确差值为10 // if( abs(ix)<5 && abs(iy)<5 ) { break; } //保存上一个位置 LastPos.x = pt.x; LastPos.y = pt.y; //x if( ix < 0 ) { //光标移太过去的情况 pt.x -= abs(ix); } else { //光标移不够的情况 pt.x += abs(ix); } //y if( iy < 0 ) { //光标移太下面的情况 pt.y -= abs(iy); } else { //光标移太上面的情况 pt.y += abs(iy); } //处理负坐标 if( pt.x < 0 ) { pt.x = abs(pt.x); } if( pt.y < 0 ) { pt.y = abs(pt.y); } DebugPrintA( _T("调整坐标为[%d,%d]"),pt.x,pt.y ); // // 新的调整点是否在游戏窗口内 // //移动新的位置 SetCursorPos( pt.x,pt.y ); //延时 Sleep( 200 ); // // 加延时,以免死循环在这里 // uSleeped ++; if( uSleeped >= 20 ) { DebugPrintA( _T("移动鼠标失败") ); break; } } while ( TRUE ); }
完!