本来是想介绍一些具体的代码,但是这些代码只适合我玩的这款游戏,对大家没什么帮助。不过就此停笔,又好像太突然了。那就介绍一些思路供大家参考。

如何在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() {
	}


}