两点之间的线性运动,不断移动位置

Jef*_*loo 0 javascript linear-algebra

我目前的代码存在问题(用Javascript编写); 我有数组对象,随着时间的推移不断填充.对象的示例:

monster.push({
range: 200, 
attackSpeed: 500, 
lastFire: 100,
id: 'ogre',
speed : 50,
pos:[canvas.width*Math.random(), canvas.height*Math.random()],
sprite: new Sprite('images/sheet_characters.png',[508,224],64,64],6,[0])
Run Code Online (Sandbox Code Playgroud)

hero={
attackSpeed: 200,
lastGetHit: Date.now(),
lastFire: Date.now(),
health : 100,
speed: 256, //pixel/second
pos:[canvas.width/2,canvas.height/2],
sprite: new Sprite('images/sheet_characters.png',[256,0],[32,32],8,[0]) };
Run Code Online (Sandbox Code Playgroud)

对象的位置字段经常变化,我想添加一个确定怪物和英雄之间斜率的函数(我们希望怪物向英雄射击),然后攻击应该遵循线性运动.

我现在有什么

for(var i=0; i<monster.length; i++){
        var mob = monster[i];
        mob.sprite.update(delta); //animatie

        var newPos = moveTowards(mob, hero, delta);
        mob.pos[0] = newPos[0]
        mob.pos[1] = newPos[1]
        if(checkBounds(mob.pos,mob.sprite.size)){
            monster.splice(i,1);
        }
        mobAttacks(mob);


        var attack = enemyAttacks[i]; //atacks updaten
        attack.sprite.update(delta);
        attack.pos[0] = attack.speed * Math.cos(attack.direction)));
        attack.pos[1] = attack.speed * Math.sin(attack.direction)));
        if(checkBounds(attack.pos,attack.sprite.sieze)){
            enemyAttacks.splice(i,1);
        }
    }
Run Code Online (Sandbox Code Playgroud)

在这个for循环中,我可以访问发射的怪物的位置以及英雄位置,因为它是一个全局变量.现在攻击的功能是:

function mobAttacks(object)
{
    var distance = Math.sqrt(Math.pow((hero.pos[0]-object.pos[0]),2) +                Math.pow((hero.pos[1]-object.pos[1]),2));
    if( Date.now() - object.lastFire > object.attackSpeed && object.range >= distance)
    {
        deltaY = hero.pos[1] - object.pos[1];
        deltaX = hero.pos[0] - object.pos[0];
        var direction = Math.atan(deltaY/deltaX);
        enemyAttacks.push({ 

        pos:[(object.pos[0]+object.sprite.size[0]/2), (object.pos[1]+object.sprite.size[1]/2)],                     
        direction: direction,
        speed: 128, //pixel/s
        sprite: new Sprite('images/sheet_objects.png', [231,3],[24,24],6,[0])
        });
        object.lastFire = Date.now();
    }
}
Run Code Online (Sandbox Code Playgroud)

计算两个物体之间的角度,然后用怪物的起始位置制作一个新物体(攻击).

结果很奇怪:

斜坡是关闭的,巨石的Y位置也是如此.此外,当英雄在怪物的左侧时,没有巨石被发现.

经过几个小时修改代码后,我得出的结论是,我无法解决当前的问题.

编辑:

attack.pos[0] += attack.speed * Math.cos(attack.direction)*delta;
attack.pos[1] += attack.speed * Math.sin(attack.direction)*delta;
Run Code Online (Sandbox Code Playgroud)

解决了巨石不再从随机位置施放的问题.现在,当我处于第2或第3个kwadrant时,角度不会变为负值(从怪物角度看时位置离开)

hob*_*bbs 5

从代码中获取所有内容,这是不必要的.让

deltaX = hero.pos[0] - object.pos[0];
deltaY = hero.pos[1] - object.pos[1];
Run Code Online (Sandbox Code Playgroud)

然后

distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
deltaX /= distance;
deltaY /= distance;
Run Code Online (Sandbox Code Playgroud)

将生成<deltaX,deltaY>一个标准化的向量(长度为1的向量).

然后你可以delta使用简单的方法更新攻击的位置:

attack.pos[0] += attack.speed * attack.deltaX * delta;
attack.pos[1] += attack.speed * attack.deltaY * delta;
Run Code Online (Sandbox Code Playgroud)

如果你不具备的速度和方向的任何单独使用,也可以预先乘speeddeltaXdeltaY在初始化的攻击,这意味着只更新变得

attack.pos[0] += attack.deltaX * delta;
attack.pos[1] += attack.deltaY * delta;
Run Code Online (Sandbox Code Playgroud)

这很好,很简单.