I am creating a catching game where eggs are dropped. In my Panel subclass, I have this code
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 is a subclass of PictureBox and I want to change its location on loop so it looks like the eggs are dropping. I use the EggDropper subclass with this method:
public int drop(Egg egg, int speed)
{
int y = egg.Location.Y;
y += speed;
return y;
}
but somehow, I don’t see any of the Egg objects dropping. I’m guessing it is a problem with the thread accessing the PictureBox subclass? But I can’t seem to find any solution online.
Thank you very much in advance.
You call
dropon the main UI thread. This quickly runs a loop that incrementsyuntil it is > 1000. The UI cannot update while this loop is running, so all you will see is the egg at the bottom of the screen whendropfinishes and the UI can run its message loop again.The solution is to change
dropto just decrementyonce and then return control to yourgameloop. You will have to move they <= 1000check to this loop as well.UPDATE:
Your “step” is an iteration of the
while( run )loop – that’s where you have theSleepto control the animation. You must only make one update toegg.Location.Yon each “step” – don’t run the wholewhile( y <= 1000 )loop on each “step”.