Today’s mostly been spent with the kids, but I did manage to eek in a bit of progress this morning.

Ascend/Descend animation

When you step on a stairwell, the screen now fades to black, then switches levels, then fades back in to view.  This gives a cheap but effective smooth transition; I’ll throw in some footstep sound effects later, and this should be good to go.

With the AnimationMgr and the Animation class, this was easy to add. Here’s the entirey of the Animation_AscendDescendStairs class:

public class Animation_AscendDescendStair : Animation
    /// <summary>
    /// Constructor
    /// </summary>
    /// <param name="stair">Stair way to ascend/descend</param>
    public Animation_AscendDescendStair(Cell_Stair stair)
        : base()
        // This animation works in phases; phase 0 = fade out, phase 1 = fade in
        _curPhase = 0;

        // Track the stairwell being used
        _stair = stair;

        // Determine the number of the level to which we're ascending or descending.
        int levelNum = stair.IsUpStair ? stair.Level.LevelNumber - 1 : stair.Level.LevelNumber + 1;

        // Pre-calculate the strings to display and their widths
        _strAscDesc = _stair.IsUpStair ? "Ascending" : "Descending";
        _strDest = levelNum == 0 ? "to exit" : "to level " + levelNum;
        _ascDescWidth = (int)RenderMgr.MeasureString(_strAscDesc, AssetMgr.ActorTalkFont).X;
        _destWidth = (int)RenderMgr.MeasureString(_strDest, AssetMgr.ActorTalkFont).X;

        // Don't let the player move while fading in/out
        InputMgr.IgnoreInput = true;

    /// <summary>
    /// Return true when the animation has completed and should be removed
    /// </summary>
    /// <returns>True when the animation has completed</returns>
    public override bool Completed()
        // We're done when we reach phase #2.
        return _curPhase == 2;

    /// <summary>
    /// Render the message above the Actor
    /// </summary>
    public override void Render()
        // Determine how far complete we are
        int msGoneBy = (int)(AnimationMgr.CurrentTime - this.StartTime).TotalMilliseconds;
        float percentComplete = (float)msGoneBy / _msToDisplay;

        switch (_curPhase)
            case 0: // fade out
                if (percentComplete >= 1)
                    // faded to black - switch level and start fade back in
                    _curPhase = 1;
                    this.StartTime = AnimationMgr.CurrentTime;
                    percentComplete = 1;
                Color color = Color.FromNonPremultiplied(0, 0, 0, (int)(255f * percentComplete));
                RenderMgr.FillRectangle(color, 0, 0, RenderMgr.Width, RenderMgr.Height);


            case 1: // fade back in
                if (percentComplete >= 1)
                    _curPhase = 2;
                    InputMgr.IgnoreInput = false;
                    Color color1 = Color.FromNonPremultiplied(0, 0, 0, (int)(255f * (1-percentComplete)));
                    RenderMgr.FillRectangle(color1, 0, 0, RenderMgr.Width, RenderMgr.Height);

        // output the ascending/descending message
        RenderMgr.DrawString(_strAscDesc, AssetMgr.ActorTalkFont, Color.White, 240 - _ascDescWidth / 2, 400);
        RenderMgr.DrawString(_strDest, AssetMgr.ActorTalkFont, Color.White, 240 - _destWidth / 2, 430);

    // _strAscDesc: Either "Ascending" or "Descending" based on stairwell being used
    string _strAscDesc;

    // _strDest: Contains the level the user's going to
    string _strDest;

    // _ascDescWidth: Width of the _strAscDesc string.  Used to center on the screen.
    int _ascDescWidth;

    // _destWidth: Width of _ascdescWidth string.  Used to center on the screen.
    int _destWidth;

    // _stair: Stairwell being ascended or descended
    Cell_Stair _stair;

    // _msToDisplay: Number of milliseconds to fade in and to fade out
    int _msToDisplay = 1250;

    // _curPhase: Current phase we're in: fade out (phase 0) or fade in (phase 1)
    int _curPhase;

The animation is created and started in Action_Move when the player steps on a Cell_Stair:

                AnimationMgr.AddAnimation(new Animation_AscendDescendStair(destCell as Cell_Stair));

Player death!

Your days of immortality are at an end; I’ve implemented Player death.  At this point, death just re-enters you at the top of a new dungeon, but later I’ll need to revert changes to the player (e.g. experience gained, new items, etc).  I’ll likely do that by  saving a snapshot of them in EnterDungeonForFirstTime, and restore to that snapshot upon death.  But for now, be careful out there!

(I also implemented Settings.GodMode for test purposes).

Player Death Animation

This was fun; building on the ascend/descend animation, I built an Animation_PlayerDeath class which first fades to red and then to black while a somewhat opaque skull ominously grows in the background.  A cheesy effect, but fun :).

I’ll post a new WiP video on YouTube that includes both of these new Animations.

Misc fixes

I also flipped the “up stairwell” to match the “down stairwell,” and added floor tiles underneath them.

Updated source:

Updated executable: