Animation In Visual Basic .NET: Interacting with Objects
In previous Animation articles we've covered many different methods and aspects of the animation. This article looks at interacting with objects on a playing field. As usual the article will use a game as a base for the code. This time we will work on a simple Solitaire game base, and as usual I will only be doing the animation and leave it up to you to complete the rest of the game.
When you think about Solitaire, you don't necessarily think of animation. However there is an aspect of animation that is very heavily used in Solitaire — Object interaction. We will be looking at interaction with several objects, with some that may be overlapping each other.
Not long ago there was a thread on CodeGuru where someone was looking for a method to detect mouse movement over different areas of an image, clickable Hotspots, so to speak. There are many ways to achieve the same results, and the method shown here might not be ideal for all applications, but is a good tool to have in your box of tricks.
The Graphics for Our Animation Example
Let's start with the graphics. Firstly let me say that, yes, I am aware that there is a DLL with all the card graphics in it that you can use, however I decided to use image files so that you can replace them with any that you choose. There are 60 odd images, including all the playing cards, two jokers and several Backings. So the first task is to load the images.
Private Cards() As Image
Private Backs() As Image
Private CardSize As Size
Private Sub BuildCards()
ReDim Cards(53)
ReDim Backs(1)
Dim Tmp As Integer
Dim Path As String = Application.StartupPath
For Tmp = 0 To 53
Cards(Tmp) = New Bitmap(Path & "\card\" & (Tmp + 1).ToString & ".png")
Next
For Tmp = 0 To 1
Backs(Tmp) = New Bitmap(Path & "\card\b" & (Tmp + 1).ToString & "fv.png")
Next
'Lets use one of the cards to get the size..
CardSize = Cards(0).Size
End Sub
But now there is additional information that is needed. We want the draw order of the cards, so that one card can be put on top of another. We also want to know if the card is not shown, or turned over, and then we want the position of the card. And all of this can be initialized with the card loading, so our above sub can be expanded a little.
Private Cards() As Image
Private Backs() As Image
Private CardPos() As Point
Private CardShow() As ShowMode
Private DrawOrder() As Integer
Private CardSize As Size
Private MyBrushs() As SolidBrush
Private Enum ShowMode
Hidden
Show
Back
End Enum
Private Sub BuildCards()
ReDim Cards(53)
ReDim Backs(1)
ReDim CardShow(53)
ReDim CardPos(53)
ReDim MyBrushs(53)
ReDim DrawOrder(53)
Dim Tmp As Integer
Dim Path As String = Application.StartupPath
For Tmp = 0 To 53
Cards(Tmp) = New Bitmap(Path & "\card\" & (Tmp + 1).ToString & ".png")
MyBrushs(Tmp) = New SolidBrush(Color.FromArgb(&HFF000000 Or (Tmp + 1)))
DrawOrder(Tmp) = Tmp
Next
For Tmp = 0 To 1
Backs(Tmp) = New Bitmap(Path & "\card\b" & (Tmp + 1).ToString & "fv.png")
Next
'Lets use one of the cards to get the size..
CardSize = Cards(0).Size
End Sub
At the same time, we are also setting up a color brush for our hotspots. For each unique card we have a unique colored Hotspot image, I used RGB colors 1-54 for the 54 unique cards and RGB 0 for the board.
The Board
Now we have the cards in memory, you can now start building the game board. We will be using the Standard Green that most people associate with card games for the background. So we have our Form, and I normally like to place a picturebox on the form, however you can use the form's image too. So our game board is this image, and we will use it to build our Buffer. Buffers is explained in full on previous articles so I'm not going into in here
Private Buffer As Image
Private BufferG As Graphics
Private HotSpots As Image
Private HotSpotsG As Graphics
Private Boardsize As Rectangle
Private Sub InitBuffer()
Buffer = New Bitmap(Board.Width, Board.Height)
BufferG = System.Drawing.Graphics.FromImage(Buffer)
Boardsize.Size = Buffer.Size
HotSpots = New Bitmap(Board.Width, Board.Height)
HotSpotsG = System.Drawing.Graphics.FromImage(HotSpots)
End Sub
As you may have noticed, I'm initializing two Buffers, The second one will not be drawn but used for the hotspot detection. When a card is drawn on the board's buffer, the Hotspot image will be drawn in the same position in the second buffer. Of course now we need some code to draw these images.
Private Sub DoDisplay()
BuildBuffer()
ShowCards()
Board.Image = Buffer
End Sub
Private Sub BuildBuffer()
BufferG.FillRectangle(Brushes.Green, Boardsize)
HotSpotsG.FillRectangle(BackBrush, Boardsize)
End Sub
Private Sub ShowCards()
Dim Tmp As Integer
Dim Order As Integer
For Tmp = 0 To 53
Order = DrawOrder(Tmp)
Select Case CardShow(Order)
Case ShowMode.Show
BufferG.DrawImage(Cards(Order), CardPos(Order))
HotSpotsG.FillRectangle(MyBrushs(Order), CardPos(Order).X, _
CardPos(Order).Y, CardSize.Width, _
CardSize.Height)
Case ShowMode.Back
BufferG.DrawImage(Backs(0), CardPos(Order).X, CardPos(Order).Y, _
CardSize.Width, CardSize.Height)
HotSpotsG.FillRectangle(MyBrushs(Order), CardPos(Order).X, _
CardPos(Order).Y, CardSize.Width, _
CardSize.Height)
Case ShowMode.Hidden
If MouseCard - 1 = Order Then
BufferG.DrawImage(Cards(Order), CardPos(Order))
End If
End Select
Next
End Sub
Here I've split the key codes into several different subs so that it's easier to see what's doing what.
- BuildBuffer simply paints our initial background, so we have a clean image to place cards on.
- ShowCards paints each card on the buffer in the order listed in the Cardshow Array, with bottom card first.
- Dodisplay pulls it all together, and places the buffer image on the form.

Comments
There are no comments yet. Be the first to comment!