如何为每个 PictrueBox 单独使用 make 方法

问题描述

我正在制作一个游戏,您需要点击某些对象(使用 PictureBoxes),这些对象以类似 DVDscreensaver 的方式移动(边缘反弹)。问题是当我在屏幕上有超过 1 个 PictureBox 时。当一个接触边缘时,所有其他 PictureBoxes 将它们的 X 或 Y 速度值更改为负值并开始移动,就好像它们接触到边缘一样。我怎样才能让它为每个 PictureBox 单独工作?

运动引擎:

private void MovementTimer_Tick(object sender,EventArgs e) //movement engine
    {
        foreach (Control z in this.Controls)
        {
            if (z is PictureBox)
            {
                if (z.Location.X < 0 || z.Location.X + z.Width > Size.Width) //bouncing effect in horizontal
                {
                    x = -x;
                }
                if (z.Location.Y < 0 || z.Location.Y + z.Height > Size.Height) //bouncing effect in vertical
                {
                    y = -y;
                }
                z.Location = new Point(z.Location.X + x,z.Location.Y + y);
            }
        }
    }

生成图片框:

private void InitializePictureBox()
    {
        PictureBox[] pb = new PictureBox[12];
        for (int i = 0; i < 12; i++)
        {
            x = rng.Next(10,16) * (rng.Next(0,2) * 2 - 1); //veLocity in horz dim
            y = rng.Next(10,2) * 2 - 1);  //veLocity in vert dim
            locx = rng.Next(100,500); //random locations
            locy = rng.Next(100,500);
            pb[i] = new PictureBox(); 
            pb[i].Image = Image.FromFile("../red/rbr.png");
            pb[i].Location = new Point(locx,locy);
            pb[i].SizeMode = PictureBoxSizeMode.StretchImage;
            Controls.Add(pb[i]);
        }
    }

解决方法

代替全局 xy 变量,将 Point 存储在每个 PictureBox 的 .Tag 属性中,以便它们每个都有自己可以独立更改的值彼此。

所以在您的 InitializePictureBox() 方法中:

private void InitializePictureBox()
{
    PictureBox[] pb = new PictureBox[12];
    for (int i = 0; i < 12; i++)
    {
        x = rng.Next(10,16) * (rng.Next(0,2) * 2 - 1); //velocity in horz dim
        y = rng.Next(10,2) * 2 - 1);  //velocity in vert dim
        locx = rng.Next(100,500); //random locations
        locy = rng.Next(100,500);
        pb[i] = new PictureBox(); 
        pb[i].Image = Image.FromFile("../red/rbr.png");
        pb[i].Location = new Point(locx,locy);
        pb[i].SizeMode = PictureBoxSizeMode.StretchImage;

        pb[i].Tag = new Point(x,y); // <-- Store a Point() in the Tag()!

        Controls.Add(pb[i]);
    }
}

然后在您的计时器中:

private void MovementTimer_Tick(object sender,EventArgs e) //movement engine
{
    foreach (Control z in this.Controls)
    {
        if (z is PictureBox)
        {

            Point pt = (Point)z.Tag; // <-- cast Tag() back to a Point()
            // Note the use of "pt" in the code below:
            if (z.Location.X < 0 || z.Location.X + z.Width > Size.Width) //bouncing effect in horizontal
            {
                pt = new Point(-pt.X,pt.Y);
            }
            if (z.Location.Y < 0 || z.Location.Y + z.Height > Size.Height) //bouncing effect in vertical
            {
                pt = new Point(pt.X,-pt.Y);
            }
            z.Location = new Point(z.Location.X + pt.X,z.Location.Y + pt.Y);
            z.Tag = pt; // <-- put updated Point() back in the Tag
        }
    }
}