Skip to content

Commit c3a635f

Browse files
committed
# 修改
## PointsBuilder.kt - 简化了PointsBuilder的 addPoints系列方法 - 为了减少Math3DUtil类的书写导致键盘暴走, 在此Builder中引用了大多数Math3DUtil的方法 ## ScaleCircleGroupClient.kt - 修改了粒子图形样式(测试 # 新增 ## ParticleGroupStyle 在进行客户端和服务器的数据渲染同步时发现, 每次进行一个新的操作都要在服务器类上复制一样的代码 创建一样的变量, 相当的麻烦 于是基于 ControlableParticleGroup 和 ServerParticleGroup 构造了此类 ## item 一个新的用于测试上述框架的物品
1 parent de0361d commit c3a635f

22 files changed

Lines changed: 1372 additions & 83 deletions

File tree

README.md

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -483,3 +483,162 @@ class SequencedMagicCircleServer(val bindPlayer: UUID) : SequencedServerParticle
483483
}
484484
}
485485
```
486+
487+
# 使用 ParticleGroupStyle
488+
## 使用此类的原因
489+
在进行客户端和服务器的数据渲染同步时发现, 每次进行一个新的操作都要在服务器类上复制一样的代码 创建一样的变量, 相当的麻烦
490+
于是基于 ControlableParticleGroup 和 ServerParticleGroup 构造了此类
491+
## 使用方法
492+
```kotlin
493+
class ExampleStyle(val bindPlayer: UUID, uuid: UUID = UUID.randomUUID()) :
494+
/**
495+
* 第一个参数代表玩家可视范围 默认32.0
496+
* 第二个参数代表这个粒子样式的唯一标识符
497+
* 在这里直接使用默认值(randomUUID)即可
498+
*/
499+
ParticleGroupStyle(16.0, uuid) {
500+
/**
501+
* 和 ControlableParticleGroup一样 为了在服务器构建这个类 同时也需要自己制作构建器
502+
*/
503+
class Provider : ParticleStyleProvider {
504+
override fun createStyle(
505+
uuid: UUID,
506+
args: Map<String, ParticleControlerDataBuffer<*>>
507+
): ParticleGroupStyle {
508+
val player = args["bind_player"]!!.loadedValue as UUID
509+
return ExampleStyle(player, uuid)
510+
}
511+
}
512+
513+
// 自定义参数
514+
val maxScaleTick = 60
515+
var scaleTick = 0
516+
val maxTick = 240
517+
var current = 0
518+
var angleSpeed = PI / 72
519+
520+
init {
521+
// 如果你想要修改基类 (ParticleGroupStyle)
522+
// 不要在beforeDisplay修改 在构造方法内修改
523+
// 否则会出现联机客户端不同步的问题 (或者使用change?)
524+
scale = 1.0 / maxScaleTick
525+
}
526+
527+
/**
528+
* 对应 ControlableParticleGroup的loadParticleLocations方法
529+
*/
530+
override fun getCurrentFrames(): Map<StyleData, RelativeLocation> {
531+
// 这里采用了自制的点图形制作器 查阅 cn.coostack.cooparticlesapi.utils.builder.PointsBuilder
532+
val res = mutableMapOf<StyleData, RelativeLocation>().apply {
533+
putAll(
534+
PointsBuilder()
535+
.addDiscreteCircleXZ(8.0, 720, 10.0)
536+
.createWithStyleData {
537+
// 支持单个粒子
538+
StyleData { ParticleDisplayer.withSingle(ControlableCloudEffect(it)) }
539+
.withParticleHandler {
540+
colorOfRGB(127, 139, 175)
541+
this.scale(1.5f)
542+
textureSheet = ParticleTextureSheet.PARTICLE_SHEET_LIT
543+
}
544+
})
545+
putAll(
546+
PointsBuilder()
547+
.addCircle(6.0, 4)
548+
.pointsOnEach { it.y -= 12.0 }
549+
.addCircle(6.0, 4)
550+
.pointsOnEach { it.y += 6.0 }
551+
// 这里要你的Data构建器
552+
.createWithStyleData {
553+
// 相当于ControlableParticleGroup的 withEffect
554+
StyleData {
555+
// 也支持粒子组合
556+
// 如果有其他style也可以改成 ParticleDisplayer.withStyle(xxxStyle(it,...))
557+
ParticleDisplayer.withGroup(
558+
MagicSubGroup(it, bindPlayer)
559+
)
560+
}
561+
}
562+
)
563+
}
564+
return res
565+
}
566+
567+
568+
override fun onDisplay() {
569+
// 开启参数自动同步
570+
autoToggle = true
571+
572+
/**
573+
* 对于区分客户端环境和服务器环境
574+
* 此类提供了 client 属性
575+
* 或者使用 world!!.isClient 也可以查询是否为客户端
576+
*/
577+
addPreTickAction {
578+
if (scaleTick++ >= maxScaleTick) {
579+
return@addPreTickAction
580+
}
581+
scale(scale + 1.0 / maxScaleTick)
582+
}
583+
addPreTickAction {
584+
current++
585+
if (current >= maxTick) {
586+
remove()
587+
}
588+
val player = world!!.getPlayerByUuid(bindPlayer) ?: return@addPreTickAction
589+
teleportTo(player.pos)
590+
rotateParticlesAsAxis(angleSpeed)
591+
}
592+
}
593+
594+
// 参数自动同步时, 服务器的这些参数会自动同步到每一个客户端上
595+
override fun writePacketArgs(): Map<String, ParticleControlerDataBuffer<*>> {
596+
return mapOf(
597+
"current" to ParticleControlerDataBuffers.int(current),
598+
"angle_speed" to ParticleControlerDataBuffers.double(angleSpeed),
599+
"bind_player" to ParticleControlerDataBuffers.uuid(bindPlayer),
600+
"scaleTick" to ParticleControlerDataBuffers.int(scaleTick),
601+
)
602+
}
603+
// 获取来自服务器的同步数据时, 执行此方法
604+
override fun readPacketArgs(args: Map<String, ParticleControlerDataBuffer<*>>) {
605+
if (args.containsKey("current")) {
606+
current = args["current"]!!.loadedValue as Int
607+
}
608+
if (args.containsKey("angle_speed")) {
609+
angleSpeed = args["angle_speed"]!!.loadedValue as Double
610+
}
611+
if (args.containsKey("scaleTick")) {
612+
scaleTick = args["scaleTick"]!!.loadedValue as Int
613+
}
614+
}
615+
}
616+
```
617+
618+
完成类的构建时 需要在ClientModInitializer进行注册
619+
```kotlin
620+
ParticleStyleManager.register(ExampleStyle::class.java, ExampleStyle.Provider())
621+
```
622+
如何在服务器生成此粒子样式?
623+
这里以Item为例
624+
```kotlin
625+
class TestStyleItem : Item(Settings()) {
626+
override fun use(world: World, user: PlayerEntity, hand: Hand): TypedActionResult<ItemStack?>? {
627+
val res = super.use(world, user, hand)
628+
// 如果你在world.isClient 为true环境下生成粒子
629+
// 则该生成只会针对这一个客户端
630+
// 否则就是在服务器生成- 所有符合条件的玩家都能看到
631+
if (world.isClient) {
632+
return res
633+
}
634+
val style = ExampleStyle(user.uuid)
635+
// server world
636+
ParticleStyleManager.spawnStyle(world, user.pos, style)
637+
// 测试自动同步用的延时
638+
CooParticleAPI.scheduler.runTask(30) {
639+
style.angleSpeed += PI / 72
640+
}
641+
return res
642+
}
643+
}
644+
```

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ loader_version=0.16.10
1010
fabric_kotlin_version=1.13.2+kotlin.2.1.20
1111

1212
# Mod Properties
13-
mod_version=1.7
13+
mod_version=1.8.1
1414
maven_group=cn.coostack
1515
archives_base_name=coo-particles-api
1616

src/main/generated/assets/cooparticlesapi/lang/zh_cn.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@
22
"item.coo_group": "§b粒子测试分组",
33
"item.cooparticlesapi.sequenced_test_item": "§a顺序出现粒子组测试工具",
44
"item.cooparticlesapi.test_barrier_item": "弹幕测试法杖",
5-
"item.cooparticlesapi.test_particle": "测试粒子物品"
5+
"item.cooparticlesapi.test_particle": "测试粒子物品",
6+
"item.cooparticlesapi.test_style": "§a粒子样式测试工具-C-S共用"
67
}

src/main/kotlin/cn/coostack/cooparticlesapi/CooParticleAPI.kt

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@ import cn.coostack.cooparticlesapi.items.CooItems
66
import cn.coostack.cooparticlesapi.items.group.CooItemGroup
77
import cn.coostack.cooparticlesapi.network.packet.PacketParticleGroupS2C
88
import cn.coostack.cooparticlesapi.network.packet.PacketParticleS2C
9+
import cn.coostack.cooparticlesapi.network.packet.PacketParticleStyleS2C
910
import cn.coostack.cooparticlesapi.network.particle.ServerParticleGroupManager
1011
import cn.coostack.cooparticlesapi.network.particle.ServerParticleGroup
12+
import cn.coostack.cooparticlesapi.network.particle.style.ParticleStyleManager
1113
import cn.coostack.cooparticlesapi.particles.ControlableParticle
1214
import cn.coostack.cooparticlesapi.particles.control.group.ClientParticleGroupManager
1315
import cn.coostack.cooparticlesapi.particles.control.group.ControlableParticleGroup
@@ -16,10 +18,9 @@ import cn.coostack.cooparticlesapi.scheduler.CooScheduler
1618
import net.fabricmc.api.ModInitializer
1719
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents
1820
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents
19-
import net.minecraft.particle.ParticleEffect
2021
import net.minecraft.server.MinecraftServer
2122
import org.slf4j.LoggerFactory
22-
23+
import cn.coostack.cooparticlesapi.particles.ControlableParticleEffect
2324
object CooParticleAPI : ModInitializer {
2425
val logger = LoggerFactory.getLogger("CooParticleAPI")!!
2526
const val MOD_ID = "cooparticlesapi"
@@ -51,21 +52,23 @@ object CooParticleAPI : ModInitializer {
5152
* @see ControlableParticleGroupProvider 服务端发送数据包后 解析成ControlableParticleGroup的构造器
5253
* @see ServerParticleGroup 用于同步给其他客户端的服务器粒子组控制器对象
5354
* @see ControlableParticle 能够被控制的粒子 (原版addParticle是不提供粒子对象的)
54-
* @see ParticleEffect 对应所需要的粒子效果
55+
* @see ControlableParticleEffect 对应所需要的粒子效果
5556
*/
5657
override fun onInitialize() {
5758
CooItemGroup.reg()
5859
CooItems.reg()
5960
APIConfigManager.loadConfig()
6061
ServerTickEvents.START_SERVER_TICK.register { _ ->
6162
ServerParticleGroupManager.upgrade()
63+
ParticleStyleManager.doTickServer()
6264
BarrageManager.doTick()
6365
scheduler.doTick()
6466
}
6567
ServerLifecycleEvents.SERVER_STARTED.register { server ->
6668
this.server = server
6769
}
68-
PacketParticleGroupS2C.Companion.init()
69-
PacketParticleS2C.Companion.init()
70+
PacketParticleGroupS2C.init()
71+
PacketParticleS2C.init()
72+
PacketParticleStyleS2C.init()
7073
}
7174
}

src/main/kotlin/cn/coostack/cooparticlesapi/CooParticleAPIClient.kt

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@ package cn.coostack.cooparticlesapi
22

33
import cn.coostack.cooparticlesapi.network.packet.PacketParticleGroupS2C
44
import cn.coostack.cooparticlesapi.network.packet.PacketParticleS2C
5+
import cn.coostack.cooparticlesapi.network.packet.PacketParticleStyleS2C
56
import cn.coostack.cooparticlesapi.network.packet.client.listener.ClientParticleGroupPacketHandler
67
import cn.coostack.cooparticlesapi.network.packet.client.listener.ClientParticlePacketHandler
8+
import cn.coostack.cooparticlesapi.network.packet.client.listener.ClientParticleStylePacketHandler
9+
import cn.coostack.cooparticlesapi.network.particle.style.ParticleStyleManager
710
import cn.coostack.cooparticlesapi.particles.CooModParticles
811
import cn.coostack.cooparticlesapi.particles.control.group.ClientParticleGroupManager
912
import cn.coostack.cooparticlesapi.particles.impl.ControlableCloudEffect
@@ -15,6 +18,7 @@ import cn.coostack.cooparticlesapi.test.particle.client.BarrierSwordGroupClient
1518
import cn.coostack.cooparticlesapi.test.particle.client.ScaleCircleGroupClient
1619
import cn.coostack.cooparticlesapi.test.particle.client.SequencedMagicCircleClient
1720
import cn.coostack.cooparticlesapi.test.particle.client.TestGroupClient
21+
import cn.coostack.cooparticlesapi.test.particle.style.ExampleStyle
1822
import net.fabricmc.api.ClientModInitializer
1923
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents
2024
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientWorldEvents
@@ -27,6 +31,7 @@ object CooParticleAPIClient : ClientModInitializer {
2731
particleGroupPacketListener()
2832
ClientTickEvents.START_WORLD_TICK.register {
2933
ClientParticleGroupManager.doClientTick()
34+
ParticleStyleManager.doTickClient()
3035
}
3136
ClientWorldEvents.AfterClientWorldChange { _, _ ->
3237
ClientParticleGroupManager.clearAllVisible()
@@ -55,16 +60,24 @@ object CooParticleAPIClient : ClientModInitializer {
5560
ClientParticleGroupManager.register(
5661
SequencedMagicCircleClient::class.java, SequencedMagicCircleClient.Provider()
5762
)
63+
ParticleStyleManager.register(ExampleStyle::class.java, ExampleStyle.Provider())
5864
CooModParticles.reg()
5965
}
6066

6167

6268
private fun particleGroupPacketListener() {
6369
ClientPlayNetworking.registerGlobalReceiver(
64-
PacketParticleGroupS2C.Companion.payloadID,
70+
PacketParticleGroupS2C.payloadID,
6571
ClientParticleGroupPacketHandler
6672
)
67-
ClientPlayNetworking.registerGlobalReceiver(PacketParticleS2C.Companion.payloadID, ClientParticlePacketHandler)
73+
ClientPlayNetworking.registerGlobalReceiver(
74+
PacketParticleStyleS2C.payloadID,
75+
ClientParticleStylePacketHandler
76+
)
77+
ClientPlayNetworking.registerGlobalReceiver(
78+
PacketParticleS2C.payloadID,
79+
ClientParticlePacketHandler
80+
)
6881
}
6982

7083

src/main/kotlin/cn/coostack/cooparticlesapi/datagen/ItemModelProvider.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ class ItemModelProvider(output: FabricDataOutput?) : FabricModelProvider(output)
1717
register(CooItems.testParticle, Models.GENERATED)
1818
register(CooItems.testBarrierItem, Models.HANDHELD)
1919
register(CooItems.testSequencedParticle, Models.HANDHELD)
20+
register(CooItems.testStyleItem, Models.HANDHELD)
2021
}
2122
}
2223
}

src/main/kotlin/cn/coostack/cooparticlesapi/datagen/LanguageProvider.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ class LanguageProvider(
1616
add(CooItems.testParticle, "测试粒子物品")
1717
add(CooItems.testBarrierItem, "弹幕测试法杖")
1818
add(CooItems.testSequencedParticle, "§a顺序出现粒子组测试工具")
19+
add(CooItems.testStyleItem, "§a粒子样式测试工具-C-S共用")
1920
}
2021
}
2122
}

src/main/kotlin/cn/coostack/cooparticlesapi/items/CooItems.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ object CooItems {
2323
"sequenced_test_item", TestSequencedItem()
2424
)
2525

26+
val testStyleItem = register(
27+
"test_style", TestStyleItem()
28+
)
29+
2630
fun register(id: String, item: Item): Item {
2731
val res = Registry.register(
2832
Registries.ITEM, Identifier.of(CooParticleAPI.MOD_ID, id), item
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package cn.coostack.cooparticlesapi.items
2+
3+
import cn.coostack.cooparticlesapi.CooParticleAPI
4+
import cn.coostack.cooparticlesapi.network.particle.style.ParticleStyleManager
5+
import cn.coostack.cooparticlesapi.test.particle.style.ExampleStyle
6+
import net.minecraft.entity.player.PlayerEntity
7+
import net.minecraft.item.Item
8+
import net.minecraft.item.ItemStack
9+
import net.minecraft.util.Hand
10+
import net.minecraft.util.TypedActionResult
11+
import net.minecraft.world.World
12+
import kotlin.math.PI
13+
14+
class TestStyleItem : Item(Settings()) {
15+
override fun use(world: World, user: PlayerEntity, hand: Hand): TypedActionResult<ItemStack?>? {
16+
val res = super.use(world, user, hand)
17+
18+
if (world.isClient) {
19+
return res
20+
}
21+
val style = ExampleStyle(user.uuid)
22+
ParticleStyleManager.spawnStyle(world, user.pos, style)
23+
CooParticleAPI.scheduler.runTask(30) {
24+
style.angleSpeed += PI / 72
25+
}
26+
return res
27+
}
28+
}

0 commit comments

Comments
 (0)