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

How to make method be used individually for every PictrueBox

我正在制作一款游戏,您需要点击某些对象(使用 PictureBoxes),这些对象以类似 DVD 屏幕保护程序的方式移动(边缘弹跳)。问题是当我在屏幕上有超过 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, 16) * (rng.Next(0, 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, 16) * (rng.Next(0, 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
        }
    }
}