使用线程移动PictureBox位置

时间:2011-11-30 05:02:39

标签: c# multithreading visual-studio panel picturebox

我正在创造一个捕捉鸡蛋的捕捉游戏。在我的Panel子类中,我有这段代码

public void startGame()
    {
        Thread t = new Thread(new ThreadStart(game));
        t.Start();
    }

private void game()
    {
        bool run = true;

        int level = 1;

        while (run)
        {
            Egg egg = dropper.selectEgg();
            int speed = dropper.getSpeed(level);

            if (this.InvokeRequired)
            {
                this.Invoke(new MethodInvoker(delegate { 
                    this.Controls.Add(egg);
                    egg.setInitialLocation(dropper.selectPosition());

                    int x = egg.Location.X;
                    int y = egg.Location.Y;

                    while (y <= 1000)
                    {
                        egg.setCurrentLocation(x, dropper.drop(egg, speed));
                        y = egg.Location.Y;
                    }
                }));
            }
            else
            {
                this.Controls.Add(egg);
                egg.setInitialLocation(dropper.selectPosition());

                int x = egg.Location.X;
                int y = egg.Location.Y;

                while (y <= 1000)
                {
                    egg.setCurrentLocation(x, dropper.drop(egg, speed));
                    y = egg.Location.Y;
                }
            }
            Thread.Sleep(3000);
        }
    }

Egg是PictureBox的子类,我想在循环中改变它的位置,所以看起来鸡蛋正在下降。我使用此方法使用EggDropper子类:

public int drop(Egg egg, int speed)
    {

        int y = egg.Location.Y;
        y += speed;

        return y;
    }

但不知何故,我没有看到任何Egg对象掉落。我猜这是访问PictureBox子类的线程的问题?但我似乎无法在网上找到任何解决方案。

非常感谢你。

1 个答案:

答案 0 :(得分:1)

您在主UI线程上调用drop。这会快速运行一个循环,增加y直到它> 1000.当这个循环运行时,UI无法更新,因此当drop完成并且UI可以再次运行其消息循环时,您将看到的是屏幕底部的蛋。

解决方案是将drop更改为仅减少y一次,然后将控制权返回到game循环。您还必须将y <= 1000检查移至此循环。


<强>更新

您的“步骤”是while( run )循环的迭代 - 您可以使用Sleep来控制动画。您必须在每个“步骤”中仅对egg.Location.Y进行一次更新 - 不要在每个“步骤”上运行整个while( y <= 1000 )循环。