A burst that lights the room: the source
Open the live demo · Read the guide · View on GitHub
Regions the guide quotes: source (line 40), follow (line 62), check (line 79).
1/// A single burst that lights the room it goes off in, the way a muzzle
2/// flash or an explosion should but a burst with nobody keyed to it cannot.
3///
4/// Quoted by `burst_light.md` and shown whole in the Source tab.
5library;
7import 'package:flutter3d/flutter3d.dart';
8import 'package:flutter3d_particles/flutter3d_particles.dart';
9import 'package:flutter3d_showcase/src/demo/demo.dart';
10import 'package:vector_math/vector_math.dart';
12final class _Flash with LightEmitter {}
14final class BurstLightDemo extends ShowcaseDemo {
15 late final ParticleSystem _particles;
16 late final ParticleEffect _flashEffect;
17 late final LightNode _glow;
19 final _Flash _flash = _Flash();
21 // A muzzle flash that fired once and went dark would be a demo you had to
22 // catch. A second's pause between bursts reads as a repeating flash rather
23 // than a machine gun, and only starts once the particles from the last one
24 // are gone, so it never overlaps a burst still lighting the room.
25 static const double _pause = 1.0;
26 double _cooldown = 0.0;
29 void configureView(DemoContext context) {
30 context.orbit
31 ..distance = 4.0
32 ..pitch = 0.2
33 ..yaw = 0.4;
34 }
37 Scene build(DemoContext context) {
38 _particles = ParticleSystem(capacity: 128, seed: 512);
40 // Nothing above this differs from an ordinary burst. `source` is the
41 // whole of what makes it a light: a `LightEmitter` passed here has its
42 // glow fed by exactly these particles, for as long as they live.
43 _flashEffect = ParticleEffect(
44 count: 60,
45 emitter: const SphereEmitter(speed: Range(2.0, 5.0)),
46 lifetime: const Range(0.2, 0.4),
47 size: const Range(0.05, 0.09),
48 color: Vector4(1.0, 0.85, 0.5, 1.0),
49 );
50 _particles.burst(_flashEffect, Vector3.zero(), source: _flash);
52 context.renderer.addContributor(ParticleContributor(_particles));
54 _glow = LightNode(name: 'flash', type: LightType.point, intensity: 0.0);
55 return Scene()..add(_glow);
56 }
59 void update(DemoContext context, double dt) {
60 _particles.advance(dt);
62 final ParticleGlow glow = _flash.glow;
63 if (glow.located) {
64 _glow.setPositionFrom(glow.centre);
65 _glow.intensity = glow.power * 0.6;
66 }
68 if (_particles.aliveCount == 0) {
69 _cooldown -= dt;
70 if (_cooldown <= 0.0) {
71 _particles.burst(_flashEffect, Vector3.zero(), source: _flash);
72 _cooldown = _pause;
73 }
74 }
75 }
78 void verify(Scene scene, FrameResult frame) {
79 if (_flash.glow.count == 0 || _flash.glow.power <= 0.0) {
80 throw StateError('the burst should have lit its own flash');
81 }
82 if (frame.drawCalls < 1) {
83 throw StateError('the flash did not reach the frame');
84 }
85 }
86}