zh_cn:tutorial:blockentityrenderers
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
zh_cn:tutorial:blockentityrenderers [2019/12/19 10:14] – lightcolour | zh_cn:tutorial:blockentityrenderers [2024/08/27 04:42] (current) – solidblock | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== | + | ====== 使用方块实体渲染器动态渲染方块和物品 ====== |
+ | // | ||
- | // | + | 阅读本教程之前,请确保您已[[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 22: | ||
} | } | ||
</ | </ | ||
- | 我们将需要注册我们的'' | ||
- | 在单人游戏设置中这无关紧要,因为服务器与客户端在同一进程中运行。 | ||
- | 但是,在多人游戏设置中,服务器在与客户端不同的进程中运行,服务器代码 | ||
- | 没有'' | ||
- | 要仅为客户端运行初始化代码,我们需要设置一个'' | ||
- | 在实现'' | + | 我们将需要注册我们的 '' |
+ | |||
+ | 在实现了 '' | ||
<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 " | ||
- | " | + | { |
+ | [...] | ||
+ | | ||
[...] | [...] | ||
" | " | ||
{ | { | ||
- | " | + | " |
} | } | ||
] | ] | ||
+ | }, | ||
+ | [...] | ||
} | } | ||
</ | </ | ||
- | 并在我们的ClientModInitializer中注册'' | + | 在我们的 |
<code java> | <code java> | ||
- | @Override | + | |
- | public void onInitializeClient() { | + | public void onInitializeClient() { |
- | BlockEntityRendererRegistry.INSTANCE.register(DEMO_BLOCK_ENTITY, | + | |
- | } | + | // 旧版本如果不行就试试这个: |
+ | // BlockEntityRendererRegistry.INSTANCE.register(DEMO_BLOCK_ENTITY, | ||
+ | } | ||
</ | </ | ||
- | 我们重写了'' | + | 我们重写在每一帧都会被调用的 |
- | -对于初学者,请调用'' | + | |
<code java> | <code java> | ||
public void render(DemoBlockEntity blockEntity, | public void render(DemoBlockEntity blockEntity, | ||
Line 69: | Line 68: | ||
} | } | ||
</ | </ | ||
- | 然后,我们执行自动点唱机的移动(matrices.translate)和旋转(matrices.multiply)。 | + | 然后,我们对唱片机进行平移('' |
- | 转换分为两部分:将其转换为高于方块中心的0.5、1.25和0.5。 | + | |
- | 第二部分是更改的部分:y值的偏移量。 偏移量是任何给定框架的项目高度。 | + | |
- | 每次我们都要重新计算,因为我们希望它可以动画上下跳跃。 我们通过以下方式计算: | + | |
| | ||
- | | + | |
- | *用8除以减慢运动速度。 | + | *将其除以8以减慢运动速度。 |
- | | + | |
- | * 将其除以4可垂直压缩正弦波,因此该项目不会上下移动太多。 | + | * 将其除以4可垂直压缩正弦波,这样该物品不会过度上下移动。 |
<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(RotationAxis.POSITIVE_Y.rotationDegrees((blockEntity.getWorld().getTime() + tickDelta) * 4)); |
} | } | ||
</ | </ | ||
- | 最后,我们将获得Minecraft的'' | + | 最后,我们将获得 Minecraft 的 '' |
- | 我们还将'' | + | |
- | 躺在地上的物品。 尝试尝试使用此值,看看会发生什么(这是一个枚举)。 | + | |
- | 在这些GL调用之后,我们还需要调用'' | + | |
<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(); | ||
} | } | ||
</ | </ | ||
- | 您可以立即尝试新创建的方块实体渲染器。 | + | 现在就可以尝试新创建的方块实体渲染器。但是,如果您没有使方块透明,您会发现有些不对劲——这个浮动的方块,即唱片机,是黑色的!这是因为默认情况下,//无论您在方块实体中渲染什么,都将接收该方块实体所在位置的光照度// |
- | 但是,如果您没有使方块透明,您会发现有些不对劲-浮动方块,点唱机是黑色的! | + | |
- | 这是因为默认情况下,无论您在方块实体中进行渲染的任何内容,都将接收光线,就好像它与方块实体处于同一位置一样。 | + | |
- | 因此,浮动方块从不透明的方块中接收inside的光,这意味着它没有接收到光! | + | |
- | 为了解决这个问题,我们将告诉Minecraft从上方的一个方块方块实体的位置接收光。 | + | |
- | 要获取灯光,我们在方块实体上方的位置调用'' | + | 要获取光照,我们在方块实体上方的位置调用 '' |
- | 并使用灯光,我们在'' | + | |
<code java> | <code java> | ||
@Override | @Override | ||
Line 118: | Line 106: | ||
| | ||
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 112: | ||
</ | </ | ||
- | 点唱机现在应具有适当的照明。 | + | 唱片机现在应该得到了适当的光照。 |
+ | |||
+ | ===== 根据方块实体数据进行渲染 ===== | ||
+ | 有时候你需要根据方块实体的数据(nbt)进行渲染,结果发现这些数据全是空的,尽管通过 ''/ |
zh_cn/tutorial/blockentityrenderers.1576750459.txt.gz · Last modified: 2019/12/19 10:14 by lightcolour