我正在写一个塔防游戏。它运作良好,直到我尝试创建射弹:
当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;
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
由于
答案 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小时。