Flash 两个物体相互跟随,但距离将它们分开

Flash 两个物体相互跟随,但距离将它们分开,flash,actionscript-3,actionscript,Flash,Actionscript 3,Actionscript,基本上,我在做一个游戏,当英雄出现时,敌人会追上他。我要做的就是做到这一点 var distx = hero.px - px; var disty = hero.py - py; moveX += distx * .00005; moveY += disty * .00005; 现在我必须把它乘以0.00005,因为再高一点,他就会很快找到英雄。我希望敌人行动缓慢,所以我把它乘以.00005。我的问题是,距离越远,怪物移动得越快,英雄越难逃脱。我知道这是为什么,我只需要知道如何解决它 我开

基本上,我在做一个游戏,当英雄出现时,敌人会追上他。我要做的就是做到这一点

var distx = hero.px - px;
var disty = hero.py - py;


moveX += distx * .00005;
moveY += disty * .00005;
现在我必须把它乘以0.00005,因为再高一点,他就会很快找到英雄。我希望敌人行动缓慢,所以我把它乘以.00005。我的问题是,距离越远,怪物移动得越快,英雄越难逃脱。我知道这是为什么,我只需要知道如何解决它

我开发了一个游戏,如果怪物离我太远,我就把他从舞台上移开。但问题是如何逃脱。我希望他以恒定的速度移动,无论他们相距多远

我还希望通过不使用任何类属性来实现这一点。(即,我希望所有变量都是本地变量)。这个方法也是循环的

我做错了什么?解决方案是什么


谢谢大家,这是我想出来的,看起来不错

var distx = hero.px - px;
            var disty = hero.py - py;

            if(Math.abs(distx) > 100 && Math.abs(disty) > 100)
            {
                moveX += distx * .00001;
                moveY += disty * .00001;                
            }
            else
            {
                moveX += distx * .00005;
                moveY += disty * .00005;
            }

看起来很好用。如果我能用更少的线,那就太好了,但我想我会坚持这样的

那么你想设定一个恒定的速度,只改变方向

var speed = 1;

if (hero.px > px) moveX += speed;
else if (hero.px < px) moveX -= speed;

if (hero.py > py) moveY += speed;
else if (hero.py < py) moveY -= speed;
var速度=1;
如果(hero.px>px)moveX+=速度;
否则,如果(hero.pxpy)moveY+=速度;
否则,如果(hero.py
你所要做的就是限制敌人的速度

// Calculate velocity just as you're doing it
var p = .00005;
var velx = distx * p;
var vely = disty * p;

// Rate limit that velocity
var maxVel = 5; // You will have to tune this value as your max speed
var vel = Math.sqrt(velx*velx + vely*vely);
if (vel > maxVel) {
    var r = maxVel / vel;
    velx *= r;
    vely *= r;
}

// Move the enemy
moveX += velx;
moveY += vely;
实际上,您只实现了控制系统工程师(1)所称的“比例”部分。你的愿望是让敌人跟踪玩家,PID控制器是一个很好的简单可调的跟踪控制器

在跟踪PID控制器中,首先测量期望目标和当前状态之间的误差。(您现在这样做,并调用变量
distx
disty
)在PID控制器中,您保留过去错误的内存,以便根据错误的不同角度采取不同的行动

PID = function() {
    this.p = 0;
    this.i = 0;
    this.d = 0;
    this.reset(0);
};

PID.prototype.reset = function(error) {
    this.error = error;
    this.integral = 0;
    this.differential = 0;
}   

PID.prototype.step = function(error) {
    this.integral += error;
    this.differential = (error - this.error);
    this.error = error;
    var control = this.p * this.error +
                  this.i * this.integral +
                  this.d * this.differential;
    return control;
};
为要控制的对象(敌人)的每个可控状态创建PID控制器。因此,您的更新逻辑将更改为:

// distx and disty are calculated as normal
var velx = pidx.step(distx);
var vely = pidy.step(disty);

moveX += velx;
moveY += vely;
现在,通过改变
PID
对象的
p,i,d
参数,您可以从敌人身上获得各种行为。要复制当前AI,您需要设置:

pidx.p = 0.00005;
pidx.i = 0;
pidx.d = 0;
// same for pidy
通过增加
i
参数并进一步减少
p
可以获得更有趣的AI:

pidx.p = 0.000005;
pidx.i = 0.0005;
pidx.d = 0;
如果敌人持续很长时间,你常常会想清除他的记忆。只需调用
pidx.reset(distx)
即可重置该内存

此外,您还需要对
velx,vely
进行评级限制,如本答案前面所述

所有这些复杂性的好处是什么?与简单的数学相比,敌人的行为非常自然。我还想指出,使用
distx*0.00005
逻辑,您正在沿着正确的轨道前进


(1)把控制工程师想象成那些研究封闭系统行为的人,他们利用这些知识迫使系统按照他们想要的方式运行。

使用一些三角函数来计算你想要移动的角度,然后以恒定的速度朝那个方向移动

disty和distx是直角三角形的腿,斜边是sqrt(distydistry+distxditsx)。sin(角度)=距离/斜边,cos(角度)=距离/斜边(假设x和y向上并向右上升)

我做错了什么

随着英雄和敌人的距离越来越远,他们之间的距离(自然)也越来越大。然后你从这个距离中取一小部分(精确地说是1/200000)移动敌人。但这意味着随着距离的增加或减少,你移动敌人的数量也相应地增加或减少


正如这里的一些其他答案所述,你需要找出敌人需要向玩家移动的方向,然后以固定的数量(而不是分数)向该方向移动他。

如果你想让怪物的速度保持恒定,为什么不使用恒定或硬编码的值呢?是的,但他也遵循这个角色。如果它是硬编码的,他只能朝一个方向移动。这将导致怪物只能朝8个方向中的一个方向移动(N/S/E/W/NE/NW/SE/SW)…这与你最初的解决方案有相同的问题,因为你移动敌人的数量是一个分数,而不是一个固定的数量。
var distx = hero.px - px;
var disty = hero.py - py;
var hyp = Math.sqrt(disty*disty + distx*ditsx);
moveX += speed * distx / hyp;
moveY += speed * disty / hyp;