2个物体彼此相继但距离将它们拉开

时间:2010-01-13 18:34:40

标签: flash actionscript-3 actionscript

基本上我正在制作一个游戏,当敌人在他面前时,敌人来到英雄之后。我要做的是

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


moveX += distx * .00005;
moveY += disty * .00005;

现在我不得不将它乘以.00005因为任何更高的东西,让他很快就能成为英雄。我希望敌人移动慢,所以我乘以.00005。我的问题是他们距离越远,怪物移动的速度就越快,这使得英雄更难逃脱。我知道为什么会这样,我只需要知道如何解决它。

我开发游戏,如果怪物离得太远,我会把他从舞台上移走。但问题是越来越远。无论他们相隔多远,我都希望他以恒定的速度行动。

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

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

谢谢你们

5 个答案:

答案 0 :(得分:7)

你所要做的就是限制敌人的速度。

// 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 controller的“比例”部分。你的愿望是让敌人跟踪玩家,而PID控制器是一个很好的简单tunable(想想敌人的困难)跟踪控制器。

在跟踪PID控制器中,首先测量所需目标与当前事态之间的误差。 (您现在就执行此操作,并调用变量distxdisty。)在PID控制器中,您可以记住过去的错误,以便您可以根据错误的不同视角采取不同的行动。 / p>

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;

现在,您可以通过更改p,i,d对象的PID参数来获取敌人的各种行为。要复制当前的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)将控制工程师视为研究封闭系统行为的人,并利用这些知识迫使系统以他们想要的方式行事。

答案 1 :(得分:3)

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

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

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;

答案 2 :(得分:0)

这就是我提出的似乎工作正常

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;
            }

似乎工作正常。如果我可以使用的线路较少,那就太棒了,但我想我会坚持这样的事情。

答案 3 :(得分:0)

所以你想设定一个恒定的速度,只改变方向?

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;

答案 4 :(得分:0)

  

我做错了什么?

当英雄和敌人移动得更远时,它们之间的距离(自然)会变得更大。然后你拿这个距离的一小部分(确切地说是1/20000)并通过它移动敌人。但这意味着随着距离的增大或缩小,你移动敌人的数量会相应增加或缩小。

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