14 private bool _isJiggling;
15 private float _jiggleElapsedSeconds;
16 private double _jiggleAccumulatedSeconds;
18 private float _jiggleIntensityX;
19 private float _jiggleIntensityY;
20 private float _jiggleSpeed;
21 private float _jiggleScaleIntensity;
22 private bool _jiggleAffectsScale;
23 private bool _jiggleLoop;
24 private float _jiggleDurationSeconds;
27 private float _jigglePhaseX1;
28 private float _jigglePhaseX2;
29 private float _jigglePhaseY1;
30 private float _jigglePhaseY2;
31 private float _jigglePhaseScale;
34 private float _prevJiggleOffsetX;
35 private float _prevJiggleOffsetY;
36 private float _jiggleOffsetX;
37 private float _jiggleOffsetY;
38 private float _jiggleScale = 1f;
41 private bool _jiggleDecay;
42 private float _jiggleStartIntensityX;
43 private float _jiggleStartIntensityY;
44 private float _jiggleStartScaleIntensity;
85 float intensityX = 2f,
86 float intensityY = 2f,
88 float durationSeconds = 0.25f,
90 bool affectsScale =
false,
91 float scaleIntensity = 0.02f,
95 _jiggleElapsedSeconds = 0f;
97 _jiggleIntensityX = MathF.Max(0f, intensityX);
98 _jiggleIntensityY = MathF.Max(0f, intensityY);
99 _jiggleSpeed = MathF.Max(0f, speed);
100 _jiggleScaleIntensity = MathF.Max(0f, scaleIntensity);
101 _jiggleAffectsScale = affectsScale;
103 _jiggleDurationSeconds = MathF.Max(0f, durationSeconds);
105 _jiggleDecay = decay;
106 _jiggleStartIntensityX = _jiggleIntensityX;
107 _jiggleStartIntensityY = _jiggleIntensityY;
108 _jiggleStartScaleIntensity = _jiggleScaleIntensity;
111 _jigglePhaseX1 = Random.Shared.NextSingle() * MathF.PI * 2f;
112 _jigglePhaseX2 = Random.Shared.NextSingle() * MathF.PI * 2f;
113 _jigglePhaseY1 = Random.Shared.NextSingle() * MathF.PI * 2f;
114 _jigglePhaseY2 = Random.Shared.NextSingle() * MathF.PI * 2f;
115 _jigglePhaseScale = Random.Shared.NextSingle() * MathF.PI * 2f;
128 _prevJiggleOffsetX = 0f;
129 _prevJiggleOffsetY = 0f;
141 internal void AdvanceJiggle(
float deltaSeconds)
148 float step = (targetFps > 0) ? (1f / targetFps) : deltaSeconds;
150 _jiggleAccumulatedSeconds += deltaSeconds;
153 if (_jiggleAccumulatedSeconds < step)
158 _jiggleAccumulatedSeconds -= step;
160 _prevJiggleOffsetX = _jiggleOffsetX;
161 _prevJiggleOffsetY = _jiggleOffsetY;
163 _jiggleElapsedSeconds += dt;
165 if (!_jiggleLoop && _jiggleDurationSeconds > 0f && _jiggleElapsedSeconds >= _jiggleDurationSeconds)
171 float intensityX = _jiggleIntensityX;
172 float intensityY = _jiggleIntensityY;
173 float scaleIntensity = _jiggleScaleIntensity;
175 if (_jiggleDecay && !_jiggleLoop && _jiggleDurationSeconds > 0f)
177 float lifeT = _jiggleElapsedSeconds / _jiggleDurationSeconds;
178 lifeT = Math.Clamp(lifeT, 0f, 1f);
180 float decayFactor = 1f - lifeT;
182 intensityX = _jiggleStartIntensityX * decayFactor;
183 intensityY = _jiggleStartIntensityY * decayFactor;
184 scaleIntensity = _jiggleStartScaleIntensity * decayFactor;
187 float t = _jiggleElapsedSeconds * _jiggleSpeed;
190 MathF.Sin(t + _jigglePhaseX1) +
191 (0.5f * MathF.Sin((t * 2.37f) + _jigglePhaseX2));
194 MathF.Cos((t * 1.13f) + _jigglePhaseY1) +
195 (0.5f * MathF.Cos((t * 2.91f) + _jigglePhaseY2));
197 _jiggleOffsetX = xWave * 0.6667f * intensityX;
198 _jiggleOffsetY = yWave * 0.6667f * intensityY;
200 if (_jiggleAffectsScale && scaleIntensity > 0f)
203 MathF.Sin((t * 1.41f) + _jigglePhaseScale) +
204 (0.35f * MathF.Sin((t * 3.17f) + (_jigglePhaseScale * 0.5f)));
206 _jiggleScale = 1f + (scaleWave * 0.7407f * scaleIntensity);
207 if (_jiggleScale < 0.01f)
208 _jiggleScale = 0.01f;
216 Math.Abs(_jiggleOffsetX - _prevJiggleOffsetX) > 0.01f ||
217 Math.Abs(_jiggleOffsetY - _prevJiggleOffsetY) > 0.01f;
219 if (changed && _sceneLayer !=
null)
223 int inflateX = (int)MathF.Ceiling(_jiggleIntensityX);
224 int inflateY = (int)MathF.Ceiling(_jiggleIntensityY);
226 rect.Inflate(inflateX, inflateY);
228 _sceneLayer.RefreshQueue.AddWorldRect(rect);
238 internal RectangleF ApplyJiggleToDestRect(RectangleF destRect)
243 RectangleF result = destRect;
244 result.Offset(_jiggleOffsetX, _jiggleOffsetY);
246 if (Math.Abs(_jiggleScale - 1f) > 0.0001f)
248 float centerX = result.X + (result.Width / 2f);
249 float centerY = result.Y + (result.Height / 2f);
251 result.Width *= _jiggleScale;
252 result.Height *= _jiggleScale;
253 result.X = centerX - (result.Width / 2f);
254 result.Y = centerY - (result.Height / 2f);
271 float intensityX = 2f,
272 float intensityY = 2f,
274 float durationSeconds = 0.18f,
275 bool affectsScale =
false,
276 float scaleIntensity = 0.015f)
279 intensityX: intensityX,
280 intensityY: intensityY,
282 durationSeconds: durationSeconds,
284 affectsScale: affectsScale,
285 scaleIntensity: scaleIntensity,
Represents a movable visual element on a scene layer.
override Rectangle DrawLocationWorld
void StopJiggle()
Stops the current jiggle effect.
void StartJiggle(float intensityX=2f, float intensityY=2f, float speed=8f, float durationSeconds=0.25f, bool loop=false, bool affectsScale=false, float scaleIntensity=0.02f, bool decay=true)
Starts a smooth, randomized-looking jiggle animation. This jiggle is visual only and does not modify ...
PointF JiggleOffset
Gets the current visual jiggle offset in screen/world pixels, depending on how the sprite is being dr...
bool IsJiggling
Gets whether the sprite is currently jiggling.
float JiggleScale
Gets the current visual jiggle scale multiplier. This is intended to be applied at draw time only.
void JiggleOnce(float intensityX=2f, float intensityY=2f, float speed=12f, float durationSeconds=0.18f, bool affectsScale=false, float scaleIntensity=0.015f)
Starts a one-shot impact-style jiggle. Handy for hits, invalid selections, bump feedback,...
Represents the core game engine singleton responsible for managing the main update loop,...
static Engine Instance
Gets the singleton instance of the Engine.
EngineConfiguration Configuration
Gets the current engine configuration settings.