У меня есть несколько теоретический и основанный на мнениях вопрос. Я строю небольшой генератор частиц с целью создания анимированных изображений (разработанных с использованием JS Web2D Canvas, чтобы легко загрузить полученный файл позже). Проблема заключается в том, что текущее движение от одной точки к другой (например, генератор частиц к конечной точке разрушения) является очень простым, и я хотел бы достичь чего -то более естественного. Я пробовал несколько вещей, но я хотел бы услышать мнение других людей о математических формулах или просто интересных и естественных моделях, которым нужно следовать. Ниже приведен пример того, как он работает в настоящее время, и базовый код, который я использую для путей.class Particle {
/** @type {Vec2} */
pos = { x: 0, y: 0 };
/** @type {string} */
color;
/** @type {number} */
lifespan = PARTICLE_LIFESPAN;
/** @type {Vec2[]} */
trail = [];
/** @type {number} */
trailLength = Math.floor(Math.random() * PARTICLE_MAX_LENGTH);
/** @type {number} */
targetIndex = Math.floor(Math.random() * targets.length);
/** @type {Vec2} */
target =
targets.length > 0
? targets[this.targetIndex]
: { x: Math.random() * -CANVAS_SIZE_X, y: Math.random() * CANVAS_SIZE_Y * 2 };
/** @type {number} */
spawnIndex = Math.floor(Math.random() * spawners.length);
constructor() {
// particle spawn position
this.pos.x =
spawners.length > 0
? spawners[this.spawnIndex].x
: Math.floor(Math.random() * CANVAS_SIZE_X) + 50;
this.pos.y =
spawners.length > 0
? spawners[this.spawnIndex].y
: Math.floor(Math.random() * CANVAS_SIZE_Y) - 50;
// particle color
this.color = PARTICLE_COLOR
? PARTICLE_COLOR
: `#${Math.max(0x100, Math.round(Math.random() * 0xfff))}`;
// creating trail
for (let i = 0; i < this.trailLength; ++i) {
this.trail.push({ x: this.pos.x, y: this.pos.y });
}
}
spread() {
switch (Math.round(Math.random() * 4)) {
case 0:
this.pos.x += PARTICLE_SPREAD;
break;
case 1:
this.pos.x -= PARTICLE_SPREAD;
break;
case 2:
this.pos.y += PARTICLE_SPREAD;
break;
case 3:
this.pos.y -= PARTICLE_SPREAD;
break;
}
}
/** @param {Vec2} target */
follow(target) {
this.trail.push({ x: this.pos.x, y: this.pos.y });
if (this.trail.length > this.trailLength) {
this.trail.shift();
}
if (this.pos.x target.x + 10) {
this.pos.x -= PARTICLE_VELOCITY;
}
if (this.pos.y target.y) {
this.pos.y -= PARTICLE_VELOCITY;
}
if (this.pos.x === target.x && this.pos.y === target.y) {
if (targets.length > 0) {
this.target = targets[this.targetIndex - 1];
}
}
}
}
< /code>
[рендеринговый код] < /p>
/** @param {CanvasRenderingContext2D} ctx */
function render(ctx) {
/** @type {Particle[]} */
const ps = [];
// reusable variables
let i = 0,
y = 0;
const loop = () => {
ctx.fillStyle = CANVAS_BACKGROUND_COLOR;
ctx.fillRect(0, 0, CANVAS_SIZE_X, CANVAS_SIZE_Y);
if (ps.length < PARTICLE_NUMBER) {
for (; i < PARTICLE_NUMBER - ps.length; ++i) ps.push(new Particle());
i = 0;
}
// rendering particles
for (; i < ps.length; ++i) {
ps.lifespan -= 1;
for (; y < ps.trail.length - 1; ++y) {
ctx.strokeStyle = ps.color;
ctx.beginPath();
ctx.moveTo(ps.trail[y].x, ps.trail[y].y);
ctx.lineTo(ps.trail[y + 1].x, ps.trail[y + 1].y);
ctx.stroke();
}
y = 0;
ps.spread();
ps.follow(ps.target);
if (
ps[i].lifespan CANVAS_SIZE_X + PARTICLE_MAX_LENGTH * 2 ||
ps[i].pos.y < -PARTICLE_MAX_LENGTH * 2 ||
ps[i].pos.y > CANVAS_SIZE_Y + (CANVAS_THRESHOLD + PARTICLE_MAX_LENGTH)
) {
ps.splice(i, 1);
}
}
i = 0;
// rendering targets
for (; i < targets.length; ++i) {
ctx.fillStyle = "#ffffff95";
ctx.fillRect(targets[i].x, targets[i].y, 4, 4);
ctx.fillStyle = "#fff";
ctx.fillText(`${i}`, targets[i].x + 2, targets[i].y - 6, 12);
}
i = 0;
// rendering spawnpoints
for (; i < spawners.length; ++i) {
ctx.fillStyle = "#4800c695";
ctx.fillRect(spawners[i].x, spawners[i].y, 4, 4);
ctx.fillStyle = "#0fde00ff";
ctx.fillText(`${i}`, spawners[i].x + 2, spawners[i].y - 6, 12);
}
i = 0;
window.requestAnimationFrame(loop);
};
loop();
}
Подробнее здесь: https://stackoverflow.com/questions/797 ... to-another
Как сделать гладкую дуговую дорожку для одной точки VEC2 в другую? ⇐ Javascript
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
SceneKit, как нарисовать сферу, показывающую сетку, похожую на поверхность, а не гладкую?
Anonymous » » в форуме IOS - 0 Ответы
- 39 Просмотры
-
Последнее сообщение Anonymous
-
-
-
Как установить большой палец и дорожку полосы прокрутки в ExpedDropdownMenu
Anonymous » » в форуме Android - 0 Ответы
- 6 Просмотры
-
Последнее сообщение Anonymous
-