Results 1 to 35 of 35

Thread: [RESOLVED] Moving an object again, Maybe not an object

  1. #1

    Thread Starter
    Fanatic Member AccessShell's Avatar
    Join Date
    Oct 2013
    Posts
    794

    Resolved [RESOLVED] Moving an object again, Maybe not an object

    I have several picture boxes on a form. I can move any pb. But that's just too easy. I need to drag the picture in the pb and place it in another pb. The original pb will then show what is "under" it. Not under the pb, under the picture that I dragged. And, I need to place it on top of a picture in another pb. I can't even get an idea how to attack this.

    I recently realized that when I do a mouse down on a pb in an array, I capture the index, but when I do the mouse up, I get the same index. I know why, but I really need the index of the destination.

    I also can't seem to place the dragged picture in the exact location on the dest pb.

    Yes,, I'm confused. I hope you're not.

    Thanks

  2. #2
    Frenzied Member
    Join Date
    Dec 2008
    Location
    Melbourne Australia
    Posts
    1,487

    Re: Moving an object again, Maybe not an object

    Trim down a copy of what you have.
    Enough to just demonstrate what you are trying to achieve, and indicating what aint working right for you.
    And attach it

  3. #3
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: Moving an object again, Maybe not an object

    Sounds like you need to use local drag/drop. Maybe this is close to what you are after?

    Name:  sshot1.png
Views: 476
Size:  1.4 KB

    Before

    Name:  sshot2.png
Views: 488
Size:  1.3 KB

    After dragging all 3 pics to the same PB

    The small numbers show the stack pointer value for the stack associated with each PictureBox.

    Code:
    Option Explicit
    
    Private Const WIN32_NULL As Long = 0
    
    Private Stacks() As StdPicture 'A stack of StdPicture for each Picture1.
    Private StackPtrs() As Integer 'A stack top "pointer" for each Picture1.
    
    Private Sub Form_Load()
        Dim I As Integer
    
        With Picture1
            ReDim Stacks(.LBound To .UBound, 0 To 0)
            ReDim StackPtrs(.LBound To .UBound)
            For I = .LBound To .UBound
                With .Item(I)
                    Set .DragIcon = LoadResPicture("DRAGMOVE", vbResCursor)
                    'This is the proper test for "Nothing" on a control's Picture proerty:
                    If .Picture.Handle = WIN32_NULL Then
                        StackPtrs(I) = -1
                        .DragMode = vbManual
                    Else
                        StackPtrs(I) = 0
                        Set Stacks(I, StackPtrs(I)) = .Picture
                        .DragMode = vbAutomatic
                    End If
                End With
                Label1(I) = CStr(StackPtrs(I))
            Next
        End With
    End Sub
    
    Private Sub Picture1_DragDrop(Index As Integer, Source As Control, X As Single, Y As Single)
        Dim SourcePB As PictureBox
    
        Set SourcePB = Source
        With SourcePB
            'Move pic from source to dest, push onto dest's stack:
            Set Picture1(Index).Picture = .Picture
            StackPtrs(Index) = StackPtrs(Index) + 1
            If StackPtrs(Index) > UBound(Stacks, 2) Then
                With Picture1
                    ReDim Preserve Stacks(.LBound To .UBound, 0 To StackPtrs(Index))
                End With
            End If
            Set Stacks(Index, StackPtrs(Index)) = .Picture
            Label1(Index) = CStr(StackPtrs(Index))
            Picture1(Index).DragMode = vbAutomatic
            'Pop pic from dest's stack, updating dest's pic if stack is not empty:
            StackPtrs(.Index) = StackPtrs(.Index) - 1
            Label1(.Index) = CStr(StackPtrs(.Index))
            If StackPtrs(.Index) < 0 Then
                Set .Picture = Nothing
                .DragMode = vbManual
            Else
                Set .Picture = Stacks(.Index, StackPtrs(.Index))
            End If
        End With
    End Sub
    I'd probably use UserControls instead of dumb PictureBoxes though. That way the Form doesn't have to contain all of the gory details like you are forced to in the much more primitive Office VBA.
    Attached Files Attached Files

  4. #4

    Thread Starter
    Fanatic Member AccessShell's Avatar
    Join Date
    Oct 2013
    Posts
    794

    Re: Moving an object again, Maybe not an object

    I think a user control is something I create, unlike a pb. I have never created a uc. This might be the time to learn.

    The example shown in the previous post is almost what I need. When a pic is dragged, during the drag I want to show a pic at the source (like another pic and pb was underneath. When I drop the pic in the correct place, the new pic at the source is replaced with another pic that was underneath.

    I'll study your code Dilettante

  5. #5

    Thread Starter
    Fanatic Member AccessShell's Avatar
    Join Date
    Oct 2013
    Posts
    794

    Re: Moving an object again, Maybe not an object

    I studied and ran Dilettante's code. I like it. I understand most of it. A couple of questions please.
    1. In Picture1_DragDrop, is Source the handle of the picture that is being moved?
    if so, ho do you get t he handle of the pics in the destination?

    2. In form load, how do you stack pictures in each pb? I would need to stack 4 pics in each pb and know(in code) whick pb is on top.

    3. When the source pb has no more pics I can easily make the pb NOT visible, thereby making that location unusable. But, at the destination, how can in can I, in code, delete pics starting from the top of the stack?

    Thanks

  6. #6

    Thread Starter
    Fanatic Member AccessShell's Avatar
    Join Date
    Oct 2013
    Posts
    794

    Re: Moving an object again, Maybe not an object

    Also, How can I show the actual picture being dragged and stacked, not the draganddrop mouse pointer?

    Thanks

  7. #7
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: Moving an object again, Maybe not an object

    Quote Originally Posted by AccessShell View Post
    1. In Picture1_DragDrop, is Source the handle of the picture that is being moved?
    No, Source is the source control for the drag/drop operation.

    Quote Originally Posted by AccessShell View Post
    if so, ho do you get t he handle of the pics in the destination?
    The only handle I did anything with was to check for an "empty" Picture1(n).Picture during Form_Load. That's because "clearing" that property to Nothing results in an empty StdPicture object and not actually Nothing.

    As far as drop destinations go, those are Picture1() instances. Each one can only have one .Picture, not multiples.

    This is what the Stacks() array is for. It holds 0 to many StdPicture objects for each Picture1() instance. If you need handles look at the .Handle property of each valid array element.

    Quote Originally Posted by AccessShell View Post
    2. In form load, how do you stack pictures in each pb? I would need to stack 4 pics in each pb and know(in code) whick pb is on top.
    The code above only stacks 0 or 1 StdPicture for each Picture1() instance during Form_Load. If you wanted more, just place more into those stacks, assigning the top/last entry to Picture1(n).Picture.

    Note that a StackPtrs(n) = -1 means "empty."

    Quote Originally Posted by AccessShell View Post
    3. When the source pb has no more pics I can easily make the pb NOT visible, thereby making that location unusable. But, at the destination, how can in can I, in code, delete pics starting from the top of the stack?
    In the example above, pics are "deleted" by drag/dropping them elsewhere.

    I suppose you might have some additional "black hole" drop target to discard them without moving them. Or you might have right-click a PB mean "delete" instead. Or something else.

  8. #8

    Thread Starter
    Fanatic Member AccessShell's Avatar
    Join Date
    Oct 2013
    Posts
    794

    Re: Moving an object again, Maybe not an object

    The code above only stacks 0 or 1 StdPicture for each Picture1() instance during Form_Load. If you wanted more, just place more into those stacks, assigning the top/last entry to Picture1(n).Picture.

    Note that a StackPtrs(n) = -1 means "empty."
    In other words, the pics are not really on top of one another. The reference to the pics underneath the top pic is in the Stacksptrs array.

  9. #9
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: Moving an object again, Maybe not an object

    Yes. A PictureBox has only a simple Picture property.

  10. #10

    Thread Starter
    Fanatic Member AccessShell's Avatar
    Join Date
    Oct 2013
    Posts
    794

    Re: Moving an object again, Maybe not an object

    Referring to the code in post #3.
    1. I never liked using the property "Picture" found in the properties listing when the form is highlighted, for the Picture1(n) control. So I use, in code, the LoadPicture statement. I placed this in the Form_Load procedure before the 'With Picture1' statement. I think that just after this statement I would add the picturenames to the Stacks() array. I am not really sure how to do this. I don't think the Stacks() array can really hold picturenames, since there is no LoadPucture statement in the Picture1_DragDrop routine. Maybe it is a handle. This confusion is brought about because I really don't know what the type is for stdPicture.

    2. I think, but still not sure, if the "With Picture1/End With" code fills the StackPtrs() array. This array is bit confusing. It can be interpreted two different ways. 1. The top pic is used for any Picture(n) that becomes available, or 2. I can have a top picture for each of the 5 different pics on the form. I think the first option is much easier to deal with. The program would not be compromised if either method were used. I also think that values in StackPtrs() depend of which method is being employed.

    Any reply would be greatly appreciated.

  11. #11
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: Moving an object again, Maybe not an object

    Quote Originally Posted by AccessShell View Post
    I never liked using the property "Picture" found in the properties listing when the form is highlighted, for the Picture1(n) control. So I use, in code, the LoadPicture statement.
    Get used to it. It's the right way to do things.

    The image file gets compiled into the program as a resource. No messy separate file to carry around. When the control gets loaded the image gets assigned as part of its internal ReadProperties operation.

    Quote Originally Posted by AccessShell View Post
    I think that just after this statement I would add the picturenames to the Stacks() array. I am not really sure how to do this. I don't think the Stacks() array can really hold picturenames, since there is no LoadPucture statement in the Picture1_DragDrop routine. Maybe it is a handle. This confusion is brought about because I really don't know what the type is for stdPicture.
    Wow. It's hard to know where to begin. StdPicture is a type. It's an object that wraps a bitmap, icon, or metafile image along with the Render() method used to display it.

    Sure, you could carry a tubful of separate files along and then juggle file names, repeatedly loading/destroying StdPicture objects. But why would you do this?

    I have no idea what your goals are, so there might be scenarios were that makes sense. Do you have a large number of very large images to juggle or something?

    Quote Originally Posted by AccessShell View Post
    I think, but still not sure, if the "With Picture1/End With" code fills the StackPtrs() array. This array is bit confusing. It can be interpreted two different ways. 1. The top pic is used for any Picture(n) that becomes available, or 2. I can have a top picture for each of the 5 different pics on the form. I think the first option is much easier to deal with. The program would not be compromised if either method were used. I also think that values in StackPtrs() depend of which method is being employed.
    I'm not sure what to tell you.

    StackPtrs() is a list of indexes, one per Picture1() and Stacks() array row, and these are the indexes of each corresponding Stacks() element containing the "top of stack" value.

    What does "becomes available" mean?

    The "top" picture for each Picture1() is the one "on top" and currently visible. When there are none the Picture1()'s StackPtrs() value is -1, which means both "stack is empty" and "Picture1() has no current picture.


    UserControls instead of PictureBoxes simplify this. Each UserControl instance could have its own internal stack and stack pointer as well as encapsulating the push/pop logic away from the host Form. That's one of the main reasons why we have Classes (and by extension UserControls): code and data hiding through encapsulation.

    In this case we'd gain some simplification as well as efficiency. We could use a simple 1-D array for the stack and we'd be able to limit each instance to only the entries it needs. 2-D arrays cannot be sparse or ragged, so in the code above if one Picture1() needs 5 slots in its stack all of them need to hold 5 even if none are in use. That's just how arrays work.


    I wasn't trying to offer you a finished product tailored to your needs. It was merely an example. Hopefully you would see the concepts involved and apply them as they fit your program's needs.
    Last edited by dilettante; Jan 2nd, 2021 at 09:05 PM.

  12. #12

    Thread Starter
    Fanatic Member AccessShell's Avatar
    Join Date
    Oct 2013
    Posts
    794

    Re: Moving an object again, Maybe not an object

    I never expected a finished product. I do expect, that after studying the offered code, I would understand it. Obviously, I did not.
    I was just trying to get clarification. It is obvious that you are a much more accomplished VB programmer and analyst that I am.

    Now I will study your last response.

  13. #13
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: Moving an object again, Maybe not an object

    Perhaps I just presented it poorly. Maybe somebody else can explain it more simply.

  14. #14
    Sinecure devotee
    Join Date
    Aug 2013
    Location
    Southern Tier NY
    Posts
    6,582

    Re: Moving an object again, Maybe not an object

    I posted the Seahaven game in one of your other threads, and it allows stacking cards. Since there is code to allow dragging multiple cards, and rules to test for valid dragging situations to different type of stacks, and code to allow undo/redo history, etc... the overall code can overwhelm the basic process of linking/unlinking cards from a stack to another.

    Therefore, I've pulled out the minimal functions necessary to stack the cards, and allow dragging between the stacks, and pared out the various checks and multiple drag and move history manipulation, to create a basic example of what my code does to drag and drop between stacks of cards.

    The game (and this example) uses a simple User Defined Type to allow cards to be linked to each other.
    Code:
    'The Card_Type holds placement information (left, top) and a double link (prev, next) for each card or stack.
    'The left and top fields identify where the upper left corner of the card for positioning
    'The Prev field identifies the card this card is linked to.
    'The next field identifies the card linked to it.
    Private Type Card_Type
      Left As Long
      Top As Long
      Prev As Integer
      Next As Integer
    End Type
    Note that the comments says "a double link (prev, next) for each card or stack".
    That is because the Prev and Next values are just indexes into an array of Card_Type, so object in the array can be linked to two other objects in the array, and we can designate specific indexes in the array to be the root object of a stack, so a card can be linked to that root object, and then another card linked to that card, and so on.
    Code:
    'Rather than have unique Types to define the Stacks, and having to have extra code to link
    'and unlink cards to the stacks, we will use the existing Card_Type to also define the stacks.
    'So, for this example, 0 to 51 are the 52 cards, and 52 to 59 are 8 "stacks", where cards can be
    'stacked one on top of the other.
    
    Public Card(0 To 51 + 8) As Card_Type   '52 cards + 8 "stack" areas
    All the routines that manipulate the cards in the stacks are put in a module, named CardSubs {even though it is more than just Subs}.
    The code in the form is primarily just the User Interface handling, so isn't much. Here is the whole code that is in the form for the example.
    Code:
    Option Explicit
    
    Private Sub Form_Load()
      ScaleMode = vbPixels
      Initialize_Everything
    End Sub
    
    Private Sub picCards_MouseDown(index As Integer, Button As Integer, Shift As Integer, X As Single, Y As Single)
      
      'update information associated with this card
      Set_Dragged_Card_Info index
                                  
      XL = X   'Save X and Y for
      YL = Y   'dragging purposes
    
      If Button = vbLeftButton Then
        Drag_Allowed = True
        picCards(index).ZOrder 'raise the dragged card so it drags over all other cards
      End If
    End Sub
    
    Private Sub picCards_MouseMove(index As Integer, Button As Integer, Shift As Integer, X As Single, Y As Single)
      If Drag_Allowed Then    'if dragging allowed (left button must be down and other requirements met)
        Move_Card_To X, Y     '  Move the card (and others dragged with it) to follow the mouse
        Me.Refresh            '  Refresh the form so we don't leave a temporary trail if we drag fast
      End If
    End Sub
    
    Private Sub picCards_MouseUp(index As Integer, Button As Integer, Shift As Integer, X As Single, Y As Single)
      
      If Drag_Allowed Then                'if we were dragging cards then
        Drag_Allowed = False              '  we are no longer dragging
        To_Stack = Stack_Dropped_on       '  Get the number of the Stack the card(s) were dropped on
       
        If To_Stack <> From_Stack Then    '  don't need to process if dropped on the same stack
          link_card                       '    Link the Card(s) to the Normal Stack dropped on
        End If
        Reposition_Card                   '  Draw cards in their new location
      End If
    End Sub
    Functions like Stack_Dropped_on and Subs link_card, Reposition_Card, etc... are defined in the CardSubs module.
    I won't post that code, it has a lot of comments, so may be a bit bulky for posting, but you can download the project to examine it.

    The example will just create a control array of 52 pictureboxes for the cards and another control array of 8 pictureboxes for destination stacks.
    Technically the 8 pictureboxes for the stacks are not necessary, but gives a visual target for the user to drag a card to.
    What really defines the stacks position is the values placed in the Card(52 to 59) array values (the Card_Type UDT).

    It will link the 52 cards to the first stack at startup.
    You can then drag and drop the cards between any of the eight stacks defined in the example.
    Attached Files Attached Files
    Last edited by passel; Jan 2nd, 2021 at 08:59 PM.
    "Anyone can do any amount of work, provided it isn't the work he is supposed to be doing at that moment" Robert Benchley, 1930

  15. #15

    Thread Starter
    Fanatic Member AccessShell's Avatar
    Join Date
    Oct 2013
    Posts
    794

    Re: Moving an object again, Maybe not an object

    Whoa, This is interesting. It will take me a couple of days to analyze this.

    Thanks Passel

  16. #16

    Thread Starter
    Fanatic Member AccessShell's Avatar
    Join Date
    Oct 2013
    Posts
    794

    Re: Moving an object again, Maybe not an object

    I have 2 questions on post #14

    1. Look at the layout i added. The transparent rectangles are the ones from your code I repositioned. The red rectangles I am trying to add. Not red, but looking like the others .Please just tell me where I would do this. I need to figure out how.

    2. When I drag any card, it goes to the top card in the column. Where would I change that so the dragged card goes the lower position rectangles if needed. Just tell me where, I need to figure out the code myself.

    Thanks
    Attached Images Attached Images  

  17. #17
    Sinecure devotee
    Join Date
    Aug 2013
    Location
    Southern Tier NY
    Posts
    6,582

    Re: Moving an object again, Maybe not an object

    1. Did you reposition them in code, or are you laying them out in the IDE?
    Where it is currently setting that up is in the "Initialize_Everything" Sub.
    The Card array holds the position and link for all the cards, and for the stacks.
    The cards come first (0 to 51), and then the stacks follow, (52 to ...) depending on how many stacks you want.
    Since I had 8 stacks I just indicate that by adding 8 to the ubound value.
    Code:
    Public Card(0 To 51 + 8) As Card_Type   '52 cards + 8 "stack" areas
    It looks like you want 6 more stacks, so add 14 instead of 8.

    My example both loads the additional 7 stack markers (.picDest(i)) and aligns the stack's root card with those markers.
    Code:
        For i = 1 To 7
          Load .picDest(i)
          .picDest(i).Left = xo + xw * i
          .picDest(i).Visible = True
          
          Card(i + 52).Left = .picDest(i).Left
          Card(i + 52).Top = .picDest(i).Top
          Card(i + 52).Next = -1  'there are no cards linked to this stack
        Next
    If you laid the markers out in the IDE, then of course you don't need to load and position the markers.
    Just loop through the markers and align the stacks to them (the bottom portion of the loop).


    2. You would need to change the "Closest_Stack_in_Range" Function.

    The function was pulled from the "Normal_Stacks" code of the seahaven game.
    The normal stacks were like the columns of overlapping cards in the main field of cards, so since the cards were stacked in columns, the cards were offset vertically so the stack was a column of cards where you could see enough of the card underneath to tell what the card was. Since the height of stack of cards depended on how many cards were in each column, the code didn't check the Y coordinate to find the stack, it just checked the X coordinate to determine which column the card was dropped on.
    The card would automatically be placed at the bottom of the column of cards.

    I assumed you would update that function to check both X and Y to see which stack the card is dropped on if your stacks were not all in a horizontal row.
    Also, if the card is not allowed to be dropped on the stack, or was not dropped on a stack, then you would return the "From_Stack" so that the card would be moved back to where it was dragged from.

    p.s. I tested the changes and there wasn't a lot to modify and it went quick. I assume you're laying out the picDest pictureboxes in the IDE, so that simplifies that code, i.e. remove the initial aliging of Card 52 to picDest(0), and just loop through all of the picDest pictureboxes (0 to 13) and align the Card(52 + i) to them.

    For #2, I just used the standard square root distance calculation ( d = sqr( dx*dx + dy *dy), changing dl and d to double type and adding Y and dx, dy (dx and dy also doubles).
    Added the check after the loop if d > 76, then Closest_Stack_in_Range = From_Stack, to return the card to the dragged from stack if the card wasn't dropped on a stack.

    I changed the range of stacks checked, to not allow dropping cards on the 0 stack, where the cards were originally stacked.
    Code:
    Stack_Dropped_on = Closest_Stack_in_Range(53, 65)
    i.e. don't check for dropping on stack 52, only stacks 53 to 65.

    It didn't take long to modify. I won't post the modified project, so you can learn better by doing the changes yourself, as requested.
    Last edited by passel; Jan 5th, 2021 at 12:56 AM.
    "Anyone can do any amount of work, provided it isn't the work he is supposed to be doing at that moment" Robert Benchley, 1930

  18. #18

    Thread Starter
    Fanatic Member AccessShell's Avatar
    Join Date
    Oct 2013
    Posts
    794

    Re: Moving an object again, Maybe not an object

    I repositioned in code. I changed "Public Card(0 To 51 + 8) As Card_Type" to Public Card(0 To 51 + 14) As Card_Type.
    I cleared the "clutter" on the main form. I moved picDeck to frmTemp2. everything work just as befor. I could se the ccard going from ppicCards to pic Dest(0).

    Since if needed to randomize the input, I created a frmTemp1. This contained 52 individual pics which I could shuffle. I temporarily created a picShuffledCards just below picCards on the main form. While picCards always had the same card on top, picShuffledCards did not. The card on top matched what was shown on frmTeeemp1.

    However, I could only get picCards to move to picDest(0). AS I stepped thru the program, I could see the cards from frmTemp2 (picDeck) moving to picDest(0).

    When I tried the same with picShuffledCards, I got nothing. I was able to get picShuffledCards into picCards, but the movement to picDest(0) did not happen. I know that I don't need to go to picDest(0), but I wanted to try it.

    I did not yet address the Closest_Stack_In_Range issue. I did notice that in the original code there is no sqr function. I also noticed "Stack_Dropped_on = Closest_Stack_in_Range(53, 65)". Why 53,65 when I need picDest (1 to 13)?

  19. #19
    Sinecure devotee
    Join Date
    Aug 2013
    Location
    Southern Tier NY
    Posts
    6,582

    Re: Moving an object again, Maybe not an object

    Quote Originally Posted by AccessShell View Post
    ...
    I did not yet address the Closest_Stack_In_Range issue. I did notice that in the original code there is no sqr function. I also noticed "Stack_Dropped_on = Closest_Stack_in_Range(53, 65)". Why 53,65 when I need picDest (1 to 13)?
    There was no sqr function because it was only checking one dimension, i.e. X. So the Distance in pixels is simply the difference between two X values.
    When you go to two dimensions (X,Y) then the distance in pixels between two X,Y coordinates is the square root of the difference in X squared + the difference in Y squared, i.e. Distance = Sqr( dx^2 + dy^2). Multiplication is faster than raising a number to a power, so I use Distance = Sqr(dx * dx + dy * dy)
    If you didn't actually care about the distance in pixels, you could avoid the square root. In my case, I was using 76 pixels as the threshold of being close enough to be dropped on a stack. If the card was more than 76 pixels away from all stacks, it is returned to the From_Stack.
    So, the 76 pixel value could be squared once and the threshold set to that. Then you would calculate the distance without the square root.

    The picDest pictureboxes are never really used. They are only a visible place holder to show where the stacks are. You could have used image controls, or even rectangular shape controls, or just draw a rectangle at that location. What defines where the stack is, is the same thing that defines where the card is, i.e. the left,top value in the Card array UDTs. So the first 52 positions in the card array (0 to 51) define where the cards are, and the positions in the array after the cards (52 to ...) define where the stacks are.

    When you want to move a card, you change the location in the Card array. Then the Reposition_Card Sub is called to actually move the picturebox holding the card image to the location specified in the Card array.
    If you didn't use pictureboxes for the cards, but rather drew the cards on the form, then the logic would still be the same, i.e. you move the card by updating the position in the Card array. The difference would be that the Reposition_Card Sub would draw the card at that location, rather than move a picturebox to that location.

    Since a card can link to another card to stack it, then the stack itself uses an entry in the Card array to be the placeholder where the first card to be placed on the stack is link to. If the .Next link of a stack or card is -1, that means a card is not linked to that card, so in the case of a stack, the stack is empty.

    As for shuffling the deck, you shouldn't need any other pictures and you shouldn't be modifying what pictures are in which picturebox.
    picCards(0) should be the Ace of Clubs, and will always be the Ace of Clubs. It is card number 0. Likewise, card number 1 should always be the 2 of Clubs.
    You don't shuffle the pictures around, you just choose a random card (0 to 51), and you place that card (the picturebox) where you want.
    For instance, if I want to shuffle a deck, I would just have an array (0 to 51) which represents the deck of cards. You would fill that array with the numbers from 0 to 51. Then you would shuffle those numbers around in the array. So, now your deck of cards may have a 15 in deck(0), 23 in deck(1), 3 in deck(2), etc...

    Once you've shuffled the numbers in the deck, you can then deal the deck by looping through the deck array and placing each card specified where you want, e.g. given the order I mentioned above, card 15 would be dealt first, card 23 would be dealt second and card 3 would be dealt third, etc...

    If you need to know the rank and suit of a card, that is easily calculated from the card number.
    For instance, we mentioned card 23.
    The rank of a card is 0 = Ace, 1 = 2, 2 = 3, .... 12 = King.

    You mod the card number by 13 to get the rank.
    rank = 23 mod 13
    So rank is 10, which is the Jack.

    You do an Integer Divide by 13 to get the suit.
    suit = 23 \ 13
    So suit is 1, which is Diamonds, so the card is the Jack of Diamonds.

    Suits are 0=Clubs, 1=Diamonds, 2=Hearts, 3-Spades

    p.s. As for clutter on the form, I just dragged the picturebox with the card images off the side of the form so I don't see it in the IDE. The visible property is False, so you never see it when running and there isn't any need to see it when in the IDE, so having it off to the side is what I usually do. I don't like adding unnecessary forms to the project, but hat is your prerogative.
    Also, there is no reason the picturebox has to be big enough to see all the cards. I would normally just resize the picturebox so you see a small amount of the Ace of clubs, and then just position it out of the way on the form.
    Last edited by passel; Jan 5th, 2021 at 09:00 PM.
    "Anyone can do any amount of work, provided it isn't the work he is supposed to be doing at that moment" Robert Benchley, 1930

  20. #20

    Thread Starter
    Fanatic Member AccessShell's Avatar
    Join Date
    Oct 2013
    Posts
    794

    Re: Moving an object again, Maybe not an object

    I did not yet address all the suggestions from the previous post. However, I do have a question.
    I, in the IDE, created 13 PBs. In code I places 13 sorted cards in these PBs. That was straightforward. Then I loaded, in code, 13 more PBs on top of the original PBs. Stepping thru I can see the picture in index i-13 being overlaid with no picture in the PBs. (I think). The using the came code as before to place pictures in the overlaid PBs. The index was different to address the new index positions. Just be sure I placed PB(26) below PB(13). The top of PB(26) match the bottom of PB(13). No pictures got placed from the code. The code dis display correctly, what card "were" placed. That code was correct. That's what I am working on now.

  21. #21

    Thread Starter
    Fanatic Member AccessShell's Avatar
    Join Date
    Oct 2013
    Posts
    794

    Re: Moving an object again, Maybe not an object

    Please ignore the last post. As usual, once I post something I solve it.

  22. #22

    Thread Starter
    Fanatic Member AccessShell's Avatar
    Join Date
    Oct 2013
    Posts
    794

    Re: Moving an object again, Maybe not an object

    Oh, I guess I should say what the problem was. I forgot to make the new PBs, that I added in code, ScaleMode - pixels.

  23. #23

    Thread Starter
    Fanatic Member AccessShell's Avatar
    Join Date
    Oct 2013
    Posts
    794

    Re: Moving an object again, Maybe not an object

    Ok, I finally got the layout as I needed it. I am now ready to do the "Closest_Stack_in_Range" code. Right now I have just simple, normal mousedown, mousemove, and mouseup code. I find that when I move a card, any image under it gets erased. If the dragged card only travels over 1/2 of another card, then that half gets erased. The other 1.2 can still be seen. I don't think I've ever seen anything like this before.

  24. #24

    Thread Starter
    Fanatic Member AccessShell's Avatar
    Join Date
    Oct 2013
    Posts
    794

    Re: Moving an object again, Maybe not an object

    Addendum to previous post. If part of the card dragged happens to be off the form, that part does not 'repaint' when coming back on the form.

  25. #25

    Thread Starter
    Fanatic Member AccessShell's Avatar
    Join Date
    Oct 2013
    Posts
    794

    Re: Moving an object again, Maybe not an object

    More info. I have 13 stacks. Each stack contains:
    Level 1: Card images cardDest(1 to 13)
    Level 2: Card Backs cardBacks(1 to 13)
    Level 3: Card Images cardDest(14 to 26)
    Level 4: Card Backs cardBacks(14 to 26
    Level 5: Card Images cardDest(27 to 39)
    Level 6: Card Backs cardBacks(27 to 39)
    Level 7: Card Images cardDest(40 to 52)

    When only level 1 has been coded, card movement is great. No erasing when part of card is off the form.
    When coded to level 2, I cam move the cardbacks with no erasure of cards underneath. No erasing of cardback when card if off the form.
    Any level above causes the erasure of the level beneath. Erasing also occurs if the top exposed layer moved partially off the form

  26. #26
    Sinecure devotee
    Join Date
    Aug 2013
    Location
    Southern Tier NY
    Posts
    6,582

    Re: Moving an object again, Maybe not an object

    I'm not sure what you've done at this point.
    The code I gave just uses one picturebox to represent one card. AutoRedraw should be set to true on all the picCards, so the card should never erase. Perhaps you added new pictureboxes to the array without setting AutoRedraw to true.
    The code just stacks pictureboxes on top of each other.

    I think if you need to have a card show either the card face or the back, then one way would be to save the card face in the .Picture context and then draw the cardback image in the card of those cards that you want to show the back.

    When you want to show the face of the card you can just do a .Cls to clear the back image and the face will be shown. If you need to "flip" the card back over for some reason, then redraw the back image in that picturebox, covering the face picture.
    Last edited by passel; Jan 11th, 2021 at 06:32 AM.
    "Anyone can do any amount of work, provided it isn't the work he is supposed to be doing at that moment" Robert Benchley, 1930

  27. #27

    Thread Starter
    Fanatic Member AccessShell's Avatar
    Join Date
    Oct 2013
    Posts
    794

    Re: Moving an object again, Maybe not an object

    I had 13 PBs .picDest(1-13) arranged on the form - Level 1. They all had AutoRedraw = True. After I saw the previous post I looked for .picDest(0). Found it and discovered it had AutoRedraw = False. I changed it and everything worked fine.

    Thanks.

  28. #28
    Sinecure devotee
    Join Date
    Aug 2013
    Location
    Southern Tier NY
    Posts
    6,582

    Re: Moving an object again, Maybe not an object

    .picDest(1-13) should never be drawn into, so AutoRedraw shouldn't be set for those, it would be a waste. (same for .picDest(0)).
    If setting .picDest(0) AutoRedraw property to True fixed anything, then it means you are misusing what the .picDest array is for, i.e. just a simple collection of "boxes" to indicate where cards can be dropped.

    p.s.
    Since I've implemented the various things I've mentioned in my posts in my example, I'll attach the latest version of the example. I know you didn't want me to code what I was suggesting, and to do it yourself, but they were simple changes, and I changed them as I went along just to have what I suggested available for an example if needed.
    I'll go ahead and post it now, in case others may be interested in seeing the various things implemented.

    The main changes from the earlier example,
    1. More destination stacks were added and laid out how you had them in your post.
    2. The Closest_Stack_in_Range function was changed to compare both X and Y to choose the stack, not just X to choose a column.
    3. Added an array of integers to represent "the deck", so that the numbers in the array could be shuffled and then the "cards" would be dealt in deck order.
    4. To demonstrate drawing a card back added an array of boolean to indicate whether the back was showing for each card. Added a check for the right button being clicked on the card, which would toggle the boolean, and then either "draw the back" in the card picturebox (just fill with blue for the example), or do a .Cls to clear the card back drawing, revealing the face of the card. To prepare for that, I changed the routine that loaded the card images in the pictureboxes, to copy the .Image to the .Picture, so that the .Picture becomes a permanent image of the card face, and the .Image can be drawn into to obscure the card face for whatever purpose desired.
    Attached Files Attached Files
    Last edited by passel; Jan 11th, 2021 at 11:02 AM.
    "Anyone can do any amount of work, provided it isn't the work he is supposed to be doing at that moment" Robert Benchley, 1930

  29. #29

    Thread Starter
    Fanatic Member AccessShell's Avatar
    Join Date
    Oct 2013
    Posts
    794

    Re: Moving an object again, Maybe not an object

    The layout of the cards is as I stated in Post #16. I think the confusion is that when the game starts, all the cards are already in place in the layout. Four cards per position. Therefore, 4 PBs on top of one another. This is the minimum setup. For extra flair, I put a card back between each layer. When I move a card from the layers, the card back for the next card shows, If the move is valid, then the card back is removed and the next card in that layer of cards is revealed. I think you yave thinking of my situation differently. That's my fault for not explaining enough. The point is, your code is extremely helpful, and gives me many ides how I can write the game.

    With this in mind, maybe you can explain a couple of points.
    1. I see no AutoRedraw in your latest code, or in the PB layout. Your statement in the previous post
    ".picDest(1-13) should never be drawn into, so AutoRedraw shouldn't be set for those, it would be a waste." doesn't make sense to me. Without the Autoredraw = True, I get erasing.

    2. For my needs, I do not understand the need for linking.

  30. #30
    Sinecure devotee
    Join Date
    Aug 2013
    Location
    Southern Tier NY
    Posts
    6,582

    Re: Moving an object again, Maybe not an object

    Quote Originally Posted by AccessShell View Post
    ...
    1. I see no AutoRedraw in your latest code, or in the PB layout. Your statement in the previous post
    ".picDest(1-13) should never be drawn into, so AutoRedraw shouldn't be set for those, it would be a waste." doesn't make sense to me. Without the Autoredraw = True, I get erasing.
    ...
    I assume it doesn't make sense to you because you are drawing in the picDest pictureboxes. I am not drawing in the picDest pictureboxes, so setting AutoRedraw to True is wasted for the way I do it. The picCards array pictureboxes do have Autoredraw set to True. The picDest array in the example just show where the stacks are, they are not part of the stack. They don't need to be there. They are just a visual indication. As I said, they don't need to exist and are not used in the code, except during initialization, the root card of the stack is placed there. But the root card of the stack could have been located in that area of the screen there through other means.

    Quote Originally Posted by AccessShell View Post
    ...
    2. For my needs, I do not understand the need for linking.
    If you don't need to link the cards, then don't. You probably wouldn't need the card array at all, only the picCard array. If you stack the "cards" on top of each other, you can only click on the topmost card, and if you can only move one card, then linking cards together so you can move them as a group isn't necessary. Although, it seems like you would have to keep track of what cards were on top of each of the stacks to evaluate the drop
    "Anyone can do any amount of work, provided it isn't the work he is supposed to be doing at that moment" Robert Benchley, 1930

  31. #31

    Thread Starter
    Fanatic Member AccessShell's Avatar
    Join Date
    Oct 2013
    Posts
    794

    Re: Moving an object again, Maybe not an object

    I have successfully integrated the Closest_Stack_in_Range into the program. I am now at the point where

  32. #32

    Thread Starter
    Fanatic Member AccessShell's Avatar
    Join Date
    Oct 2013
    Posts
    794

    Re: Moving an object again, Maybe not an object

    Sorry for the incomplete post. I will try again.

    I have successfully integrated the 'Closest_Stack in Range' into the program.' Since I dont have stacks I renamed it 'Closest_Card_in_Range'.
    I am now writing the rules for the game.

    Thanks for all your help..


  33. #33

    Thread Starter
    Fanatic Member AccessShell's Avatar
    Join Date
    Oct 2013
    Posts
    794

    Re: [RESOLVED] Moving an object again, Maybe not an object

    I have tried to increase the size of the cards by 50%. That is width * 1.5 and Height * 1.5. When I use the 'PaintPicture' method, I find that as the card rank gets higher, the image is shifted to the left in the destination PB. I took the original jpg of all the card as increased the height and width by 50% each.

    The only thing I changed in code is
    # cWidth = 71 * 1.5
    cHeight = 96 * 1.5 #

    Do you know what I might be doing wrong?

    Thanks

  34. #34
    Sinecure devotee
    Join Date
    Aug 2013
    Location
    Southern Tier NY
    Posts
    6,582

    Re: [RESOLVED] Moving an object again, Maybe not an object

    I imagine you didn't increase the size of the picture by an integral amount, i.e. 71 * 1.5 is 106.5 and a picture can't be 106.5 pixels wide. It is either 106 or 107.
    The card images themselves may not all be the same if you stretched the source.

    You said it is shifted left, so it may have rounded to 107, so you could change it to 106 to see if that looks better, but it may end up shifting to the right.
    It might look better if you left the original image at its original size, and just increase the horizontal height and width when you draw the image into the larger pictureboxes, i.e. copy the 71x96 part of the picture into a 106 (or 107) by 144 picturebox, i.e. leave the source coordinates and size the same and change the destination size in the paintpicture statement.
    cWidth is still 71, and half of that is about 35 for add 35 to the destination size.
    cHeight is still 96, and half of that is 48, so add 48 to the destination size.
    Code:
          .picCards(i).PaintPicture .picDeck.Picture, 0, 0, cWidth + 35, cHeight + 48, sx, sy, cWidth, cHeight
    If you would rather stretch the source, then make it an integral amount in the program you use to stretch it, i.e. since there are 13 cards, increment the width in units of 13 pixels, i.e. the bitmap is currently 923 pixels wide (71 * 13), so if you want the cards to be 106 pixels wide, then the image should be stretched to (106 * 13) 1378 pixels wide, and cwidth would be 106.
    "Anyone can do any amount of work, provided it isn't the work he is supposed to be doing at that moment" Robert Benchley, 1930

  35. #35

    Thread Starter
    Fanatic Member AccessShell's Avatar
    Join Date
    Oct 2013
    Posts
    794

    Re: [RESOLVED] Moving an object again, Maybe not an object

    I used the code you suggested
    #.picCards(i).PaintPicture .picDeck.Picture, 0, 0, cWidth + 35, cHeight + 48, sx, sy, cWidth, cHeight#
    along with keeping the original size of the cards picture.

    Thanks it works perfectly. Yes, the resolution is not as good as with no size increase, but it is good enough.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width