简体   繁体   中英

Bitmap animation stops working, after running a few frames

I have tried to create an animated bitmap on windows forms application. A timer object is set to an interval of 100ms, and the code works like this:

I have a 2560x2560 bitmap that is my map, a picture box called 'pb' contains this map and the size of the picture box is 800x800 with image stretch parameter on to give better resolution. I have a bitmap array of 7 elements containing the frames for a torch. The idea is that i draw the current torch bitmap onto the map, set the image of 'pb' to the map and call invalidate procedure to redraw it. Then the bitmap with torch drawn onto it is reverted to the original map bitmap 'org_btm'.

The code is below:

        private void animationtick_Tick(object sender, EventArgs e)
        {
            using (Graphics g = Graphics.FromImage(btm))
            { g.DrawImage(torch_anim[torch_anim_c], new Point(20*64, 20*64)); }
            pb.Image = btm;
            pb.Invalidate();
            btm = org_btm;

            if (torch_anim_c < 6)
            {
                torch_anim_c++;
            }
            else
            {
                torch_anim_c = 0;
            }
            pb.Invalidate();
        }

'torch_anim_c' is the index counter of the bitmap array. So the problem that occurs is that the torch works for the first few frames and stops working there after, being stuck on 1 frame, when i run the code in debugger with a break point, it shows that the code runs through even when the image is stuck, and the program is responsive with other functions still working. Do you have any ideas how to fix this? Thank you in advance.

I have a snippet of the map with the stuck torch animation: Torch Stuck Snippet

edit: the 'Point()' is 20*64 because the torch size is 64x64 and it's at position 20 and the map is 40*40 tiles.

convert it to gif format using photoshop and then use this class

public class GifImage
{
    private Image gifImage;
    private FrameDimension dimension;
    private int frameCount;
    private int currentFrame = -1;
    private bool reverse;
    private int step = 1;

    public GifImage(string path)
    {
        gifImage = Image.FromFile(path);
        dimension = new FrameDimension(gifImage.FrameDimensionsList[0]);
        frameCount = gifImage.GetFrameCount(dimension);
    }

    public bool ReverseAtEnd {
        get { return reverse; }
        set { reverse = value; }
    }

    public Image GetNextFrame()
    {

        currentFrame += step;
        if (currentFrame >= frameCount || currentFrame < 1) {
            if (reverse) {
                step *= -1;
                currentFrame += step;
            }
            else {
                currentFrame = 0;
            }
        }
        return GetFrame(currentFrame);
    }

    public Image GetFrame(int index)
    {
        gifImage.SelectActiveFrame(dimension, index);
        return (Image)gifImage.Clone();
    }
}

Initialize it at formload ot whenever

GifImage gifImage = new GifImage(filePath);

set the Reverse variable to true if youn want to reverse it at the end

at timer tick use that code

pb.Image = gifImage.GetNextFrame();

change pb.Invalidate(); with pb.Update();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM