Qt Quick Particles Ejemplos - Afectores
Esta es una colección de ejemplos usando Afectores en el sistema de partículas QML.

Esta es una colección de pequeños ejemplos QML relacionados con el uso de Afectores en el sistema de partículas. Cada ejemplo es un pequeño archivo QML que enfatiza un tipo o característica particular.
Edad demuestra el uso de un afector Edad para terminar prematuramente la vida de las partículas.
Age { anchors.fill: parent system: particles once: true lifeLeft: 1200 advancePosition: false }
A medida que mueves el afector por la pantalla, las partículas dentro de él (que aún no han sido afectadas) saltan a un periodo cercano al final de su vida. Esto les da un corto periodo para terminar de desvanecerse, pero cambiando lifeLeft a 0 (por defecto), causaría que alcanzaran el final de su vida instantáneamente.
Attractor demuestra el uso de un afector Attractor para simular un agujero negro
Attractor { id: gs; pointX: root.width/2; pointY: root.height/2; strength: 4000000; affectedParameter: Attractor.Acceleration proportionalToDistance: Attractor.InverseQuadratic }
Todas las partículas de la escena, incluyendo el escape del cohete y las bolitas, son atraídas hacia el agujero negro. Este efecto es más fuerte cerca del agujero negro, por lo que los asteroides situados cerca de la parte superior de la pantalla apenas se ven afectados, mientras que los situados hacia el centro a veces se curvan drásticamente. Para completar el efecto, un afector de Edad cubre el agujero negro para destruir las partículas que entran en contacto con él.
El Afector Personalizado manipula las propiedades de las partículas directamente en javascript. Un afector se utiliza para hacer que las hojas se balanceen hacia adelante y hacia atrás mientras caen, pareciendo más hojas que simplemente girando en círculos:
Affector { width: parent.width height: parent.height - 100 onAffectParticles: (particles, dt) => { //Wobbly movement for (var i=0; i<particles.length; i++) { var particle = particles[i]; particle.rotation += particle.vx * 0.15 * dt; particle.update = true; } } }
Otro se utiliza para proporcionar una fricción ligeramente variable a las hojas cuando "aterrizan", para que parezcan más naturales:
Affector {//Custom Friction, adds some 'randomness' x: -60 width: parent.width + 120 height: 100 anchors.bottom: parent.bottom onAffectParticles: (particles, dt) => { for (var i=0; i<particles.length; i++) { var particle = particles[i]; var pseudoRand = (Math.floor(particle.t*1327) % 10) + 1; var yslow = dt * pseudoRand * 0.5 + 1; var xslow = dt * pseudoRand * 0.05 + 1; if (particle.vy < 1) particle.vy = 0; else particle.vy = (particle.vy / yslow); if (particle.vx < 1) particle.vx = 0; else particle.vx = (particle.vx / xslow); particle.update = true; } } }
La fricción es similar a la caída de las hojas en el afector personalizado, excepto que utiliza una fricción plana en todo el camino hacia abajo en lugar de afectores personalizados.
Friction { anchors.fill: parent anchors.margins: -40 factor: 0.4 }
Gravedad es un afector de conveniencia para aplicar una aceleración constante a las partículas en su interior
Gravity { system: sys magnitude: 32 angle: ground.rotation + 90 }
GroupGoal Establece dos grupos de partículas para bolas llameantes y no llameantes, y te da varias formas de transición entre ellas.
ParticleGroup { name: "unlit" duration: 1000 to: {"lighting":1, "unlit":99} ImageParticle { source: "images/particleA.png" colorVariation: 0.1 color: "#2060160f" } GroupGoal { whenCollidingWith: ["lit"] goalState: "lighting" jump: true } }
Las bolas no flameantes tienen una probabilidad entre cien de encenderse por sí solas cada segundo, pero también tienen un GroupGoal establecido en todo el grupo. Este afector afecta a todas las partículas del grupo no iluminado, cuando colisionan con partículas del grupo iluminado, y hace que se muevan al grupo de iluminación.
ParticleGroup { name: "lighting" duration: 100 to: {"lit":1} }
La iluminación es un grupo intermedio para que el brillo se acumule y la transición sea menos brusca. Así que se mueve automáticamente en el grupo iluminado después de 100ms.
ParticleGroup { name: "lit" duration: 10000 onEntered: root.score++ TrailEmitter { id: fireballFlame group: "flame" emitRatePerParticle: 48 lifeSpan: 200 emitWidth: 8 emitHeight: 8 size: 24 sizeVariation: 8 endSize: 4 } TrailEmitter { id: fireballSmoke group: "smoke"
El grupo iluminado también tiene TrailEmitters en él para el fuego y el humo adicional, pero no la transición en cualquier lugar. Hay dos objetos más en GroupGoal que permiten que las partículas del grupo no iluminado pasen al grupo iluminado (y luego al grupo iluminado).
GroupGoal { groups: ["unlit"] goalState: "lit" jump: true system: particles x: -15 y: -55 height: 75 width: 30 shape: MaskShape {source: "images/matchmask.png"} }
El primero es sólo un área ligada a la ubicación de una imagen de una llama piloto. Cuando las bolas no iluminadas atraviesan la llama, pasan directamente al grupo iluminado porque la llama piloto está muy caliente.
//Click to enflame GroupGoal { groups: ["unlit"] goalState: "lighting" jump: true enabled: ma.pressed width: 18 height: 18 x: ma.mouseX - width/2 y: ma.mouseY - height/2 }
La segunda está ligada a la ubicación de la última interacción con el puntero, de modo que tocar o hacer clic en las bolas no encendidas (lo que es difícil debido a su constante movimiento) hace que se muevan al grupo de iluminación.
Mover muestra algunos efectos simples que puedes conseguir alterando la trayectoria a mitad de camino. Las partículas rojas tienen un afector que afecta a su posición, haciéndolas saltar 120px hacia delante.
Affector { groups: ["A"] x: 120 width: 80 height: 80 once: true position: PointDirection { x: 120; } }
Las partículas verdes tienen un afector que afecta a su velocidad, pero con alguna variación de ángulo. Añadiendo un poco de velocidad de dirección aleatoria a su velocidad existente hacia delante, empiezan a salir pulverizadas en forma de cono.
Affector { groups: ["B"] x: 120 y: 240 width: 80 height: 80 once: true velocity: AngleDirection { angleVariation:360; magnitude: 72 } }
Las partículas azules tienen un afector que afecta a su aceleración, y debido a que se establece en relación con falso esto restablece la aceleración en lugar de añadir a ella. Una vez que las partículas azules alcanzan el afector, su velocidad horizontal deja de aumentar a medida que disminuye su velocidad vertical.
Affector { groups: ["C"] x: 120 y: 400 width: 80 height: 120 once: true relative: false acceleration: PointDirection { y: -80; } }
SpriteGoal tiene un afector que interactúa con el motor de sprites de las partículas, si están siendo dibujadas como sprites por ImageParticle.
SpriteGoal { groups: ["meteor"] system: sys goalState: "explode" jump: true anchors.fill: rocketShip width: 60 height: 60 }
El SpriteGoal sigue la imagen del cohete en pantalla, y cuando interactúa con las partículas dibujadas por ImageParticle como sprites, les ordena moverse inmediatamente al estado "explotar", que en este caso es la animación del asteroide rompiéndose en muchos pedazos.
Turbulencia tiene una llama con humo, y ambos conjuntos de partículas siendo afectadas por un afector de Turbulencia. Esto da un efecto de viento débil.
Turbulence { id: turb enabled: true height: (parent.height / 2) - 4 width: parent.width x: parent. width / 4 anchors.fill: parent NumberAnimation on strength{from: 16; to: 64; easing.type: Easing.InOutBounce; duration: 1800; loops: -1} }
Para hacer que el viento cambie de dirección, sustituye una imagen de ruido en blanco y negro en el parámetro noiseSource (actualmente utiliza una fuente de ruido por defecto).
Wander utiliza un afector Wander para añadir un poco de deriva horizontal a los copos de nieve a medida que caen.
Wander { id: wanderer system: particles anchors.fill: parent xVariance: 360/(wanderer.affectedParameter+1); pace: 100*(wanderer.affectedParameter+1); }
Hay diferentes movimientos dados por la aplicación del Wander a diferentes atributos de la trayectoria, por lo que el ejemplo hace que sea fácil jugar y ver la diferencia.
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.