【直播】我要做一个玩游戏自动机



我打算做一个玩游戏自动机。

楼主 dtph007  发布于 2015-07-30 21:32:00 +0800 CST  
最近玩一个手机游戏叫打炮英雄,控制角度发射炮弹 抛物线打中敌人。
总是打不中就想做一个程序来打。
但由于是安卓游戏,实现有不便之处。
就想着找个PC上的游戏,做一个可以自动打的程序。
就想起了很多年前玩过的一个游戏,没想到现在还有。


那就是弹弹堂。

楼主 dtph007  发布于 2015-07-30 21:34:00 +0800 CST  
首先第一步是识别出左下角的角度,和最上面中间的风力和风向。
第二步是识别出两个人的距离和高度。


其实这个第一步是很容易实现的,位置在页面中固定的,只要写个算法识别出来就行。
这个可以采用编辑距离,用我以前写过的识别验证码的算法就可以。
风向的话,识别一下箭头,这个很明显,也比较容易。


第二步我目前还没有想到,图中这个只是在一个屏幕中的情况。实际中还有超过一个屏幕的,两个屏幕的情况。


这个周末先实现这两步。

楼主 dtph007  发布于 2015-07-30 21:38:00 +0800 CST  
好像好多人不知道外挂是什么意思。
外挂是非法利用游戏BUG,或者游戏接口,修改或截取数据包。
比如DNF弄一个刀刀风暴,这绝壁是外挂。


但我做的是一个自动机,是一个机器人,只是把我的聪明才智用程序表达出来。

楼主 dtph007  发布于 2015-07-31 12:11:00 +0800 CST  
今天给大家讲讲什么是玩游戏自动机。
玩游戏自动机,就是有限状态机 + 自动的状态转换。
什么是有限状态机呢?
就是一个机器,它有一些状态,是有限的。

楼主 dtph007  发布于 2015-07-31 13:51:00 +0800 CST  
以弹弹堂玩游戏自动机为例。
它就是有几个有限的状态。
进入游戏之后,轮到自己了,这是轮到自己的状态。
在这个状态下可以移动和调整大炮的角度。
点击空格之后,是准备发射的状态。
这个状态下可以蓄力和调整大炮角度。
释放空格之后,是发射中的状态。
这个状态下,只能看。

楼主 dtph007  发布于 2015-07-31 13:53:00 +0800 CST  
发射完毕之后,炮弹落地,是发射完毕的状态。


然后就该敌人玩了,和自己没关系了。
敌人发射炮弹完毕之后,又轮到自己了。


又回到了就绪状态。
所以这些状态转换是有限的。

楼主 dtph007  发布于 2015-07-31 13:54:00 +0800 CST  
画成状态转换图就是:


楼主 dtph007  发布于 2015-07-31 14:06:00 +0800 CST  
周末了。开始撸码

楼主 dtph007  发布于 2015-08-01 08:52:00 +0800 CST  
把状态机用注解的形式描述出来。




楼主 dtph007  发布于 2015-08-01 09:53:00 +0800 CST  
今天撸了一天,把状态机的代码撸出来了。




状态机代码运行效果:


楼主 dtph007  发布于 2015-08-01 16:40:00 +0800 CST  
发错图了。状态机代码运行效果:


楼主 dtph007  发布于 2015-08-01 16:41:00 +0800 CST  
状态机的逻辑代码可以先不写。
接下来是写识别游戏中的一些必要信息。

楼主 dtph007  发布于 2015-08-01 16:45:00 +0800 CST  
定义一下游戏世界中的基本元素。
风力的信息:
public class Wind {
/**
* 左右
*/
boolean isLeft;


/**
* 风力值
*/
double value;


public boolean isLeft() {
return isLeft;
}


public void setLeft(boolean isLeft) {
this.isLeft = isLeft;
}


public double getValue() {
return value;
}


public void setValue(double value) {
this.value = value;
}
}

楼主 dtph007  发布于 2015-08-01 17:00:00 +0800 CST  
自己的信息。
public class SelfInfo {


/**
* 角度
*/
Integer angle;


/**
* 力量
*/
Integer power;


Integer width;


Integer height;


public Integer getAngle() {
return angle;
}


public void setAngle(Integer angle) {
this.angle = angle;
}


public Integer getPower() {
return power;
}


public void setPower(Integer power) {
this.power = power;
}


public Integer getWidth() {
return width;
}


public void setWidth(Integer width) {
this.width = width;
}


public Integer getHeight() {
return height;
}


public void setHeight(Integer height) {
this.height = height;
}
}

楼主 dtph007  发布于 2015-08-01 17:00:00 +0800 CST  
游戏世界的重力加速度,力量系数,风力系数。
这个自动机的目的之一,就是让机器学到这3个系数。
这几个系数我不会手动给出,最终会让机器学习到。


public class WorldInfo {
/**
* 重力加速度
*/
double gravity;


/**
* 力量系数
*/
double powerRatio;


/**
* 风力系数
*/
double windRatio;


public double getGravity() {
return gravity;
}


public void setGravity(double gravity) {
this.gravity = gravity;
}


public double getPowerRatio() {
return powerRatio;
}


public void setPowerRatio(double powerRatio) {
this.powerRatio = powerRatio;
}


public double getWindRatio() {
return windRatio;
}


public void setWindRatio(double windRatio) {
this.windRatio = windRatio;
}
}

楼主 dtph007  发布于 2015-08-01 17:02:00 +0800 CST  
今天处理了一下图像。
角度很容易识别。
发现风力不太容易,暂时先不搞了。


楼主 dtph007  发布于 2015-08-02 17:39:00 +0800 CST  
就绪时,屏幕固定位置有固定字体的PASS,很容易识别。
写个汉明距离就OK了。


楼主 dtph007  发布于 2015-08-02 17:57:00 +0800 CST  
把pass获取出来,二值化。




转成数组:(还看得出来是pass吗)


楼主 dtph007  发布于 2015-08-02 17:59:00 +0800 CST  
5秒检测一次屏幕:




fire(ready)会走到状态机的
public void fromReadyToReadyOnReady(Context context) throws Exception {
dandanTangGame.ready();
}


就调用到dandanTangGame.ready()方法里了。

楼主 dtph007  发布于 2015-08-02 18:01:00 +0800 CST  

楼主:dtph007

字数:6969

发表时间:2015-07-31 05:32:00 +0800 CST

更新时间:2017-10-17 09:52:12 +0800 CST

评论数:603条评论

帖子来源:百度贴吧  访问原帖

 

热门帖子

随机列表

大家在看