音乐唱片 1.21 Fabric
本篇教程的视频
本篇教程的源代码
Github地址:TutorialMod-MusicDisc-1.21
介绍
前面我们讲到了自定义声音,那么这一篇我们就来讲讲自定义音乐唱片
在1.20
中我们也讲到了音乐唱片,但是在1.21
中,音乐唱片的注册方式有了一些变化,它有单独的数据文件得写
那么同样的,在开始之前准备一个ogg
格式的音频文件,这个是我们音乐唱片对应的音频文件
查看源代码
关于注册的源代码就粗略看一眼,前一篇教程都解释过了,这里就不再赘述了
1 | public static final RegistryEntry.Reference<SoundEvent> MUSIC_DISC_5 = registerReference("music_disc.5"); |
我们就直接以这个音乐唱片为例,这里注册的类型是RegistryEntry.Reference<SoundEvent>
,其注册方法也是层层叠叠的,后面我们整合一下即可
而后,我们查找这个字段的用法
1 | static void bootstrap(Registerable<JukeboxSong> registry) { |
这个是在JukeboxSongs
这个接口中的bootstrap
方法,用于动态注册,后面的两个数字代表的是音乐唱片的播放时间
和比较器输出的红石信号强度
(0~15)
1 | RegistryKey<JukeboxSong> FIVE = of("5"); |
上面的FIVE
是一个RegistryKey
类型的字段,它是音乐唱片的注册键(说白了,其实就是你音乐的音频文件的名字,你后面就可以发现)
下面的of
方法,返回的是一个RegistryKey
类型的字段,用于注册音乐唱片的注册键
再进一步发掘,除了这个接口本身的bootstrap
方法,还有一个地方用到了FIVE
这个字段
1 | public static final Item MUSIC_DISC_5 = register( |
它便是我们物品的注册,这里的jukeboxPlayable
方法就是用于设置音乐唱片的播放音乐
这里的JukeboxSongs.FIVE
就是我们上面注册的音乐唱片的注册键
其他的方法像maxCount
,这是物品最大堆叠数量,rarity
是物品的稀有度,直接影响的是物品名称文字的颜色,这里的RARE
是稀有的意思,文字是蓝色的(AQUA
),它还有EPIC
,这是史诗的意思,文字是紫色的(LIGHT_PURPLE
)
这里就是一个完整的注册流程
稍微捋一下,SoundEvents
注册的是播放这个音乐唱片的事件,JukeboxSongs
注册的是实际音乐唱片对应的音频文件,Item
注册的是音乐唱片这个物品,这三者之间的关系就是这样的
注册音乐唱片
注册声音事件
首先我们要注册声音事件,这个是播放音乐唱片的事件
不过在注册之前,先把注册方法整合一下
1 | private static RegistryEntry.Reference<SoundEvent> registerReference(String name) { |
其实就是原版的方法,整合到了一起,并用我们自己的命名空间
然后我们就可以注册音乐唱片的声音事件了
1 | public static final RegistryEntry.Reference<SoundEvent> MUSIC_DISC_TEST = registerReference("music_disc.test"); |
这里我们注册了一个名为music_disc.test
的音乐唱片的声音事件
创建ModJukeboxSongs接口
和原版的一样,我们创建一个接口,用于注册音乐唱片的对应的音频文件
1 | public interface ModJukeboxSongs { |
当然,这里我们需要写一个注册方法
1 | private static RegistryKey<JukeboxSong> of(String id) { |
随后我们就可以用这个注册方法来注册音乐唱片的音频文件了
1 | RegistryKey<JukeboxSong> TEST = of("test"); |
再接下来我们写一个bootstrap
方法,用于动态注册
不过同样的,它也有一个注册方法
1 | private static void register( |
这个方法用于注册音乐唱片的音频文件,lengthInSeconds
是音乐唱片的播放时间,comparatorOutput
是比较器输出的红石信号强度
在下面的bootstrap
方法中,我们就可以用这个方法来注册音乐唱片的音频文件了
DataGen调用
以后见到bootstrap
,都记得去我们的数据生成类中调用一下,因为这个方法是动态注册的,即你要用到它的时候才会给你注册,塞到注册表里去(并不是像前面的方块或者物品那样,启动游戏就完成了注册)
1 |
|
这里我们在TutorialModDataGenerator
中重写buildRegistry
方法,调用ModJukeboxSongs
的bootstrap
方法
注册物品
接下来我们注册对应的音乐唱片这个物品
1 | public static final Item TEST_MUSIC_DISC = registerItems("test_music_disc", |
和原版一样写就好了
加入物品栏
最后我们把这个音乐唱片加入到物品栏中
1 | entries.add(ModItems.TEST_MUSIC_DISC); |
数据文件
语言文件
1 | translationBuilder.add(ModItems.TEST_MUSIC_DISC, "Test Music Disc"); |
一个是我们音乐唱片这个物品的名字,另一个则是当我们播放唱片的时候,蹦出来的那一段彩色字幕(正在播放:...
)
而最后一句,是音乐唱片的描述信息,这个不写其实没关系,不知为何如果不写也会显示用jukebox_song.tutorialmod.test
翻译的Test
模型文件
1 | itemModelGenerator.register(ModItems.TEST_MUSIC_DISC, Models.TEMPLATE_MUSIC_DISC); |
模型文件也有些特殊,它的模型父级用的是TEMPLATE_MUSIC_DISC
,这个是原版的音乐唱片的模型
音乐唱片的音频文件
和前面一样,放在src/main/resources/assets/tutorialmod/sounds
下
sounds.json
1 | "music_disc.test": { |
在我们之前写的上面加上这一段就好
材质文件
材质文件也不要忘记了
但是,当我们这里都设置好之后,我们进入游戏想拿音乐唱片来播放时,却发现它虽然可以放到唱片机里面,也有这个彩色的字幕蹦出来,但却没有声音(当然,先确保音频文件没问题)
为什么嘞?因为在1.21
中,我们还得为音乐唱片写单独的数据文件
test.json
这个文件名是我们在JukeboxSongs
中注册的音乐唱片的注册键的名字,这里是test
路径是resources/data/tutorialmod/jukebox_song/test.json
1 | { |
在这里面我们塞一些参数
comparator_output
是比较器输出的红石信号强度,这里是15
(和bootstrap
中的一致)
description
是音乐唱片的描述信息,这里是jukebox_song.tutorialmod.test
(对应我们语言文件写的第二句)
length_in_seconds
是音乐唱片的播放时间,这里是247.0
(单位秒,要自己换算一下,和bootstrap
中的一致)
sound_event
是音乐唱片的声音事件,这里是tutorialmod:music_disc.test
在此之后,我们进入游戏就可以正常播放音乐唱片了
同时,你也可以感受一下单声道音频文件和立体声(双声道或是多声道)的音频文件的区别,这个在音乐唱片上尤为明显(在视频教程中用的是单声道的)
单声道
当我们玩家转到不同方向时,左右声道的声音会有所变化(戴耳机的话);同时远离唱片机会感受到声音的衰减
但是立体声
就不一样了,它没有衰减,也没有左右声道的变化(除非你写的是整个游戏的背景音乐,那到可以用立体声的)