Qt Quick Particles 예제 - 어펙터
QML 파티클 시스템에서 어펙터를 사용한 예제 모음입니다.
파티클 시스템에서 어펙터를 사용하는 것과 관련된 작은 QML 예제 모음입니다. 각 예제는 특정 유형이나 기능을 강조하는 작은 QML 파일입니다.
Age는 Age 어펙터를 사용하여 파티클의 수명을 조기에 종료하는 방법을 보여줍니다.
Age { anchors.fill: parent system: particles once: true lifeLeft: 1200 advancePosition: false }
화면에서 이 어펙터를 움직이면 아직 영향을 받지 않은 파티클 내부의 파티클이 수명이 거의 끝나는 시점으로 이동합니다. 이렇게 하면 페이드아웃이 완료될 때까지 짧은 기간이 주어지지만, lifeLeft를 0(기본값)으로 변경하면 즉시 수명이 끝나게 됩니다.
Attractor 어펙터를 사용하여 블랙홀을 시뮬레이션하는 데모를 보여줍니다.
Attractor { id: gs; pointX: root.width/2; pointY: root.height/2; strength: 4000000; affectedParameter: Attractor.Acceleration proportionalToDistance: Attractor.InverseQuadratic }
로켓선의 배기 가스 및 펠릿을 포함한 씬의 모든 파티클이 블랙홀 쪽으로 당겨집니다. 이 효과는 블랙홀에 가까울수록 강해지므로 화면 위쪽의 소행성은 거의 영향을 받지 않지만 가운데에 있는 소행성은 때때로 급격하게 구부러집니다. 이 효과를 완성하기 위해 나이 어펙터가 블랙홀을 덮어 블랙홀과 접촉하는 파티클을 파괴합니다.
커스텀 어펙터는 자바스크립트에서 직접 파티클의 프로퍼티를 조작합니다. 하나의 어펙터는 나뭇잎이 떨어질 때 앞뒤로 흔들리도록 하여 단순히 원을 그리며 회전하는 것보다 더 나뭇잎처럼 보이도록 하는 데 사용됩니다:
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; } } }
다른 하나는 나뭇잎이 '착지'할 때 나뭇잎에 약간의 마찰을 주어 보다 자연스럽게 보이도록 하는 데 사용됩니다:
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; } } }
마찰은 커스텀 어펙터의 낙엽과 비슷하지만 커스텀 어펙터 대신 전체적으로 평평한 마찰을 사용한다는 점을 제외하면 비슷합니다.
Friction { anchors.fill: parent anchors.margins: -40 factor: 0.4 }
중력은 내부 파티클에 일정한 가속도를 적용하기 위한 편리한 이펙터입니다.
Gravity { system: sys magnitude: 32 angle: ground.rotation + 90 }
GroupGoal 는 타오르는 공과 타지 않는 공에 대한 두 개의 파티클 그룹을 설정하고 다양한 방식으로 전환할 수 있습니다.
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 } }
타오르지 않는 공은 매초 100분의 1의 확률로 자체적으로 불이 붙지만, 전체 그룹에 GroupGoal 설정도 있습니다. 이 어펙터는 조명 그룹의 파티클과 충돌할 때 조명되지 않은 그룹의 모든 파티클에 영향을 주어 조명 그룹으로 이동하게 합니다.
ParticleGroup { name: "lighting" duration: 100 to: {"lit":1} }
조명은 중간 그룹이므로 빛이 쌓이고 전환이 덜 어색합니다. 따라서 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"
조명 그룹에는 추가 불빛과 연기를 위한 트레일 이미터도 있지만 아무데도 전환되지 않습니다. 비조명 그룹의 파티클이 조명 그룹으로(그리고 조명 그룹으로) 전환할 수 있는 GroupGoal 오브젝트가 두 개 더 있습니다.
GroupGoal { groups: ["unlit"] goalState: "lit" jump: true system: particles x: -15 y: -55 height: 75 width: 30 shape: MaskShape {source: "images/matchmask.png"} }
첫 번째는 파일럿 불꽃 이미지의 위치에 바인딩된 영역입니다. 조명이 없는 공이 불꽃을 통과하면 파일럿 불꽃이 너무 뜨겁기 때문에 곧바로 조명이 켜진 그룹으로 이동합니다.
//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 }
두 번째는 마지막 포인터 상호 작용의 위치에 바인딩되어 조명이 없는 공을 터치하거나 클릭하면(계속 움직이기 때문에 어렵습니다) 조명 그룹으로 이동합니다.
이동은 중간에 궤적을 변경하여 얻을 수 있는 몇 가지 간단한 효과를 보여줍니다. 빨간색 입자에는 위치에 영향을 주는 이펙터가 있어 120px 앞으로 이동합니다.
Affector { groups: ["A"] x: 120 width: 80 height: 80 once: true position: PointDirection { x: 120; } }
녹색 파티클에는 속도에 영향을 주는 어펙터가 있지만 각도에 약간의 변화가 있습니다. 기존 전진 속도에 임의의 방향 속도를 더하면 원뿔 모양으로 분사되기 시작합니다.
Affector { groups: ["B"] x: 120 y: 240 width: 80 height: 80 once: true velocity: AngleDirection { angleVariation:360; magnitude: 72 } }
파란색 입자에는 가속도에 영향을 미치는 어펙터가 있으며, 이 어펙터는 거짓을 기준으로 설정되므로 가속도에 더하는 대신 가속도를 초기화합니다. 파란색 입자가 어펙터에 도달하면 수직 속도가 감소하면서 수평 속도의 증가가 멈춥니다.
Affector { groups: ["C"] x: 120 y: 400 width: 80 height: 120 once: true relative: false acceleration: PointDirection { y: -80; } }
SpriteGoal 에 의해 스프라이트로 그려지는 경우 파티클의 스프라이트 엔진과 상호 작용하는 어펙터가 있습니다( ImageParticle).
SpriteGoal { groups: ["meteor"] system: sys goalState: "explode" jump: true anchors.fill: rocketShip width: 60 height: 60 }
SpriteGoal 은 화면의 로켓 우주선 이미지를 따르고 ImageParticle 에서 스프라이트로 그린 파티클과 상호작용하면 즉시 '폭발' 상태로 이동하도록 지시하며, 이 경우 소행성이 여러 조각으로 부서지는 애니메이션이 됩니다.
난기류에는 연기와 함께 불꽃이 있으며, 두 파티클 세트 모두 난기류 효과의 영향을 받습니다. 이는 희미한 바람 효과를 줍니다.
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} }
바람의 방향을 바꾸려면 noiseSource 파라미터에 흑백 노이즈 이미지를 대체합니다(현재 기본 노이즈 소스 사용).
Wander는 Wander 어펙터를 사용하여 눈송이가 떨어질 때 수평 드리프트를 추가합니다.
Wander { id: wanderer system: particles anchors.fill: parent xVariance: 360/(wanderer.affectedParameter+1); pace: 100*(wanderer.affectedParameter+1); }
궤적의 다양한 속성에 Wander를 적용하면 다양한 움직임이 주어지므로 이 예제를 통해 쉽게 놀면서 차이를 확인할 수 있습니다.
© 2025 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.