问题描述
我正在制作一个游戏,您需要点击某些对象(使用 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]);
}
}
解决方法
代替全局 x
和 y
变量,将 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
}
}
}