Search code examples
c#arraysvisual-studioimagebitmap

I'm trying to have a picture box switch between 4 images to simulate a spinning wheel animation but I can't wrap my head around how to make it work


I have to use bitmap and a picture box. I'm new to c# and still trying to figure out how everything works. I've been stuck on this problem for 2 days with no success

namespace WheelOfFortune
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        private void Spin_wheel()
        {
            // 1.Create Bitmap Array to loop pictures 
            //Create data set to hold strings which the user can change


            //Array for wheel
            //2-1-4-3(order of pictures)
            string image1 = (@"C:\Users\adm1\Documents\Programing\WheelOfFortune\WheelOfFortune\Resources\wheel2.png");
            string image2 = (@"C:\Users\adm1\Documents\Programing\WheelOfFortune\WheelOfFortune\Resources\wheel1.png");
            string image3 = (@"C:\Users\adm1\Documents\Programing\WheelOfFortune\WheelOfFortune\Resources\wheel4.png");
            string image4 = (@"C:\Users\adm1\Documents\Programing\WheelOfFortune\WheelOfFortune\Resources\wheel3.png");

            //Array
            string[] arr = new string[4];
            arr[0] = image1;
            arr[1] = image2;
            arr[2] = image3;
            arr[3] = image4;

            if (File.Exists(image4))
            {
                //Random count to randomize rotation
                //Bitmap pictures
                Bitmap picture = new Bitmap(arr[0]);
                wheelPictureBox.Image = picture;
                Random rnd = new Random(4);
                int rotation = rnd.Next();
                for (int i = 0; i < rotation; i++)
                {
                    while (i == 0) ;
                    picture = new Bitmap(arr[0]);
                    Thread.Sleep(100);
                    while (i == 1) ;
                    picture = new Bitmap(arr[1]);
                    Thread.Sleep(100);
                    while (i == 2) ;
                    picture = new Bitmap(arr[2]);
                    Thread.Sleep(100);
                    while (i == 3) ;
                    picture = new Bitmap(arr[3]);
                    Thread.Sleep(100);

                }
                
                
            }
            else
            {
                MessageBox.Show("Please make sure the file integrity is intact");
            }

        }

        private void button1_Click(object sender, EventArgs e)
        {
            Spin_wheel();
        }
    }
}

Solution

  • Your code doesn't make a lot of sense, so let's go over it a bit at a time:

    //Array for wheel
    //2-1-4-3(order of pictures)
    string image1 = (@"C:\Users\adm1\Documents\Programing\WheelOfFortune\WheelOfFortune\Resources\wheel2.png");
    string image2 = (@"C:\Users\adm1\Documents\Programing\WheelOfFortune\WheelOfFortune\Resources\wheel1.png");
    string image3 = (@"C:\Users\adm1\Documents\Programing\WheelOfFortune\WheelOfFortune\Resources\wheel4.png");
    string image4 = (@"C:\Users\adm1\Documents\Programing\WheelOfFortune\WheelOfFortune\Resources\wheel3.png");
    
    //Array
    string[] arr = new string[4];
    arr[0] = image1;
    arr[1] = image2;
    arr[2] = image3;
    arr[3] = image4;
    

    Here we would better be served with a List structure of Bitmaps rather than strings. We will want to swap between bitmaps to produce the animation, not build a bitmap every time we want to display an image. Ideally it should use a relative path, which will be from the ./Bin/Debug during debugging or wherever the executable is run from. The bitmaps could be embedded resources within the assembly or kept in a /Resources sub folder. List is a simpler structure to work with since we can easily append items while still accessing items by index like an array. Whether a List or array we should use a set of bitmaps rather than merely file names.

    List images = new List(); if (File.Exists("Resources/wheel2.png")) images.Add(new Bitmap("Resources/wheel2.png"); if (File.Exists("Resources/wheel1.png")) images.Add(new Bitmap("Resources/wheel1.png"); if (File.Exists("Resources/wheel4.png")) images.Add(new Bitmap("Resources/wheel4.png"); if (File.Exists("Resources/wheel3.png")) images.Add(new Bitmap("Resources/wheel3.png");

    I don't know why you need to load the images as 2-1-4-3 vs. just rename the files if they are out of order...

    So now we have a set of actual bitmaps to rotate through. Next:

    Random rnd = new Random(4);
    int rotation = rnd.Next();
    

    This says: "Make a random generator with a seed of 4 and give me a random integer from 0 to int.Max". If you wanted a random number from 0-3 what you'd really be looking for is:

    Random rnd = new Random();
    int rotation = rnd.Next(0,4);
    

    The "seed" is just a starting value to use, not a limiter or directly linked to the value returned by Next. It is just provided in cases where you want a predictable, repeatable pattern for the initial Random.Next value.

    We can come back to what you intend from the random number rotation afterwards.

    for (int i = 0; i < rotation; i++)
    {
        while (i == 0) ;
        picture = new Bitmap(arr[0]);
        Thread.Sleep(100);
        while (i == 1) ;
        picture = new Bitmap(arr[1]);
        Thread.Sleep(100);
        while (i == 2) ;
        picture = new Bitmap(arr[2]);
        Thread.Sleep(100);
        while (i == 3) ;
        picture = new Bitmap(arr[3]);
        Thread.Sleep(100);
    }
    

    Now the above code has several things wrong. while is a loop structure, what it looks like is that you wanted a conditional structure with is if:

        if (i == 0)
        {
            picture = new Bitmap(arr[0]);
        }
        else if (i == 1)
        {
            picture = new Bitmap(arr[1]);
        }
        ...
    

    However, this is really doing nothing more than:

        picture = new Bitmap(arr[i]);
    

    This is setting picture to a new Bitmap instance but you are not updating your actual control's image reference, so setting "picture" here does nothing.

    With the new List<Bitmap> images this can be simplified. for instance if we want to do one full rotation:

     for (int count = 0; count < 4; count ++)
     {
         wheelPictureBox.Image = images[count];
         Thread.Sleep(100);
     }
    

    Now if you want to introduce a random # of rotations, such as 1-4 full rotations:

     int rotations = new Random().Next(1,5); // 1-4
     int index = 0;
     for (int count = 0; count < rotations * 4; count ++)
     {
         wheelPictureBox.Image = images[index++];
         if (index > 3) index = 0;
         Thread.Sleep(100);
     }
    

    That would give you a randomized spin of 1-4 full rotations. Here we use a "index" variable to keep count of the rotation index in the list of images, from 0 to 3 then back to 0. We cannot use "count" since that will go beyond 3 and result in an index out of range exception since we want to loop through the 4 bitmaps in our list then go back to the first image. index++ says "take the current index value, then after using it, increment". After that we have a check to see if it has been incremented past 3, and if so, reset it to 0.

    If you wanted to include partial rotations for up to 4 full rotations:

     int rotationTicks = new Random().Next(1,17); // 1-4 full rotations (16 quarter rotations)
     int index = 0;
     for (int count = 0; count < rotationTicks; count ++)
     {
         wheelPictureBox.Image = images[index++];
         if (index > 3) index = 0;
         Thread.Sleep(100);
     }
    

    That should hopefully get you moving in the right direction around understanding how to get a simple animation loop running.