Состояния блока
Состояния блока — это фрагмент данных, привязанный к одному блоку в мире Minecraft, содержащий информацию о блоке в виде свойств. Вот несколько примеров свойств, которые стандартный Minecraft хранит в состояниях блока:
- Rotation: В основном используется для древесины и других природных блоков.
- Activated: Широко используется в редстоун-устройствах, а также в таких блоках, как печь или коптильня.
- Age: Используется для культур, растений, саженцев, водорослей и т.п.
Вы, вероятно, понимаете, почему они полезны — они позволяют избежать необходимости хранения данных NBT в сущности блока, что уменьшает размер мира и предотвращает проблемы с TPS!
Определения блокстейтов находятся в папке assets/example-mod/blockstates.
Пример: Блок Колонна
Minecraft уже имеет несколько пользовательских классов, которые позволяют быстро создавать определенные типы блоков. Этот пример демонстрирует создание блока со свойством axis на примере блока "Обтёсанная дубовая древесина".
Стандартный класс RotatedPillarBlock позволяет размещать блоки вдоль осей X, Y или Z.
java
public static final Block CONDENSED_OAK_LOG = register(
"condensed_oak_log",
RotatedPillarBlock::new,
BlockBehaviour.Properties.of().sound(SoundType.WOOD),
true
);1
2
3
4
5
6
2
3
4
5
6
Блоки колонн имеют две текстуры: верхнюю и боковую. Они используют модель block/cube_column.
Как обычно, все текстуры блоков находятся в папке assets/example-mod/textures/block
Из-за того что блок колонны имеет две позиции: горизонтальную и вертикальную, мы должны сделать два отдельных файла моделей:
condensed_oak_log_horizontal.json, который дополняет модельblock/cube_column_horizontal.condensed_oak_log.json, который дополняет модельblock/cube_column.
Пример файла condensed_oak_log_horizontal.json:
json
{
"parent": "minecraft:block/cube_column_horizontal",
"textures": {
"end": "example-mod:block/condensed_oak_log_top",
"side": "example-mod:block/condensed_oak_log"
}
}1
2
3
4
5
6
7
2
3
4
5
6
7
INFO
Помните, что файлы blockstate находятся в папке assets/example-mod/blockstates, а имя файла blockstate должно совпадать с ID блока, используемым при регистрации блока в классе ModBlocks. Например, если ID блока condensed_oak_log, файл должен называться condensed_oak_log.json.
Более подробный обзор всех модификаторов, доступных в файлах blockstate, можно найти на странице Minecraft Wiki — Модели (состояния блоков).
Далее, нам нужно создать файл состояний блока. Файл состояний блока — это где происходит магия — колоновые блоки имеют три оси, поэтому мы будем использовать конкретные модели для следующих ситуаций:
axis=x- Когда блок помещён вдоль оси X, мы повернём модель так, чтобы она была ориентирована в положительном направлении по оси X.axis=y- Когда блок помещён вдоль оси Y, мы будем использовать нормальную вертикальную модель.axis=z— когда блок размещён вдоль оси Z, мы поворачиваем модель так, чтобы она была направлена в положительном направлении Z.
json
{
"variants": {
"axis=x": {
"model": "example-mod:block/condensed_oak_log_horizontal",
"x": 90,
"y": 90
},
"axis=y": {
"model": "example-mod:block/condensed_oak_log"
},
"axis=z": {
"model": "example-mod:block/condensed_oak_log_horizontal",
"x": 90
}
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Как всегда, вам нужно создать перевод для вашего блока и модель предмета, которая будет наследовать одну из двух моделей.

Пользовательские состояния блока
Пользовательские состояния блока хороши если ваш блок имеет уникальные свойства. Иногда вы можете обнаружить, что ваш блок может использовать стандартные свойства.
Этот пример создаст уникальное boolean-свойство под названием activated - когда игрок нажимает ПКМ на блок, состояние блока меняется с activated=false на activated=true - соответствующим образом меняя его текстуру.
Создаём свойство
Сначала вам нужно создать свойство — так как это булево значение, мы будем использовать метод BooleanProperty.create.
java
public class PrismarineLampBlock extends Block {
public static final BooleanProperty ACTIVATED = BooleanProperty.create("activated");
}1
2
3
4
2
3
4
Далее, мы должны добавить свойство к менеджеру состояния блока в методе createBlockStateDefinition. Вам необходимо переопределить метод для доступа к конструктору:
java
@Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
builder.add(ACTIVATED);
}1
2
3
4
2
3
4
Вам также придется установить состояние по умолчанию для свойства activated в конструкторе вашего пользовательского блока.
java
public PrismarineLampBlock(Properties settings) {
super(settings);
// Set the default state of the block to be deactivated.
registerDefaultState(defaultBlockState().setValue(ACTIVATED, false));
}1
2
3
4
5
6
2
3
4
5
6
Использование свойства
В этом примере булево свойство activated инвертируется, когда игрок взаимодействует с блоком. Для этого мы можем переопределить метод useWithoutItem:
java
@Override
protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hit) {
if (!player.getAbilities().mayBuild) {
// Skip if the player isn't allowed to modify the level.
return InteractionResult.PASS;
} else {
// Get the current value of the "activated" property
boolean activated = state.getValue(ACTIVATED);
// Flip the value of activated and save the new blockstate.
level.setBlockAndUpdate(pos, state.setValue(ACTIVATED, !activated));
// Play a click sound to emphasise the interaction.
level.playSound(player, pos, SoundEvents.COMPARATOR_CLICK, SoundSource.BLOCKS, 1.0F, 1.0F);
return InteractionResult.SUCCESS;
}
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Визуализация недвижимости
Перед созданием файла состояния блока вам необходимо предоставить текстуры для активированного и деактивированного состояний блока, а также модель блока.
Используйте свои знания о моделях блоков, чтобы создать две модели блока: одну для активированного состояния и одну для деактивированного состояния. После этого можно приступать к созданию файла blockstate.
Поскольку вы создали новое свойство, вам необходимо обновить файл blockstate для блока, чтобы учесть это свойство.
Если в блоке имеется несколько свой блока, вам необходимо учитывать все возможные комбинации. Например, «activated» и «axis» приведут к 6 комбинациям (два возможных значения для «activated» и три возможных значения для «axis»).
Поскольку этот блок имеет только два возможных варианта, поскольку у него есть только одно свойство (activated), JSON-код состояния блока будет выглядеть примерно так:
json
{
"variants": {
"activated=false": {
"model": "example-mod:block/prismarine_lamp"
},
"activated=true": {
"model": "example-mod:block/prismarine_lamp_on"
}
}
}1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
TIP
Не забудьте добавить Клиентский предмет для блока, чтобы он отображался в инвентаре!
Поскольку пример блока представляет собой лампу, нам также необходимо заставить ее излучать свет, когда свойство activated имеет значение true. Это можно сделать с помощью настроек блока, передаваемых конструктору при регистрации блока.
Вы можете использовать метод lightLevel для установки уровня освещенности, излучаемого блоком. Мы можем создать статический метод в классе PrismarineLampBlock, который будет возвращать уровень освещенности на основе свойства activated, и передать его в качестве ссылки на метод в метод lightLevel:
java
public static int getLuminance(BlockState currentBlockState) {
// Get the value of the "activated" property.
boolean activated = currentBlockState.getValue(PrismarineLampBlock.ACTIVATED);
// Return a light level if activated = true
return activated ? 15 : 0;
}1
2
3
4
5
6
7
2
3
4
5
6
7
java
public static final Block PRISMARINE_LAMP = register(
"prismarine_lamp",
PrismarineLampBlock::new,
BlockBehaviour.Properties.of()
.sound(SoundType.LANTERN)
.lightLevel(PrismarineLampBlock::getLuminance),
true
);1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
После того как вы все завершите, конечный результат должен выглядеть примерно так:



