11 Replies - 10767 Views - Last Post: 26 November 2011 - 07:26 PM Rate Topic: -----

#1 TheCodeNoob   User is offline

  • New D.I.C Head

Reputation: -12
  • View blog
  • Posts: 36
  • Joined: 21-November 11

Interesting (and frustrating) glitch in homemade MTG simulator

Posted 21 November 2011 - 09:32 PM

Recently I've been working on a homemade simulator for Magic: the gathering matches since I can't seem to find one that is both easy to operate and free to use (and because I need something to work on for my Visual Basic class's final project). For the most part, I've been able to get rather far into it and have been able to use Google to solve most of the roadbumps I've found. However, the other day I noticed a glitch that seems to occur every time a new card is created and I try to display information about it. Since the details of the problem seemed far too specific for a Google search to remedy, I've come here hoping to get some advice on what to do.

Below is the code for the card class I created for each card generated by this program:

Public Class Card
    Inherits PictureBox
    Dim off As Point
    Dim FullArt As Bitmap
    Dim TapStatus As Boolean
    Dim RotatedImage As Bitmap
    Dim LoyaltyCounters, PlusCounters, MinusCounters, ChargeCounters As Integer
    Dim EnlargedCardImage As New PictureBox
    Dim LoyaltyDisplay, PlusDisplay, MinusDisplay, ChargeDisplay As New Label
    
    Public Sub New(ByVal Location As Point, ByVal Size As Point, ByVal Sprite As Bitmap, ByVal FullArt As Bitmap)
        Me.Image = Sprite
        RotatedImage = Sprite
        Me.FullArt = FullArt
        Me.Location = Location
        Me.Size = Size
    End Sub

    Private Sub obj1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseDown
        'This is part of code used to move the card generated with the button
        off.X = MousePosition.X - sender.Left
        off.Y = MousePosition.Y - sender.Top
        Me.BringToFront() 

        'This part of the code is used to create a context menu for adding counters to a card if the right mouse button is clicked
        If e.Button = MouseButtons.Right Then
            Dim CardActionMenu As New ContextMenuStrip
            Dim AddCounters As New ToolStripMenuItem
            AddCounters.Text = "Add Counters"
            CardActionMenu.Items.Add(AddCounters)
            CardActionMenu.Show(sender, New Point(e.X, e.Y))
            AddHandler AddCounters.Click, AddressOf AddCountersToCard
        End If

    End Sub

    Private Sub AddCountersToCard()
        PlusCounters += 1

    End Sub

    Private Sub obj1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove
        'Used to drag the card across the screen with the mouse
        If e.Button = MouseButtons.Left Then
            sender.Left = MousePosition.X - off.X
            sender.Top = MousePosition.Y - off.Y
        End If

        'My lousy attempt at creating an artificial boundry that cards of this class can't cross
        If (MousePosition.X + 74) - off.X > 624 Then
            sender.left = 624 - 98
            sender.visible = False
        End If
        sender.visible = True
    End Sub

    Private Sub Tap(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.DoubleClick
        'Taps and untaps the card (As in turning it horizontally when doubleclicked and vertically again when doubleclicked again)

        If TapStatus = False Then
            RotatedImage.RotateFlip(RotateFlipType.Rotate90FlipXY)
            Me.Image = RotatedImage
            TapStatus = True
        ElseIf TapStatus = True Then
            RotatedImage.RotateFlip(RotateFlipType.Rotate270FlipXY)
            Me.Image = RotatedImage
            TapStatus = False
        End If
        Dim placeholder As Integer = Me.Width
        Me.Width = Me.Height
        Me.Height = placeholder
    End Sub

    Private Sub ShowEnlargedImage(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.MouseHover
        'Used to dynamically create the labels and picturebox used to display the card's information. This is the information that I believe
        'may be responsible for the information flip-flop when the second card is made.

        Dim ObjectLocation As New Point(661, 12)
        Dim EnlargedCardImageSize As New Point(314, 447)

        EnlargedCardImage.Location = ObjectLocation
        EnlargedCardImage.Size = EnlargedCardImageSize
        EnlargedCardImage.Image = FullArt
        Form1.Controls.Add(EnlargedCardImage)

        ObjectLocation.X = 658
        ObjectLocation.Y = 480
        PlusDisplay.Location = ObjectLocation
        PlusDisplay.Text = "+1/+1 Counters: " & PlusCounters.ToString
        Form1.Controls.Add(PlusDisplay)

        ObjectLocation.X = 882
        ObjectLocation.Y = 480
        MinusDisplay.Location = ObjectLocation
        MinusDisplay.Text = "-1/-1 Counters: " & MinusCounters.ToString
        Form1.Controls.Add(MinusDisplay)

        ObjectLocation.X = 658
        ObjectLocation.Y = 526
        LoyaltyDisplay.Location = ObjectLocation
        LoyaltyDisplay.Text = "Loyalty Counters: " & LoyaltyCounters.ToString
        Form1.Controls.Add(LoyaltyDisplay)

        ObjectLocation.X = 871
        ObjectLocation.Y = 526
        ChargeDisplay.Location = ObjectLocation
        ChargeDisplay.Text = "Charge Counters: " & ChargeCounters.ToString
        Form1.Controls.Add(ChargeDisplay)
    End Sub
End Class


And this is the code for the button I created to "draw" the cards (Added because the student aid said that every bit of code I can post here will help).

Public Class Form1
    Dim type As Boolean

    Private Sub GenerateCard() Handles Button1.Click
        'Forest, Island, Blue_Card_Sprite, and Green_Card_Sprite are the names of resources on file

        'Forest the full art image of a Forest card in Magic: the Gathering as is Island for an Island card. the sprites are colored
        'representations of the cards that can be moved around, tapped, etc.

        'The idea was that "Type" was suppose to cause the button to alternate between generating a forest card and an island card.

        Dim CardLocation As New Point(30, 30)
        Dim CardSize As New Point(51, 71)
        Dim FullImage As String = " "
        Dim Sprite As String = " "
        If type = False Then
            FullImage = "Forest"
            Sprite = "Green_Card_Sprite"
            type = True
        ElseIf type = True Then
            FullImage = "Island"
            Sprite = "Blue_Card_Sprite"
            type = False
        End If
        Dim NewCard As New Card(CardLocation, CardSize, My.Resources.ResourceManager.GetObject(Sprite), My.Resources.ResourceManager.GetObject(FullImage))
        Me.Controls.Add(NewCard)
    End Sub
End Class


What seems to specifically happen is that, the first time the button is pressed to generate a card, everything is fine. Hovering over the card displays the right full art picture meant to be associated with the card and displays the proper amount of counters on the card (which is 0 when it's created). When you right-click the card, the context menu appears as it should and the "add counters" option (currently the only option) adds a counter to the card which is properly displayed by the counter label.

However, when the second card is created and the mouse hovers over it even once, the information from the first card (the full art image and the amount of counters on it) become associated with the second card. Afterwords, when I hover over the first card with my mouse, the full art image and the number of counters on the card become that of what SHOULD be on the second card (in this case, an island with no counters on it despite having the sprite of a forest). Additionally, whenever I try to add counters on one card while there are two on the form, it adds the counters to the other card regardless of which one I tried adding the counters to.

As for what happens when there are more than two cards on the form, even I don't know what's going on exactly.

Things I've tried ranged from referencing all the variables I can as me.(whatever the variable's name is), changing the level the picturebox and labels are declared to inside the mousehover sub (which causes the image and values of when the first card was created to be permanently ingrained in that spot), creating the labels and image in the "New" sub, and even trying to create the picturebox/labels in the form class. None of these things, however, have seemed to work.

If anyone has any ideas how to fix this glitch, I'd be more than happy to try them out. Or, if anyone has suggestions for how I can display this card information more easily, that would be welcome as well.

Is This A Good Question/Topic? 0
  • +

Replies To: Interesting (and frustrating) glitch in homemade MTG simulator

#2 janne_panne   User is offline

  • WinRT Dev
  • member icon

Reputation: 428
  • View blog
  • Posts: 1,047
  • Joined: 09-June 09

Re: Interesting (and frustrating) glitch in homemade MTG simulator

Posted 22 November 2011 - 02:20 AM

Your problem is that you just add controls never removing them. This kind of programming will lead to lots of problems at some point. Also when adding handler, you should remove it when you no longer need the object.

Here is your code with some fixes made, now it seems to be working the way you want it to. (I had to edit some values to make it run, like the resources on GenerateCard method, you can change those back if you want to)

Form1:
Public Class Form1
    Dim type As Boolean

    Private card As Card

    Private Sub GenerateCard()
        If card IsNot Nothing Then
            card.Dispose()
            Controls.Remove(card)
            card = Nothing
        End If
        'Forest, Island, Blue_Card_Sprite, and Green_Card_Sprite are the names of resources on file

        'Forest the full art image of a Forest card in Magic: the Gathering as is Island for an Island card. the sprites are colored
        'representations of the cards that can be moved around, tapped, etc.

        'The idea was that "Type" was suppose to cause the button to alternate between generating a forest card and an island card.

        Dim CardLocation As New Point(30, 30)
        Dim CardSize As New Point(200, 200)
        Dim FullImage As Bitmap = Nothing
        Dim Sprite As Bitmap = Nothing
        If type = False Then
            FullImage = My.Resources.Resource1.Forest
            Sprite = My.Resources.Resource1.Forest
            type = True
        ElseIf type = True Then
            FullImage = My.Resources.Resource1.Island
            Sprite = My.Resources.Resource1.Island
            type = False
        End If
        card = New Card(CardLocation, CardSize, Sprite, FullImage)
        Me.Controls.Add(card)
    End Sub

    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
        GenerateCard()
    End Sub
End Class



Card:
The dispose might be a bit of overkill, maybe not that much of dispose calls and setting object to nothing is required but on the other hand, it doesn't hurt to make sure everything is gone.
Public Class Card
    Inherits PictureBox

    Protected Overrides Sub Dispose(disposing As Boolean)
        FullArt.Dispose()
        FullArt = Nothing
        RotatedImage.Dispose()
        RotatedImage = Nothing
        EnlargedCardImage.Dispose()
        EnlargedCardImage = Nothing
        LoyaltyDisplay.Dispose()
        LoyaltyDisplay = Nothing
        PlusDisplay.Dispose()
        PlusDisplay = Nothing
        MinusDisplay.Dispose()
        MinusDisplay = Nothing
        ChargeDisplay.Dispose()
        ChargeDisplay = Nothing

        RemoveHandler AddCounters.Click, AddressOf AddCountersToCard
        AddCounters.Dispose()
        AddCounters = Nothing
        CardActionMenu.Dispose()
        CardActionMenu = Nothing
        Me.Controls.Clear()
        MyBase.Dispose(disposing)
    End Sub

    Dim off As Point
    Dim FullArt As Bitmap
    Dim TapStatus As Boolean
    Dim RotatedImage As Bitmap
    Dim LoyaltyCounters, PlusCounters, MinusCounters, ChargeCounters As Integer
    Dim EnlargedCardImage As New PictureBox
    Dim LoyaltyDisplay, PlusDisplay, MinusDisplay, ChargeDisplay As New Label

    Dim CardActionMenu As New ContextMenuStrip
    Dim AddCounters As New ToolStripMenuItem

    Public Sub New(ByVal Location As Point, ByVal Size As Point, ByVal Sprite As Bitmap, ByVal FullArt As Bitmap)
        Me.Image = Sprite
        RotatedImage = Sprite
        Me.FullArt = FullArt
        Me.Location = Location
        Me.Size = Size

        AddCounters.Text = "Add Counters"
        CardActionMenu.Items.Add(AddCounters)
        AddHandler AddCounters.Click, AddressOf AddCountersToCard
    End Sub

    Private Sub obj1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseDown
        'This is part of code used to move the card generated with the button
        off.X = MousePosition.X - sender.Left
        off.Y = MousePosition.Y - sender.Top
        Me.BringToFront()

        'This part of the code is used to create a context menu for adding counters to a card if the right mouse button is clicked
        If e.Button = MouseButtons.Right Then
            CardActionMenu.Show(sender, New Point(e.X, e.Y))
        End If

    End Sub

    Private Sub AddCountersToCard(sender As Object, e As System.EventArgs)
        PlusCounters += 1
    End Sub

    Private Sub obj1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove
        'Used to drag the card across the screen with the mouse
        If e.Button = MouseButtons.Left Then
            sender.Left = MousePosition.X - off.X
            sender.Top = MousePosition.Y - off.Y
        End If

        'My lousy attempt at creating an artificial boundry that cards of this class can't cross
        If (MousePosition.X + 74) - off.X > 624 Then
            sender.left = 624 - 98
            sender.visible = False
        End If
        sender.visible = True
    End Sub

    Private Sub Tap(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.DoubleClick
        'Taps and untaps the card (As in turning it horizontally when doubleclicked and vertically again when doubleclicked again)

        If TapStatus = False Then
            RotatedImage.RotateFlip(RotateFlipType.Rotate90FlipXY)
            Me.Image = RotatedImage
            TapStatus = True
        ElseIf TapStatus = True Then
            RotatedImage.RotateFlip(RotateFlipType.Rotate270FlipXY)
            Me.Image = RotatedImage
            TapStatus = False
        End If
        Dim placeholder As Integer = Me.Width
        Me.Width = Me.Height
        Me.Height = placeholder
    End Sub

    Private Sub ShowEnlargedImage(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.MouseHover
        'Used to dynamically create the labels and picturebox used to display the card's information. This is the information that I believe
        'may be responsible for the information flip-flop when the second card is made.

        Dim ObjectLocation As New Point(661, 12)
        Dim EnlargedCardImageSize As New Point(314, 447)

        EnlargedCardImage.Location = ObjectLocation
        EnlargedCardImage.Size = EnlargedCardImageSize
        EnlargedCardImage.Image = FullArt
        Form1.Controls.Add(EnlargedCardImage)

        ObjectLocation.X = 658
        ObjectLocation.Y = 480
        PlusDisplay.Location = ObjectLocation
        PlusDisplay.Text = "+1/+1 Counters: " & PlusCounters.ToString
        Form1.Controls.Add(PlusDisplay)

        ObjectLocation.X = 882
        ObjectLocation.Y = 480
        MinusDisplay.Location = ObjectLocation
        MinusDisplay.Text = "-1/-1 Counters: " & MinusCounters.ToString
        Form1.Controls.Add(MinusDisplay)

        ObjectLocation.X = 658
        ObjectLocation.Y = 526
        LoyaltyDisplay.Location = ObjectLocation
        LoyaltyDisplay.Text = "Loyalty Counters: " & LoyaltyCounters.ToString
        Form1.Controls.Add(LoyaltyDisplay)

        ObjectLocation.X = 871
        ObjectLocation.Y = 526
        ChargeDisplay.Location = ObjectLocation
        ChargeDisplay.Text = "Charge Counters: " & ChargeCounters.ToString
        Form1.Controls.Add(ChargeDisplay)
    End Sub
End Class


Was This Post Helpful? 0
  • +
  • -

#3 TheCodeNoob   User is offline

  • New D.I.C Head

Reputation: -12
  • View blog
  • Posts: 36
  • Joined: 21-November 11

Re: Interesting (and frustrating) glitch in homemade MTG simulator

Posted 22 November 2011 - 03:37 PM

The problem with that code is that it deletes the card that was already drawn though. The idea is to still keep that card until it is sent to a different zone (which is meant to be handled via more context menu items).
Was This Post Helpful? 0
  • +
  • -

#4 _HAWK_   User is offline

  • Master(Of Foo)
  • member icon

Reputation: 1162
  • View blog
  • Posts: 4,444
  • Joined: 02-July 08

Re: Interesting (and frustrating) glitch in homemade MTG simulator

Posted 22 November 2011 - 09:21 PM

Diff concept; make your card class, but not inherit a picturebox - you just new a well defined object. In your form you make a collection for each user. As the dealer deals cards you create a new card object and paint it's image to the canvas. When many cards are drawn you move the X coordinate of the cards and as they are drawn they will overlap each as you draw them. They are still click-able objects if you give them a Bounds property that is a rectangle structure. On mouse down you can iterate the hands to check for a rectangle.Contains(e.Location). This would make a more OOP design. I still embrace the Dispose concept especially since you will be using Bitmaps.
Was This Post Helpful? 0
  • +
  • -

#5 TheCodeNoob   User is offline

  • New D.I.C Head

Reputation: -12
  • View blog
  • Posts: 36
  • Joined: 21-November 11

Re: Interesting (and frustrating) glitch in homemade MTG simulator

Posted 22 November 2011 - 10:48 PM

But how does that fix my problem? The trouble is from the information attached to the card, not the cards themselves. I can still rotate them and move them just fine.
Was This Post Helpful? 0
  • +
  • -

#6 Recoil   User is offline

  • D.I.C Addict

Reputation: 51
  • View blog
  • Posts: 504
  • Joined: 28-June 08

Re: Interesting (and frustrating) glitch in homemade MTG simulator

Posted 23 November 2011 - 01:06 AM

I am not sure if this addresses your issue, but I think it is because your card isn't actually holding anything. What it looks like to me is that you are saving the information for each card in variables in your program. Each time a new card is generated, the variables become overwritten, and the first card adapts information from the second card, because the second card now takes place of the first card...if that makes sense?

I think to solve the issue you might try associating the information you are wanting for each card on each card. This can be done by creating properties for your cards and enumerating the data:

Public Class Card

    Dim _ct As CardType

    Public Enum CardType

        Forest

        Island

        Mountains

        Swamp

        Plains

    End Enum

    Public Property ButtonType() As CardType

        Get

            Return _ct

        End Get

        Set(ByVal value As CardType)

            _ct = value

        End Set

    End Property


End Class



I believe doing that for all the information associated with each "Card" will help. Then, you do your calculations in your program based off of the information you have that is held in each card.

Also,it has been a while since I have played MTG, so I do not understand the Loyalty part here, but I wouldn't tell Form1 to do anything from the Card class:

ObjectLocation.X = 658
ObjectLocation.Y = 526
LoyaltyDisplay.Location = ObjectLocation
LoyaltyDisplay.Text = "Loyalty Counters: " & LoyaltyCounters.ToString
Form1.Controls.Add(LoyaltyDisplay)



Instead I would create public properties to hold whatever information, and pull those from each card whenever you needed it on Form1. However, if you are wanting stuff to be done on each <card> then you make it happen for the card, which essentially has nothing to do with Form1...you might want this action to be done of Form2 also.
Was This Post Helpful? 0
  • +
  • -

#7 TheCodeNoob   User is offline

  • New D.I.C Head

Reputation: -12
  • View blog
  • Posts: 36
  • Joined: 21-November 11

Re: Interesting (and frustrating) glitch in homemade MTG simulator

Posted 24 November 2011 - 08:54 PM

So I tried making the full art image and the counters into properties and that didn't help.
Was This Post Helpful? 0
  • +
  • -

#8 Recoil   User is offline

  • D.I.C Addict

Reputation: 51
  • View blog
  • Posts: 504
  • Joined: 28-June 08

Re: Interesting (and frustrating) glitch in homemade MTG simulator

Posted 25 November 2011 - 09:38 AM

Well, when you are creating the actual cards themselves I do not see how you are specifying they type of card...because currently when you click the button to add the card to the form, it is being created by the default value of the Boolean. This should be created as an actual card type, and not a Boolean.

You might try posting any changes you have made to the initial code as what is listed is not working.
Was This Post Helpful? 0
  • +
  • -

#9 TheCodeNoob   User is offline

  • New D.I.C Head

Reputation: -12
  • View blog
  • Posts: 36
  • Joined: 21-November 11

Re: Interesting (and frustrating) glitch in homemade MTG simulator

Posted 25 November 2011 - 03:34 PM

The "Type" variable was meant to be a placeholder for what's suppose to be a numeric value that's suppose to fish data out of a database and set all of the card's information based on that data. Because I don't know how to do much with databases yet, I created "Type" to try and see if this glitch occurred with the card's image as well since before it was doing it to the counters.

The code I added to create the properties is this, though:

Inherits PictureBox
    Dim off As Point
    Dim FullArt As Bitmap
    Dim TapStatus As Boolean
    Dim RotatedImage As Bitmap
    Dim LoyaltyCounters, PlusCounters, MinusCounters, ChargeCounters As Integer
    Dim EnlargedCardImage As New PictureBox
    Dim LoyaltyDisplay, PlusDisplay, MinusDisplay, ChargeDisplay As New Label
    Dim CardActionMenu As New ContextMenuStrip
    Dim AddCounters As New ToolStripMenuItem

    Public Property EnlargedImage
        Get
            Return FullArt
        End Get
        Set(ByVal value)
            FullArt = value
        End Set
    End Property

    Public Property Plus
        Get
            Return PlusCounters
        End Get
        Set(ByVal value)
            PlusCounters = value
        End Set
    End Property

    Public Property Minus
        Get
            Return MinusCounters
        End Get
        Set(ByVal value)
            MinusCounters = value
        End Set
    End Property

    Public Property Loyalty
        Get
            Return LoyaltyCounters
        End Get
        Set(ByVal value)
            LoyaltyCounters = value
        End Set
    End Property

    Public Property Charge
        Get
            Return ChargeCounters
        End Get
        Set(ByVal value)
            ChargeCounters = value
        End Set
    End Property


And this is the code for the mousehover event sub:

Dim ObjectLocation As New Point(661, 12)
        Dim EnlargedCardImageSize As New Point(314, 447)

        EnlargedCardImage.Location = ObjectLocation
        EnlargedCardImage.Size = EnlargedCardImageSize
        EnlargedCardImage.Image = Me.EnlargedImage
        Form1.Controls.Add(EnlargedCardImage)

        ObjectLocation.X = 658
        ObjectLocation.Y = 480
        PlusDisplay.Location = ObjectLocation
        PlusDisplay.Text = "+1/+1 Counters: " & Me.Plus.ToString
        Form1.Controls.Add(PlusDisplay)

        ObjectLocation.X = 882
        ObjectLocation.Y = 480
        MinusDisplay.Location = ObjectLocation
        MinusDisplay.Text = "-1/-1 Counters: " & Me.Minus.ToString
        Form1.Controls.Add(MinusDisplay)

        ObjectLocation.X = 658
        ObjectLocation.Y = 526
        LoyaltyDisplay.Location = ObjectLocation
        LoyaltyDisplay.Text = "Loyalty Counters: " & Me.Loyalty.ToString
        Form1.Controls.Add(LoyaltyDisplay)

        ObjectLocation.X = 871
        ObjectLocation.Y = 526
        ChargeDisplay.Location = ObjectLocation
        ChargeDisplay.Text = "Charge Counters: " & Me.Charge.ToString
        Form1.Controls.Add(ChargeDisplay)


Right now I'm starting to think that the problem may have something to do with the sub actually creating a picturebox and labels instead of using ones that already exist. I tried remedying that by placing a picturebox and labels into the same spots in the form and controlling them with this code in the card's mousehover sub:

EnlargedCardImage.Image = FullArt
            PlusDisplay.Text = "+1/+1 Counters: " & PlusCounters
            MinusDisplay.Text = "-1/-1 Counters: " & MinusCounters
            LoyaltyDisplay.Text = "Loyalty Counters: " & LoyaltyCounters
            ChargeDisplay.Text = "Charge Counters: " & ChargeCounters


However, what seems to result is a blue underline under each of the object names and an error saying "Reference to a non-shared member requires an object reference". I have no idea how to get around this error.
Was This Post Helpful? 0
  • +
  • -

#10 Recoil   User is offline

  • D.I.C Addict

Reputation: 51
  • View blog
  • Posts: 504
  • Joined: 28-June 08

Re: Interesting (and frustrating) glitch in homemade MTG simulator

Posted 25 November 2011 - 11:46 PM

What you will need:
Resource1.resx with all 10 pictures (5 sprite images/5 full images) with the same naming convention like you currently have ("Forest" / "Green_Card_Sprite").

Form1 @ 1024x768

Button1 - .text = "Add Land"

GroupBox1 - large enough to hold 5 radio buttons.

RadioButtons - (.name = "radForest" / .text = "Forest") - do this for each land...

Public Class Form1

    Private Sub GenerateCard() Handles Button1.Click
        'Forest, Island, Blue_Card_Sprite, and Green_Card_Sprite are the names of resources on file

        'Forest the full art image of a Forest card in Magic: the Gathering as is Island for an Island card. the sprites are colored
        'representations of the cards that can be moved around, tapped, etc.

        'The idea was that "Type" was suppose to cause the button to alternate between generating a forest card and an island card.

        Dim CardLocation As New Point(30, 30)
        Dim CardSize As New Point(51, 71)
        Dim FullImage As Bitmap
        Dim Sprite As Bitmap
        If radForest.Checked = True Then
            FullImage = My.Resources.Resource1.Forest
            Sprite = My.Resources.Resource1.Green_Card_Sprite
        ElseIf radIsland.Checked = True Then
            FullImage = My.Resources.Resource1.Island
            Sprite = My.Resources.Resource1.Blue_Card_Sprite
        ElseIf radMountain.Checked = True Then
            FullImage = My.Resources.Resource1.Mountain
            Sprite = My.Resources.Resource1.Red_Card_Sprite
        ElseIf radPlains.Checked = True Then
            FullImage = My.Resources.Resource1.Plains
            Sprite = My.Resources.Resource1.White_Card_Sprite
        ElseIf radSwamp.Checked = True Then
            FullImage = My.Resources.Resource1.Swamp
            Sprite = My.Resources.Resource1.Black_Card_Sprite
        End If
        Dim NewCard As New Card(CardLocation, CardSize, Sprite, FullImage)
        Me.Controls.Add(NewCard)
    End Sub

End Class

Public Class Card
    Inherits PictureBox
    Dim off As Point
    Dim FullArt As Bitmap
    Dim TapStatus As Boolean
    Dim RotatedImage As Bitmap
    Dim LoyaltyCounters, PlusCounters, MinusCounters, ChargeCounters As Integer
    Dim EnlargedCardImage As New PictureBox
    Dim LoyaltyDisplay, PlusDisplay, MinusDisplay, ChargeDisplay As New Label

    Dim CardActionMenu As New ContextMenuStrip
    Dim AddCounters As New ToolStripMenuItem

    Public Property EnlargedImage
        Get
            Return FullArt
        End Get
        Set(ByVal value)
            FullArt = value
        End Set
    End Property

    Public Property Plus
        Get
            Return PlusCounters
        End Get
        Set(ByVal value)
            PlusCounters = value
        End Set
    End Property

    Public Property Minus
        Get
            Return MinusCounters
        End Get
        Set(ByVal value)
            MinusCounters = value
        End Set
    End Property

    Public Property Loyalty
        Get
            Return LoyaltyCounters
        End Get
        Set(ByVal value)
            LoyaltyCounters = value
        End Set
    End Property

    Public Property Charge
        Get
            Return ChargeCounters
        End Get
        Set(ByVal value)
            ChargeCounters = value
        End Set
    End Property


    Public Sub New(ByVal Location As Point, ByVal Size As Point, ByVal Sprite As Bitmap, ByVal FullArt As Bitmap)
        Me.Image = Sprite
        RotatedImage = Sprite
        Me.FullArt = FullArt
        Me.Location = Location
        Me.Size = Size
        Me.BorderStyle = Windows.Forms.BorderStyle.FixedSingle
        Me.BackgroundImage = Sprite

    End Sub

    Private Sub obj1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseDown
        'This is part of code used to move the card generated with the button
        off.X = MousePosition.X - sender.Left
        off.Y = MousePosition.Y - sender.Top
        Me.BringToFront()

        'This part of the code is used to create a context menu for adding counters to a card if the right mouse button is clicked
        If e.Button = MouseButtons.Right Then
            Dim CardActionMenu As New ContextMenuStrip
            Dim AddCounters As New ToolStripMenuItem
            AddCounters.Text = "Add Counters"
            CardActionMenu.Items.Add(AddCounters)
            CardActionMenu.Show(sender, New Point(e.X, e.Y))
            AddHandler AddCounters.Click, AddressOf AddCountersToCard
        End If

    End Sub

    Private Sub AddCountersToCard()
        PlusCounters += 1

    End Sub

    Private Sub obj1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseMove
        'Used to drag the card across the screen with the mouse
        If e.Button = MouseButtons.Left Then
            sender.Left = MousePosition.X - off.X
            sender.Top = MousePosition.Y - off.Y
        End If

        'My lousy attempt at creating an artificial boundry that cards of this class can't cross
        If (MousePosition.X + 74) - off.X > 624 Then
            sender.left = 624 - 98
            sender.visible = False
        End If
        sender.visible = True
    End Sub

    Private Sub Tap(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.DoubleClick
        'Taps and untaps the card (As in turning it horizontally when doubleclicked and vertically again when doubleclicked again)

        If TapStatus = False Then
            RotatedImage.RotateFlip(RotateFlipType.Rotate90FlipXY)
            Me.Image = RotatedImage
            TapStatus = True
        ElseIf TapStatus = True Then
            RotatedImage.RotateFlip(RotateFlipType.Rotate270FlipXY)
            Me.Image = RotatedImage
            TapStatus = False
        End If
        Dim placeholder As Integer = Me.Width
        Me.Width = Me.Height
        Me.Height = placeholder
    End Sub

    Private Sub ShowEnlargedImage(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.MouseHover
        'Used to dynamically create the labels and picturebox used to display the card's information. This is the information that I believe
        'may be responsible for the information flip-flop when the second card is made.

        Dim ObjectLocation As New Point(661, 12)
        Dim EnlargedCardImageSize As New Point(314, 447)

        EnlargedCardImage.Location = ObjectLocation
        EnlargedCardImage.Size = EnlargedCardImageSize
        EnlargedCardImage.Image = FullArt
        Form1.Controls.Add(EnlargedCardImage)

        ObjectLocation.X = 658
        ObjectLocation.Y = 480
        PlusDisplay.Location = ObjectLocation
        PlusDisplay.Text = "+1/+1 Counters: " & PlusCounters.ToString
        Form1.Controls.Add(PlusDisplay)

        ObjectLocation.X = 882
        ObjectLocation.Y = 480
        MinusDisplay.Location = ObjectLocation
        MinusDisplay.Text = "-1/-1 Counters: " & MinusCounters.ToString
        Form1.Controls.Add(MinusDisplay)

        ObjectLocation.X = 658
        ObjectLocation.Y = 526
        LoyaltyDisplay.Location = ObjectLocation
        LoyaltyDisplay.Text = "Loyalty Counters: " & LoyaltyCounters.ToString
        Form1.Controls.Add(LoyaltyDisplay)

        ObjectLocation.X = 871
        ObjectLocation.Y = 526
        ChargeDisplay.Location = ObjectLocation
        ChargeDisplay.Text = "Charge Counters: " & ChargeCounters.ToString
        Form1.Controls.Add(ChargeDisplay)

    End Sub

    Private Sub Card_MouseLeave(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.MouseLeave

        Form1.Controls.Remove(EnlargedCardImage)
        Form1.Controls.Remove(PlusDisplay)
        Form1.Controls.Remove(MinusDisplay)
        Form1.Controls.Remove(LoyaltyDisplay)
        Form1.Controls.Remove(ChargeDisplay)

    End Sub

End Class



On the very last Card_MouseLeave sub removes all the stuff you have previously created by the cards MouseHover event. Now you will see that no matter how many cards you have, if you add counters to it it will keep the counters and display them properly, along with displaying the correct image for the full image. You can still add a card type like I mentioned before, but I just added radio button for simplicity trying to explain.

Just to note, I am not sure how much you have planned exactly for this project, but if I can provide any advice it is make detailed plans for complex stuff...it really does help when you get into a bind.

I hope this helps solve your issue though :)
Was This Post Helpful? 0
  • +
  • -

#11 TheCodeNoob   User is offline

  • New D.I.C Head

Reputation: -12
  • View blog
  • Posts: 36
  • Joined: 21-November 11

Re: Interesting (and frustrating) glitch in homemade MTG simulator

Posted 26 November 2011 - 04:26 PM

While it's not exactly the most user friendly way to solve the problem, it definitely does work and well enough to at least finish my final project. Thank you.

Now it's on to finishing context menus and databases.
Was This Post Helpful? 0
  • +
  • -

#12 Recoil   User is offline

  • D.I.C Addict

Reputation: 51
  • View blog
  • Posts: 504
  • Joined: 28-June 08

Re: Interesting (and frustrating) glitch in homemade MTG simulator

Posted 26 November 2011 - 07:26 PM

janne_panne had you on the right track...you weren't removing the cards controls being displayed..this added cards on top of cards on top of cards, referencing the exact card you were wanting, just not being viewed properly because it was stacked...also the labels associated were not referenced properly...

You can edit the code to work for you ya know...saving the types of land as properties again to make it cleaner. This was just a quick fix though to try to explain what I meant in my initial post. I'm not exactly sure what you meant my simulator for MTG aside from something that actually allows you to play the game with people...but if you are wanting a more user friendly approach for dealing with the card issue, you are probably going about it the wrong way just by seeing how you are trying to store stuff on the cards instead of in something like a data file...

However, if you are wanting the hovered card to display until another one is hovered, the define an area to store the full image and labels in, such as a separate panel, and just clear all the controls in it everytime you hover over a card, before you create new ones with the hover event.

Also, if these posts helped, the little green + sign at the bottom of the messages helps back ;)
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1