Skip to content

Commit ee45df9

Browse files
committed
添加了一个从小放大的粒子组示例
1 parent 034fbfe commit ee45df9

14 files changed

Lines changed: 135 additions & 28 deletions

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import cn.coostack.network.packet.PacketParticleGroupS2C
44
import cn.coostack.network.packet.client.listener.ClientParticleGroupPacketHandler
55
import cn.coostack.particles.ModParticles
66
import cn.coostack.particles.control.group.ClientParticleGroupManager
7+
import cn.coostack.particles.control.group.impl.ScaleCircleGroupClient
78
import cn.coostack.particles.control.group.impl.TestGroupClient
89
import cn.coostack.particles.impl.TestEndRodParticle
910
import net.fabricmc.api.ClientModInitializer
@@ -30,6 +31,9 @@ object CooParticleAPIClient : ClientModInitializer {
3031
ClientParticleGroupManager.register(
3132
TestGroupClient::class.java, TestGroupClient.Provider()
3233
)
34+
ClientParticleGroupManager.register(
35+
ScaleCircleGroupClient::class.java, ScaleCircleGroupClient.Provider()
36+
)
3337
ModParticles.reg()
3438
}
3539

src/main/kotlin/cn/coostack/items/TestParticleItem.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package cn.coostack.items
22

33
import cn.coostack.network.buffer.ParticleControlerDataBuffers
4+
import cn.coostack.network.particle.ScaleCircleGroupServer
45
import cn.coostack.network.particle.ServerParticleGroupManager
56
import cn.coostack.network.particle.TestParticleGroup
7+
import cn.coostack.particles.control.group.impl.ScaleCircleGroupClient
68
import cn.coostack.particles.control.group.impl.TestGroupClient
79
import net.minecraft.entity.player.PlayerEntity
810
import net.minecraft.item.Item
@@ -19,9 +21,9 @@ class TestParticleItem(settings: Settings) : Item(settings) {
1921
if (world.isClient) {
2022
return TypedActionResult.success(user.getStackInHand(hand))
2123
}
22-
val serverGroup = TestParticleGroup(user as ServerPlayerEntity)
24+
val serverGroup = ScaleCircleGroupServer(user as ServerPlayerEntity)
2325
ServerParticleGroupManager.addParticleGroup(
24-
TestGroupClient::class.java, serverGroup, user.pos, world as ServerWorld
26+
ScaleCircleGroupClient::class.java, serverGroup, user.pos, world as ServerWorld
2527
)
2628
return super.use(world, user, hand)
2729
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package cn.coostack.network.particle
2+
3+
import cn.coostack.network.buffer.ParticleControlerDataBuffer
4+
import cn.coostack.network.buffer.ParticleControlerDataBuffers
5+
import net.minecraft.server.network.ServerPlayerEntity
6+
import java.util.*
7+
8+
class ScaleCircleGroupServer(private val bindPlayer: ServerPlayerEntity, visibleRange: Double = 32.0) :
9+
ServerParticleGroup(visibleRange) {
10+
private var anTick = 0
11+
private var anMaxTick = 30
12+
override fun tick() {
13+
if (anTick++ >= anMaxTick) {
14+
anTick = anMaxTick
15+
}
16+
teleportGroupTo(bindPlayer.pos)
17+
}
18+
19+
override fun otherPacketArgs(): Map<String, ParticleControlerDataBuffer<out Any>> {
20+
return mapOf(
21+
"bind_player" to ParticleControlerDataBuffers.uuid(bindPlayer.uuid),
22+
"an_tick" to ParticleControlerDataBuffers.int(anTick)
23+
)
24+
}
25+
}

src/main/kotlin/cn/coostack/network/particle/ServerParticleGroup.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@ import java.util.UUID
2020
* @param visibleRange 玩家可见范围 (origin)
2121
*/
2222
abstract class ServerParticleGroup(
23-
val uuid: UUID,
2423
var visibleRange: Double = 32.0
2524
) {
25+
val uuid: UUID = UUID.randomUUID()
2626
var pos: Vec3d = Vec3d.ZERO
2727
internal set
2828
var world: World? = null

src/main/kotlin/cn/coostack/network/particle/SimpleParticleGroup.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package cn.coostack.network.particle
33
import cn.coostack.network.buffer.ParticleControlerDataBuffer
44
import java.util.*
55

6-
class SimpleParticleGroup(uuid: UUID, visibleRange: Double = 32.0) : ServerParticleGroup(uuid, visibleRange) {
6+
class SimpleParticleGroup(visibleRange: Double = 32.0) : ServerParticleGroup(visibleRange) {
77
override fun tick() {}
88
override fun otherPacketArgs(): Map<String, ParticleControlerDataBuffer<out Any>> {
99
return mapOf()

src/main/kotlin/cn/coostack/network/particle/TestParticleGroup.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import cn.coostack.network.buffer.ParticleControlerDataBuffers
55
import net.minecraft.server.network.ServerPlayerEntity
66
import java.util.*
77

8-
class TestParticleGroup(private val bindPlayer: ServerPlayerEntity) : ServerParticleGroup(UUID.randomUUID(), 16.0) {
8+
class TestParticleGroup(private val bindPlayer: ServerPlayerEntity) : ServerParticleGroup(16.0) {
99
override fun tick() {
1010
withPlayerStats(bindPlayer)
1111
setPosOnServer(bindPlayer.eyePos)

src/main/kotlin/cn/coostack/particles/ControlableParticle.kt

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,10 @@ package cn.coostack.particles
22

33
import cn.coostack.particles.control.ControlParticleManager
44
import cn.coostack.particles.control.ParticleControler
5-
import cn.coostack.test.util.RelativeLocation
65
import net.fabricmc.api.EnvType
76
import net.fabricmc.api.Environment
8-
import net.minecraft.client.particle.Particle
9-
import net.minecraft.client.particle.ParticleTextureSheet
107
import net.minecraft.client.particle.SpriteBillboardParticle
118
import net.minecraft.client.world.ClientWorld
12-
import net.minecraft.particle.ParticleEffect
139
import net.minecraft.util.math.Box
1410
import net.minecraft.util.math.Vec3d
1511
import net.minecraft.util.math.random.Random
@@ -30,6 +26,7 @@ abstract class ControlableParticle(
3026
* 是否调用 net.minecraft.client.particle.Particle中的tick方法
3127
*/
3228
var minecraftTick: Boolean = false
29+
3330
/**
3431
* @see x
3532
* @see y
@@ -125,20 +122,12 @@ abstract class ControlableParticle(
125122
/**
126123
* @see age
127124
*/
128-
var currentTick: Int
125+
var currentAge: Int
129126
get() = age
130127
set(value) {
131128
age = value
132129
}
133130

134-
/**
135-
* @see maxAge
136-
*/
137-
var maxAliveTick: Int
138-
get() = maxAge
139-
set(value) {
140-
maxAge = value
141-
}
142131

143132
/**
144133
* @see gravityStrength

src/main/kotlin/cn/coostack/particles/control/ParticleControler.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ class ParticleControler(private val uuid: UUID) : Controlable<ControlableParticl
2525
/**
2626
* 参数缓存 (tick等)
2727
*/
28-
val bufferedData = ConcurrentHashMap<String, ParticleControlerDataBuffer<*>>()
28+
val bufferedData = ConcurrentHashMap<String, Any>()
2929
lateinit var initInvoker: ControlableParticle.() -> Unit
3030

3131
fun addPreTickAction(action: ControlableParticle.() -> Unit): ParticleControler {

src/main/kotlin/cn/coostack/particles/control/group/ControlableParticleGroup.kt

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,8 @@ import cn.coostack.test.util.Math3DUtil
99
import cn.coostack.test.util.RelativeLocation
1010
import net.fabricmc.api.EnvType
1111
import net.fabricmc.api.Environment
12-
import net.fabricmc.loader.impl.lib.sat4j.core.Vec
1312
import net.minecraft.client.world.ClientWorld
14-
import net.minecraft.particle.ParticleEffect
1513
import net.minecraft.util.math.Vec3d
16-
import java.util.HashMap
1714
import java.util.UUID
1815
import java.util.concurrent.ConcurrentHashMap
1916

@@ -116,6 +113,9 @@ abstract class ControlableParticleGroup(val uuid: UUID) : Controlable<Controlabl
116113
}
117114
val toPos = Vec3d(pos.x + rl.x, pos.y + rl.y, pos.z + rl.z)
118115
val controler = particleDisplayer.display(toPos, world) ?: continue
116+
if (controler is ParticleControler) {
117+
v.controlerAction(controler)
118+
}
119119
// world.addParticle(
120120
// v.effect(uuid), pos.x + rl.x, pos.y + rl.y, pos.z + rl.z, 0.0, 0.0, 0.0
121121
// )
@@ -175,9 +175,8 @@ abstract class ControlableParticleGroup(val uuid: UUID) : Controlable<Controlabl
175175

176176
@Deprecated("使用 teleportTo")
177177
fun teleportGroupTo(pos: Vec3d) {
178-
val relativeMapper = particlesLocations
179178
this.origin = pos
180-
relativeMapper.forEach { (t, u) ->
179+
particlesLocations.forEach { (t, u) ->
181180
t.teleportTo(u.x + pos.x, u.y + pos.y, u.z + pos.z)
182181
}
183182
}
@@ -206,5 +205,11 @@ abstract class ControlableParticleGroup(val uuid: UUID) : Controlable<Controlabl
206205
class ParticleRelativeData(
207206
val effect: (UUID) -> ParticleDisplayer,
208207
val invoker: ControlableParticle.() -> Unit
209-
)
208+
) {
209+
var controlerAction: (ParticleControler) -> Unit = {}
210+
fun withControler(controler: (ParticleControler) -> Unit): ParticleRelativeData {
211+
controlerAction = controler
212+
return this
213+
}
214+
}
210215
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
package cn.coostack.particles.control.group.impl
2+
3+
import cn.coostack.network.buffer.ParticleControlerDataBuffer
4+
import cn.coostack.particles.ParticleDisplayer
5+
import cn.coostack.particles.control.group.ControlableParticleGroup
6+
import cn.coostack.particles.control.group.ControlableParticleGroupProvider
7+
import cn.coostack.particles.impl.TestEndRodEffect
8+
import cn.coostack.test.util.Math3DUtil
9+
import cn.coostack.test.util.RelativeLocation
10+
import org.joml.Vector3f
11+
import java.util.*
12+
13+
class ScaleCircleGroupClient(uuid: UUID, val bindPlayer: UUID) : ControlableParticleGroup(uuid) {
14+
internal var anTick = 0
15+
internal var anMaxTick = 30
16+
17+
class Provider : ControlableParticleGroupProvider {
18+
override fun createGroup(
19+
uuid: UUID,
20+
args: Map<String, ParticleControlerDataBuffer<*>>
21+
): ControlableParticleGroup {
22+
val bindPlayer = args["bind_player"]!!.loadedValue as UUID
23+
val group = ScaleCircleGroupClient(uuid, bindPlayer)
24+
group.anTick = args["an_tick"]!!.loadedValue as Int
25+
return group
26+
}
27+
}
28+
29+
override fun loadParticleLocations(): Map<ParticleRelativeData, RelativeLocation> {
30+
val res = mutableMapOf<ParticleRelativeData, RelativeLocation>()
31+
val points = Math3DUtil.getCycloidGraphic(3.0, 5.0, -2, 3, 360, .5)
32+
points.forEach {
33+
val withData = withEffect({ ParticleDisplayer.withSingle(TestEndRodEffect(it)) }) {
34+
color = Vector3f(100 / 255f, 100 / 255f, 255 / 255f)
35+
maxAge = 120
36+
}.withControler { c ->
37+
c.addPreTickAction {
38+
currentAge++
39+
if (currentAge >= maxAge) {
40+
this@ScaleCircleGroupClient.canceled = true
41+
}
42+
}
43+
}
44+
res[withData] = it.multiply(1.0 / anMaxTick)
45+
}
46+
return res
47+
}
48+
49+
50+
override fun onGroupDisplay() {
51+
// 保存最初始的长度
52+
// 用于做稳定的长度添加
53+
val firstClone = particlesLocations.map {
54+
it.key to it.value.length()
55+
}.toMap()
56+
addPreTickAction {
57+
val player = world!!.getPlayerByUuid(bindPlayer) ?: return@addPreTickAction
58+
// 同步位置
59+
teleportTo(player.pos)
60+
// 在变大的过程中也能旋转
61+
rotateParticlesAsAxis(Math.toRadians(10.0))
62+
// 旋转时间设定
63+
if (anTick++ >= anMaxTick) {
64+
anTick = anMaxTick
65+
return@addPreTickAction
66+
}
67+
particlesLocations.forEach {
68+
val cloneLength = firstClone[it.key]!!
69+
// 确保添加的方向和长度正确
70+
it.value.add(it.value.normalize().multiply(cloneLength))
71+
}
72+
}
73+
}
74+
}

0 commit comments

Comments
 (0)