Skip to content

Commit 0f02ebc

Browse files
committed
Fixed crash for particlefx example.
1 parent 90c71b0 commit 0f02ebc

File tree

3 files changed

+55
-46
lines changed

3 files changed

+55
-46
lines changed

particles/particlefx_set_get/example.md

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ This example focuses on this feature. It toggles a ParticleFX between two setups
3232
- `default_material`
3333
- `glow_material`
3434

35-
This makes it easy to switch the emitter `image` and `material` directly from code.
35+
The current script switches the emitter `image` directly from code and keeps `default_material` active for the shown setup.
3636

3737
4. The example uses 2 atlases with given animations:
3838

@@ -45,20 +45,22 @@ The atlases are set up to contain the animation ids used by the script, so the e
4545

4646
The script keeps two hardcoded setups and toggles between them whenever you click or tap:
4747

48-
1. `particles.atlas` + glow material
48+
1. `particles.atlas` + default particle material
4949
`emitter_top` uses `coin`
5050
`emitter_bottom` uses `smoke`
5151
2. `sprites.atlas` + default particle material
5252
`emitter_top` uses `ship_red`
5353
`emitter_bottom` uses `ship_dark`
5454

55-
When the setup changes, the script:
55+
On startup the script stores the current atlas name, reads back the authored emitter properties, writes them into the labels, and starts the ParticleFX. When the setup changes after that, the script:
5656

57-
1. stops the ParticleFX
58-
2. calls `set_emitter_properties()` for each emitter to set `image`, `animation`, and `material`
59-
3. calls `get_emitter_properties()` to read the current values back with `go.get()`
60-
4. writes the values into the two labels
61-
5. plays the ParticleFX again
57+
1. stops the ParticleFX with `{ clear = true }`
58+
2. flips `self.atlas_name` between `sprites_atlas` and `particles_atlas`
59+
3. looks up the atlas resource and the correct animation pair from the `ANIMATIONS` table
60+
4. calls `set_emitter_properties()` for each emitter to set `image`, `animation`, and `material`
61+
5. calls `get_and_print_emitter_properties()` to read the current values back with `go.get()`
62+
6. writes them into the two labels
63+
7. plays the ParticleFX again
6264

6365
The helper function `set_emitter_properties()` applies properties per emitter by passing the emitter id in `keys`:
6466

@@ -68,6 +70,6 @@ go.set("#particles", "animation", animation, { keys = { "emitter_top" } })
6870
go.set("#particles", "material", material, { keys = { "emitter_top" } })
6971
```
7072

71-
The helper function `get_emitter_properties()` uses the same `keys` pattern with `go.get()` and writes the result into the labels, so the example shows which values are currently active for each emitter.
73+
The helper function `get_and_print_emitter_properties()` uses the same `keys` pattern with `go.get()` and writes the result into the labels, so the example shows which values are currently active for each emitter.
7274

73-
One important limitation: **emitter property changes only affect the next play**. That is why the script stops and plays the ParticleFX around each property update.
75+
One important limitation: **emitter property changes only affect the next play**. The script therefore stops the ParticleFX, clears any already spawned particles, applies the new emitter overrides, and then plays it again.

particles/particlefx_set_get/example/particlefx.particlefx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
emitters {
22
id: "emitter_top"
33
mode: PLAY_MODE_LOOP
4-
duration: 0.18
4+
duration: 1.0
55
space: EMISSION_SPACE_WORLD
66
position {
77
y: 150.0
88
}
9-
tile_source: "/assets/particles.atlas"
10-
animation: "coin"
11-
material: "/example/particlefx_glow.material"
9+
tile_source: "/assets/sprites.atlas"
10+
animation: "ship_red"
11+
material: "/builtins/materials/particlefx.material"
1212
particle_orientation: PARTICLE_ORIENTATION_MOVEMENT_DIRECTION
1313
max_particle_count: 128
1414
type: EMITTER_TYPE_CIRCLE
@@ -162,14 +162,14 @@ emitters {
162162
emitters {
163163
id: "emitter_bottom"
164164
mode: PLAY_MODE_LOOP
165-
duration: 0.18
165+
duration: 1.0
166166
space: EMISSION_SPACE_WORLD
167167
position {
168168
y: -150.0
169169
}
170-
tile_source: "/assets/particles.atlas"
171-
animation: "coin"
172-
material: "/example/particlefx_glow.material"
170+
tile_source: "/assets/sprites.atlas"
171+
animation: "ship_dark"
172+
material: "/builtins/materials/particlefx.material"
173173
particle_orientation: PARTICLE_ORIENTATION_MOVEMENT_DIRECTION
174174
max_particle_count: 128
175175
type: EMITTER_TYPE_CIRCLE

particles/particlefx_set_get/example/particlefx_set_get.script

Lines changed: 35 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,20 @@ go.property("sprites_atlas", resource.atlas("/assets/sprites.atlas"))
66
go.property("default_material", resource.material("/builtins/materials/particlefx.material"))
77
go.property("glow_material", resource.material("/example/particlefx_glow.material"))
88

9-
-- Address of the particlefx component:
10-
local PARTICLEFX = "#particles"
11-
12-
-- The example only switches between two simple atlas setups,
13-
-- so each atlas gets one animation per emitter.
9+
-- Predefined table with animations for given atlases:
10+
-- (One can get the animations from resource.get_atlas() too)
1411
local ANIMATIONS = {
1512
["particles_atlas"] = { hash("coin"), hash("smoke") },
1613
["sprites_atlas"] = { hash("ship_red"), hash("ship_dark") }
1714
}
1815

16+
-- Relative address of the particlefx component:
17+
local PARTICLEFX = "#particles"
18+
1919
-- Read the current emitter properties back from the particlefx component
2020
-- and show them in the on-screen labels.
21-
local function get_emitter_properties(emitter, url)
21+
local function get_and_print_emitter_properties(emitter, url)
22+
-- Get the properties of the emitter:
2223
local image = go.get(PARTICLEFX, "image", { keys = { emitter } })
2324
local animation = go.get(PARTICLEFX, "animation", { keys = { emitter } })
2425
local material = go.get(PARTICLEFX, "material", { keys = { emitter } })
@@ -38,46 +39,52 @@ end
3839
-- Toggle between the two hardcoded setups:
3940
-- particles atlas + glow material, or sprites atlas + default material.
4041
local function change_particlefx_properties(self)
41-
particlefx.stop(PARTICLEFX)
42-
43-
local core_animation = ANIMATIONS["particles_atlas"][1]
44-
local spark_animation = ANIMATIONS["particles_atlas"][2]
42+
-- Stop the particlefx before swapping atlas/material overrides.
43+
particlefx.stop(PARTICLEFX, { clear = true })
4544

46-
if self.atlas == self.particles_atlas then
47-
self.atlas = self.sprites_atlas
48-
self.material = self.default_material
49-
core_animation = ANIMATIONS["sprites_atlas"][1]
50-
spark_animation = ANIMATIONS["sprites_atlas"][2]
51-
else
52-
self.atlas = self.particles_atlas
45+
-- Swap the atlas name and material:
46+
if self.atlas_name == "sprites_atlas" then
47+
self.atlas_name = "particles_atlas"
5348
self.material = self.glow_material
49+
else
50+
self.atlas_name = "sprites_atlas"
51+
self.material = self.default_material
5452
end
5553

56-
pprint(core_animation, spark_animation, self.atlas, self.material)
54+
-- Get current atlas resource and animations set for it:
55+
local atlas = self[self.atlas_name]
56+
local animations = ANIMATIONS[self.atlas_name]
5757

58-
-- Both emitters use the same atlas/material for a given setup,
59-
-- but each emitter gets its own animation.
60-
set_emitter_properties("emitter_top", self.atlas, core_animation, self.material)
61-
set_emitter_properties("emitter_bottom", self.atlas, spark_animation, self.material)
58+
-- Set the atlas, animation and material for each emitter:
59+
set_emitter_properties("emitter_top", atlas, animations[1], self.material)
60+
set_emitter_properties("emitter_bottom", atlas, animations[2], self.material)
6261

63-
get_emitter_properties("emitter_top", "#label_core")
64-
get_emitter_properties("emitter_bottom", "#label_spark")
62+
-- Get the current properties and print them in the label for each emitter:
63+
get_and_print_emitter_properties("emitter_top", "#label_core")
64+
get_and_print_emitter_properties("emitter_bottom", "#label_spark")
6565

66+
-- Play the particlefx again:
6667
particlefx.play(PARTICLEFX)
6768
end
6869

6970
function init(self)
71+
-- Acquire input focus to react to the mouse click/touch:
7072
msg.post(".", "acquire_input_focus")
7173

72-
-- Start with sprites/default so the first click flips to particles/glow.
73-
self.atlas = self.sprites_atlas
74+
-- Initialize the atlas name:
75+
self.atlas_name = "sprites_atlas"
7476
self.material = self.default_material
7577

76-
change_particlefx_properties(self)
78+
-- Get the current properties and print them in the label for each emitter:
79+
get_and_print_emitter_properties("emitter_top", "#label_core")
80+
get_and_print_emitter_properties("emitter_bottom", "#label_spark")
81+
82+
-- Start the ParticleFX:
83+
particlefx.play(PARTICLEFX)
7784
end
7885

7986
function on_input(self, action_id, action)
80-
-- Toggle the setup on touch release.
87+
-- Toggle the setup on touch release:
8188
if action_id == hash("touch") and action.released then
8289
change_particlefx_properties(self)
8390
end

0 commit comments

Comments
 (0)