Link to home
Start Free TrialLog in
Avatar of deucalion0
deucalion0

asked on

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!
Avatar of Carl Tawn
Carl Tawn
Flag of United Kingdom of Great Britain and Northern Ireland image

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.
Avatar of deucalion0
deucalion0

ASKER

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!
SOLUTION
Avatar of Carl Tawn
Carl Tawn
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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

"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();
        }
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!
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.
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.
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.
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

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!

:)
Glad that was helpful.  Just keep programming and it will come eventually!  =)