diff --git a/Blarg.GameFramework/Blarg.GameFramework.csproj b/Blarg.GameFramework/Blarg.GameFramework.csproj index fbe2608..ebb1f38 100644 --- a/Blarg.GameFramework/Blarg.GameFramework.csproj +++ b/Blarg.GameFramework/Blarg.GameFramework.csproj @@ -151,6 +151,12 @@ + + + + + + @@ -168,6 +174,7 @@ + diff --git a/Blarg.GameFramework/Graphics/ScreenEffects/DimEffect.cs b/Blarg.GameFramework/Graphics/ScreenEffects/DimEffect.cs new file mode 100644 index 0000000..c7fb5e7 --- /dev/null +++ b/Blarg.GameFramework/Graphics/ScreenEffects/DimEffect.cs @@ -0,0 +1,31 @@ +using System; + +namespace Blarg.GameFramework.Graphics.ScreenEffects +{ + public class DimEffect : ScreenEffect + { + public static readonly Color DefaultDimColor = Color.Black; + public const float DefaultDimAlpha = 0.5f; + + public Color Color; + public float Alpha; + + public DimEffect() + { + Color = DefaultDimColor; + Alpha = DefaultDimAlpha; + } + + public override void OnRender(float delta) + { + int width = Platform.GraphicsDevice.ViewContext.ViewportWidth; + int height = Platform.GraphicsDevice.ViewContext.ViewportHeight; + + var texture = Platform.GraphicsDevice.GetSolidColorTexture(Color.White); + var color = Color; + color.A = Alpha; + + //Platform.SpriteBatch.Render(texture, 0, 0, width, height, ref color); + } + } +} diff --git a/Blarg.GameFramework/Graphics/ScreenEffects/EffectInfo.cs b/Blarg.GameFramework/Graphics/ScreenEffects/EffectInfo.cs new file mode 100644 index 0000000..80bfc2a --- /dev/null +++ b/Blarg.GameFramework/Graphics/ScreenEffects/EffectInfo.cs @@ -0,0 +1,19 @@ +using System; + +namespace Blarg.GameFramework.Graphics.ScreenEffects +{ + internal class EffectInfo + { + public readonly ScreenEffect Effect; + public bool IsLocal; + + public EffectInfo(ScreenEffect effect, bool isLocal) + { + if (effect == null) + throw new ArgumentNullException("effect"); + + Effect = effect; + IsLocal = isLocal; + } + } +} diff --git a/Blarg.GameFramework/Graphics/ScreenEffects/FadeEffect.cs b/Blarg.GameFramework/Graphics/ScreenEffects/FadeEffect.cs new file mode 100644 index 0000000..eb9494d --- /dev/null +++ b/Blarg.GameFramework/Graphics/ScreenEffects/FadeEffect.cs @@ -0,0 +1,81 @@ +using System; + +namespace Blarg.GameFramework.Graphics.ScreenEffects +{ + public class FadeEffect : ScreenEffect + { + public const float DefaultFadeSpeed = 3.0f; + + float _fadeSpeed; + bool _isFadingOut; + float _alpha; + Color _color; + float _fadeToAlpha; + + public bool IsDoneFading { get; private set; } + + public FadeEffect() + { + } + + public void FadeOut(float toAlpha, Color color, float speed = DefaultFadeSpeed) + { + if (toAlpha < 0.0f || toAlpha > 1.0f) + throw new ArgumentOutOfRangeException("toAlpha"); + + _color = color; + _fadeSpeed = speed; + _isFadingOut = true; + _alpha = Color.AlphaTransparent; + _fadeToAlpha = toAlpha; + } + + public void FadeIn(float toAlpha, Color color, float speed = DefaultFadeSpeed) + { + if (toAlpha < 0.0f || toAlpha > 1.0f) + throw new ArgumentOutOfRangeException("toAlpha"); + + _color = color; + _fadeSpeed = speed; + _isFadingOut = false; + _alpha = Color.AlphaOpaque; + _fadeToAlpha = toAlpha; + } + + public override void OnRender(float delta) + { + int width = Platform.GraphicsDevice.ViewContext.ViewportWidth; + int height = Platform.GraphicsDevice.ViewContext.ViewportHeight; + + var texture = Platform.GraphicsDevice.GetSolidColorTexture(Color.White); + _color.A = _alpha; + + //Platform.SpriteBatch.Render(texture, 0, 0, width, height, ref _color); + } + + public override void OnUpdate(float delta) + { + if (IsDoneFading) + return; + + if (_isFadingOut) + { + _alpha += (delta + _fadeSpeed); + if (_alpha >= _fadeToAlpha) + { + _alpha = _fadeToAlpha; + IsDoneFading = true; + } + } + else + { + _alpha -= (delta + _fadeSpeed); + if (_alpha < _fadeToAlpha) + { + _alpha = _fadeToAlpha; + IsDoneFading = true; + } + } + } + } +} diff --git a/Blarg.GameFramework/Graphics/ScreenEffects/FlashEffect.cs b/Blarg.GameFramework/Graphics/ScreenEffects/FlashEffect.cs new file mode 100644 index 0000000..cc6fb9a --- /dev/null +++ b/Blarg.GameFramework/Graphics/ScreenEffects/FlashEffect.cs @@ -0,0 +1,61 @@ +using System; + +namespace Blarg.GameFramework.Graphics.ScreenEffects +{ + public class FlashEffect : ScreenEffect + { + public const float DefaultFlashSpeed = 16.0f; + public const float DefaultMaxIntensity = 1.0f; + + public float FlashInSpeed; + public float FlashOutSpeed; + public float MaximumIntensity; + public Color Color; + + bool _isFlashingIn; + float _alpha; + + public FlashEffect() + { + _isFlashingIn = true; + FlashInSpeed = DefaultFlashSpeed; + FlashOutSpeed = DefaultFlashSpeed; + MaximumIntensity = DefaultMaxIntensity; + Color = Color.White; + } + + public override void OnRender(float delta) + { + int width = Platform.GraphicsDevice.ViewContext.ViewportWidth; + int height = Platform.GraphicsDevice.ViewContext.ViewportHeight; + + var texture = Platform.GraphicsDevice.GetSolidColorTexture(Color.White); + var color = Color; + color.A = _alpha; + + //Platform.SpriteBatch.Render(texture, 0, 0, width, height, ref color); + } + + public override void OnUpdate(float delta) + { + if (_isFlashingIn) + { + _alpha += (delta * FlashInSpeed); + if (_alpha >= MaximumIntensity) + { + _alpha = MaximumIntensity; + _isFlashingIn = false; + } + } + else + { + _alpha -= (delta * FlashOutSpeed); + if (_alpha < 0.0f) + _alpha = 0.0f; + } + + if (_alpha == 0.0f && _isFlashingIn == false) + IsActive = false; + } + } +} diff --git a/Blarg.GameFramework/Graphics/ScreenEffects/ScreenEffect.cs b/Blarg.GameFramework/Graphics/ScreenEffects/ScreenEffect.cs new file mode 100644 index 0000000..276603e --- /dev/null +++ b/Blarg.GameFramework/Graphics/ScreenEffects/ScreenEffect.cs @@ -0,0 +1,65 @@ +using System; + +namespace Blarg.GameFramework.Graphics.ScreenEffects +{ + public abstract class ScreenEffect : IDisposable + { + public bool IsActive; + + public ScreenEffect() + { + } + + #region Events + + public virtual void OnAdd() + { + } + + public virtual void OnRemove() + { + } + + public virtual void OnAppGainFocus() + { + } + + public virtual void OnAppLostFocus() + { + } + + public virtual void OnAppPause() + { + } + + public virtual void OnAppResume() + { + } + + public virtual void OnLostContext() + { + } + + public virtual void OnNewContext() + { + } + + public virtual void OnRender(float delta) + { + } + + public virtual void OnResize() + { + } + + public virtual void OnUpdate(float delta) + { + } + + #endregion + + public virtual void Dispose() + { + } + } +} diff --git a/Blarg.GameFramework/Graphics/ScreenEffects/ScreenEffectManager.cs b/Blarg.GameFramework/Graphics/ScreenEffects/ScreenEffectManager.cs new file mode 100644 index 0000000..74bacc2 --- /dev/null +++ b/Blarg.GameFramework/Graphics/ScreenEffects/ScreenEffectManager.cs @@ -0,0 +1,206 @@ +using System; +using System.Collections.Generic; + +namespace Blarg.GameFramework.Graphics.ScreenEffects +{ + public class EffectManager : IDisposable + { + LinkedList _effects; + int _numLocalEffects; + int _numGlobalEffects; + + public EffectManager() + { + _effects = new LinkedList(); + _numLocalEffects = 0; + _numGlobalEffects = 0; + } + + #region Get / Add / Remove + + public T Get() where T : ScreenEffect + { + var type = typeof(T); + var node = GetNodeFor(type); + if (node == null) + return null; + else + return (T)node.Value.Effect; + } + + public T Add(bool isLocalEffect = true) where T : ScreenEffect + { + var type = typeof(T); + if (GetNodeFor(type) != null) + throw new InvalidOperationException("Cannot add an effect of the same type as an existing effect already being managed."); + + T effect = (T)Activator.CreateInstance(type); + var effectInfo = new EffectInfo(effect, isLocalEffect); + Add(effectInfo); + + return effect; + } + + public void Remove() where T : ScreenEffect + { + var type = typeof(T); + var node = GetNodeFor(type); + if (node != null) + Remove(node); + } + + public void RemoveAll() + { + while (_effects.Count > 0) + Remove(_effects.First); + } + + private void Add(EffectInfo effectInfo) + { + if (effectInfo == null) + throw new ArgumentNullException("effectInfo"); + + _effects.AddLast(effectInfo); + effectInfo.Effect.OnAdd(); + + if (effectInfo.IsLocal) + ++_numLocalEffects; + else + ++_numGlobalEffects; + } + + private void Remove(LinkedListNode node) + { + if (node == null) + throw new ArgumentNullException("node"); + + var effectInfo = node.Value; + if (effectInfo.IsLocal) + --_numLocalEffects; + else + --_numGlobalEffects; + + effectInfo.Effect.OnRemove(); + effectInfo.Effect.Dispose(); + _effects.Remove(node); + } + + #endregion + + #region Events + + public void OnAppGainFocus() + { + for (var node = _effects.First; node != null; node = node.Next) + node.Value.Effect.OnAppGainFocus(); + } + + public void OnAppLostFocus() + { + for (var node = _effects.First; node != null; node = node.Next) + node.Value.Effect.OnAppLostFocus(); + } + + public void OnAppPause() + { + for (var node = _effects.First; node != null; node = node.Next) + node.Value.Effect.OnAppPause(); + } + + public void OnAppResume() + { + for (var node = _effects.First; node != null; node = node.Next) + node.Value.Effect.OnAppResume(); + } + + public void OnLostContext() + { + for (var node = _effects.First; node != null; node = node.Next) + node.Value.Effect.OnLostContext(); + } + + public void OnNewContext() + { + for (var node = _effects.First; node != null; node = node.Next) + node.Value.Effect.OnNewContext(); + } + + public void OnRenderLocal(float delta) + { + if (_numLocalEffects == 0) + return; + + for (var node = _effects.First; node != null; node = node.Next) + { + if (node.Value.IsLocal) + node.Value.Effect.OnRender(delta); + } + } + + public void OnRenderGlobal(float delta) + { + if (_numGlobalEffects == 0) + return; + + for (var node = _effects.First; node != null; node = node.Next) + { + if (!node.Value.IsLocal) + node.Value.Effect.OnRender(delta); + } + } + + public void OnResize() + { + for (var node = _effects.First; node != null; node = node.Next) + node.Value.Effect.OnResize(); + } + + public void OnUpdate(float delta) + { + var node = _effects.First; + while (node != null) + { + var effect = node.Value.Effect; + if (!effect.IsActive) + { + var next = node.Next; + Remove(node); + node = next; + } + else + { + effect.OnUpdate(delta); + node = node.Next; + } + } + } + + #endregion + + #region Misc + + private LinkedListNode GetNodeFor(Type effectType) + { + if (effectType == null) + throw new ArgumentNullException("effectType"); + + for (var node = _effects.First; node != null; node = node.Next) + { + if (node.Value.Effect.GetType() == effectType) + return node; + } + return null; + } + + #endregion + + public void Dispose() + { + if (_effects == null) + return; + + RemoveAll(); + _effects = null; + } + } +}