English 中文(简体)
Windows Forms / C#: only one object instance out of many will paint
原标题:

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!

最佳回答

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

问题回答

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.

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).





相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

热门标签