【直播】我要做一个玩游戏自动机
最近玩一个手机游戏叫打炮英雄,控制角度发射炮弹 抛物线打中敌人。
总是打不中就想做一个程序来打。
但由于是安卓游戏,实现有不便之处。
就想着找个PC上的游戏,做一个可以自动打的程序。
就想起了很多年前玩过的一个游戏,没想到现在还有。
那就是弹弹堂。
总是打不中就想做一个程序来打。
但由于是安卓游戏,实现有不便之处。
就想着找个PC上的游戏,做一个可以自动打的程序。
就想起了很多年前玩过的一个游戏,没想到现在还有。
那就是弹弹堂。
首先第一步是识别出左下角的角度,和最上面中间的风力和风向。
第二步是识别出两个人的距离和高度。
其实这个第一步是很容易实现的,位置在页面中固定的,只要写个算法识别出来就行。
这个可以采用编辑距离,用我以前写过的识别验证码的算法就可以。
风向的话,识别一下箭头,这个很明显,也比较容易。
第二步我目前还没有想到,图中这个只是在一个屏幕中的情况。实际中还有超过一个屏幕的,两个屏幕的情况。
这个周末先实现这两步。
第二步是识别出两个人的距离和高度。
其实这个第一步是很容易实现的,位置在页面中固定的,只要写个算法识别出来就行。
这个可以采用编辑距离,用我以前写过的识别验证码的算法就可以。
风向的话,识别一下箭头,这个很明显,也比较容易。
第二步我目前还没有想到,图中这个只是在一个屏幕中的情况。实际中还有超过一个屏幕的,两个屏幕的情况。
这个周末先实现这两步。
好像好多人不知道外挂是什么意思。
外挂是非法利用游戏BUG,或者游戏接口,修改或截取数据包。
比如DNF弄一个刀刀风暴,这绝壁是外挂。
但我做的是一个自动机,是一个机器人,只是把我的聪明才智用程序表达出来。
外挂是非法利用游戏BUG,或者游戏接口,修改或截取数据包。
比如DNF弄一个刀刀风暴,这绝壁是外挂。
但我做的是一个自动机,是一个机器人,只是把我的聪明才智用程序表达出来。
今天给大家讲讲什么是玩游戏自动机。
玩游戏自动机,就是有限状态机 + 自动的状态转换。
什么是有限状态机呢?
就是一个机器,它有一些状态,是有限的。
玩游戏自动机,就是有限状态机 + 自动的状态转换。
什么是有限状态机呢?
就是一个机器,它有一些状态,是有限的。
以弹弹堂玩游戏自动机为例。
它就是有几个有限的状态。
进入游戏之后,轮到自己了,这是轮到自己的状态。
在这个状态下可以移动和调整大炮的角度。
点击空格之后,是准备发射的状态。
这个状态下可以蓄力和调整大炮角度。
释放空格之后,是发射中的状态。
这个状态下,只能看。
它就是有几个有限的状态。
进入游戏之后,轮到自己了,这是轮到自己的状态。
在这个状态下可以移动和调整大炮的角度。
点击空格之后,是准备发射的状态。
这个状态下可以蓄力和调整大炮角度。
释放空格之后,是发射中的状态。
这个状态下,只能看。
发射完毕之后,炮弹落地,是发射完毕的状态。
然后就该敌人玩了,和自己没关系了。
敌人发射炮弹完毕之后,又轮到自己了。
又回到了就绪状态。
所以这些状态转换是有限的。
然后就该敌人玩了,和自己没关系了。
敌人发射炮弹完毕之后,又轮到自己了。
又回到了就绪状态。
所以这些状态转换是有限的。
定义一下游戏世界中的基本元素。
风力的信息:
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;
}
}
风力的信息:
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;
}
}
自己的信息。
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;
}
}
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;
}
}
游戏世界的重力加速度,力量系数,风力系数。
这个自动机的目的之一,就是让机器学到这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;
}
}
这个自动机的目的之一,就是让机器学到这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;
}
}
5秒检测一次屏幕:
fire(ready)会走到状态机的
public void fromReadyToReadyOnReady(Context context) throws Exception {
dandanTangGame.ready();
}
就调用到dandanTangGame.ready()方法里了。
fire(ready)会走到状态机的
public void fromReadyToReadyOnReady(Context context) throws Exception {
dandanTangGame.ready();
}
就调用到dandanTangGame.ready()方法里了。