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 & "cardb" & (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 & "cardb" & (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.

More by Author

Must Read