feat:学习方块
Some checks failed
build / build (push) Has been cancelled

This commit is contained in:
m0_75251201
2025-10-22 21:44:06 +08:00
parent 825b9e2958
commit 9d1a9f3cfe
18 changed files with 401 additions and 87 deletions

View File

@@ -9,7 +9,8 @@ public class InitModMain implements ModInitializer {
public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID); public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID);
@Override @Override
public void onInitialize() { public void onInitialize() {
LOGGER.info("Hello Fabric world!"); ModItems.LoadItems.initialize();
Item.LoadItems.initialize(); ModBlocks.LoadBlocks.initialize();
ModEntity.LoadEntities.initialize();
} }
} }

View File

@@ -1,36 +0,0 @@
package Item;
import Init.InitModMain;
import net.fabricmc.fabric.api.itemgroup.v1.ItemGroupEvents;
import net.minecraft.item.Item;
import net.minecraft.item.ItemGroups;
import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry;
import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.util.Identifier;
import java.util.function.Function;
public class LoadItems {
public static final Item QI = register("qi", Item::new, new Item.Settings());
public static void initialize() {
ItemGroupEvents.modifyEntriesEvent(ItemGroups.INGREDIENTS)
.register((itemGroup) -> itemGroup.add(LoadItems.QI));
}
public static Item register(String name, Function<Item.Settings, Item> itemFactory, Item.Settings settings) {
// Create the item key.
RegistryKey<Item> itemKey = RegistryKey.of(RegistryKeys.ITEM, Identifier.of(InitModMain.MOD_ID, name));
// Create the item instance.
Item item = itemFactory.apply(settings.registryKey(itemKey));
// Register the item.
Registry.register(Registries.ITEM, itemKey, item);
return item;
}
}

View File

@@ -0,0 +1,66 @@
package ModBlocks;
import net.fabricmc.fabric.api.itemgroup.v1.ItemGroupEvents;
import net.minecraft.block.AbstractBlock;
import net.minecraft.block.Block;
import net.minecraft.item.BlockItem;
import net.minecraft.item.Item;
import net.minecraft.item.ItemGroups;
import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry;
import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.sound.BlockSoundGroup;
import net.minecraft.util.Identifier;
import java.util.function.Function;
public class LoadBlocks {
public static final Block MAGIC_STONE_MINE = register(
"magic_stone_mine",
Block::new,
AbstractBlock.Settings.create().sounds(BlockSoundGroup.GRASS),
true
);
public static void initialize() {
ItemGroupEvents.modifyEntriesEvent(ItemGroups.INGREDIENTS).register((itemGroup) -> {
itemGroup.add(MAGIC_STONE_MINE.asItem());
});
}
private static Block register(String name, Function<AbstractBlock.Settings, Block> blockFactory, AbstractBlock.Settings settings, boolean shouldRegisterItem) {
// 为方块创建一个注册表键。
// 这个键是方块在游戏内部的唯一标识符。
RegistryKey<Block> blockKey = keyOfBlock(name);
// 根据提供的工厂函数和设置创建方块实例。
// 注意:这里将之前创建的 blockKey 传递给 settings确保方块实例内部知道自己的注册键。
Block block = blockFactory.apply(settings.registryKey(blockKey));
// 有时,你可能不希望为某个方块注册物品形式。
// 例如:如果它是一个技术性方块,比如 `minecraft:moving_piston` (移动中的活塞) 或 `minecraft:end_gateway` (末影之门)
// 这些方块通常不能通过物品形式获得或放置。
if (shouldRegisterItem) {
// 物品需要使用不同类型的注册表键进行注册但通常可以与方块使用相同的ID字符串`name`)。
RegistryKey<Item> itemKey = keyOfItem(name);
// 创建一个 BlockItem 实例。BlockItem 是一个特殊的物品,当被放置时会变成对应的方块。
// 新的 Item.Settings() 创建了一个默认的物品设置。
// .registryKey(itemKey) 为这个物品设置其注册键。
// .useBlockPrefixedTranslationKey() 是一个有用的方法,它告诉游戏这个物品的本地化字符串(例如,在鼠标悬停时显示的名称)
// 应该尝试使用方块的本地化字符串(例如,如果方块叫 "mystuff:my_block",物品名称也会尝试显示为 "My Block")。
BlockItem blockItem = new BlockItem(block, new Item.Settings().registryKey(itemKey).useBlockPrefixedTranslationKey());
// 将创建的 BlockItem 注册到物品注册表中。
Registry.register(Registries.ITEM, itemKey, blockItem);
}
// 最后,将创建的方块实例注册到方块注册表中,并返回这个注册后的方块。
return Registry.register(Registries.BLOCK, blockKey, block);
}
private static RegistryKey<Block> keyOfBlock(String name) {
return RegistryKey.of(RegistryKeys.BLOCK, Identifier.of(Init.InitModMain.MOD_ID, name));
}
private static RegistryKey<Item> keyOfItem(String name) {
return RegistryKey.of(RegistryKeys.ITEM, Identifier.of(Init.InitModMain.MOD_ID, name));
}
}

View File

@@ -0,0 +1,20 @@
package ModEntity;
import Init.InitModMain;
import net.fabricmc.fabric.api.object.builder.v1.entity.FabricDefaultAttributeRegistry;
import net.fabricmc.fabric.api.object.builder.v1.entity.FabricEntityTypeBuilder;
import net.minecraft.entity.EntityDimensions;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.SpawnGroup;
import net.minecraft.entity.mob.ZombieEntity;
import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry;
import net.minecraft.util.Identifier;
public class LoadEntities {
public static void initialize() {
}
}

View File

@@ -0,0 +1,11 @@
package ModEntity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.mob.PathAwareEntity;
import net.minecraft.world.World;
public class QiEntity extends PathAwareEntity {
protected QiEntity(EntityType<? extends PathAwareEntity> entityType, World world) {
super(entityType, world);
}
}

View File

@@ -1,9 +1,10 @@
package Item; package ModItems;
import net.minecraft.item.Item; import net.minecraft.item.Item;
public class BigApple extends Item { public class BigApple extends Item {
public BigApple(Settings settings) { public BigApple(Settings settings) {
super(settings); super(settings);
} }
} }

View File

@@ -0,0 +1,56 @@
package ModItems;
import Init.InitModMain;
import net.fabricmc.fabric.api.itemgroup.v1.ItemGroupEvents;
import net.minecraft.item.Item;
import net.minecraft.item.ItemGroups;
import net.minecraft.registry.Registries;
import net.minecraft.registry.Registry;
import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.RegistryKeys;
import net.minecraft.util.Identifier;
import java.util.function.Function;
public class LoadItems {
public static final Item QI = register("qi", Item::new, new Item.Settings().maxCount(64));
public static void initialize() {
ItemGroupEvents.modifyEntriesEvent(ItemGroups.INGREDIENTS)
.register((itemGroup) -> itemGroup.add(LoadItems.QI));
}
/**
* 注册一个新的物品到游戏的物品注册表。
* 这是一个通用的注册方法,允许使用自定义的物品工厂和物品设置。
*
* @param name 物品的注册名称或ID在模块ID命名空间内应是唯一的。
* 例如:"my_custom_item"。
* @param itemFactory 一个函数,接收物品设置 {@code Item.Settings} 作为参数,
* 并返回一个物品实例 {@code Item}。
* 这允许注册普通的 {@code Item} 实例或其自定义子类。
* 例如:{@code Item::new} 或 {@code MyCustomItem::new}。
* @param settings 用于创建此物品实例的物品设置 {@code Item.Settings}。
* 这些设置定义了物品的各种属性,如堆叠大小、工具提示、是否可附魔等。
* @return 注册成功的物品实例。
*/
public static Item register(String name, Function<Item.Settings, Item> itemFactory, Item.Settings settings) {
// Step 1: 为物品创建唯一的注册键 (RegistryKey)。
// RegistryKey 是用于在注册表中唯一标识资源的句柄。
// 它由注册表类型 (RegistryKeys.ITEM)、模块ID (InitModMain.MOD_ID) 和物品的自定义名称 (name) 组成。
// Identifier.of(InitModMain.MOD_ID, name) 将模块ID和名称组合成一个统一的标识符。
RegistryKey<Item> itemKey = RegistryKey.of(RegistryKeys.ITEM, Identifier.of(InitModMain.MOD_ID, name));
// Step 2: 使用提供的工厂函数实例化物品。
// itemFactory.apply() 会调用工厂函数来创建物品实例。
// settings.registryKey(itemKey) 会将这个物品的注册键添加到其设置中。
// 这对于物品本身识别其在注册表中的身份很重要。
Item item = itemFactory.apply(settings.registryKey(itemKey));
// Step 3: 将物品实例注册到 Minecraft 的物品注册表 (Registries.ITEM)。
// Registry.register() 是实际进行注册操作的方法。
// 它将物品键 (itemKey) 与物品实例 (item) 关联起来,使游戏能够识别和加载此物品。
Registry.register(Registries.ITEM, itemKey, item);
// Step 4: 返回注册的物品实例,以便在代码中进一步使用。
return item;
}
}

View File

@@ -0,0 +1,203 @@
package WorldGenerator;
import com.mojang.serialization.MapCodec;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.ChunkRegion;
import net.minecraft.world.HeightLimitView;
import net.minecraft.world.Heightmap;
import net.minecraft.world.biome.source.BiomeAccess;
import net.minecraft.world.biome.source.BiomeSource;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.gen.StructureAccessor;
import net.minecraft.world.gen.chunk.Blender;
import net.minecraft.world.gen.chunk.ChunkGenerator;
import net.minecraft.world.gen.chunk.VerticalBlockSample;
import net.minecraft.world.gen.noise.NoiseConfig;
import java.util.List;
import java.util.concurrent.CompletableFuture;
/**
* 这是一个基础的世界生成器类继承自Minecraft的ChunkGenerator。
* 它提供了一个骨架,用于创建自定义的世界地形和地貌。
*
* 当前版本中,所有核心生成方法均为空实现或返回默认值。
* 开发者需要重写这些方法以实现自定义的生成逻辑。
*/
public class Base extends ChunkGenerator {
public Base(BiomeSource biomeSource) {
super(biomeSource);
}
/**
* 获取此ChunkGenerator的序列化/反序列化编解码器。
* 用于保存和加载世界生成器的配置。
*
* @return 返回用于序列化ChunkGenerator实例的MapCodec。如果不需要保存自定义配置可以返回null。
* 但最佳实践是提供一个有效的Codec以支持配置的持久化。
*/
@Override
protected MapCodec<? extends ChunkGenerator> getCodec() {
// TODO: 如果需要保存或加载此生成器的特定配置例如生成参数应在此处提供一个MapCodec。
// 目前返回null表示此生成器没有可序列化的自定义配置。
return null;
}
/**
* 在给定的区块中进行地形“雕刻”操作。
* 这主要用于生成自然特征,如洞穴、峡谷、隧道、裂缝等。
*
* @param chunkRegion 当前区块所在的区域,用于访问周围的区块。
* @param seed 世界种子,用于随机数生成。
* @param noiseConfig 噪声配置,用于噪声函数的参数。
* @param biomeAccess 生物群系访问器,用于获取区块的生物群系信息。
* @param structureAccessor 结构访问器,用于查询和放置结构。
* @param chunk 正在被雕刻的区块实例。
*/
@Override
public void carve(ChunkRegion chunkRegion, long seed, NoiseConfig noiseConfig, BiomeAccess biomeAccess, StructureAccessor structureAccessor, Chunk chunk) {
// TODO: 在此处实现自定义的洞穴、峡谷等地形雕刻逻辑。
// 例如,可以使用噪声函数来决定哪些方块应该被移除以形成洞穴。
// 目前为空实现,意味着不会生成任何雕刻特征。
}
/**
* 构建区块的地表层。
* 这包括铺设泥土、草方块、沙子等,以及处理水体和熔岩湖。
* 这通常在 `populateNoise` 之后调用。
*
* @param region 当前区块所在的区域。
* @param structures 结构访问器。
* @param noiseConfig 噪声配置。
* @param chunk 正在构建地表的区块实例。
*/
@Override
public void buildSurface(ChunkRegion region, StructureAccessor structures, NoiseConfig noiseConfig, Chunk chunk) {
// TODO: 在此处实现自定义的地表生成逻辑。
// 例如,根据生物群系和噪声高度,放置不同类型的地表方块(草方块、泥土、沙子、石头等)。
// 目前为空实现,意味着不会生成标准的地表层。
}
/**
* 在给定的区块区域中填充实体(如生物、物品)。
* 这通常是世界生成过程的最后几个阶段之一。
*
* @param region 当前区块所在的区域。
*/
@Override
public void populateEntities(ChunkRegion region) {
// TODO: 在此处实现自定义的实体生成逻辑。
// 例如,根据生物群系生成特定的生物,或者放置一些物品。
// 目前为空实现,意味着不会生成任何自定义实体。
}
/**
* 获取此生成器生成的世界的最大高度。
* 这是世界的“天花板”Y坐标通常为256或384。
*
* @return 世界的最大高度Y坐标
*/
@Override
public int getWorldHeight() {
// TODO: 返回你的世界生成器所支持的实际最大高度。
// Minecraft 1.18+ 版本的默认世界高度通常为 384。
// 如果设置为0可能会导致渲染、物理或其他生成问题。
return 0; // 这是一个占位符,需要被修改为实际值,例如 384
}
/**
* 填充区块的噪声数据。这是地形生成的核心步骤,决定了方块的垂直分布。
* 例如,通过噪声函数计算每个(x, z)坐标在Y轴上的高度。
* 此方法应返回一个CompletableFuture表示异步完成的区块操作。
*
* @param blender 用于平滑不同区块之间噪声的混合器。
* @param noiseConfig 噪声配置。
* @param structureAccessor 结构访问器。
* @param chunk 正在填充噪声的区块实例。
* @return 一个CompletableFuture在区块噪声填充完成后返回该区块。
*/
@Override
public CompletableFuture<Chunk> populateNoise(Blender blender, NoiseConfig noiseConfig, StructureAccessor structureAccessor, Chunk chunk) {
// TODO: 在此处实现核心的地形噪声生成逻辑,决定区块的方块分布。
// 这通常涉及循环一个区块内的所有(x, z)坐标使用噪声函数计算每个点的Y值和方块类型。
// 目前返回null表示没有进行噪声填充区块将是空的或默认状态。
return null;
}
/**
* 获取此生成器生成世界的平均海平面高度。
*
* @return 海洋的Y坐标。
*/
@Override
public int getSeaLevel() {
// TODO: 返回你的世界生成器所使用的实际海平面高度。
// Minecraft 默认海平面通常为 63。
return 0; // 这是一个占位符,需要被修改为实际值,例如 63
}
/**
* 获取此生成器生成世界的最小高度。
* 这是世界的“地板”Y坐标通常为0或-64。
*
* @return 世界的最小高度Y坐标
*/
@Override
public int getMinimumY() {
// TODO: 返回你的世界生成器所支持的实际最小高度。
// Minecraft 1.18+ 版本的默认最小高度通常为 -64。
return 0; // 这是一个占位符,需要被修改为实际值,例如 -64
}
/**
* 获取给定(x, z)坐标处特定Heightmap类型如WORLD_SURFACE, OCEAN_FLOOR的方块最高Y坐标。
*
* @param x 世界坐标X。
* @param z 世界坐标Z。
* @param heightmap Heightmap的类型如 WORLD_SURFACE, OCEAN_FLOOR, LIGHT_BLOCKING
* @param world 当前世界视图,用于获取其他区块信息。
* @param noiseConfig 噪声配置。
* @return 该(x, z)坐标处指定Heightmap类型的最高方块的Y坐标。
*/
@Override
public int getHeight(int x, int z, Heightmap.Type heightmap, HeightLimitView world, NoiseConfig noiseConfig) {
// TODO: 实现根据Heightmap类型返回正确的高度。
// 这通常需要基于你的噪声生成逻辑来计算。
// 目前返回0可能导致Heightmap计算不准确。
return 0;
}
/**
* 获取指定(x, z)坐标处的垂直方块列采样。
* 用于获取该列中所有方块的信息。
*
* @param x 世界坐标X。
* @param z 世界坐标Z。
* @param world 当前世界视图。
* @param noiseConfig 噪声配置。
* @return 一个VerticalBlockSample对象包含该列的方块数据。
*/
@Override
public VerticalBlockSample getColumnSample(int x, int z, HeightLimitView world, NoiseConfig noiseConfig) {
// TODO: 实现根据噪声和生物群系等数据,返回该(x, z)列的完整方块采样。
// 这是许多世界功能(如树木生成、结构放置)依赖的关键方法。
// 目前返回null可能会导致依赖此采样的功能异常。
return null;
}
/**
* 在调试HUD (F3界面) 上添加自定义文本信息。
* 对于世界生成器的调试非常有用。
*
* @param text 将要添加到调试HUD的文本列表。
* @param noiseConfig 噪声配置。
* @param pos 玩家当前所在的方块位置。
*/
@Override
public void appendDebugHudText(List<String> text, NoiseConfig noiseConfig, BlockPos pos) {
// TODO: 在此处添加自定义的调试信息这些信息会显示在F3调试屏幕上。
// 例如可以显示当前Y坐标的噪声值或者当前生物群系的名字。
// 目前为空实现,不会显示任何额外调试信息。
}
}

View File

@@ -1,44 +0,0 @@
package com.example; // 定义包名,通常遵循反域名命名规范,例如 com.yourcompany.yourmod。
import net.fabricmc.api.ModInitializer; // 导入 Fabric Mod 初始化接口,所有 Fabric 主 Mod 类都必须实现它。
import net.minecraft.server.MinecraftServer;
import org.slf4j.Logger; // 导入 SLF4J (Simple Logging Facade for Java) 的 Logger 接口,用于日志输出。
import org.slf4j.LoggerFactory; // 导入 SLF4J 的 LoggerFactory 类,用于获取 Logger 实例。
public class ExampleMod implements ModInitializer {
// 定义主 Mod 类 ExampleMod并实现 ModInitializer 接口。
// 这意味着这个类必须实现 onInitialize() 方法。
public static final String MOD_ID = "modid";
// 定义一个公共静态最终字符串常量 MOD_ID。
// 这是一个 Mod 的唯一标识符,通常与 fabric.mod.json 中的 "id" 字段对应。
// 最佳实践是将其定义为常量,方便在代码中引用。
// 这里使用了 "modid",实际项目中应替换为你的 Mod 的真实 ID例如 "mymod"。
// This logger is used to write text to the console and the log file.
// 这个记录器logger用于将文本写入控制台和日志文件。
// It is considered best practice to use your mod id as the logger's name.
// 最佳实践是使用你的 Mod ID 作为记录器的名称。
// That way, it's clear which mod wrote info, warnings, and errors.
// 这样,就能清楚地知道是哪个 Mod 记录了信息、警告和错误。
public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID);
// 创建一个公共静态最终的 Logger 实例。
// LoggerFactory.getLogger(MOD_ID) 会创建一个以你的 Mod ID 命名的日志记录器。
// 这有助于在日志文件中区分来自不同 Mod 的消息。
@Override // 这是一个注解,表示 onInitialize 方法是重写了 ModInitializer 接口中的方法。
public void onInitialize() {
// This code runs as soon as Minecraft is in a mod-load-ready state.
// 这段代码在 Minecraft 处于Mod加载就绪状态时立即运行。
// However, some things (like resources) may still be uninitialized.
// 然而,有些东西(例如资源)可能尚未完全初始化。
// Proceed with mild caution.
// 请谨慎处理。
LOGGER.info("Hello Fabric world!");
// 使用 LOGGER 实例输出一条信息级别INFO的日志消息。
// 这条消息会在控制台和 Minecraft 的日志文件中显示,表明你的 Mod 已经成功加载并执行了初始化代码。
}
}

View File

@@ -0,0 +1,7 @@
{
"variants": {
"": {
"model": "zzdxxz_qi:block/magic_stone_mine"
}
}
}

View File

Before

Width:  |  Height:  |  Size: 453 B

After

Width:  |  Height:  |  Size: 453 B

View File

@@ -0,0 +1,6 @@
{
"model": {
"type": "minecraft:model",
"model": "zzdxxz_qi:block/magic_stone_mine"
}
}

View File

@@ -1,3 +0,0 @@
{
"item.zzdxxz_qi.qi": "Qi"
}

View File

@@ -1,3 +1,4 @@
{ {
"block.zzdxxz_qi.magic_stone_mine": "灵石矿",
"item.zzdxxz_qi.qi": "气" "item.zzdxxz_qi.qi": "气"
} }

View File

@@ -0,0 +1,6 @@
{
"parent": "minecraft:block/cube_all",
"textures": {
"all": "zzdxxz_qi:block/magic_stone_mine"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 381 B

View File

@@ -0,0 +1,19 @@
{
"type": "minecraft:block",
"pools": [
{
"rolls": 1,
"entries": [
{
"type": "minecraft:item",
"name": "zzdxxz:magic_stone_mine"
}
],
"conditions": [
{
"condition": "minecraft:survives_explosion"
}
]
}
]
}

View File

@@ -12,7 +12,7 @@
"sources": "http://111.228.9.32:3000/zzdxxz/mcMod" "sources": "http://111.228.9.32:3000/zzdxxz/mcMod"
}, },
"license": "CC0-1.0", "license": "CC0-1.0",
"icon": "assets/modid/icon.png", "icon": "zzdxxz_qi/icon.png",
"environment": "*", "environment": "*",
"entrypoints": { "entrypoints": {
"main": [ "main": [