1. Вики
  2. /Частицы
  3. /Ваша первая частица

Ваша первая частица

Создайте частицу рубиновой искры для Minecraft Bedrock шаг за шагом: файл частицы, текстура, кривые, события и как показать её в игре.

Частицы - это маленькие плоские картинки, которые в Minecraft повсюду: дым от костра, сердечки над довольным животным, пузырьки под водой. В этом гайде вы сделаете свою: рубиновую искру. Это вспышка маленьких красных огоньков, которые поднимаются вверх, мерцают и гаснут.

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

Только пакет ресурсов

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

Файлы

Пакет ресурсов
RP/
  particles/
    ruby_sparkle.json
    ruby_dust.json
  textures/
    particle/
      ruby_sparkle.png

Игра загружает каждый файл .json из папки particles. Имя файла не важно, но если оно совпадает с именем частицы, всё легче найти.

Эмиттеры и частицы

Прежде чем что-то писать, полезно знать две части любого эффекта:

  • Эмиттер - это невидимый спавнер. Он решает, сколько частиц появится, где они начнут путь и как долго он будет их создавать.
  • Частицы - это маленькие картинки. Каждая решает, как она двигается, как выглядит и когда исчезает.

Поэтому компоненты частиц делятся на два семейства. Названия, которые начинаются с minecraft:emitter_, настраивают спавнер. Названия, которые начинаются с minecraft:particle_, настраивают каждую картинку. Писать их можно в любом порядке.

Часть файлаЧто в ней
descriptionИмя частицы, а также её материал и текстура
curvesНеобязательно. Значения, которые меняются за время жизни частицы
eventsНеобязательно. То, что происходит в определённые моменты, например появление новых частиц
componentsВсё остальное: настройки эмиттера и частиц

Шаг 1: текстура

Нарисуйте PNG 8x8 и сохраните его как RP/textures/particle/ruby_sparkle.png. Хорошо подойдёт маленькая четырёхконечная звёздочка.

Рисуйте её белым и светло-серым, а не красным. Потом вы окрасите её в нужный цвет, а окрашивание умножает пиксели. Белый превращается в любой цвет, а вот красная картинка, окрашенная в синий, станет почти чёрной.

Оставьте фон полностью прозрачным. Частицы всегда плоские квадраты, так что форму им дают именно прозрачные пиксели.

Шаг 2: описание

Создайте файл частицы и начните с её имени и внешнего вида:

RP/particles/ruby_sparkle.json
{
  "format_version": "1.10.0",
  "particle_effect": {
    "description": {
      "identifier": "wiki:ruby_sparkle",
      "basic_render_parameters": {
        "material": "particles_alpha",
        "texture": "textures/particle/ruby_sparkle"
      }
    },
    "components": {}
  }
}
  • identifier - имя, по которому вы запускаете частицу. Всегда давайте ей своё пространство имён (здесь wiki:), чтобы она никогда не пересеклась с ванилью или другим аддоном.
  • texture - путь к вашему PNG от корня пакета ресурсов, без .png.
  • material решает, как рисуются прозрачные пиксели:
МатериалПикселиПодходит для
particles_alphaЛибо полностью непрозрачные, либо полностью невидимыеПиксель-арт, как ванильные сердечки и криты. Безопасный выбор.
particles_blendМогут быть полупрозрачнымиМягкий дым, туман, тающая пыль
particles_addДобавляются поверх того, что за ними, поэтому светятсяМагия, искры, огонь, свет

Наша искра должна светиться, поэтому, когда всё заработает, смените материал на particles_add. Пока тестируете, начните с particles_alpha, его проще всего разглядеть.

Версия формата

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

Шаг 3: эмиттер

Теперь заполните components. Сначала спавнер. Нам нужна одна быстрая вспышка из 12 искр, разбросанных вокруг небольшого шара:

RP/particles/ruby_sparkle.json (внутри components)
"minecraft:emitter_lifetime_once": {
  "active_time": 0.5
},
"minecraft:emitter_rate_instant": {
  "num_particles": 12
},
"minecraft:emitter_shape_sphere": {
  "radius": 0.4,
  "direction": "outwards"
},
  • emitter_lifetime_once запускает эмиттер один раз и затем удаляет его.
  • emitter_rate_instant создаёт все 12 частиц в один момент.
  • emitter_shape_sphere размещает их внутри шара радиусом 0.4 блока, и каждая смотрит от центра наружу.

Каждому эмиттеру нужен один компонент времени жизни и один компонент частоты. Без них ничего не появится. Форма необязательна: если её не указать, каждая частица начнёт точно из центра.

Шаг 4: частицы

Теперь расскажите каждой искре, как двигаться и выглядеть. Добавьте это после компонентов эмиттера:

RP/particles/ruby_sparkle.json (внутри components)
"minecraft:particle_lifetime_expression": {
  "max_lifetime": "math.random(0.6, 1.2)"
},
"minecraft:particle_initial_speed": 1.5,
"minecraft:particle_motion_dynamic": {
  "linear_acceleration": [0, 1.2, 0],
  "linear_drag_coefficient": 3
},
"minecraft:particle_appearance_billboard": {
  "size": [0.12, 0.12],
  "facing_camera_mode": "lookat_xyz",
  "uv": {
    "texture_width": 8,
    "texture_height": 8,
    "uv": [0, 0],
    "uv_size": [8, 8]
  }
},
"minecraft:particle_appearance_tinting": {
  "color": [1, 0.15, 0.3, 1]
}

Вот что делает каждый из них:

  • Время жизни. Каждая искра живёт от 0.6 до 1.2 секунды. math.random выбирает новое число для каждой частицы, поэтому они исчезают не все сразу. Это Molang, маленький математический язык Bedrock.
  • Скорость. Они вылетают со скоростью 1.5 блока в секунду в направлении, которое задала сфера.
  • Движение. linear_acceleration каждую секунду немного подталкивает их вверх, и они парят, как угольки. linear_drag_coefficient - сопротивление воздуха: оно быстро гасит первый рывок.
  • Билборд. Каждая частица - плоский квадрат. size - половина его ширины и высоты в блоках, так что 0.12 даёт квадрат шириной примерно в четверть блока. lookat_xyz держит его повёрнутым к игроку.
  • UV. Выбирает, какую часть текстуры показывать. Наша текстура - одна картинка 8x8, поэтому берём её целиком: начинаем с 0, 0 и берём 8, 8.
  • Окрашивание. Красный, зелёный, синий и альфа, каждый от 0 до 1. [1, 0.15, 0.3, 1] - это рубиново-красный. Можно также написать "#FF2650".

Сохраните, загрузите мир и введите:

Чат
/particle wiki:ruby_sparkle ~ ~1 ~

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

Шаг 5: заставьте её мерцать с помощью кривой

Сейчас каждая искра сохраняет один размер, пока внезапно не исчезнет. Это исправляет кривая. Это значение, которое следует форме, заданной несколькими числами.

Добавьте блок curves рядом с description и components:

RP/particles/ruby_sparkle.json (внутри particle_effect)
"curves": {
  "variable.ruby_size": {
    "type": "linear",
    "input": "variable.particle_age / variable.particle_lifetime",
    "nodes": [0.2, 1, 0.6, 0]
  }
},
  • Имя должно начинаться с variable.. Игра вычисляет кривую для каждой частицы в каждом кадре и сохраняет результат в эту переменную.
  • input - в каком месте кривой мы находимся. Возраст, делённый на время жизни, идёт от 0 (только родилась) до 1 (вот-вот исчезнет).
  • nodes - значения по пути, равномерно распределённые от начала до конца. Наша искра начинается маленькой (0.2), вырастает до полного размера (1), уменьшается (0.6) и пропадает (0).
  • type - как кривая идёт между узлами. linear рисует прямые линии. catmull_rom и bezier делают плавные изгибы, а bezier_chain позволяет самому задать каждую точку и наклон.

Теперь используйте переменную в размере билборда:

Внутри minecraft:particle_appearance_billboard
"size": ["0.12 * variable.ruby_size", "0.12 * variable.ruby_size"],

Чтобы частица угасала, окрашивание тоже может менять цвет за время её жизни. gradient перечисляет цвета, а interpolant выбирает, где мы между ними:

Внутри components
"minecraft:particle_appearance_tinting": {
  "color": {
    "gradient": ["#FFFF8FA8", "#FFFF2650", "#00A0002A"],
    "interpolant": "variable.particle_age / variable.particle_lifetime"
  }
}

Каждый цвет здесь записан как #AARRGGBB, то есть первые два символа - это альфа. Искра начинается бледно-розовой, становится рубиново-красной и заканчивается тёмной и невидимой. С particles_add тёмные цвета растворяются в ничто, и для светящихся эффектов это смотрится чудесно.

Шаг 6: добавьте хлопок с помощью события

События заставляют что-то происходить в определённый момент. Давайте оставлять крошечное облачко пыли там, где исчезает каждая искра.

Сначала сделайте пыль. Это второй, более мелкий эффект:

RP/particles/ruby_dust.json
{
  "format_version": "1.10.0",
  "particle_effect": {
    "description": {
      "identifier": "wiki:ruby_dust",
      "basic_render_parameters": {
        "material": "particles_add",
        "texture": "textures/particle/ruby_sparkle"
      }
    },
    "components": {
      "minecraft:emitter_lifetime_once": { "active_time": 0.2 },
      "minecraft:emitter_rate_instant": { "num_particles": 3 },
      "minecraft:emitter_shape_point": {},
      "minecraft:particle_initial_speed": 0.4,
      "minecraft:particle_lifetime_expression": { "max_lifetime": 0.3 },
      "minecraft:particle_appearance_billboard": {
        "size": [0.04, 0.04],
        "facing_camera_mode": "lookat_xyz",
        "uv": {
          "texture_width": 8,
          "texture_height": 8,
          "uv": [0, 0],
          "uv_size": [8, 8]
        }
      },
      "minecraft:particle_appearance_tinting": { "color": "#FF7A0F2E" }
    }
  }
}

Затем вернитесь в ruby_sparkle.json, дайте событию имя и скажите, что оно делает:

RP/particles/ruby_sparkle.json (внутри particle_effect)
"events": {
  "pop": {
    "particle_effect": {
      "effect": "wiki:ruby_dust",
      "type": "emitter"
    }
  }
},

И наконец, запускайте событие, когда у каждой искры заканчивается жизнь:

RP/particles/ruby_sparkle.json (внутри components)
"minecraft:particle_lifetime_events": {
  "expiration_event": "pop"
}

Событие умеет не только создавать частицы:

Поле событияЧто делает
particle_effectЗапускает другой эффект. type бывает emitter, emitter_bound, particle или particle_with_velocity
sound_effectПроигрывает звук по имени звукового события в event_name
expressionВыполняет выражение Molang на эмиттере
logПишет сообщение в журнал контента, удобно для тестов
sequenceСписок событий, которые выполняются все, одно за другим
randomizeСписок событий, из которых выполняется только одно, выбранное по weight

Не давайте эффекту создавать самого себя

Если бы wiki:ruby_sparkle запускал wiki:ruby_sparkle из своего же события, каждая частица создавала бы новые частицы, и так бесконечно. Всегда направляйте события на другой, более мелкий эффект.

Готовый файл

Вот искра целиком, со включённым светящимся материалом:

RP/particles/ruby_sparkle.json
{
  "format_version": "1.10.0",
  "particle_effect": {
    "description": {
      "identifier": "wiki:ruby_sparkle",
      "basic_render_parameters": {
        "material": "particles_add",
        "texture": "textures/particle/ruby_sparkle"
      }
    },
    "curves": {
      "variable.ruby_size": {
        "type": "linear",
        "input": "variable.particle_age / variable.particle_lifetime",
        "nodes": [0.2, 1, 0.6, 0]
      }
    },
    "events": {
      "pop": {
        "particle_effect": {
          "effect": "wiki:ruby_dust",
          "type": "emitter"
        }
      }
    },
    "components": {
      "minecraft:emitter_lifetime_once": {
        "active_time": 0.5
      },
      "minecraft:emitter_rate_instant": {
        "num_particles": 12
      },
      "minecraft:emitter_shape_sphere": {
        "radius": 0.4,
        "direction": "outwards"
      },
      "minecraft:particle_lifetime_expression": {
        "max_lifetime": "math.random(0.6, 1.2)"
      },
      "minecraft:particle_lifetime_events": {
        "expiration_event": "pop"
      },
      "minecraft:particle_initial_speed": 1.5,
      "minecraft:particle_initial_spin": {
        "rotation": "math.random(0, 360)",
        "rotation_rate": 90
      },
      "minecraft:particle_motion_dynamic": {
        "linear_acceleration": [0, 1.2, 0],
        "linear_drag_coefficient": 3
      },
      "minecraft:particle_appearance_billboard": {
        "size": ["0.12 * variable.ruby_size", "0.12 * variable.ruby_size"],
        "facing_camera_mode": "lookat_xyz",
        "uv": {
          "texture_width": 8,
          "texture_height": 8,
          "uv": [0, 0],
          "uv_size": [8, 8]
        }
      },
      "minecraft:particle_appearance_tinting": {
        "color": {
          "gradient": ["#FFFF8FA8", "#FFFF2650", "#00A0002A"],
          "interpolant": "variable.particle_age / variable.particle_lifetime"
        }
      }
    }
  }
}

Мы ещё незаметно добавили particle_initial_spin: каждая искра начинает под случайным углом и медленно вращается, так что двух одинаковых не будет.

Как показать частицу

Командой

/particle проигрывает эффект в заданной точке. Для неё нужны включённые читы.

Чат или функция
/particle wiki:ruby_sparkle ~ ~1 ~

Её можно поставить и в функцию или командный блок. Чтобы показать её на ком-то, используйте execute: /execute as @a at @s run particle wiki:ruby_sparkle ~ ~2 ~ покажет искру над головой каждого игрока.

Из анимации моба

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

1. Дайте эффекту короткое имя в description клиентской сущности:

RP/entity/ruby_golem.entity.json (внутри description)
"particle_effects": {
  "sparkle": "wiki:ruby_sparkle"
}

2. Запустите его из анимации в нужный момент времени. locator необязателен: это именованная точка на модели, и эффект следует за ней, пока моб двигается. Без него эффект появляется у ног моба.

RP/animations/ruby_golem.animation.json (внутри одной анимации)
"particle_effects": {
  "0.5": {
    "effect": "sparkle",
    "locator": "head"
  }
}

3. Или запустите его из состояния контроллера анимаций. Он начнётся, когда моб войдёт в это состояние:

RP/animation_controllers/ruby_golem.ac.json (внутри одного состояния)
"particle_effects": [
  { "effect": "sparkle" }
]

У каждого из них может быть pre_effect_script: немного Molang, который выполняется прямо перед стартом эффекта. С его помощью можно передать значения в файл частицы, например цвет, который зависит от моба.

Зацикленные эффекты - для мобов

Когда моб проигрывает эффект, эмиттер эффекта прикрепляется к нему. Вот где раскрываются emitter_lifetime_looping и emitter_lifetime_expression: след, который тянется за мобом, пока он идёт, или свечение, пока включено значение Molang.

Из скрипта

Скрипты могут показывать частицы где угодно и когда угодно. В манифесте пакета поведения нужен модуль скриптов: как его добавить, показано в разделе Настройка проекта.

BP/scripts/main.js
import { world } from "@minecraft/server";

world.afterEvents.itemUse.subscribe(({ source, itemStack }) => {
  if (itemStack.typeId !== "wiki:ruby_wand") return;

  const { x, y, z } = source.location;
  source.dimension.spawnParticle("wiki:ruby_sparkle", { x, y: y + 1.5, z });
});

Каждый раз, когда игрок использует предмет wiki:ruby_wand, над ним вспыхивает искра. dimension.spawnParticle показывает эффект всем вокруг. player.spawnParticle работает так же, но видит его только этот игрок.

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

BP/scripts/main.js
import { MolangVariableMap } from "@minecraft/server";

// Inside the same itemUse handler as above:
const vars = new MolangVariableMap();
vars.setColorRGB("variable.tint", { red: 0.2, green: 0.6, blue: 1 });
source.dimension.spawnParticle("wiki:ruby_sparkle", { x, y: y + 1.5, z }, vars);

В файле частицы читайте три части цвета как variable.tint.r, variable.tint.g и variable.tint.b:

Внутри components
"minecraft:particle_appearance_tinting": {
  "color": ["variable.tint.r", "variable.tint.g", "variable.tint.b", 1]
}

Полезные переменные Molang

Эти значения игра заполняет за вас. Используйте их в любом поле Molang.

ПеременнаяЗначение
variable.particle_ageСколько секунд эта частица уже живёт
variable.particle_lifetimeСколько всего проживёт эта частица
variable.particle_random_1 до _4Четыре случайных числа от 0 до 1, свои у каждой частицы
variable.emitter_ageСколько уже работает эмиттер
variable.emitter_lifetimeСколько всего работает эмиттер
variable.emitter_random_1 до _4Четыре случайных числа от 0 до 1, общие для всего эмиттера
variable.entity_scaleРазмер моба, к которому прикреплён эффект

variable.particle_random_1 отлично подходит для разнообразия. Например, "0.1 + variable.particle_random_1 * 0.05" даёт каждой искре чуть другой размер.

Если что-то не работает

Что вы видитеСамая вероятная причина
Вообще ничегоУ эмиттера нет компонента времени жизни или частоты, или identifier в команде не совпадает с файлом
/particle пишет, что эффекта не существуетОпечатка в JSON. Откройте журнал контента, чтобы найти сломанную строку
Фиолетово-чёрный квадратНеверный путь texture, или он заканчивается на .png
Вся текстура сжата в одну частицуНет блока uv, или texture_width и texture_height не совпадают с PNG
Чёрные квадраты вокруг каждой частицыФон PNG не прозрачный, или вы использовали particles_add с тёмной картинкой
Частица не того цветаОкрашивание умножает текстуру. Рисуйте текстуру белым
Она никогда не заканчиваетсяИспользуется emitter_lifetime_looping. Для разовой вспышки используйте emitter_lifetime_once

Больше помощи в разделе Когда что-то сломалось. Хотите больше? Все настройки эмиттера есть на странице Компоненты эмиттера, а все настройки частиц на странице Компоненты частиц.

We use cookies to improve your experience and analyse site traffic. Learn more