Супердекомпрессия, реализовать универсальный гравитационный и отталкивающий эффект частиц

внешний интерфейс JavaScript
Супердекомпрессия, реализовать универсальный гравитационный и отталкивающий эффект частиц

предисловие

Предыдущий Xiaobao реализовал классный эффект использования частиц для формирования «Пакета поля битвы», который открыл дверь в мир частиц для Xiaobao. Мир частиц действительно классный. Простая комбинация и преобразование могут создавать суперкрасочные эффекты. Сегодня Xiaobao будет показать вам, как реализовать частицы Эффект всасывания и отталкивания, вы можете попробовать, супер декомпрессия и счастье.

Адрес опыта:Гравитация и отталкивание частиц

частица реализации

Во-первых, для достижения полноэкранного случайного распределения частиц в этой статье генерируется в общей сложности2500частица, положение(x,y)Генерируется случайными числами, форма частицы передается черезfillRectрисовать.

// 创建粒子类
class Particle {
  constructor() {
    // rand 是封装的生成 (n,m) 之间随机数的函数
    // x, y 粒子位置
    this.x = rand(0, canvas.width);
    this.y = rand(0, canvas.height);
    // vx, vy 粒子在x, y 轴的移动速度
    this.vx = rand(-1, 1);
    this.vy = rand(-1, 1);
    // 粒子大小
    this.r = rand(1, 3);
    // 粒子颜色
    this.col = `rgba(${Math.round(rand(150, 200))}, ${Math.round(
      rand(100, 255)
    )}, ${Math.round(rand(180, 255))},${Math.random() + 0.2})`;
  }
}
// 生成粒子
function initParticle() {
    for (var i = 0; i < part_num; i++) {
      P.push(new Particle());
    }
}

particles.png

После того, как частицы, заполняющие экран, сгенерированы, давайте займемся эффектами частиц.

гравитационный эффект

Для достижения эффекта всемирного тяготения сначала нужен центр тяжести, начальное положение — центральное положение, а когда мышь начинает двигаться, положение мыши — центр тяжести. Чтобы сделать это более очевидным, передайтеcanvasНарисуйте крест в центре тяжести.

// X, Y 为引力中心位置
// X, Y 初始化
X = window.innerWidth / 2;
Y = window.innerHeight / 2;

// 绘制十字架
ctx.beginPath();
ctx.moveTo(X, Y - 10);
ctx.lineTo(X, Y + 10);
ctx.moveTo(X - 10, Y);
ctx.lineTo(X + 10, Y);
ctx.stroke();

// 移动鼠标时,修改引力中心位置
window.onmousemove = function (e) {
    X = e.clientX;
    Y = e.clientY;
};

После определения центра тяжести уточняется, что частица движется в направлении, радиально приближающемся к центру тяжести, и чем он ближе, тем больше скорость. При инициализации частиц укажитеvx,vyсвойства частиц вдольx,yСкорость, с которой движется ось, и поэтому может быть измененаvx,vyСвойство заставляет частицы постоянно закрывают гравитационный центр.

Прежде чем реализовать вышеупомянутые эффекты, давайте рассмотрим какие знания тригонометрические функции:

Из приведенного выше рисунка видно, чтоr*cos, r*sinдляrСоответственноx,yпроекция на ось, еслиrзаменена очень маленькой длиной,r*cos, r*sinТо есть частица в единицу времениx,yРасстояние, которое необходимо переместить по оси, то есть скоростьvx,vy. Итак, нам нужно найти угол частицы к центру тяжести.angle.

var dx = p.x - X, // 水平距离
    dy = p.y - Y, // 垂直距离
    dist = Math.sqrt(dx * dx + dy * dy), // 到引力中心的距离
    angle = Math.atan2(dy, dx); // 角度

Система координат в интерфейсе немного отличается от системы координат в математике,xПоложительное направление оси такое же, ноyПоложительное направление оси направлено вниз, а косинус и синус каждого квадранта следующие:

condiFront.jpg

Следующим шагом после рассмотрения вышеизложенных знаний является вычисление того, как движутся частицы. (Чем ближе частица к центру тяжести, тем быстрее она движется)

Возьмем три частицы в системе координат, потренируемся:

zuobiao.png

частица cos/sin dx/dy len*cos/len*sin
A позитивный негативный позитивный негативный позитивный негативный
C отрицательный/отрицательный отрицательный/отрицательный отрицательный/отрицательный
D положительный / положительный положительный / положительный положительный / положительный

dxа такжеdy- длина частицы от центра тяжести вx,yВ проекции на ось есть положительные и отрицательные значения, например точка А,dxA > 0, dyA < 0, так что если частица A хочет быть близко к центру тяжести B , ей нужно установитьvx < 0, vy > 0, чтобы уменьшить расстояние между A и B.

Из таблицы мы видим, чтоlen*cosа такжеlen*sinточно сdxа такжеdyтот же знак, поэтому установите-len*cosа также-len*sin- скорость движения частицы частицы, которая может заставить частицу A продолжать приближаться к гравитационному центру B (lenна любую длину)

// 粒子越靠近引力中心,dist越小,一方面可以保证粒子速度越来越快,另一方面也达成len不断修改的要求
p.vx -= (20 / (p.r * dist)) * Math.cos(angle);
p.vy -= (20 / (p.r * dist)) * Math.sin(angle);

p.x += p.vx;
p.y += p.vy;

attact.gif

Эффект отталкивания

Если свет имеет гравитационный эффект, большая часть частиц будет притягиваться к середине после игры в течение некоторого времени, а окружающая область будет казаться пустой, и после долгой игры она будет несколько монотонной. Тогда давайте добавим эффект отталкивания, есть всасывание, есть отталкивание и эффект живой.

Эффект эффекта отталкиванияЩелкните мышью, частицы будут распространяться по кругу, чтобы обеспечить эффективность диффузии, установите большой радиус диффузии..

При реализации основы гравитации частице нужно только обеспечить, чтобы окружающиеlen*cosа такжеlen*sinточно сdxа такжеdyОдин и тот же номер может быть.

p.vx += (250 / (p.r * dist)) * Math.cos(angle);
p.vy += (250 / (p.r * dist)) * Math.sin(angle);

bounce.gif

Эффект отталкивания частиц не очень распаковывается, но можно найти относительно очевидную проблему.Многие частицы отталкиваются от страницы, а частиц на странице становится все меньше и меньше.Это не весело, поэтому добавляйте логику для обработки границ .

Граничная обработка

Логику обработки границы реализовать несложно: когда частица достигает границы, например, достигает верхней границы в вертикальном направлении, это означает, что частицаvyЕсли это отрицательное значение, измените его на противоположный знак, тогда частица сможет отскакивать назад, а остальные направления обрабатываются аналогично.

function bounce(b) {
  // 左边界
  if (b.x < b.r) {
    b.x = b.r;
    b.vx *= -1;
  }
  // 右边界
  if (b.x > canvas.width - b.r) {
    b.x = canvas.width - b.r;
    b.vx *= -1;
  }
  // 上边界
  if (b.y - b.r < 0) {
    b.y = b.r;
    b.vy *= -1;
  }
  // 下边界
  if (b.y > canvas.height - b.r) {
    b.y = canvas.height - b.r;
    b.vy *= -1;
  }
}

attactAndBounce.gif

Репозиторий исходного кода

Адрес источника:Гравитация и отталкивание частиц

Адрес опыта:Гравитация и отталкивание частиц

Не забудьте поставить пакету ⭐, если вы считаете его полезным.

Замечательные статьи в прошлом

послесловие

Друзья, если вы чувствуете, что эта статья вам полезна, ставьте лайк Абао👍 или подписывайтесь➕ — это самая большая поддержка для меня.

Кроме того, если есть какие-либо проблемы с этой статьей или если вы не понимаете часть статьи, вы можете ответить мне в области комментариев, давайте обсудим, изучим и добьемся успеха вместе!