在XNA中随时间变化不透明度

时间:2011-04-26 20:14:45

标签: c# animation xna

我想设置包含级别名称的文本字符串的不透明度值,并在中间延迟。

所以事件的顺序如下:

  1. 开始透明
  2. 在比赛时间的一秒钟内淡入纯白色
  3. 等一下
  4. 在一秒钟内再次淡出透明。
  5. 我为阿尔法值设置动画的代码不起作用。另外,它非常丑陋,我确信使用XNA框架有更好的方法。

    我一直无法在其他地方找到任何关于这样做的建议。当然,像这样的动画值并不常见。我该怎么办?

    这是我要求的当前代码(是的,它太可怕了)。

    private int fadeStringDirection = +1;
    private int fadeStringDuration = 1000;
    private float stringAlpha = 0;
    private int stringRef = 0;
    private int stringPhase = 1;
    
    ...
    
    if (!pause)
    {
        totalMillisecondsElapsed += gameTime.ElapsedGameTime.Milliseconds;
        if (fadestringDirection != 0)
        {
            stringAlpha = ((float)(totalMillisecondsElapsed - stringRef) / (float)(fadeStringDuration*stringPhase)) * fadeStringDirection;
            stringAlpha = MathHelper.Clamp(stringAlpha, 0, 1);
            if (topAlpha / 2 + 0.5 == fadeStringDirection)
            {
                fadeStringDirection = 0;
                stringRef = totalMillisecondsElapsed;
                stringPhase++;
            }
        }
        else
        {
            stringRef += gameTime.ElapsedGameTime.Milliseconds;
            if (stringRef >= fadeStringDuration * stringPhase)
            {
                stringPhase++;
                fadeStringDirection = -1;
                stringRef = totalMillisecondsElapsed;
            }
        }
    }
    

1 个答案:

答案 0 :(得分:2)

这是我现在的解决方案。比我之前(以及它自己的一类)更好。

/// <summary>
/// Animation helper class.
/// </summary>
public class Animation
{
    List<Keyframe> keyframes = new List<Keyframe>();

    int timeline;

    int lastFrame = 0;

    bool run = false;

    int currentIndex;

    /// <summary>
    /// Construct new animation helper.
    /// </summary>
    public Animation()
    {
    }

    public void AddKeyframe(int time, float value)
    {
        Keyframe k = new Keyframe();
        k.time = time;
        k.value = value;
        keyframes.Add(k);
        keyframes.Sort(delegate(Keyframe a, Keyframe b) { return a.time.CompareTo(b.time); });
        lastFrame = (time > lastFrame) ? time : lastFrame;
    }

    public void Start()
    {
        timeline = 0;
        currentIndex = 0;
        run = true;
    }

    public void Update(GameTime gameTime, ref float value)
    {
        if (run)
        {
            timeline += gameTime.ElapsedGameTime.Milliseconds;
            value = MathHelper.SmoothStep(keyframes[currentIndex].value, keyframes[currentIndex + 1].value, (float)timeline / (float)keyframes[currentIndex + 1].time);
            if (timeline >= keyframes[currentIndex + 1].time && currentIndex != keyframes.Count) { currentIndex++; }
            if (timeline >= lastFrame) { run = false; }
        }
    }

    public struct Keyframe
    {
        public int time;
        public float value;
    }
}