163 lines
4.3 KiB
C#
163 lines
4.3 KiB
C#
using System;
|
||
|
||
namespace Ichni.RhythmGame
|
||
{
|
||
public abstract class EffectBase : IBaseElement
|
||
{
|
||
#region [枚举定义] Enums
|
||
public enum EffectState
|
||
{
|
||
Before = -1,
|
||
Middle = 0,
|
||
After = 1,
|
||
Error = 100
|
||
}
|
||
#endregion
|
||
|
||
#region [核心属性] Properties
|
||
public Beatmap.BaseElement_BM matchedBM { get; set; }
|
||
public GameElement attachedGameElement;
|
||
|
||
/// <summary>
|
||
/// 效果的持续时间,如果为0则表示瞬间效果
|
||
/// </summary>
|
||
public float effectTime;
|
||
|
||
/// <summary>
|
||
/// 是否是瞬间效果
|
||
/// </summary>
|
||
public bool isInstantEffect => effectTime <= 0;
|
||
|
||
/// <summary>
|
||
/// 效果的进度百分比
|
||
/// </summary>
|
||
public float effectProgressPercent;
|
||
|
||
/// <summary>
|
||
/// 效果当前的状态
|
||
/// </summary>
|
||
public EffectState nowEffectState;
|
||
#endregion
|
||
|
||
#region [初始化] Initialization
|
||
protected EffectBase()
|
||
{
|
||
this.effectTime = 0;
|
||
this.nowEffectState = EffectState.Before;
|
||
this.effectProgressPercent = 0;
|
||
}
|
||
|
||
protected EffectBase(float effectTime)
|
||
{
|
||
this.effectTime = effectTime;
|
||
this.nowEffectState = EffectState.Before;
|
||
this.effectProgressPercent = 0;
|
||
}
|
||
#endregion
|
||
|
||
#region [基础逻辑] Main Update Logic
|
||
public virtual void UpdateEffect(float judgeTime)
|
||
{
|
||
EffectState state = CheckEffectState(judgeTime);
|
||
float songTime = CoreServices.TimeProvider.SongTime;
|
||
|
||
if (state == EffectState.Before && nowEffectState != EffectState.Before)
|
||
{
|
||
nowEffectState = EffectState.Before;
|
||
effectProgressPercent = 0;
|
||
Recover();
|
||
}
|
||
else if (state == EffectState.Middle)
|
||
{
|
||
if (nowEffectState == EffectState.Before)
|
||
{
|
||
PreExecute();
|
||
}
|
||
|
||
nowEffectState = EffectState.Middle;
|
||
effectProgressPercent = (songTime - judgeTime) / effectTime;
|
||
Execute();
|
||
}
|
||
else if (state == EffectState.After && nowEffectState != EffectState.After)
|
||
{
|
||
nowEffectState = EffectState.After;
|
||
effectProgressPercent = 1;
|
||
Adjust();
|
||
}
|
||
}
|
||
|
||
protected virtual EffectState CheckEffectState(float triggerTime)
|
||
{
|
||
float songTime = CoreServices.TimeProvider.SongTime;
|
||
|
||
if (songTime < triggerTime)
|
||
{
|
||
return EffectState.Before;
|
||
}
|
||
|
||
if (songTime >= triggerTime &&
|
||
songTime <= triggerTime + effectTime)
|
||
{
|
||
return EffectState.Middle;
|
||
}
|
||
|
||
if (songTime > triggerTime + effectTime)
|
||
{
|
||
return EffectState.After;
|
||
}
|
||
|
||
return EffectState.Error;
|
||
}
|
||
#endregion
|
||
|
||
#region [效果重写] Effect Overrides
|
||
/// <summary>
|
||
/// 当从Before状态进入Middle状态时,仅在效果的开始时触发一次方法
|
||
/// </summary>
|
||
public virtual void PreExecute()
|
||
{
|
||
|
||
}
|
||
|
||
/// <summary>
|
||
/// 在效果的持续时间内,触发这个方法
|
||
/// </summary>
|
||
public virtual void Execute()
|
||
{
|
||
|
||
}
|
||
|
||
/// <summary>
|
||
/// 如果是非瞬间效果,在效果完成后,触发这个方法;
|
||
/// 如果是瞬间效果,则此方法即为Execute。原有的Execute方法不被调用。
|
||
/// </summary>
|
||
public virtual void Adjust()
|
||
{
|
||
|
||
}
|
||
|
||
/// <summary>
|
||
/// 如果时间轴回退到效果的触发时间之前,则触发这个方法
|
||
/// </summary>
|
||
public virtual void Recover()
|
||
{
|
||
|
||
}
|
||
|
||
/// <summary>
|
||
/// 如果效果被打断,则触发这个方法
|
||
/// </summary>
|
||
public virtual void Disrupt()
|
||
{
|
||
|
||
}
|
||
|
||
public void Refresh()
|
||
{
|
||
|
||
}
|
||
#endregion
|
||
|
||
}
|
||
}
|