DrawableParticles
Extends: Drawable
Emits and simulates lightweight particles (lines, rectangles, or images) with randomized velocity, constant acceleration, and lifetime-driven fade/color/size interpolation. Draws through a single SceneObjectParticle per emitter rather than one SceneObject per particle, so spawning/expiring particles never touches Renderer.addSceneObject/removeSceneObject - see specs/2026-08-18-particle-system-design.md for why that matters for depth-sort performance.
Properties
shape(ParticleShape) — Shape drawn for every particle. See BGE.ParticleShape.image(dynamic) — Bitmap or region drawn for each particle when shape = BGE.ParticleShape.Image. ' Ignored for other shapes.cellWidth(integer) — Width/height (pixels) of one animation cell ifimageis a sprite sheet, the 'BGE.ParticleShape.Imageshape only. When both are >0,imageis sliced into a ' row-major grid of frames and ' each particle's current frame is driven by its own age/lifetime - a fade-style sheet ' (bright to transparent) reproduces its own fade this way, with no extra frame-rate ' config needed. 0 (the default) meansimageis drawn as a single static bitmap, ' unchanged from previous behavior.cellHeight(integer)regions(dynamic)spawnRate(float) — Particles spawned per second while emitting (see start()/stop()).lifetime(float) — Base lifetime in seconds each particle survives, randomized by +/- lifetimeSpread.lifetimeSpread(float)velocity(BGE.Math.Vector) — Base emission velocity (world units/second) shared by every particle before ' randomization is applied.velocitySpreadAngleDegrees(float) — Randomizes each particle's velocity direction by +/- this many degrees around 'velocity.velocitySpreadMagnitude(float) — Randomizes each particle's velocity magnitude by +/- this amount. Ifvelocity' is zero, particles instead radiate outward in a uniformly random direction at this ' magnitude - this is what makes a stationary emitter usable for an explosion/burst ' effect.acceleration(BGE.Math.Vector) — Constant acceleration (world units/second^2) applied to every particle every ' frame, e.g. gravity.startColor(integer) — Packed RGB (0xRRGGBB) color interpolated over each particle's lifetime.endColor(integer)startAlpha(float) — Alpha (0-255) interpolated over each particle's lifetime.endAlpha(float)startSize(float) — Size interpolated over each particle's lifetime - a line's length, a rectangle's ' side length, or an image's scale multiplier (1.0 = the image's native size), ' depending onshape.endSize(float)rotationSpeed(float) — Degrees/second of rotation applied to each particle. Only used when ' shape = BGE.ParticleShape.Image - see the design spec for why line/rectangle ' particles never rotate.maxParticles(integer) — Hard cap on live particles. Once reached, further spawns (continuous emission or ' burst()) are silently dropped until a slot frees up via natural expiry.particles(dynamic) — Live particle records. See BGE.ParticleRecord.emitting(boolean)spawnAccumulator(float)timer(dynamic)
Constructor
new DrawableParticles(
owner: GameEntity,
shape: ParticleShape,
args?: roAssociativeArray,
): DrawableParticlesParameters
owner(GameEntity)shape(ParticleShape)args(roAssociativeArray, optional, default: "{}")
Instance Methods
start(): void
Starts continuous emission at spawnRate particles/second.
Returns
void
stop(): void
Stops continuous emission. Already-live particles keep simulating and drawing until they expire naturally.
Returns
void
burst(count: integer): void
Immediately spawns count particles, regardless of start()/stop() state.
Parameters
count(integer) — number of particles to spawn right now
Returns
void
addToScene(rendererScene: Renderer): BGE.SceneObject
Parameters
rendererScene(Renderer)
Returns
update(): void
Returns
void
getFrameRegions(): dynamic
Lazily slices image into a row-major grid of cellWidth x cellHeight regions (built once, cached) - mirrors Sprite.setCellRegions()'s exact slicing convention.
configured as a sprite sheet (cellWidth/cellHeight are 0) or image isn't set yet
Caches on first call - reassigning image/cellWidth/cellHeight after that has no effect on an already-built cache.
Returns
dynamic— the per-frame regions, orinvalidif this emitter isn't