make元素遵循另一个元素

时间:2016-07-20 13:48:29

标签: javascript

我正在写一个塔防游戏。它运作良好,直到我尝试创建射弹:

当Creeps在范围内时,My Towers会创建弹丸元素。我希望这些弹丸在X,Y位置移动到Creep,当触碰时(因此位置相同)应触发某些东西。

没有看到任何好的例子。 我试过了: 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>
&#13;
&#13;
&#13;

3)循环的递归函数抛出将射弹与目标分开的距离并加上+ 1px直到距离为0 - 这让我很头疼,因为元素在空间中非常奇怪地移动,其次这不灵活最大移动速度是0.1s延迟的递归,速度不是那么快,每次运行增加更多像+ 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); }); }
  }
}

你会如何写这个&#34;运动&#34;功能

[T] - - - Creep

由于

1 个答案:

答案 0 :(得分:0)

好吧,这就是我解决它的方式,感谢霍尔格斯回答:

/* 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小时。