C# windows form, how to load a random image into a picturebox

Hey guys, I am working on a program in visual studio which is designed to work with a wii remote. I have calibrated thewii remote so that it has 8 directions left, upleft, up etc in a circle around. The problem is that I need to load a random image of an arrow into the picturebox and the user needs to match the image so that it is a success. The level will progress so there will be two random pictures, then three etc... The idea is a memory game, to see how many pictures or gestures can be memorised.

I am struggling to load a random image into the picturebox, I want to do this efficiently, perhaps using an array or a list. If the user holds the wii remote at the correct angle and matches the arrow then a successful output will happen, ie a positive image and perhaps sound.

If anyone can assist me in getting the random image to load once the start game button is pressed then that would be great! I won't post any code as all I have so far is code that uses teh wii mote library and out puts a different colour in the picturebox depedning on which angle the wiimote is being held.

I know it may be a simple thing I am sking about but for some reason I can't do it.

Thank you!
deucalion0Asked:
Who is Participating?
 
Mike TomlinsonConnect With a Mentor Middle School Assistant TeacherCommented:
I would add the .GIFs to your app as embedded resources:
(1) Project --> Add Existing File --> Select GIF.
(2) In Solution Explorer, select the GIF.
(3) In the Properties Pane, change the "Build Action" to "Embedded Resource".

Now the GIFs are embedded inside your .EXE.

You can use code like this to load the GIFs into a List:   *assuming all the embedded images end with ".gif"*
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private int LastIndex = -1;
        private Random R = new Random();
        private List<Bitmap> images = new List<Bitmap>();

        private void Form1_Load(object sender, EventArgs e)
        {
            string filter = ".gif".ToLower() ;
            foreach(string resource in System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceNames())
            {
                if (resource.ToLower().EndsWith(filter))
                {
                    images.Add(new Bitmap(System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(resource)));
                }
            }
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            pictureBox1.Image = NextImage();
        }

        private Bitmap NextImage()
        {
            int index;
            do
            {
                index = R.Next(0, images.Count);
            } while (index == LastIndex);
            LastIndex = index;
            return images[index];
        }

    }
}

Open in new window

0
 
Carl TawnSystems and Integration DeveloperCommented:
I'm assuming you have a set of eight images already, one for each direction? I guess the easiest way would be to preload the images into an array and then use the Random object to take a random number between 0 and seven, and use that as an index into the array of images.
0
 
deucalion0Author Commented:
Hey carl, that is what I have been trying to do but I am not good at arrays, I have been trying to figure out how to use the array. I have eight images up.gif, upright.gif, right.gif etc... and I cannot for teh life of me figure out how to put them into an array. Also they need to be random and they cannot be the same two images consecutively. Cold you provide an exampl on how I could do this please?

thank you!
0
Cloud Class® Course: MCSA MCSE Windows Server 2012

This course teaches how to install and configure Windows Server 2012 R2.  It is the first step on your path to becoming a Microsoft Certified Solutions Expert (MCSE).

 
Carl TawnConnect With a Mentor Systems and Integration DeveloperCommented:
In a simple scenario you could use something like the folowing:
        private void Form1_Load(object sender, EventArgs e)
        {
            images = new Image[8];
            images[0] = Image.FromFile("Path-to-image1");
            images[1] = Image.FromFile("Path-to-image2");
            images[2] = Image.FromFile("Path-to-image3");
            images[3] = Image.FromFile("Path-to-image4");
            images[4] = Image.FromFile("Path-to-image5");
            images[5] = Image.FromFile("Path-to-image6");
            images[6] = Image.FromFile("Path-to-image7");
            images[7] = Image.FromFile("Path-to-image8");
        }

        private Image GetRandomImage()
        {
            int index = random.Next(7);
            while (index == lastIndex)
                index = random.Next(7);

            lastIndex = index;

            return images[index];
        }

        System.Random random = new Random();
        int lastIndex = -1;
        Image[] images;

Open in new window

The you simply need to call the GetRandomImage method each time you want a random image from the list, and it will make sure you don't get the same one twice in a row.
0
 
deucalion0Author Commented:
Thanks guys for the code! I am trying idle minds method first as it has the embedding of the file, which makes things easier due to working on several computers.

I basically copied your code idle mind and I already had the 8 images added as resources, so I just went to the properties of each and selected embedded resource. I copied your code into the form1_load with my other code, but when I run it, nothing happens, I don't know if I am supposed to do anything else with it but there are no errors.
As the code you wrote is a bit complex, I am not sure exactly what it does but I think I am using it correctly. Is there supposed to be a random image displayed in the picturebox upon loading?

I will show you the coed I have in this class, you all seem to be professionals, so you know to ignore most of the code I have here it is all for teh wii remote and for an infrared box which at the moment is commented out.

Thanks for all your input it helps a lot!

My code:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using WiimoteLib;
using System.Diagnostics;
using RoboIrLib;
using System.Resources;

namespace WindowsFormsApplication1
{

    public partial class Form1 : Form
    {
        // create a new instance of the Wiimote
        Wiimote wm = new Wiimote();
        RoboControl rc = new RoboControl();
        bool up, down, left, right, upL, upR, downL, downR;

        public Form1()
        {
            InitializeComponent();
        }

        private int LastIndex = -1;
        private Random R = new Random();
        private List<Bitmap> images = new List<Bitmap>();



        private void Form1_Load(object sender, EventArgs e)
        {
            Control.CheckForIllegalCrossThreadCalls = false;
            // connect to the Wiimote
            wm.Connect();

            // setup the event to handle state changes
            wm.WiimoteChanged += wm_WiimoteChanged;

            // setup the event to handle insertion/removal of extensions
            wm.WiimoteExtensionChanged += wm_WiimoteExtensionChanged;

            // set the report type to return the IR sensor and accelerometer data (buttons always come back)
            wm.SetReportType(InputReport.IRAccel, true);

            string filter = ".gif".ToLower();
            foreach (string resource in System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceNames())
            {
                if (resource.ToLower().EndsWith(filter))
                {
                    images.Add(new Bitmap(System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(resource)));
                }
            }
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            pic_colour.Image = NextImage();
        }

        private Bitmap NextImage()
        {
            int index;
            do
            {
                index = R.Next(0, images.Count);
            } while (index == LastIndex);
            LastIndex = index;
            return images[index];

        }

        void wm_WiimoteExtensionChanged(object sender, WiimoteExtensionChangedEventArgs args)
        {
            if (args.Inserted)
                wm.SetReportType(InputReport.IRExtensionAccel, true);    // return extension data
            else
                wm.SetReportType(InputReport.IRAccel, true);            // back to original mode
        }

        void wm_WiimoteChanged(object sender, WiimoteChangedEventArgs args)
        {
            // current state information
            WiimoteState ws = args.WiimoteState;


            // write out the state of the A button    
            //Debug.WriteLine(ws.ButtonState.A);

            btn_up.BackColor = Color.White;
            if (ws.ButtonState.Up)
            {
                btn_up.BackColor = Color.Black;
                if (rc.Connect())
                {
                    if (!rc.Transmit("300", RoboControl.RobotType.RoboSapien_V2))
                    {
                        Console.WriteLine(rc.Error);
                    }
                }
            }


            btn_down.BackColor = Color.White;
            if (ws.ButtonState.Down)
            {
                btn_down.BackColor = Color.Black;
                if (rc.Connect())
                {
                    if (!rc.Transmit("366", RoboControl.RobotType.RoboSapien_V2))
                    {
                        Console.WriteLine(rc.Error);
                    }
                }
            }

            btn_left.BackColor = Color.White;
            if (ws.ButtonState.Left)
            {
                btn_left.BackColor = Color.Black;
                if (rc.Connect())
                {
                    if (!rc.Transmit("350", RoboControl.RobotType.RoboSapien_V2))
                    {
                        Console.WriteLine(rc.Error);
                    }
                }
            }

            btn_right.BackColor = Color.White;
            if (ws.ButtonState.Right)
            {
                btn_right.BackColor = Color.Black;
                if (rc.Connect())
                {
                    if (!rc.Transmit("35F", RoboControl.RobotType.RoboSapien_V2))
                    {
                        Console.WriteLine(rc.Error);
                    }
                }
            }



            //checkBox1.Checked = ws.ButtonState.A;
            //if (ws.ButtonState.A)
            //{
            //    if (rc.Connect())
            //    {
            //        if (!rc.Transmit("3AA", RoboControl.RobotType.RoboSapien_V2))
            //        {
            //            Console.WriteLine(rc.Error);
            //        }
            //    }
            //}
            //checkBox2.Checked = ws.ButtonState.B;
            //if (ws.ButtonState.B)
            //{
            //    if (rc.Connect())
            //    {
            //        if (!rc.Transmit("370", RoboControl.RobotType.RoboSapien_V2))
            //        {
            //            Console.WriteLine(rc.Error);
            //        }
            //    }
            //}
            //checkBox3.Checked = ws.ButtonState.Home;
            //if (ws.ButtonState.Home)
            //{
            //    if (rc.Connect())
            //    {
            //        if (!rc.Transmit("36B", RoboControl.RobotType.RoboSapien_V2))
            //        {
            //            Console.WriteLine(rc.Error);
            //        }
            //    }
            //}
            //if (ws.ButtonState.Plus)
            //{
            //    if (rc.Connect())
            //    {
            //        if (!rc.Transmit("369", RoboControl.RobotType.RoboSapien_V2))
            //        {
            //            Console.WriteLine(rc.Error);
            //        }
            //    }
            //}
            //if (ws.ButtonState.Minus)
            //{
            //    if (rc.Connect())
            //    {
            //        if (!rc.Transmit("386", RoboControl.RobotType.RoboSapien_V2))
            //        {
            //            Console.WriteLine(rc.Error);
            //        }
            //    }
            //}
            //if (ws.ButtonState.One)
            //{
            //    if (rc.Connect())
            //    {
            //        if (!rc.Transmit("368", RoboControl.RobotType.RoboSapien_V2))
            //        {
            //            Console.WriteLine(rc.Error);
            //        }
            //    }
            //}
            checkBox4.Checked = ws.ButtonState.Minus;
            checkBox5.Checked = ws.ButtonState.Plus;
            checkBox6.Checked = ws.ButtonState.One;
            checkBox7.Checked = ws.ButtonState.Two;
            wm.SetRumble(checkBox8.Checked);
            if (!ws.ButtonState.A)
            {
                label1.Text = ws.AccelState.Values.X.ToString();
                label2.Text = ws.AccelState.Values.Y.ToString();
                label3.Text = ws.AccelState.Values.Z.ToString();
            }

            btn_tilt_right.BackColor = Color.White;
            btn_tilt_left.BackColor = Color.White;
            btn_tilt_up.BackColor = Color.White;
            btn_tilt_down.BackColor = Color.White;
            btnUpL.BackColor = Color.White;
            btnUpR.BackColor = Color.White;
            btnDownL.BackColor = Color.White;
            btnDownR.BackColor = Color.White;

            //btn_tilt_right.Visible = false; //hide the buttons so the player cant see where the wii mote is tracking its movements, only show when the button is triggered to colour.

            up = down = left = right = upL = upR = downL = downR = false;

            if (ws.AccelState.Values.X > 0.7 && ws.AccelState.Values.Y > -0.3 && ws.AccelState.Values.Y < 0.3)
            {
                right = true;
            }
            else if (ws.AccelState.Values.X < -0.7 && ws.AccelState.Values.Y > -0.3 && ws.AccelState.Values.Y < 0.3)
            {
                left = true;
            }

            if (ws.AccelState.Values.X > -0.3 && ws.AccelState.Values.X < 0.3 && ws.AccelState.Values.Y > 0.3)
            {
                down = true;
            }
            else if (ws.AccelState.Values.X > -0.3 && ws.AccelState.Values.X < 0.3 && ws.AccelState.Values.Y < -0.7)
            {
                up = true;
            }

            if (((ws.AccelState.Values.Y >= -0.8) && (ws.AccelState.Values.Y <= -0.2)) && ((ws.AccelState.Values.X <= -0.2) && (ws.AccelState.Values.X >= -0.8)))
            {

                upL = true;
            }

            else if (((ws.AccelState.Values.Y >= -0.8) && (ws.AccelState.Values.Y <= -0.2)) && ((ws.AccelState.Values.X <= 0.8) && (ws.AccelState.Values.X >= 0.2)))
            {

                upR = true;
            }

            else if (((ws.AccelState.Values.Y >= 0.2) && (ws.AccelState.Values.Y <= 0.8)) && ((ws.AccelState.Values.X <= -0.2) && (ws.AccelState.Values.X >= -0.8)))
            {

                downL = true;

            }

            else if (((ws.AccelState.Values.Y >= 0.2) && (ws.AccelState.Values.Y <= 0.8)) && ((ws.AccelState.Values.X <= 0.8) && (ws.AccelState.Values.X >= 0.2)))
            {

                downR = true;
            }

            if (right) { btn_tilt_right.BackColor = Color.Pink; }
            if (right) { btn_tilt_right.Visible = true; } else { btn_tilt_right.Visible = false; }
            if (left) { btn_tilt_left.BackColor = Color.Green; }
            if (up) { btn_tilt_up.BackColor = Color.Yellow; }
            if (down) { btn_tilt_down.BackColor = Color.Purple; }
            if (upL) { btnUpL.BackColor = Color.Red; }
            if (upR) { btnUpR.BackColor = Color.Blue; }
            if (downL) { btnDownL.BackColor = Color.Orange; }
            if (downR) { btnDownR.BackColor = Color.Cyan; }

            if (upL == true)
            {
                pic_colour.BackColor = Color.Red;    //Up left
            }
            if (up == true)
            {
                pic_colour.BackColor = Color.Yellow; //Up
            }
            if (upR == true)
            {
                pic_colour.BackColor = Color.Blue;   //Up right
            }
            if (left == true)
            {
                pic_colour.BackColor = Color.Green;  //Left
            }

            if (right == true)
            {
                pic_colour.BackColor = Color.Pink;    //Right
            }

            if (downL == true)
            {
                pic_colour.BackColor = Color.Orange;     //Down Left
            }
            if (down == true)
            {
                pic_colour.BackColor = Color.Purple;     //Down
            }
            if (downR == true)
            {
                pic_colour.BackColor = Color.Cyan;     //Down right
            }

            Console.WriteLine(Math.Round(ws.AccelState.Values.X, 2) + ":" +
                 Math.Round(ws.AccelState.Values.Y, 2) + ":" +
                 Math.Round(ws.AccelState.Values.Z, 2));
            if (ws.ButtonState.One)
            {
                pic_colour.BackColor = Color.Gray;
            }
        }

    }

}

Open in new window

0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
"but when I run it, nothing happens"

My sample form had a Timer control on it to change the image in the picturebox.  It's in the ToolBox under the "Components" section.  Drop a Timer control on the form and it will appear below it.  Select that Timer control and then set the Enabled() property to true and the Interval() property to however fast you want the image to change (I used 1,000 to make it change once every second).  With the Timer control selected, click on the "lightning bolt" icon in the properties pane to get a list of its events.  Find the Tick() event and change the dropdown to the right so that it says "timer1_tick"...which will cause the code I included to run:  (you've already changed the picturebox name)

        private void timer1_Tick(object sender, EventArgs e)
        {
            pic_colour.Image = NextImage();
        }
0
 
deucalion0Author Commented:
idle mind that got it working, thank you! I saw the timer, but didnt use initiative! :(

What I was wondering was, I have the images as animated gifs, is there a reason why they only show as still images? Also, which is the best way to make this code work once, as in a levels scheme. Show one image, if correct then show the same image then another random one, if correct then show the same two images then a randome third one, so it continues to add another image to the previous ones, making the memory thing come into play.

I was thinking like a swtch case, I am not sure if thats best. I love C# but I always seem to do things teh hard way, any advice is much appreciated!!

Thank you!
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
Lemme check how to keep it as an animated GIF while an embedded resource...

For the "levels" issue, you would create another List<image> (or just store the index of the image with List<int>) and add each new image/index to it so you have a history.  You could use an Enumerator from the List to play them in the Tick() event, or simply use a counter variable and add a new entry when the count exceeds the number of entries in the List.
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
I added an Animated GIF as an embedded resource and it animated just fine with no code changes.  Not sure what you have different on your side.
0
 
deucalion0Author Commented:
idle mind, I will start again, I have no idea why it is not animating, I iwll figure it out, at least now  I know it can be done, that you have done it.

I will also research how to create a list or enum foir craeting levels with images, it may not be as tricky as it sounds.

Thank you for all your help.
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
Just to give you an idea, this shows each image in the sequence for one second with a three second delay before restarting:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private bool pause = false;
        private int CurIndex = -1;
        private int LastIndex = -1;
        private Random R = new Random();
        private List<int> sequence = new List<int>();
        private List<Bitmap> images = new List<Bitmap>();

        private void Form1_Load(object sender, EventArgs e)
        {
            string filter = ".gif".ToLower() ;
            foreach(string resource in System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceNames())
            {
                if (resource.ToLower().EndsWith(filter))
                {
                    images.Add(new Bitmap(System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(resource)));
                }
            }

            timer1.Interval = 1000;
            timer1_Tick(null, null);
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            if (pause)
            {
                pause = false;
                pictureBox1.Image = null;
                timer1.Interval = 3000;
                this.Text = "";
            }
            else
            {
                timer1.Interval = 1000;
                CurIndex++;
                if (CurIndex == sequence.Count)
                {
                    sequence.Add(NextImageIndex());
                    pictureBox1.Image = images[sequence[CurIndex]];
                    this.Text = (CurIndex + 1).ToString() + " of " + sequence.Count.ToString();

                    CurIndex = -1;
                    pause = true;
                }
                else
                {
                    pictureBox1.Image = images[sequence[CurIndex]];
                    this.Text = (CurIndex + 1).ToString() + " of " + (sequence.Count + 1).ToString();
                }
            }
        }

        private int NextImageIndex()
        {
            int index;
            do
            {
                index = R.Next(0, images.Count);
            } while (index == LastIndex);
            LastIndex = index;
            return index;
        }

    }
}

Open in new window

0
 
deucalion0Author Commented:
Idle mind, thank you so very much, that is pretty awesome! It works perfectly, I will use this to implement it into the levels, but you have saved me a lot of time it would have taken me weeks to do it the way you showed me.

Thank you I appreciate it!

I want to be able to program like that off the top of my head, I guess it may take years to get that good!

:)
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
Glad that was helpful.  Just keep programming and it will come eventually!  =)
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.