本来是想介绍一些具体的代码,但是这些代码只适合我玩的这款游戏,对大家没什么帮助。不过就此停笔,又好像太突然了。那就介绍一些思路供大家参考。
如何在action中确保只打开某个窗口
比如在“自动挂机检物”action中,只需要打开“包袱窗口”;在游戏过程,很多窗口被打开过,可能关了,也可能没关。要是一个一个判断窗口存在就关闭太麻烦;我的做法是:
单击“ESC”键,不管三七二十一,关闭全部窗口;然后按“F9”打开包袱;这样就可以确保只有“包袱”窗口打开。
方法很粗暴,但是很管用;在游戏过程中,我可能打开一些窗口,看看信息,不一定看完就关。这种情况下粗暴的方法,反而逻辑最简单。
确保从NPC下方走到NPC附近
可能是因为游戏太古老了,这个自动寻路功能有点粗糙,从上方走到NPC和从下方走到NPC,同样的目标坐标点,停止之后实际坐标差异还有点大,这种差异会导致找不到NPC。挂机过程中也不能保证人物到底在NPC上方,还是下方。
通常的做法是判断游戏坐标,然后调整目标点坐标,恰恰这个游戏很难获取游戏坐标,或者说就是获取不到。
怎么办?粗暴的方法又来了,不管人物在哪个位置,先走到一个地图的辅助坐标位置,这个坐标只要保证在NPC下方就可以了,不需要精确,在地图上随便找一个下方点就可以了。走到这个位置后,再往NPC方向走,就可以保证是从NPC下方走到NPC附近;粗暴的方法,导致简单的逻辑,哈哈哈。至于为什么是选择下方,是因为NPC在地图的上方,人物大概率在NPC下方。。基本上不走冤枉路。
“自动挂机检物”action代码
最后贴上“自动挂机检物”action的代码,仅供大家参考;
action的代码逻辑很简单,就是检查包袱最后一格是否有物品,有了代表包袱满了,然后停止挂机,执行下一个action;其中还有一些处理意外的代码,比人物意外停止挂机,需要重新启动挂机。血量太低,需要停止挂机,呆在原地自动回血等。。
package com.analog.games.mir2.actions;
import java.awt.AWTException;
import java.awt.image.BufferedImage;
import com.analog.action.ActionOrder;
import com.analog.action.GameAction;
import com.analog.games.mir2.entity.Grids;
import com.analog.games.mir2.monitor.PlayerStatus;
import com.analog.games.mir2.tools.Mir2Tools;
import com.analog.system.message.MessageManager;
import com.analog.tools.CommonUtil;
import com.analog.tools.CutImageTool;
import com.analog.tools.ImageMatchTools;
/**
* 检查包袱是否满了
* @author Jiyh
*
*/
@ActionOrder(1)
public class CheckGridsFullAction implements GameAction {
@Override
public void play() {
String actionName = this.getClass().getSimpleName();
ActionStatus.CHECK_AUTOPLAY_OK = true;
MessageManager.addRealMessage("++++++当前动作["+actionName+"]开始+++++\n");
if(!Mir2Tools.AUTO_PLAY){
//开始挂机
Mir2Tools.switchGuaji();
}
MessageManager.addRealMessage("单击ESC键, 关闭已存在窗口...");
//关闭已存在窗口(内挂关不了)
Mir2Tools.closeAllWindows();
CommonUtil.delay(1000);
MessageManager.addRealMessage("单击F9键, 打开包袱窗口...");
Mir2Tools.switchGrid();;
CommonUtil.delay(1000);
//取一下待检查格子颜色
// Grids.unFulledGridColor = CommonUtil.getPointColor(Grids.checkFulledGridPoint);
long playGameStartTime = System.currentTimeMillis();
long playTime = 0;
boolean gridsFulled = false;
do {
if(PlayerStatus.terminate){
ActionStatus.CHECK_AUTOPLAY_OK = false;
return;
}
long currentTime = System.currentTimeMillis();
playTime = currentTime - playGameStartTime;
MessageManager.addRealMessage("已挂机时间["+playTime/1000+"]...");
try {
//检查最后一格,空格子背景图是否存在
BufferedImage creenImage = CutImageTool.getScreeImage(Grids.lastGrid_topleft, Grids.lastGrid_bottomright);
int[] result = ImageMatchTools.findImage(creenImage, ActionPrama.baseDir+Grids.lastGridImageFile);
if(result[0] == -1 && result[1] == -1){
//北京不存在,包袱满了
MessageManager.addRealMessage("特征格子有物品, 包袱满了停止挂机");
gridsFulled = true;
break;
}
} catch (AWTException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
MessageManager.addRealMessage("特征格子无物品, 包袱不满继续挂机");
if(PlayerStatus.PLAYER_STOPED){
int count = 0;
for (int i = 0; i < 10; i++) {
MessageManager.addRealMessage("人物处于停止状态["+PlayerStatus.PLAYER_STOPED+"]");
if(PlayerStatus.PLAYER_STOPED){
count++;
}
MessageManager.addRealMessage("人物处于停止状态次数["+count+"]");
CommonUtil.delay(1000);
}
if(count >= 10){
//人物处于停止状态连续10次,重新开始挂机
MessageManager.addRealMessage("意外中断挂机, 重新挂机...");
Mir2Tools.switchGuaji(true);
}
}
MessageManager.addRealMessage("当前血量["+PlayerStatus.CURR_BLOOD_VOLUME+"%]");
if(PlayerStatus.CURR_BLOOD_VOLUME < ActionPrama.minStripPre){
MessageManager.addRealMessage("血量少于["+ActionPrama.minStripPre+"%], 停止挂机自动恢复血量...");
//停止挂机
Mir2Tools.switchGuaji();
CommonUtil.delay(1000);
while (PlayerStatus.CURR_BLOOD_VOLUME < ActionPrama.maxStripPre){
MessageManager.addRealMessage("当前血量["+PlayerStatus.CURR_BLOOD_VOLUME+"%]小于["+ActionPrama.maxStripPre+"%], 继续自动恢复血量...");
CommonUtil.delay(10000);
}
MessageManager.addRealMessage("当前血量["+PlayerStatus.CURR_BLOOD_VOLUME+"%]大于["+ActionPrama.maxStripPre+"%], 重新挂机...");
//重新挂机
Mir2Tools.switchGuaji();
CommonUtil.delay(1000);
}
CommonUtil.delay(30000);
} while (!gridsFulled);
if(Mir2Tools.AUTO_PLAY){
//停止挂机
Mir2Tools.switchGuaji();
}
MessageManager.addRealMessage("+++++当前动作["+actionName+"]结束+++++\n");
ActionStatus.CHECK_AUTOPLAY_OK = false;
CommonUtil.delay(1000);
}
@Override
public void init() {
}
}