Init
This commit is contained in:
788
content/advanced/effects/particles.fr.md
Normal file
788
content/advanced/effects/particles.fr.md
Normal file
@@ -0,0 +1,788 @@
|
||||
---
|
||||
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
|
||||
Reference in New Issue
Block a user