Results 1 to 4 of 4

Thread: Bitmaps Flickering

  1. #1

    Thread Starter
    Addicted Member NinjaNic's Avatar
    Join Date
    Dec 2013
    Location
    Earth
    Posts
    230

    Bitmaps Flickering

    Hello!
    Ok so I have one quick question before I start:
    Is there a difference between Me.CreateGraphics and e.Graphics?

    Anyway, my other question is, when I move a bitmap (in a game, for example) it, and the other images, occasionally flicker, my guess is that there is a problem with me using Me.Refresh(), but how do I fix this?

    Thanks.

  2. #2
    PowerPoster boops boops's Avatar
    Join Date
    Nov 2008
    Location
    Holland/France
    Posts
    3,115

    Re: Bitmaps Flickering

    Hi NinjaNic, you haven't shown any code so it's hard to be sure. You may be able to fix the flickering by setting the Form's DoubleBuffered property to True (in the Designer or in code).

    However, there are other possible causes, and CreateGraphics is one of them. Generally you should not use it for drawing with Graphics commands because it just does its painting once only. The resulting render could be corrupted by other code or by other programs. Instead, you should do your drawing with Graphics commands using the e.Graphics provided in the Paint event of the Form, PictureBox etc. That way Windows has some control over when painting takes place, so your graphics will not be corrupted by other processes. There are a few situations where CreateGraphics is useful, but that is another topic.

    Another possible cause of flickering is that painting the bitmap when you drag it takes longer than the interval between MouseMove events. Using Refresh forces the Form to repaint immediately, which means that the bitmap has to be repainted every time the MouseMove event firers. The dragging can be slow and jerky as a result. You could try using Invalidate instead of Refresh. Invalidate puts the repaint requests in a queue, so that movement of the bitmap isn't forced every time a MouseMove event fires.

    Even better is to limit the area that has to be repainted by using Invalidate(rectangle). When dragging an image, you would usually Invalidate the old position, change the position, then Invalidate the new position. You could try following that by Me.Update, which is like Refresh but it is limited to the areas invalidated.

    To sum up, you have a choice between:
    Me.Refresh
    Me.Invalidate
    Me.Invalidate(rectangle)
    Me.Invalidate(rectangle) + Me.Update

    It's not too hard to try all of these alternatives in turn to see which works best for you. But if a lot of processing (or, say, a file read) is involved in creating the bitmap each time, none of them will help. That means rethinking the code.

    BB

  3. #3

    Thread Starter
    Addicted Member NinjaNic's Avatar
    Join Date
    Dec 2013
    Location
    Earth
    Posts
    230

    Re: Bitmaps Flickering

    Thanks for the help! The Double Buffered Property is all it takes (for now... :P )
    And for Me.Invalidate(rectangle) does that mean I have to create an (invisible) rectangle graphic?

  4. #4
    Sinecure devotee
    Join Date
    Aug 2013
    Location
    Southern Tier NY
    Posts
    6,000

    Re: Bitmaps Flickering

    No. It just expects coordinates that define an area that needs to be updated, so it can limit the area it updates (fewer updated pixels means faster updates).
    I have a card game posted in one of the threads here, it was done two ways. In one case the card images were in pictureboxes, and the pictureboxes are moved around.
    In the second case, the card images are just drawn on the form, so no pictureboxes are used. That was just to give an example of two methods of meeting the requirement to move card images around to see the different techniques used for the two approaches.

    In any case, one part of the program automatically moves multiple cards in an animated fashion to the home stacks.
    As boops boops said, when the program is moving a given card, what it does is invalidate a rectangle area of where the card is, move the card, and invalidate the rectangle of the new area of the card. That excerpted code looks like this:
    Code:
            InvalidateCardArea(Fly_Stack(j).Card)          '  Invalidate area where card is now
            picCards(Fly_Stack(j).Card).rect.Location = New Point(Card(Fly_Stack(j).Card).Left, Card(Fly_Stack(j).Card).Top)
            InvalidateCardArea(Fly_Stack(j).Card)          '  Invalidate area where card moved to
    
      Private Sub InvalidateCardArea(crd As Integer)
        Dim InvalidRect As New Rectangle(0, 0, 74, 98)  'make rectangle two pixels larger than image
        InvalidRect.X = CInt(picCards(crd).rect.X - 1)  'and offset left and up by one, so no trailing garbage left at edge of card image
        InvalidRect.Y = CInt(picCards(crd).rect.Y - 1)
        Form1.Invalidate(InvalidRect)
      End Sub
    The rectangle object is created and its width and size is actually 2 pixels larger than the size of the card to ensure the area needing to be refreshed is inside the rectangle bounds. If the right or bottom edge of the area that needs to be updated is coincident with the edges of the rectangle, they won't be updated, so you can leave a bit of "garbage".
    The X,Y position of the rectangle is updated to the top/left of the area to be updated, but -1,-1 in both directions to make sure the area to be updated is withing the bounds of the rectangle, although I'm not sure if that is a requirement for the left and top.
    So, the result is the rectangle outlines the area that needs to be updated.

    p.s. In case you're interested, the versions of the card game code are in the following thread:
    http://www.vbforums.com/showthread.p...vent&p=4711925
    The picturebox version is in post #6, the DrawImage version in post #12.

    p.p.s. Warning. The card game code was written in VB3 originally (mid to late 90s) so does not take advantage of classes in any way, therefore is not a good example of the way code should be written to take advantage of the object oriented nature of VB.Net.

    p.p.p.s In the following thread:
    http://www.vbforums.com/showthread.p...zing&p=4681915
    Post #8, is another visual example of Invalidating a portion of the form when you move a "piece" around a form. If you comment out the Invalidate line, and use the two lines that invalidate a rectangle before and after, you can see the area refreshed because a green "haze" is drawn on the form when you click on the form, and is not redrawn as you drag.
    If you comment out the Invalidate in the Resize method, you get another interesting effect when you resize the form.
    Last edited by passel; Jul 27th, 2014 at 10:46 PM.

Tags for this Thread

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