zh_cn:tutorial:blockentityrenderers
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revisionNext revisionBoth sides next revision | ||
zh_cn:tutorial:blockentityrenderers [2019/12/19 10:08] – lightcolour | zh_cn:tutorial:blockentityrenderers [2022/12/16 02:29] – solidblock | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== | + | ====== 使用方块实体渲染器动态渲染方块和物品 ====== |
+ | // | ||
+ | 这是本教程的 1.15 以上版本。对于 1.14 版本,请参见[[zh_cn: | ||
- | // | + | 阅读本教程之前,请确保您已[[blockentity|添加方块实体]]! |
- | + | ||
- | 阅读本教程之前,请确保您已[[tutorial:blockentity |添加块实体]]! | + | |
===== 介绍 ===== | ===== 介绍 ===== | ||
- | 方块块本身并不是那么有趣, | + | 方块本身并不是那么有趣,只是在某个位置和某个大小保持静止直到损坏。我们可以使用方块实体渲染器(block entity renderer)更加动态地渲染与方块实体有关的物品和方块——在不同的位置、以不同的大小渲染多个物品。 |
- | 它们只是在某个位置和某个大小保持静止直到损坏。 | + | |
- | 我们可以使用块实体渲染器来更加动态地渲染与块实体相关联的项目和块-渲染多个不同的项目, | + | |
- | 在不同的位置和大小,甚至更多。 | + | |
===== 例子 ===== | ===== 例子 ===== | ||
- | 在本教程中,我们将通过向其添加'' | + | 在本教程中,我们将通过向其添加 '' |
- | 渲染器将显示一个自动点唱机,该自动点唱机漂浮在块上方,上下,旋转。 | + | |
| | ||
- | 我们需要做的第一件事是创建我们的“ BlockEntityRenderer”类: | + | 我们需要做的第一件事是创建我们的 |
<code java> | <code java> | ||
- | public class MyBlockEntityRenderer extends | + | @Environment(EnvType.CLIENT) |
- | // A jukebox itemstack | + | public class DemoBlockEntityRenderer implements |
+ | // 唱片机物品堆 | ||
private static ItemStack stack = new ItemStack(Items.JUKEBOX, | private static ItemStack stack = new ItemStack(Items.JUKEBOX, | ||
| | ||
- | public | + | public |
- | super(dispatcher); | + | |
- | | + | |
| | ||
@Override | @Override | ||
Line 28: | Line 23: | ||
} | } | ||
</ | </ | ||
- | 我们将需要注册我们的'' | ||
- | 在单人游戏设置中这无关紧要,因为服务器与客户端在同一进程中运行。 | ||
- | 但是,在多人游戏设置中,服务器在与客户端不同的进程中运行,服务器代码 | ||
- | 没有'' | ||
- | 要仅为客户端运行初始化代码,我们需要设置一个'' | ||
- | 在实现'' | + | 我们将需要注册我们的 '' |
+ | |||
+ | 在实现 '' | ||
<code java> | <code java> | ||
+ | @Environment(EnvType.CLIENT) | ||
public class ExampleModClient implements ClientModInitializer { | public class ExampleModClient implements ClientModInitializer { | ||
@Override | @Override | ||
public void onInitializeClient() { | public void onInitializeClient() { | ||
- | // Here we will put client-only registration code | + | // 这里我们放置只在客户端注册的代码 |
} | } | ||
} | } | ||
</ | </ | ||
- | 将此类设置为'' | + | 将此类设置为 '' |
<code javascript " | <code javascript " | ||
" | " | ||
Line 49: | Line 43: | ||
" | " | ||
{ | { | ||
- | " | + | " |
} | } | ||
] | ] | ||
Line 55: | Line 49: | ||
</ | </ | ||
- | 并在我们的ClientModInitializer中注册'' | + | 在我们的 ClientModInitializer 中注册 '' |
<code java> | <code java> | ||
- | @Override | + | |
- | public void onInitializeClient() { | + | public void onInitializeClient() { |
- | BlockEntityRendererRegistry.INSTANCE.register(DEMO_BLOCK_ENTITY, | + | BlockEntityRendererRegistry.register(DEMO_BLOCK_ENTITY, |
- | } | + | } |
</ | </ | ||
- | 我们重写了'' | + | 我们重写在每一帧都会被调用的 |
- | -对于初学者,请调用'' | + | |
<code java> | <code java> | ||
public void render(DemoBlockEntity blockEntity, | public void render(DemoBlockEntity blockEntity, | ||
Line 69: | Line 64: | ||
} | } | ||
</ | </ | ||
- | We then perform the movement of the jukebox (matrices.translate) and rotation (matrices.multiply). | + | 然后,我们对唱片机进行平移(matrices.translate)和旋转(matrices.multiply)。平移分为两部分:将其平移到高于方块中心的 |
- | There are two parts to the translation: | + | |
- | The second part is the part that changes: the offset in the y value. The offset is the height of the item for any given frame. | + | |
- | We recalculate this each time because we want it to be animating bouncing up and down. We calculate this by: | + | |
- | | + | |
- | * Adding the partial ticks. (The partial ticks is a fractional value representing the amount of time that’s passed between the last full tick and now. We use this because otherwise the animation would be jittery because there are fewer ticks per second than frames per second.) | + | |
- | * Dividing that by 8 to slow the movement down. | + | |
- | * Taking the sine of that to produce a value that ranges between | + | |
- | * Dividing that by 4 to compress the sine wave vertically so the item doesn’t move up and down as much. | + | |
<code java> | <code java> | ||
public void render(DemoBlockEntity blockEntity, | public void render(DemoBlockEntity blockEntity, | ||
[...] | [...] | ||
- | // Calculate the current offset in the y value | + | // 计算当前y值的偏移 |
double offset = Math.sin((blockEntity.getWorld().getTime() + tickDelta) / 8.0) / 4.0; | double offset = Math.sin((blockEntity.getWorld().getTime() + tickDelta) / 8.0) / 4.0; | ||
- | // Move the item | + | // 移动物品 |
matrices.translate(0.5, | matrices.translate(0.5, | ||
- | // Rotate the item | + | // 旋转物品 |
- | matrices.multiply(Vector3f.POSITIVE_Y.getDegreesQuaternion((blockEntity.getWorld().getTime() + tickDelta) * 4)); | + | matrices.multiply(Vec3f.POSITIVE_Y.getDegreesQuaternion((blockEntity.getWorld().getTime() + tickDelta) * 4)); |
} | } | ||
</ | </ | ||
- | Finally, we will get the Minecraft ' | + | 最后,我们将获得 |
- | We also pass '' | + | |
- | an item lying on the ground. Try experimenting with this value and see what happens (it's an enum). | + | |
- | We also need to call '' | + | |
<code java> | <code java> | ||
public void render(DemoBlockEntity blockEntity, | public void render(DemoBlockEntity blockEntity, | ||
[...] | [...] | ||
- | MinecraftClient.getInstance().getItemRenderer().renderItem(stack, | + | MinecraftClient.getInstance().getItemRenderer().renderItem(stack, |
- | // Mandatory call after GL calls | + | // GL 调用之后的必要调用 |
matrices.pop(); | matrices.pop(); | ||
} | } | ||
</ | </ | ||
- | You can try your newly created block entity renderer right now. | + | 您现在就可以尝试新创建的方块实体渲染器。但是,如果您没有使方块透明,您会发现有些不对劲——这个浮动的方块,即唱片机,是黑色的!这是因为默认情况下,//无论您在方块实体中渲染什么,都将接收该方块实体所在位置的光照度//。所以浮动的方块接收这个不透明方块内部的光照,这意味着接收不到光。为了解决此问题,我们会让Minecraft接收方块实体上方位置的光照强度。 |
- | However, if you didn't make your block transparent, | + | |
- | This is because by default, | + | |
- | So the floating block receives light from //inside// our opaque block, which means it receives no light! | + | |
- | To fix this, we will tell Minecraft | + | |
- | To get the light, we call '' | + | 要获取光照,我们在方块实体上方的位置调用 |
- | and to use the light we use it in '' | + | |
<code java> | <code java> | ||
@Override | @Override | ||
Line 118: | Line 102: | ||
| | ||
int lightAbove = WorldRenderer.getLightmapCoordinates(blockEntity.getWorld(), | int lightAbove = WorldRenderer.getLightmapCoordinates(blockEntity.getWorld(), | ||
- | MinecraftClient.getInstance().getItemRenderer().renderItem(stack, | + | MinecraftClient.getInstance().getItemRenderer().renderItem(stack, |
| | ||
[...] | [...] | ||
Line 124: | Line 108: | ||
</ | </ | ||
- | The jukebox should now have the proper lighting. | + | 唱片机现在应该得到了适当的光照。 |
+ | |||
+ | ===== 根据方块实体数据进行渲染 ===== | ||
+ | 有时候你需要根据方块实体的数据(nbt)进行渲染,结果发现这些数据全是空的,尽管通过 ''/ |
zh_cn/tutorial/blockentityrenderers.txt · Last modified: 2023/08/29 10:31 by wjz_p