2016-07-20 2 views
0

Я пишу игру обороны башни. Он работал хорошо до этого момента, когда я пытаюсь создать снаряды:make element следовать за другим элементом

Мои башни создают элементы снарядов, когда крипы находятся в радиусе действия. Я хочу, чтобы эти снаряды переместились на ползучесть в положение 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) рекурсивной функции в цикле бросали расстояние, которое отделяет снаряд от цели и добавить + 1px, пока расстояние не равно 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] - - - Creep

Благодаря

+1

Задайте объект/идентификатор ползучести в снаряде. Затем каждый шаг расчета будет выполнен с помощью * текущей позиции ползучести, которую вы должны получить от ползучести. – 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 часов.

Смежные вопросы