789 lines
21 KiB
Markdown
789 lines
21 KiB
Markdown
---
|
|
title: Particules
|
|
type: docs
|
|
weight: 1
|
|
---
|
|
|
|
Le système de particules de Hytale fournit des effets visuels riches à travers des émetteurs et renderers configurables. Créez des explosions, traînées, auras et effets visuels complexes avec un contrôle précis sur le comportement et l'apparence.
|
|
|
|
**Package :** `com.hypixel.hytale.server.core.asset.type.particle`
|
|
|
|
{{< cards cols="3" >}}
|
|
{{< card link="#générer-des-particules" title="Génération" subtitle="Créer des effets de particules" icon="sparkles" >}}
|
|
{{< card link="#configuration-du-système-de-particules" title="Configuration" subtitle="Config système et spawner" icon="adjustments" >}}
|
|
{{< card link="#attracteurs-de-particules" title="Attracteurs" subtitle="Forces et mouvement" icon="arrow-circle-right" >}}
|
|
{{< /cards >}}
|
|
|
|
---
|
|
|
|
## Générer des Particules
|
|
|
|
### Méthodes ParticleUtil
|
|
|
|
{{< tabs items="Basique,Avancé,WorldParticle" >}}
|
|
{{< tab >}}
|
|
|
|
```java
|
|
import com.hypixel.hytale.server.core.universe.world.ParticleUtil;
|
|
|
|
// Génération basique à une position (trouve auto les joueurs proches)
|
|
ParticleUtil.spawnParticleEffect(
|
|
"explosion_small", // ID du système de particules
|
|
position, // Position Vector3d
|
|
componentAccessor
|
|
);
|
|
|
|
// Générer pour des joueurs spécifiques
|
|
ParticleUtil.spawnParticleEffect(
|
|
"magic_trail",
|
|
position,
|
|
playerRefs, // List<Ref<EntityStore>>
|
|
componentAccessor
|
|
);
|
|
```
|
|
|
|
**Distance de Diffusion :** `DEFAULT_PARTICLE_DISTANCE = 75` blocs
|
|
|
|
{{< /tab >}}
|
|
{{< tab >}}
|
|
|
|
```java
|
|
// Avec référence à l'entité source
|
|
ParticleUtil.spawnParticleEffect(
|
|
"attack_swing",
|
|
position,
|
|
sourceEntityRef, // Entité qui a généré ceci
|
|
playerRefs,
|
|
componentAccessor
|
|
);
|
|
|
|
// Avec contrôle de rotation
|
|
ParticleUtil.spawnParticleEffect(
|
|
"directional_beam",
|
|
position,
|
|
yaw, pitch, roll, // Angles de rotation
|
|
sourceEntityRef,
|
|
playerRefs,
|
|
componentAccessor
|
|
);
|
|
|
|
// Avec échelle et couleur
|
|
ParticleUtil.spawnParticleEffect(
|
|
"colored_burst",
|
|
position,
|
|
yaw, pitch, roll,
|
|
2.0f, // Multiplicateur d'échelle
|
|
new Color(255, 100, 50, 255), // Couleur RGBA
|
|
playerRefs,
|
|
componentAccessor
|
|
);
|
|
```
|
|
|
|
{{< /tab >}}
|
|
{{< tab >}}
|
|
|
|
```java
|
|
import com.hypixel.hytale.server.core.asset.type.particle.config.WorldParticle;
|
|
|
|
// Contrôle complet avec le wrapper WorldParticle
|
|
WorldParticle worldParticle = new WorldParticle(
|
|
"my_particle_system",
|
|
new Color(255, 100, 50, 255), // Override couleur RGBA
|
|
1.5f, // Multiplicateur d'échelle
|
|
new Vector3f(0, 1, 0), // Offset de position
|
|
new Direction(0, 0, 0) // Offset de rotation
|
|
);
|
|
|
|
ParticleUtil.spawnParticleEffect(
|
|
worldParticle,
|
|
position,
|
|
sourceRef,
|
|
playerRefs,
|
|
componentAccessor
|
|
);
|
|
```
|
|
|
|
{{< /tab >}}
|
|
{{< /tabs >}}
|
|
|
|
---
|
|
|
|
## Configuration du Système de Particules
|
|
|
|
### Classe ParticleSystem
|
|
|
|
La configuration racine pour un effet de particules :
|
|
|
|
```java
|
|
public class ParticleSystem {
|
|
protected String id; // Identifiant unique
|
|
protected ParticleSpawnerGroup[] spawners; // Configurations de spawners
|
|
protected float lifeSpan; // Durée de vie du système (secondes)
|
|
protected float cullDistance; // Distance avant culling
|
|
protected float boundingRadius; // Boîte englobante de collision
|
|
protected boolean isImportant; // Flag de priorité réseau
|
|
}
|
|
```
|
|
|
|
| Champ | Type | Description |
|
|
|-------|------|-------------|
|
|
| `id` | String | Identifiant unique du système de particules |
|
|
| `spawners` | ParticleSpawnerGroup[] | Tableau de configurations de spawners |
|
|
| `lifeSpan` | float | Durée de vie du système (secondes) |
|
|
| `cullDistance` | float | Distance à laquelle les particules sont culled |
|
|
| `boundingRadius` | float | Sphère englobante pour les calculs de culling |
|
|
| `isImportant` | boolean | Si vrai, prioritisé dans la sync réseau |
|
|
|
|
### Configuration ParticleSpawner
|
|
|
|
Contrôle comment les particules individuelles sont émises :
|
|
|
|
{{< tabs items="Propriétés,Émission,Mouvement,Rendu" >}}
|
|
{{< tab >}}
|
|
|
|
```java
|
|
public class ParticleSpawner {
|
|
protected String id;
|
|
protected EmitShape shape;
|
|
protected RangeVector3f emitOffset;
|
|
protected boolean useEmitDirection;
|
|
protected Range totalParticles;
|
|
protected float lifeSpan;
|
|
protected int maxConcurrentParticles;
|
|
protected Rangef particleLifeSpan;
|
|
protected Rangef spawnRate;
|
|
protected boolean spawnBurst;
|
|
protected InitialVelocity initialVelocity;
|
|
protected ParticleAttractor[] attractors;
|
|
protected FXRenderMode renderMode;
|
|
protected float lightInfluence;
|
|
protected Particle particle;
|
|
}
|
|
```
|
|
|
|
{{< /tab >}}
|
|
{{< tab >}}
|
|
|
|
**Propriétés d'Émission :**
|
|
|
|
| Propriété | Type | Description |
|
|
|-----------|------|-------------|
|
|
| `shape` | EmitShape | Forme d'émission Sphere ou Cube |
|
|
| `emitOffset` | RangeVector3f | Plage d'offset aléatoire depuis l'origine |
|
|
| `useEmitDirection` | boolean | Utiliser la direction de spawn pour la vélocité |
|
|
| `totalParticles` | Range | Nombre min/max total de particules à émettre |
|
|
| `spawnRate` | Rangef | Particules par seconde |
|
|
| `spawnBurst` | boolean | Émettre tout d'un coup vs sur la durée |
|
|
|
|
**Exemple de config d'émission :**
|
|
```java
|
|
// Explosion burst - tout d'un coup
|
|
spawner.setSpawnBurst(true);
|
|
spawner.setTotalParticles(new Range(50, 100));
|
|
|
|
// Flux continu
|
|
spawner.setSpawnBurst(false);
|
|
spawner.setSpawnRate(new Rangef(10, 20)); // 10-20 par seconde
|
|
spawner.setLifeSpan(5.0f); // Émettre pendant 5 secondes
|
|
```
|
|
|
|
{{< /tab >}}
|
|
{{< tab >}}
|
|
|
|
**Propriétés de Mouvement :**
|
|
|
|
| Propriété | Type | Description |
|
|
|-----------|------|-------------|
|
|
| `initialVelocity` | InitialVelocity | Configuration de vélocité initiale |
|
|
| `attractors` | ParticleAttractor[] | Forces appliquées aux particules |
|
|
|
|
**Vélocité Initiale :**
|
|
```java
|
|
public class InitialVelocity {
|
|
protected float speed; // Vitesse de base
|
|
protected float speedVariance; // Variance aléatoire
|
|
protected Vector3f direction; // Direction de base
|
|
protected float coneAngle; // Angle de dispersion (degrés)
|
|
}
|
|
```
|
|
|
|
{{< /tab >}}
|
|
{{< tab >}}
|
|
|
|
**Propriétés de Rendu :**
|
|
|
|
| Propriété | Type | Description |
|
|
|-----------|------|-------------|
|
|
| `renderMode` | FXRenderMode | Comment les particules sont blendées |
|
|
| `lightInfluence` | float | Influence de l'éclairage sur les particules |
|
|
| `particle` | Particle | Config texture et animation |
|
|
|
|
{{< /tab >}}
|
|
{{< /tabs >}}
|
|
|
|
---
|
|
|
|
## Formes d'Émission
|
|
|
|
Contrôle le volume depuis lequel les particules apparaissent :
|
|
|
|
```java
|
|
public enum EmitShape {
|
|
Sphere, // Émettre depuis un volume sphérique
|
|
Cube // Émettre depuis un volume cubique
|
|
}
|
|
```
|
|
|
|
{{< tabs items="Sphere,Cube" >}}
|
|
{{< tab >}}
|
|
|
|
**Émission Sphérique :**
|
|
|
|
Les particules apparaissent dans un volume sphérique, avec la direction pointant vers l'extérieur du centre :
|
|
|
|
```java
|
|
// Configurer l'émission sphérique
|
|
spawner.setShape(EmitShape.Sphere);
|
|
spawner.setEmitOffset(new RangeVector3f(
|
|
new Rangef(-1, 1), // Plage X (rayon)
|
|
new Rangef(-1, 1), // Plage Y (rayon)
|
|
new Rangef(-1, 1) // Plage Z (rayon)
|
|
));
|
|
|
|
// Utiliser la direction d'émission pour la vélocité vers l'extérieur
|
|
spawner.setUseEmitDirection(true);
|
|
```
|
|
|
|
Idéal pour : Explosions, bursts, effets radiaux
|
|
|
|
{{< /tab >}}
|
|
{{< tab >}}
|
|
|
|
**Émission Cubique :**
|
|
|
|
Les particules apparaissent dans un volume de boîte aligné sur les axes :
|
|
|
|
```java
|
|
// Configurer l'émission cubique
|
|
spawner.setShape(EmitShape.Cube);
|
|
spawner.setEmitOffset(new RangeVector3f(
|
|
new Rangef(-2, 2), // Plage X
|
|
new Rangef(0, 3), // Plage Y (au-dessus du sol)
|
|
new Rangef(-2, 2) // Plage Z
|
|
));
|
|
```
|
|
|
|
Idéal pour : Effets de zone, pluie, effets au sol
|
|
|
|
{{< /tab >}}
|
|
{{< /tabs >}}
|
|
|
|
---
|
|
|
|
## Modes de Rendu
|
|
|
|
Détermine comment les particules se mélangent avec la scène :
|
|
|
|
```java
|
|
public enum FXRenderMode {
|
|
BlendLinear, // Blending de transparence standard
|
|
BlendAdd, // Blending additif (brillant/lumineux)
|
|
Erosion, // Effet d'érosion/dissolution
|
|
Distortion // Effet de distorsion/réfraction
|
|
}
|
|
```
|
|
|
|
{{< tabs items="BlendLinear,BlendAdd,Erosion,Distortion" >}}
|
|
{{< tab >}}
|
|
|
|
### BlendLinear
|
|
|
|
Blending alpha standard. Idéal pour :
|
|
- Fumée
|
|
- Poussière
|
|
- Nuages
|
|
- Particules d'apparence solide
|
|
|
|
```java
|
|
spawner.setRenderMode(FXRenderMode.BlendLinear);
|
|
```
|
|
|
|
{{< /tab >}}
|
|
{{< tab >}}
|
|
|
|
### BlendAdd
|
|
|
|
Blending additif - les particules ajoutent de la lumière à la scène. Idéal pour :
|
|
- Feu
|
|
- Étincelles
|
|
- Effets magiques
|
|
- Particules lumineuses
|
|
- Rayons de lumière
|
|
|
|
```java
|
|
spawner.setRenderMode(FXRenderMode.BlendAdd);
|
|
```
|
|
|
|
{{< callout type="info" >}}
|
|
Utilisez `BlendAdd` pour tout effet lumineux ou brillant. Plusieurs particules superposées créeront des zones plus lumineuses.
|
|
{{< /callout >}}
|
|
|
|
{{< /tab >}}
|
|
{{< tab >}}
|
|
|
|
### Erosion
|
|
|
|
Crée un effet visuel de dissolution/érosion. Idéal pour :
|
|
- Désintégration
|
|
- Transitions de dissolution
|
|
- Dissipation d'énergie
|
|
|
|
```java
|
|
spawner.setRenderMode(FXRenderMode.Erosion);
|
|
```
|
|
|
|
{{< /tab >}}
|
|
{{< tab >}}
|
|
|
|
### Distortion
|
|
|
|
Réfracte l'arrière-plan, créant des effets de miroitement de chaleur. Idéal pour :
|
|
- Vagues de chaleur
|
|
- Portails
|
|
- Champs d'énergie
|
|
- Effets sous-marins
|
|
|
|
```java
|
|
spawner.setRenderMode(FXRenderMode.Distortion);
|
|
```
|
|
|
|
{{< callout type="warning" >}}
|
|
Les effets de distorsion sont plus intensifs en GPU. Utilisez avec parcimonie.
|
|
{{< /callout >}}
|
|
|
|
{{< /tab >}}
|
|
{{< /tabs >}}
|
|
|
|
---
|
|
|
|
## Attracteurs de Particules
|
|
|
|
Applique des forces aux particules pour un mouvement dynamique :
|
|
|
|
```java
|
|
public class ParticleAttractor {
|
|
protected Vector3f position; // Position locale de l'attracteur
|
|
protected Vector3f radialAxis; // Direction de la force radiale
|
|
protected float radius; // Rayon d'influence
|
|
|
|
// Accélérations (forces continues)
|
|
protected float radialAcceleration; // Accélération vers l'extérieur/intérieur
|
|
protected float radialTangentAcceleration; // Accélération tangentielle (orbite)
|
|
protected Vector3f linearAcceleration; // Accélération linéaire directe
|
|
|
|
// Impulsions (forces ponctuelles)
|
|
protected float radialImpulse; // Impulsion vers l'extérieur/intérieur
|
|
protected float radialTangentImpulse; // Impulsion tangentielle
|
|
protected Vector3f linearImpulse; // Impulsion linéaire directe
|
|
|
|
// Amortissement
|
|
protected Vector3f dampingMultiplier; // Réduction de vélocité par frame
|
|
}
|
|
```
|
|
|
|
### Types de Forces
|
|
|
|
{{< tabs items="Radiale,Tangentielle,Linéaire,Amortissement" >}}
|
|
{{< tab >}}
|
|
|
|
**Forces Radiales :**
|
|
|
|
Pousse les particules vers ou loin de la position de l'attracteur :
|
|
|
|
```java
|
|
ParticleAttractor attractor = new ParticleAttractor();
|
|
attractor.setPosition(new Vector3f(0, 0, 0)); // Centre du système
|
|
|
|
// Explosion vers l'extérieur
|
|
attractor.setRadialAcceleration(10.0f); // Positif = vers l'extérieur
|
|
|
|
// Attraction vers l'intérieur (effet trou noir)
|
|
attractor.setRadialAcceleration(-5.0f); // Négatif = vers l'intérieur
|
|
|
|
// Burst instantané vers l'extérieur
|
|
attractor.setRadialImpulse(20.0f);
|
|
```
|
|
|
|
{{< /tab >}}
|
|
{{< tab >}}
|
|
|
|
**Forces Tangentielles :**
|
|
|
|
Crée un mouvement tourbillonnant/orbital autour de l'attracteur :
|
|
|
|
```java
|
|
ParticleAttractor attractor = new ParticleAttractor();
|
|
attractor.setPosition(new Vector3f(0, 0, 0));
|
|
attractor.setRadialAxis(new Vector3f(0, 1, 0)); // Orbite autour de l'axe Y
|
|
|
|
// Tourbillon horaire
|
|
attractor.setRadialTangentAcceleration(5.0f);
|
|
|
|
// Anti-horaire
|
|
attractor.setRadialTangentAcceleration(-5.0f);
|
|
```
|
|
|
|
{{< /tab >}}
|
|
{{< tab >}}
|
|
|
|
**Forces Linéaires :**
|
|
|
|
Applique une force directionnelle constante (comme la gravité ou le vent) :
|
|
|
|
```java
|
|
ParticleAttractor attractor = new ParticleAttractor();
|
|
|
|
// Gravité (vers le bas)
|
|
attractor.setLinearAcceleration(new Vector3f(0, -9.8f, 0));
|
|
|
|
// Vent (horizontal)
|
|
attractor.setLinearAcceleration(new Vector3f(2.0f, 0, 0));
|
|
|
|
// Flottabilité vers le haut
|
|
attractor.setLinearAcceleration(new Vector3f(0, 3.0f, 0));
|
|
```
|
|
|
|
{{< /tab >}}
|
|
{{< tab >}}
|
|
|
|
**Amortissement :**
|
|
|
|
Ralentit les particules au fil du temps :
|
|
|
|
```java
|
|
ParticleAttractor attractor = new ParticleAttractor();
|
|
|
|
// Amortissement uniforme (résistance de l'air)
|
|
attractor.setDampingMultiplier(new Vector3f(0.98f, 0.98f, 0.98f));
|
|
|
|
// Fort amortissement horizontal, faible vertical
|
|
attractor.setDampingMultiplier(new Vector3f(0.9f, 0.99f, 0.9f));
|
|
|
|
// Pas d'amortissement (particules maintiennent leur vélocité)
|
|
attractor.setDampingMultiplier(new Vector3f(1.0f, 1.0f, 1.0f));
|
|
```
|
|
|
|
{{< callout type="info" >}}
|
|
Les valeurs d'amortissement < 1.0 ralentissent les particules. Des valeurs de 0.98-0.99 donnent une résistance de l'air réaliste.
|
|
{{< /callout >}}
|
|
|
|
{{< /tab >}}
|
|
{{< /tabs >}}
|
|
|
|
---
|
|
|
|
## Configuration Visuelle des Particules
|
|
|
|
Configure l'apparence et l'animation des particules :
|
|
|
|
```java
|
|
public class Particle {
|
|
protected String texture; // Chemin de l'atlas de texture
|
|
protected Size frameSize; // Dimensions du frame
|
|
|
|
protected ParticleUVOption uvOption; // None, Animated, Random
|
|
protected SoftParticle softParticle; // Blending soft particle
|
|
protected float softParticlesFadeFactor; // 0.1 à 2.0
|
|
|
|
// Animation
|
|
protected ParticleAnimationFrame initialAnimationFrame;
|
|
protected Map<Integer, ParticleAnimationFrame> animation;
|
|
}
|
|
```
|
|
|
|
### Options d'Animation
|
|
|
|
```java
|
|
public enum ParticleUVOption {
|
|
None, // Frame unique statique
|
|
Animated, // Jouer les frames en séquence
|
|
Random // Frame aléatoire par particule
|
|
}
|
|
```
|
|
|
|
### Frames d'Animation
|
|
|
|
```java
|
|
public class ParticleAnimationFrame {
|
|
protected int frame; // Numéro de frame dans l'atlas
|
|
protected Rangef scale; // Plage de taille
|
|
protected Rangef alpha; // Plage de transparence (0-1)
|
|
protected Color color; // Teinte de couleur
|
|
protected Rangef rotation; // Plage de rotation (degrés)
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Accéder aux Assets de Particules
|
|
|
|
```java
|
|
// Obtenir un système de particules par ID
|
|
ParticleSystem system = ParticleSystem.getAssetMap().getAsset("explosion_large");
|
|
|
|
// Obtenir la configuration d'un spawner
|
|
ParticleSpawner spawner = ParticleSpawner.getAssetMap().getAsset("fire_spawner");
|
|
|
|
// Utiliser dans les arguments de commande
|
|
// ArgTypes.PARTICLE_SYSTEM pour les paramètres de commande
|
|
```
|
|
|
|
---
|
|
|
|
## Patterns Courants
|
|
|
|
### Particules Basées sur les Événements
|
|
|
|
{{< callout type="warning" >}}
|
|
**Note :** Les exemples ci-dessous sont simplifiés. Entity n'a pas de méthode `getPosition()` directe. Dans le code réel, obtenez la position via `TransformComponent` depuis le store de l'entité. Exemple :
|
|
```java
|
|
TransformComponent transform = store.getComponent(entityRef, TransformComponent.getComponentType());
|
|
Vector3d position = transform.getPosition();
|
|
```
|
|
{{< /callout >}}
|
|
|
|
{{< tabs items="Destruction Bloc,Combat,Mort" >}}
|
|
{{< tab >}}
|
|
|
|
```java
|
|
@Subscribe
|
|
public void onBlockBreak(BreakBlockEvent event) {
|
|
// Utiliser getTargetBlock() - pas getPosition()
|
|
Vector3i blockPos = event.getTargetBlock();
|
|
Vector3d pos = new Vector3d(
|
|
blockPos.x + 0.5,
|
|
blockPos.y + 0.5,
|
|
blockPos.z + 0.5
|
|
);
|
|
|
|
// Générer des particules de destruction au centre du bloc
|
|
ParticleUtil.spawnParticleEffect(
|
|
"block_break_particles",
|
|
pos,
|
|
componentAccessor
|
|
);
|
|
}
|
|
```
|
|
|
|
{{< /tab >}}
|
|
{{< tab >}}
|
|
|
|
```java
|
|
@Subscribe
|
|
public void onEntityDamage(EntityDamageEvent event) {
|
|
Entity target = event.getTarget();
|
|
Vector3d hitPos = target.getPosition().add(0, 1, 0);
|
|
|
|
// Effet de sang/dégâts
|
|
ParticleUtil.spawnParticleEffect(
|
|
"damage_hit",
|
|
hitPos,
|
|
componentAccessor
|
|
);
|
|
|
|
// Effet spécial coup critique
|
|
if (event.isCritical()) {
|
|
ParticleUtil.spawnParticleEffect(
|
|
"critical_hit_sparks",
|
|
hitPos,
|
|
0, 0, 0, // rotation
|
|
1.5f, // échelle plus grande
|
|
new Color(255, 215, 0, 255), // couleur or
|
|
getNearbyPlayers(hitPos, 50),
|
|
componentAccessor
|
|
);
|
|
}
|
|
}
|
|
```
|
|
|
|
{{< /tab >}}
|
|
{{< tab >}}
|
|
|
|
```java
|
|
@Subscribe
|
|
public void onEntityDeath(EntityDeathEvent event) {
|
|
Entity entity = event.getEntity();
|
|
Vector3d deathPos = entity.getPosition();
|
|
|
|
// Particules de mort
|
|
ParticleUtil.spawnParticleEffect(
|
|
"entity_death_poof",
|
|
deathPos,
|
|
componentAccessor
|
|
);
|
|
|
|
// Effet d'âme qui monte pour les joueurs
|
|
if (entity instanceof Player) {
|
|
ParticleUtil.spawnParticleEffect(
|
|
"soul_ascend",
|
|
deathPos.add(0, 0.5, 0),
|
|
componentAccessor
|
|
);
|
|
}
|
|
}
|
|
```
|
|
|
|
{{< /tab >}}
|
|
{{< /tabs >}}
|
|
|
|
### Effets Continus
|
|
|
|
{{< tabs items="Traînée Joueur,Aura,Effet de Zone" >}}
|
|
{{< tab >}}
|
|
|
|
```java
|
|
// Générer une traînée de particules à la position du joueur
|
|
public void spawnTrailEffect(Player player, Store<EntityStore> store,
|
|
ComponentAccessor<EntityStore> componentAccessor) {
|
|
if (hasTrailEffect(player)) {
|
|
// Obtenir la position via TransformComponent
|
|
Ref<EntityStore> entityRef = player.getReference();
|
|
TransformComponent transform = store.getComponent(entityRef, TransformComponent.getComponentType());
|
|
if (transform != null) {
|
|
Vector3d position = transform.getPosition();
|
|
ParticleUtil.spawnParticleEffect(
|
|
"magic_trail",
|
|
position,
|
|
componentAccessor
|
|
);
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
{{< callout type="warning" >}}
|
|
**Note :** Player n'a pas de méthode `getPosition()`. Obtenez la position via `TransformComponent` depuis le store d'entités.
|
|
{{< /callout >}}
|
|
|
|
{{< /tab >}}
|
|
{{< tab >}}
|
|
|
|
```java
|
|
// Aura persistante autour du joueur
|
|
public class AuraManager {
|
|
private final Map<UUID, Boolean> activeAuras = new HashMap<>();
|
|
private Store<EntityStore> store;
|
|
private ComponentAccessor<EntityStore> componentAccessor;
|
|
|
|
public void enableAura(Player player) {
|
|
// Utiliser player.getPlayerRef().getUuid() - pas player.getUuid()
|
|
activeAuras.put(player.getPlayerRef().getUuid(), true);
|
|
}
|
|
|
|
@Subscribe
|
|
public void onTick(ServerTickEvent event) {
|
|
for (Map.Entry<UUID, Boolean> entry : activeAuras.entrySet()) {
|
|
if (entry.getValue()) {
|
|
Player player = getPlayer(entry.getKey());
|
|
if (player != null) {
|
|
// Obtenir la position via TransformComponent
|
|
Ref<EntityStore> entityRef = player.getReference();
|
|
TransformComponent transform = store.getComponent(
|
|
entityRef, TransformComponent.getComponentType());
|
|
if (transform != null) {
|
|
Vector3d pos = transform.getPosition();
|
|
ParticleUtil.spawnParticleEffect(
|
|
"magic_aura",
|
|
new Vector3d(pos.getX(), pos.getY() + 1, pos.getZ()),
|
|
componentAccessor
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
{{< /tab >}}
|
|
{{< tab >}}
|
|
|
|
```java
|
|
// Effet de zone de soin
|
|
public void createHealingZone(Vector3d center, double radius, int durationTicks) {
|
|
// Générer des particules en anneau
|
|
for (int i = 0; i < 16; i++) {
|
|
double angle = (2 * Math.PI * i) / 16;
|
|
Vector3d pos = center.add(
|
|
Math.cos(angle) * radius,
|
|
0.1,
|
|
Math.sin(angle) * radius
|
|
);
|
|
|
|
ParticleUtil.spawnParticleEffect(
|
|
"healing_sparkle",
|
|
pos,
|
|
componentAccessor
|
|
);
|
|
}
|
|
|
|
// Effet pilier central
|
|
ParticleUtil.spawnParticleEffect(
|
|
"healing_pillar",
|
|
center,
|
|
componentAccessor
|
|
);
|
|
}
|
|
```
|
|
|
|
{{< /tab >}}
|
|
{{< /tabs >}}
|
|
|
|
---
|
|
|
|
## Directives de Performance
|
|
|
|
{{< callout type="warning" >}}
|
|
**Notes de Performance :**
|
|
- Distance de diffusion par défaut : **75 blocs** (`DEFAULT_PARTICLE_DISTANCE`)
|
|
- Les particules utilisent le paquet `SpawnParticleSystem` (ID : 152)
|
|
- Définissez `isImportant = true` pour les feedbacks visuels critiques
|
|
- Limitez le nombre de particules pour les performances client
|
|
- Utilisez `maxConcurrentParticles` pour limiter les particules actives
|
|
{{< /callout >}}
|
|
|
|
### Conseils d'Optimisation
|
|
|
|
| Conseil | Description |
|
|
|---------|-------------|
|
|
| Limiter le total de particules | Gardez sous 100-200 pour les effets burst |
|
|
| Utiliser une `cullDistance` appropriée | Ne pas rendre les particules trop éloignées |
|
|
| Grouper les spawns | Générer plusieurs particules dans le même tick |
|
|
| Utiliser `spawnBurst` judicieusement | Les bursts sont moins coûteux que le continu |
|
|
| Considérer le nombre de joueurs | Plus de joueurs = plus de trafic réseau |
|
|
|
|
```java
|
|
// Bon : Génération de particules efficace
|
|
public void spawnEfficiently(Vector3d position) {
|
|
// Générer seulement pour les joueurs proches
|
|
List<PlayerRef> nearbyPlayers = getNearbyPlayers(position, 50);
|
|
|
|
if (!nearbyPlayers.isEmpty()) {
|
|
ParticleUtil.spawnParticleEffect(
|
|
"my_effect",
|
|
position,
|
|
nearbyPlayers, // Audience limitée
|
|
componentAccessor
|
|
);
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Sujets Connexes
|
|
|
|
- [Effets d'Entité]({{< relref "entity-effects" >}}) - Effets de statut avec composants visuels
|
|
- [Réseau]({{< relref "/advanced/networking" >}}) - Comment les particules sont diffusées
|
|
- [Événements]({{< relref "/core-concepts/events" >}}) - Déclencher des particules depuis les événements
|