views:

205

answers:

3

Here's the problem:

I've been working on a little game where monsters bounce off the walls (edges) of the main form, and it's going swimmingly, but it only paints one of each type of monster when it should be iterating through a list of each of them and calling their OnPaint and Move methods:

private void Pacmen_Paint(object sender, PaintEventArgs e)
{
    Graphics g = e.Graphics;
    Rectangle rect = e.ClipRectangle;

    g.Clear(backgroundColor);

    foreach (Hydra h in hydraList) {
     h.OnPaint(e);
     h.Move(e);
    } // end foreach

    foreach (Ghost gh in ghostList) {
     gh.OnPaint(e);
     gh.Move(e);
    } // end foreach
}

Here's the ghost's methods:

public void OnPaint(PaintEventArgs e)
{
    Graphics g = e.Graphics;
    g.SmoothingMode = SmoothingMode.HighQuality;

    GraphicsPath path = new GraphicsPath();
    SolidBrush fillBrush = new SolidBrush(color);
    SolidBrush eyeBrush = new SolidBrush(Color.Black);

    path.AddArc(pos, (float)180, (float)180);
    path.AddLine((float)pos.Right, (float)(pos.Y + pos.Height / 2),
     (float)pos.Right, (float)pos.Bottom);
    path.AddLine((float)pos.Right, (float)pos.Bottom,
     (float)(pos.X + pos.Width / 2), (float)(pos.Bottom - radius / 2));
    path.AddLine((float)(pos.X + pos.Width / 2), (float)(pos.Bottom - radius / 2),
     (float)pos.Left, (float)pos.Bottom);
    path.AddLine((float)pos.Left, (float)pos.Bottom,
     (float)pos.Left, (float)(pos.Y + pos.Height / 2));

    g.FillPath(fillBrush, path);
    g.FillEllipse(eyeBrush, new Rectangle(pos.X + pos.Width / 4, pos.Y + pos.Height / 4, radius / 4, radius / 5));
    g.FillEllipse(eyeBrush, new Rectangle(pos.X + 3 * pos.Width / 4, pos.Y + pos.Height / 4, radius / 4, radius / 5));
} // end OnPaint

public void Move(PaintEventArgs e)
{
    pos.Offset(xSpeed, ySpeed);
}

Any ideas why only one would show up? Thanks!

A: 

You are calling the OnPaint for each hydra and ghost by using the same PaintEventArgs passed to Pacmen_Paint. Maybe the OnPaint methods are not using the correct Graphics object then.

Konamiman
I presume that `Pacmen_Paint` is the actual `Paint` event handler, so `Graphics` instance looks like the right one to use for all drawing.
Groo
Ok, I was assuming that every monster had its own Graphics object.
Konamiman
A: 

Are you sure you're giving the characters individual starting positions and speed? Maybe they are all painting, but on exactly the same spot?

danbystrom
..................Bingo.
justin
lol. You should mark danbystrom's answer as the accepted solution.
Penfold
A: 

Try replacing the body of your Ghost method with simple:

Console.WriteLine("Ghost at " +  pos.X + ", " + pos.Y);

Then run the app and check the Output window in VS to see where they are drawn exactly.

Other notes (others may have commented already):

  1. Use the using construct to dispose Brushes and other disposable graphics objects inside the Paint method, or cache them and make your Ghost and Hydra objects implement IDisposable to dispose them when they are not needed anymore.

  2. You may get some speed improvements if you simply create a Bitmap field containg an already drawn ghost, and then simply draw it inside Paint. That way you only need to create your graphic objects once (inside using construct, again).

Groo
Thanks, turns out they were drawing on top of each other... and I thought they were all random.
justin
Glad you found the problem. You should also consider about other remarks to make your app work faster and use less memory.
Groo