2016-07-20 181 views
0

我正在写一个塔防游戏。它运作良好,直到我尝试制作投射物为止:让元素跟随另一个元素

我的塔在Creeps在范围之内时创建了子弹元素。我希望这些投射物能够移动到X,Y位置的爬行位置,并且当碰触(因此位置相同)时,应该触发某些东西。

还没有看到任何好的例子。 我试过了: 1)立即将投射物的位置设置到小兵的位置 - 这是失败的,因为此时击中是瞬间的,并且之后发生移动动画。 2)立即将弹丸位置设置到爬行位置,但这次有一个转换延迟 - 这是因为目标在移动,因此弹丸从不碰到蠕变。

查看这个非常简单的例子:

var e = document.getElementById('test') 
 
var g = document.getElementById('goal') 
 

 
var i = 0; 
 
var int = setInterval(function() { 
 
    i += 1; 
 
    g.style.left = i + 'px'; 
 
    g.style.top = 50 + i + 'px'; 
 
    e.style.top = g.style.top; 
 
    e.style.left = g.style.left; 
 
    if(e.getBoundingClientRect().left >= g.getBoundingClientRect().left && e.getBoundingClientRect().top >= g.getBoundingClientRect().top) { 
 
    console.log('boom'); 
 
    } 
 
}, 50)
#test, #goal { 
 
    width: 10px; 
 
    height: 10px; 
 
    top: 0; 
 
    left: 0; 
 
    background-color: #00f; 
 
    position: absolute; 
 
    transition: top 0.5s linear, left 0.5s linear; 
 
} 
 

 
#goal { 
 
    background-color: #f00; 
 
    top: 50px; 
 
    left: 0; 
 
    transition: top 0s, left 0s; 
 
}
<div id="test"></div> 
 
<div id="goal"></div>

3)的递归功能,以循环扔的分离从目标弹丸和距离加+ 1像素,直到该距离为0 - 此让我头痛,因为元素在空间中移动非常奇怪,其次这是不灵活的,因为最大移动速度是0.1秒延迟的递归,这并不是很快,并且每次运行增加更多像+ 10px可能会导致抛射物去远。

这里是递归函数,这可能是完全错误的做法感动我猜元素:

// move element function 
function moveElement(el, dir, cb) { 
    if(!isPaused){ 
    direction = dir; 
    // negative distance augment distance 
    if(el.dist[direction] < 0) { 
     el[direction]--; 
     el.dist[direction]++; 
    // positive distance reduce distance 
    } else if(el.dist[direction] > 0) { 
     el[direction]++; 
     el.dist[direction]--; 
    } 
    // update creep 
    (dir === 'x') ? el.e.style.left = `${el.x}px` : el.e.style.top = `${el.y}px`; 
    } 
    if (el.dist[dir] !== 0) { 
    setTimeout(function() { 
     return moveElement(el, dir, cb); 
    }, el.ms); 
    } else { 
    return cb(el, dir, cb); 
    } 
} 

// the projectile 
// the creep class is actually quite similar 
class Projectile { 
    constructor(field, creep) { 
    this.ms = 10; 
    this.x = field.x; 
    this.y = field.y; 
    this.follow = true; 
    this.e = createElement('div', `projectile projectile__${field.tower.name}`); 

    this.e.style.left = `${this.x}px`; 
    this.e.style.top = `${this.y}px`; 
    field.e.appendChild(this.e); 

    this.setupMove(this, creep); 
    } 

    setupMove(fromPos, toPos) { 
    this.dist = { 
     x: toPos.x - fromPos.x, 
     y: toPos.y - fromPos.y 
    }; 
    if(this.dist.x !== 0) { 
     moveElement(this, 'x', (el) => { console.log(el.dist.x); }); } 
    if(this.dist.y !== 0) { 
     moveElement(this, 'y', (el) => { console.log(el.dist.y); }); } 
    } 
} 

你怎么会写这个“运动”的功能?

[T] - - - 蠕变

感谢

+1

在弹丸中设置蠕变物体/ ID。然后,每次移动计算都将通过您必须从蠕变中获得的* current * creep位置来完成。 – Holger

回答

0

没关系,这是我如何解决它,这要归功于Holgers答案:

/* projectile */ 
class Projectile { 
    constructor(field, creep) { 
    this.ms = field.tower.pms; 
    this.x = field.x; 
    this.y = field.y; 
    this.follow = field.tower.follow; 
    this.e = createElement('div', `projectile projectile__${field.tower.name}`); 

    this.e.style.left = `${this.x}px`; 
    this.e.style.top = `${this.y}px`; 
    field.e.appendChild(this.e); 

    moveProjectile(this, creep); 
    } 
} 

// move element 
function moveProjectile(el, creep) { 
    // calculate the distance 
    // (x:10,y:20)[cur] -dist-> [next](x:20,y:20) 
    // next.x(20) - cur.x(10) = +10 dist 
    // next.y(20) - cur.y(20) = 0 dist 
    el.dist = { 
    x: creep.x - el.x, 
    y: creep.y - el.y 
    }; 
    let loop = setInterval(interval, 60); 

    function interval() { 
    if (!isPaused) { 
     let increment = calculateIncrement(el, creep); 

     el.x += increment.x; 
     el.dist.x -= increment.x; 
     el.y += increment.y; 
     el.dist.y -= increment.y; 

     if(increment.steps < 0.5) { 
     console.log('hit'); 
     clearInterval(loop); 
     } else { 
     el.e.style.left = `${el.x}px`; 
     el.e.style.top = `${el.y}px`; 
     } 
    } 
    } 
} 

// this function calculates the x and y increments 
// that have to be added each step. Assume following example: 
// assume a movementspeed (ms) of 1 
// 0 1 2 3 -> x 
// 0 A 
// -1 
// -2  B 
// -3 
// | 
// v 
// y 
// point A is at 0,0 point B at 2,3 to get a smooth movement 
// we need to know how many steps are needed to reach the goal 
// 1. Which coordinate is further away? (regardless if positive or negative) X or Y (x = 3) 
// 2. How many steps do we need to reach B? x/ms (3/1 = 3) 
// 3. Thus per step we need an increment of _ for y? y/(x/ms) (2/(3/1) = 0.666) 
// 4. was it a positive or negative distance? 
function calculateIncrement(el, creep) { 
    let increment = {}; 

    if(el.follow) { 
    el.dist = { 
     x: creep.x - el.x, 
     y: creep.y - el.y 
    }; 
    } 

    let x = Math.abs(el.dist.x); 
    let y = Math.abs(el.dist.y); 

    if (x > y) { // 1. 
    increment.x = el.ms; 
    increment.steps = x/el.ms; // 2. 
    increment.y = y/increment.steps; // 3. 
    } else { // 1. 
    increment.y = el.ms; 
    increment.steps = y/el.ms; // 2. 
    increment.x = x/increment.steps; // 3. 
    } 

    // 4. 
    if(el.dist.x < 0) { increment.x *= -1; } 
    if(el.dist.y < 0) { increment.y *= -1; } 

    return increment; 
} 

我试图评论它一样好尽可能。希望它能帮助任何有同样问题的人。本来会救我8小时。