|
Intro
This tutorial might be a bit tricky for some (you might wonder what
the point of this is).
Alright, let's get started.
Now go to form1_paint and type in
e.Graphics.DrawLine(New Pen(Color.Black), 0,
0, 10, 10)
Run it, you should see a line going from (0,0) to (10,10). Easy
enough.
Create a new project and create a new class called GameClass.
Now, let's go to GameClass, and add a constructor:
Dim frm as Form
Public Sub New(GameForm as Form)
frm = GameForm
End Sub
Easy enough.
Now, when programming games, we
usually don't want our "game code" in form1. We usually want some
other class to handle that for us (in this case GameClass). So
create a Gameclass.Paint event:
Public Sub Paint(e as PaintEventArgs)
e.Graphics.DrawLine(New Pen(Color.Red), 20, 20, 30, 30)
End Sub
We want our GameClass to do the
painting for us, and that's what we're doing.
In form1:
Dim game as New Gameclass(Me)
In form1_paint, add:
Game.Paint(e)
Now run and you should see two lines, a black one and a red one (in
different places). Our goal is accomplished. Now our drawing code
can be kept inside gameclass and we don't have to use form1's paint
event.
AddHandler
However that's a waste of
memory. A total waste of memory. Why? Ok, think about programming an
actual game for a second. How many times are you going to call the
paint event per second? Hundreds of times (depending on how fast the
PC is of course). An average first person shooter (3d) gets 30 FPS
(meaning that 30 frames are being rendered per second). Let's go
with this 30 frames per second thing. If we pass the e
argument 30 times per second into GameClass - we're really wasting
memory if you think about it. As a matter of fact it's a complete
waste of memory.
How do we get around this? This
is where AddHandler comes in. In form1_paint delete the line that
says Game.Paint(e).
Now go to the constructor of
GameClass and type in the following:
AddHandler
Gameform.Paint, AddressOf Me.Paint
<Ignore the error you get
when you type this in>
This is basically saying, whenever the Paint event in the form is
called, let the Paint event in this class be called too.
You might wonder what AddressOf does. The word Address here
refers to the memory address. Just like you have a house address or
an IP address or an email address, memory has an address too. When
your program is compiled and when it runs, all the subs that you
create are there somewhere on your RAM. This AddHandler statement
doesn't implicitly type in ("behind the scenes") Game.Paint in the
paint event of form1. What it does is much more efficient - it calls
the gamecalss.paint event directly through memory using the
memory address provided, making this a much faster operation. If you
don't understand this, all you need to know is that this is much
faster than calling the sub directly.
Now about that error.
Method 'Public Sub Paint(e as PaintEventArgs)' does not have the
same signature as delegate 'Delegate Sub PaintEventHandler(sender As
Object, e As System.Windows.Forms.PaintEventArgs)'.
Uhh, all you have to do is change the Paint sub's arguments.... like
this:
Public Sub Paint(ByVal sender As Object, ByVal
e As System.Windows.Forms.PaintEventArgs)
It's doing this to make sure that the arguments match with
the form1_Paint arguments.
Wrap Up
As I said before, you might
wonder what the point of this is. The point of it is to speed up
your application first of all.
Also, here are some usages for it. Besides being able to draw in
GameClass, let's say you want GameClass to also handle key movement.
Heh heh. There you go! All you have to do is AddHandler for that. As
long as you have the Public Sub New(GameForm
as Form) argument, you're fine - you can use any of the
form's methods.
You'll find use for this in the RPG Programming Tutorial Series,
especially when I do the Event-Driven Programming tutorial.
There is no
source code for this tutorial as it is relatively short |