项目结构

src
├── main
│ ├── java
│ │ ├── com
│ │ │ ├── XXXYJade17
│ │ │ │ └── TestMod
│ │ │ │ ├── Registry.java
│ │ │ │ ├── StateExampleBlock.java
│ │ │ │ └── TestMod.java
│ └── resources
│ ├── assets
│ │ ├── testmod
│ │ │ ├── blockstates
│ │ │ │ └── state_example_block.json
│ │ │ ├── lang
│ │ │ │ ├── en_us.json // 英文语言文件
│ │ │ │ └── zh_cn.json // 中文语言文件
│ │ │ ├── models
│ │ │ │ ├── block
│ │ │ │ │ ├── state_exampe_block_off.json
│ │ │ │ │ └── state_exampe_block_on.json
│ │ │ │ └── item
│ │ │ │ │ └── state_exampe_block.json
│ │ │ └── textures
│ │ │ │ └── block
│ │ │ │ ├── state_exampe_block_off.json.png
│ │ │ │ └── state_exampe_block_on.json.png

一.先创建一个类并且继承Block

public class StateExampleBlock extends Block {
    //构造方法
    public StateExampleBlock(Properties properties) {
        super(properties);
    }
}

二.定义需要的状态属性

public static final BooleanProperty LIT = BooleanProperty.create("lit");

三.修改构造函数

public StateExampleBlock(Properties properties) {
    super(properties.lightLevel(state -> state.getValue(LIT) ? 15 : 0));      //设置光照等级
    this.registerDefaultState(this.stateDefinition.any().setValue(LIT, false));     // 默认状态为未发光
    }
private Properties() {
            this.soundType = SoundType.STONE;
            this.lightEmission = (p_60929_) -> 0;
            this.friction = 0.6F;
            this.speedFactor = 1.0F;
            this.jumpFactor = 1.0F;
            this.canOcclude = true;
            this.pushReaction = PushReaction.NORMAL;
            this.spawnTerrainParticles = true;
            this.instrument = NoteBlockInstrument.HARP;
            this.isValidSpawn = (p_284893_, p_284894_, p_284895_, p_284896_) -> p_284893_.isFaceSturdy(p_284894_, p_284895_, Direction.UP) && p_284893_.getLightEmission(p_284894_, p_284895_) < 14;
            this.isRedstoneConductor = (p_284888_, p_284889_, p_284890_) -> p_284888_.isCollisionShapeFullBlock(p_284889_, p_284890_);
            this.isSuffocating = (p_284885_, p_284886_, p_284887_) -> p_284885_.blocksMotion() && p_284885_.isCollisionShapeFullBlock(p_284886_, p_284887_);
            this.isViewBlocking = this.isSuffocating;
            this.hasPostProcess = (p_60963_, p_60964_, p_60965_) -> false;
            this.emissiveRendering = (p_60931_, p_60932_, p_60933_) -> false;
            this.requiredFeatures = FeatureFlags.VANILLA_SET;
            this.offsetFunction = Optional.empty();
        }

四.注册状态

@Override
protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
    builder.add(LIT);
}

五.创建交互use方法,实现右键点亮方块

@Override
public InteractionResult use(BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) {
    if (!level.isClientSide) {
        boolean isLit = state.getValue(LIT);        //获取当前状态(on|off)
        level.setBlock(pos, state.setValue(LIT, !isLit), Block.UPDATE_ALL);       
//        level.playSound(null, pos, SoundEvents.AMETHYST_BLOCK_HIT, SoundSource.BLOCKS, 1.0F, 1.0F);
    }
    return InteractionResult.sidedSuccess(level.isClientSide);
}

六.添加资源文件

先在BlockState里添加state_example_block.json

{
  "variants": {
    "lit=false": {
      "model": "testmod:block/state_example_block_off"
    },
    "lit=true":  {
      "model": "testmod:block/state_example_block_on"
    }
  }
}

然后根据前面添加Block和BlockItem一样添加对应的json文件即可

*如果原来的方块出现了吞材质的情况,在blockstate里把所有注册的Block都添加一遍就行

默认格式

{
  "variants": {
    "": {
      "model": "testmod:block/example_block_01"
    }
  }
}

附完整代码

import net.minecraft.core.BlockPos;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.StateDefinition;
import net.minecraft.world.level.block.state.properties.BooleanProperty;
import net.minecraft.world.phys.BlockHitResult;

public class StateExampleBlock extends Block {
    public static final BooleanProperty LIT = BooleanProperty.create("lit"); // 定义方块状态属性


    public StateExampleBlock(Properties properties) {
        super(properties.lightLevel(state -> state.getValue(LIT) ? 15 : 0)); // 根据 LIT 属性设置光照
        this.registerDefaultState(this.stateDefinition.any().setValue(LIT, false)); // 默认状态为未发光
    }

    @Override
    protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
        builder.add(LIT); // 注册属性
    }

    @Override
    public InteractionResult use(BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) {
        if (!level.isClientSide) {
            boolean isLit = state.getValue(LIT);
            level.setBlock(pos, state.setValue(LIT, !isLit), Block.UPDATE_ALL); // 切换发光状态
            level.playSound(null, pos, SoundEvents.AMETHYST_BLOCK_HIT, SoundSource.BLOCKS, 1.0F, 1.0F);
        }
        return InteractionResult.sidedSuccess(level.isClientSide);
    }
}