Newb question: drawing a sprite

C

Carl

I'm new to C#, and I have only limited programming experience. I've
been doing the video tutorials at MS's website, and they're very
helpful, but I decided to experiment with GDI+ and have gotten stuck.
I'm trying to draw a bitmap on my main form and then to draw a second
bitmap, as if it were a sprite (e.g., a "unit" in a wargame), on top of
the first. The main form renders fine; I handle the Paint event by
creating a temporary Graphics object, and at the same time I grab that
object so that I can use it again to draw the sprite later.

But when I try to draw the sprite, the program compiles but crashes at
runtime. It says my Point parameter is invalid. The sprite itself and
the Pointer seem to contain valid data when this happens. This happens
even if I comment out the DrawImage call that paints the main form.
What am I doing wrong?

Here's a snippet of code. Be gentle; I'm new at this. :) This code is
in my one and only Form, Form1:

public void Form1_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
SpriteGraphics = g;
Image img = Image.FromFile("d:/Artistic
Applications/Blue.jpg"); // background for the form
g.DrawImage(img, 150, 150); // this works fine
}

public Graphics SpriteGraphics; /* to grab and reuse the
Graphics object for drawing the sprite; is this the right technique? */

class Sprite
{
protected Bitmap _unit;

public Sprite(string UnitFileName)
{
_unit = new Bitmap(UnitFileName);
}

public Bitmap Unit
{
get { return _unit; }
set { _unit = value; }
}

Point keypoint = new Point(200, 200);

public void Draw(Graphics graphics)
{
graphics.DrawImage(Unit, keypoint ); /* crashes here.
Unit and keypoint both seem to contain the right values, but crashola.
*/
}
}

private void button1_Click(object sender, EventArgs e)
{
string tempfilename = "d:/Artistic
Applications/Enterprise.jpg"; // the Sprite bitmap
Sprite Enterprise = new Sprite(tempfilename);
Enterprise.Draw(SpriteGraphics);

}
 
L

Lenard Gunda

Hi Carl,

The main problem here is that you try to cache the Graphics object that
is given to your Paint event. That object would be only valid during
that event, so you should not save it.

Generally speaking you should not save the Graphics object at all. You
should create that when you are drawing, and then call Dispose() on it
or use the one provided with the Paint event.

If you want to cache something, like the background where you will be
drawing, you should save a Bitmap, that contains that background. When
you then need it, you can draw onto that bitmap.

Another problem would be, that even though you draw during your Click
event, the next time Paint is called (== the next time your window or
portion of it requires redrawing) your sprite will be erased.

Anyway, to quickly make your code working ...

Do not cache the Graphics object in the Form1_Paint event handler. Then,
in button1_Click you can get a Graphics objects as follows:

Graphics g = Graphics.FromHwnd ( this.Handle );

Make sure to call Dispose() on it, when you are done with it. Or you
could put that into a using statement. For example:

private void button1_Click(object sender, EventArgs e)
{
string tempfilename = "d:/Artistic
Applications/Enterprise.jpg"; // the Sprite bitmap
Sprite Enterprise = new Sprite(tempfilename);
using ( Graphics g = Graphics.FromHwnd ( this.Handle ) )
{
Enterprise.Draw(g);
}
}

Hope this helps,

-Lenard
 
C

Carl

Many thanks for your quick reply. I'll give that a try and, knowing me,
I'll be back here with more questions. :p Thanks again.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top