Results 1 to 16 of 16

Thread: [RESOLVED] BitBlt issue smearing the character on a moving background...

  1. #1

    Thread Starter
    Addicted Member
    Join Date
    Sep 2013
    Posts
    190

    Resolved [RESOLVED] BitBlt issue smearing the character on a moving background...

    I made visible the Character and CharacterMask for referencing
    Name:  smear2.jpg
Views: 1194
Size:  79.1 KB

    VB6
    Windows 7

    I am using BitBlt to move the map behind the character. I am also using BitBlt to draw the character. The character is animating (running). So, to keep the character centered, I am having to continually adjust the X and Y of the character, which is not the problem. The problem is the smearing I am getting. The code is in a Timer:

    Code:
    If (timerMapMover.Tag = "NORTH") And (MoveMapY < 0) Then
        MoveMapY = MoveMapY + 1
        myCharacter.Picture = LoadResPicture("NORTH" & MyAni, 0)
        MakeMask myCharacter, myCharacterMask, CLng(vbBlack), CLng(vbWhite), CLng(vbBlack)
        BltTheCharacter myBuffer, myCharacter, myCharacterMask, ConvertTwipsToPixelsX(Me.Width / 2) - MoveMapX, ConvertTwipsToPixelsY(Me.Height / 2) - MoveMapY
        BltFinal myStage, myBuffer, MoveMapX, MoveMapY
    End If
    myCharacter is my Hero
    myCharacterMask is the masked version of my Hero
    myBuffer is the buffer PictureBox
    myStage is where everything is BitBlt'd once it is all combined in the buffer

    Obviously I am moving North, therefore the map is moving down to give the appearance of the character moving North.
    I am using images loaded in a .res file.
    MakeMask calls a routine to create the mask.

    What am I missing to clear up the smearing issue?

  2. #2
    PowerPoster
    Join Date
    Jan 2008
    Posts
    11,074

    Re: BitBlt issue smearing the character on a moving background...

    Is this the same problem you had in your other thread? I thought you had that taken care of based on what you were told or is this a totally different problem.


    Anything I post is an example only and is not intended to be the only solution, the total solution nor the final solution to your request nor do I claim that it is. If you find it useful then it is entirely up to you to make whatever changes necessary you feel are adequate for your purposes.

  3. #3

    Thread Starter
    Addicted Member
    Join Date
    Sep 2013
    Posts
    190

    Re: BitBlt issue smearing the character on a moving background...

    Same project, different issue. Before, the map was smearing. I fixed that. Now my character is smearing.

  4. #4
    PowerPoster Arnoutdv's Avatar
    Join Date
    Oct 2013
    Posts
    6,734

    Re: BitBlt issue smearing the character on a moving background...

    I think this is because you don't repaint the background.
    You are just blitting stuff on it, but not removing it.

    Either restore the partial background when an item is moved, or in the main loop paint all items one by one, starting with the background.

  5. #5
    PowerPoster
    Join Date
    Jan 2008
    Posts
    11,074

    Re: BitBlt issue smearing the character on a moving background...

    I believe Arnoutdv is correct. Anytime you move a drawing by BitBlt'ing it you need to first save the area you will BitBlt to then BitBlt to that position. Now save the next area you will BitBlt to and then again BitBlt to that position then restore the area you BitBlt from.


    Anything I post is an example only and is not intended to be the only solution, the total solution nor the final solution to your request nor do I claim that it is. If you find it useful then it is entirely up to you to make whatever changes necessary you feel are adequate for your purposes.

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

    Re: BitBlt issue smearing the character on a moving background...

    edit: [I didn't see the first post, I thought this was a continuation of your ealier post... It certainly looks like you're using a tile based map, but maybe it was tiled offline, and you just moving a large map. In any case, perhaps the post can still be useful].

    Or, if you were doing a tile based map, you would probably be redrawing all the background because you would be be bitblting all the tiles of your background as you move.
    I did a short example for someone around 7 to 8 years ago. I did a search and found it, and will attach it. It doesn't do much. It was just thown to gether for someone who provided the car images to show moving the car around a tile based map. Since I didn't have a tile set, and wasn't going to take the time to build a map, I just "generate" four random tiles of different color and assign them randomly to the "map".
    In this example, the car will move toward the center of the window, and then remain there as the map moves by, until an edge is reached, in which case the car will move out of the center area and out to the edge of the window. I found a zip file of it, a little over 7 years old and didn't retry it to make sure it works but I wouldn't have zipped it up if I didn't post it back then, so should work. You use the up key to go forward, and the down key to go backwards, and the left,right keys to turn.
    Attached Files Attached Files
    Last edited by passel; Jan 17th, 2014 at 01:20 PM.

  7. #7
    New Member c080's Avatar
    Join Date
    Oct 2013
    Posts
    11

    Re: BitBlt issue smearing the character on a moving background...

    Just a note , to use picturebox.cls before drawing anything. Use once.
    I also recommend using without a timer for drawing.

    Public Const SRCAND = (&H8800C6) ' Use for your Mask , White Background
    Public Const SRCPAINT = (&HEE0086) 'Use for your Picture , Black Background


    Public Const BLACKNESS = (&H42) 'All Black
    Public Const DSINVERT = (&H550009) 'Invert.
    Public Const MERGECOPY = (&HC000CA) 'Pattern and the source
    Public Const MERGEPAINT = (&HBB0226) 'Inverted source
    Public Const NOTSRCCOPY = (&H330008) 'Copies the inverted source bitmap to the destination.
    Public Const NOTSRCERASE = (&H1100A6) 'Inverts the result of combining the destination.
    Public Const PATCOPY = (&HF00021) 'Copies the pattern to the destination bitmap.
    Public Const PATINVERT = (&H5A0049) 'Combines the destination bitmap with the pattern.
    Public Const PATPAINT = (&HFB0A09) 'Combines the inverted source bitmap with the pattern.
    Public Const SRCAND = (&H8800C6) 'Combines pixels of the destination and source bitmap.
    Public Const SRCCOPY = (&HCC0020) 'Copies the source bitmap to destination bitmap.
    Public Const SRCERASE = (&H4400328) 'Inverts the destination bitmap and combine.
    Public Const SRCINVERT = (&H660046) 'Combines pixels of the destination and source bitmap
    Public Const SRCPAINT = (&HEE0086) 'Combines pixels of the destination and source bitmap
    Public Const WHITENESS = (&HFF0062) 'Turns all output white.

    Just noting that if you havent done too much which i can see that maybe you havent.

    I would try checking out my post here for reference. Would be good for any game.

    http://www.vbforums.com/showthread.p...t=#post4557703

    Good Luck

  8. #8
    PowerPoster
    Join Date
    Jan 2008
    Posts
    11,074

    Re: BitBlt issue smearing the character on a moving background...

    C080,

    Are you sure you're posting in the correct thread? What's with this picturebox.cls


    Anything I post is an example only and is not intended to be the only solution, the total solution nor the final solution to your request nor do I claim that it is. If you find it useful then it is entirely up to you to make whatever changes necessary you feel are adequate for your purposes.

  9. #9
    New Member c080's Avatar
    Join Date
    Oct 2013
    Posts
    11

    Re: BitBlt issue smearing the character on a moving background...

    Im sorry , i wasnt specific. By not clearing what you are drawing to , it causes the smearing , whether form or picturebox.
    I used this just as a general outline of any and wasnt precise.

  10. #10
    PowerPoster
    Join Date
    Jan 2008
    Posts
    11,074

    Re: BitBlt issue smearing the character on a moving background...

    Well, anyway, that has already been mentioned previously


    Anything I post is an example only and is not intended to be the only solution, the total solution nor the final solution to your request nor do I claim that it is. If you find it useful then it is entirely up to you to make whatever changes necessary you feel are adequate for your purposes.

  11. #11
    New Member c080's Avatar
    Join Date
    Oct 2013
    Posts
    11

    Re: BitBlt issue smearing the character on a moving background...

    Just a note when blitting , the first blit is always on the bottom , behind the next , so if you do a SRCCOPY blit of a picture , that just copys the picture then use SRCAND and SCCPAINT for your pictures with masks , you can test this.

    Useful to know when game programming and wanting something in the background behind a character for sidescroll or to make something hidden.
    If you

    You could have a mainLoop which does all the drawing with coordinates and draws off screen then comes into focus. Ive noticed that with gdi , without drawing everything at once you come to a point where the game hangs or skips around. At some point or another.

    So putting all your drawing into one loop makes this simple and the only code you would need is where they will be drawn.

    Just a note.
    I do to only help and i dont know everything , i state what i do from experience as i know i have much to learn , even ever so little.
    Sometimes mentioning something in a different manor gets a better interpretation.

  12. #12
    Elite Hacker Jacob Roman's Avatar
    Join Date
    Aug 2004
    Location
    Miami Beach, FL
    Posts
    5,349

    Re: BitBlt issue smearing the character on a moving background...

    Quote Originally Posted by c080 View Post
    Just a note , to use picturebox.cls before drawing anything. Use once.
    I also recommend using without a timer for drawing.

    Public Const SRCAND = (&H8800C6) ' Use for your Mask , White Background
    Public Const SRCPAINT = (&HEE0086) 'Use for your Picture , Black Background


    Public Const BLACKNESS = (&H42) 'All Black
    Public Const DSINVERT = (&H550009) 'Invert.
    Public Const MERGECOPY = (&HC000CA) 'Pattern and the source
    Public Const MERGEPAINT = (&HBB0226) 'Inverted source
    Public Const NOTSRCCOPY = (&H330008) 'Copies the inverted source bitmap to the destination.
    Public Const NOTSRCERASE = (&H1100A6) 'Inverts the result of combining the destination.
    Public Const PATCOPY = (&HF00021) 'Copies the pattern to the destination bitmap.
    Public Const PATINVERT = (&H5A0049) 'Combines the destination bitmap with the pattern.
    Public Const PATPAINT = (&HFB0A09) 'Combines the inverted source bitmap with the pattern.
    Public Const SRCAND = (&H8800C6) 'Combines pixels of the destination and source bitmap.
    Public Const SRCCOPY = (&HCC0020) 'Copies the source bitmap to destination bitmap.
    Public Const SRCERASE = (&H4400328) 'Inverts the destination bitmap and combine.
    Public Const SRCINVERT = (&H660046) 'Combines pixels of the destination and source bitmap
    Public Const SRCPAINT = (&HEE0086) 'Combines pixels of the destination and source bitmap
    Public Const WHITENESS = (&HFF0062) 'Turns all output white.

    Just noting that if you havent done too much which i can see that maybe you havent.

    I would try checking out my post here for reference. Would be good for any game.

    http://www.vbforums.com/showthread.p...t=#post4557703

    Good Luck
    I actually don't recommend you use a Timer. Timers are horrible. Instead you use whats called a game loop locked at 60 frames per second:

    vb Code:
    1. Option Explicit
    2.  
    3. Private Declare Function QueryPerformanceCounter Lib "kernel32" (lpPerformanceCount As Currency) As Long
    4. Private Declare Function QueryPerformanceFrequency Lib "kernel32" (lpFrequency As Currency) As Long
    5.  
    6. Private Ticks_Per_Second As Currency
    7. Private Start_Time As Currency
    8. Private Milliseconds As Long
    9. Private Last_Time As Long
    10.  
    11. Private Get_Frames_Per_Second As Long
    12. Private Frame_Count As Long
    13.  
    14. Private Running As Boolean
    15.  
    16. Public Function Hi_Res_Timer_Initialize() As Boolean
    17.     If QueryPerformanceFrequency(Ticks_Per_Second) = 0 Then
    18.         Hi_Res_Timer_Initialize = False
    19.     Else
    20.         QueryPerformanceCounter Start_Time
    21.         Hi_Res_Timer_Initialize = True
    22.     End If
    23. End Function
    24.  
    25. Public Function Get_Elapsed_Time() As Single
    26.     Dim Last_Time As Currency
    27.     Dim Current_Time As Currency
    28.    
    29.     QueryPerformanceCounter Current_Time
    30.     Get_Elapsed_Time = (Current_Time - Last_Time) / Ticks_Per_Second
    31.     QueryPerformanceCounter Last_Time
    32. End Function
    33.  
    34. Private Sub Lock_Framerate(Target_FPS As Long)
    35.     Static Last_Time As Currency
    36.     Dim Current_Time As Currency
    37.     Dim FPS As Single
    38.    
    39.     Do
    40.         QueryPerformanceCounter Current_Time
    41.         FPS = Ticks_Per_Second / (Current_Time - Last_Time)
    42.     Loop While (FPS > Target_FPS)
    43.    
    44.     QueryPerformanceCounter Last_Time
    45. End Sub
    46.  
    47. Private Function Get_FPS() As String
    48.     Frame_Count = Frame_Count + 1
    49.        
    50.     If Get_Elapsed_Time - Milliseconds >= 1 Then
    51.         Get_Frames_Per_Second = Frame_Count
    52.         Frame_Count = 0
    53.         Milliseconds = Get_Elapsed_Time
    54.     End If
    55.    
    56.     Get_FPS = "FPS: " & Get_Frames_Per_Second
    57. End Function
    58.  
    59. Private Sub Shutdown()
    60.     Running = False
    61.     Unload Me
    62. End Sub
    63.  
    64. Private Sub Main()
    65.     With Me
    66.         .Show
    67.         .ScaleMode = 3
    68.         .AutoRedraw = True
    69.         .BackColor = RGB(0, 0, 0)
    70.     End With
    71.  
    72.     Running = True
    73.     Hi_Res_Timer_Initialize
    74.     Milliseconds = Get_Elapsed_Time
    75.     Game_Loop
    76.  
    77. End Sub
    78.  
    79. Private Sub Game_Loop()
    80.     Do While Running = True
    81.  
    82.         'Game code goes here
    83.  
    84.         Me.Caption = Get_FPS
    85.         Lock_Framerate 60
    86.         DoEvents
    87.     Loop
    88. End Sub
    89.  
    90. Private Sub Form_Load()
    91.     Main
    92. End Sub
    93.  
    94. Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
    95.     If KeyCode = vbKeyEscape Then
    96.         Shutdown
    97.     End If
    98. End Sub
    99.  
    100. Private Sub Form_Unload(Cancel As Integer)
    101.     Shutdown
    102. End Sub

    But if you were to build a whole game off that idea, you would have game states. This is just an example:

    vb Code:
    1. Option Explicit
    2.  
    3. Private Enum GAME_STATUS
    4.     INTRO = 1
    5.     TITLE_SCREEN = 2
    6.     LOAD_SCREEN = 3
    7.     GAME_WORLD = 4
    8.     ENDING = 5
    9. End Enum
    10.  
    11. Private Declare Function QueryPerformanceCounter Lib "kernel32" (lpPerformanceCount As Currency) As Long
    12. Private Declare Function QueryPerformanceFrequency Lib "kernel32" (lpFrequency As Currency) As Long
    13.  
    14. Private Ticks_Per_Second As Currency
    15. Private Start_Time As Currency
    16. Private Milliseconds As Long
    17. Private Last_Time As Long
    18.  
    19. Private Get_Frames_Per_Second As Long
    20. Private Frame_Count As Long
    21.  
    22. Private Running As Boolean
    23.  
    24. Public Function Hi_Res_Timer_Initialize() As Boolean
    25.     If QueryPerformanceFrequency(Ticks_Per_Second) = 0 Then
    26.         Hi_Res_Timer_Initialize = False
    27.     Else
    28.         QueryPerformanceCounter Start_Time
    29.         Hi_Res_Timer_Initialize = True
    30.     End If
    31. End Function
    32.  
    33. Public Function Get_Elapsed_Time() As Single
    34.     Dim Last_Time As Currency
    35.     Dim Current_Time As Currency
    36.    
    37.     QueryPerformanceCounter Current_Time
    38.     Get_Elapsed_Time = (Current_Time - Last_Time) / Ticks_Per_Second
    39.     QueryPerformanceCounter Last_Time
    40. End Function
    41.  
    42. Private Sub Lock_Framerate(Target_FPS As Long)
    43.     Static Last_Time As Currency
    44.     Dim Current_Time As Currency
    45.     Dim FPS As Single
    46.    
    47.     Do
    48.         QueryPerformanceCounter Current_Time
    49.         FPS = Ticks_Per_Second / (Current_Time - Last_Time)
    50.     Loop While (FPS > Target_FPS)
    51.    
    52.     QueryPerformanceCounter Last_Time
    53. End Sub
    54.  
    55. Private Function Get_FPS() As String
    56.     Frame_Count = Frame_Count + 1
    57.        
    58.     If Get_Elapsed_Time - Milliseconds >= 1 Then
    59.         Get_Frames_Per_Second = Frame_Count
    60.         Frame_Count = 0
    61.         Milliseconds = Get_Elapsed_Time
    62.     End If
    63.    
    64.     Get_FPS = "FPS: " & Get_Frames_Per_Second
    65. End Function
    66.  
    67. Private Sub Shutdown()
    68.     Running = False
    69.     Unload Me
    70. End Sub
    71.  
    72. Private Sub Main()
    73.     With Me
    74.         .Show
    75.         .ScaleMode = 3
    76.         .AutoRedraw = True
    77.         .BackColor = RGB(0, 0, 0)
    78.     End With
    79.  
    80.     Running = True
    81.     Hi_Res_Timer_Initialize
    82.     Milliseconds = Get_Elapsed_Time
    83.     Game_Loop
    84.  
    85. End Sub
    86.  
    87. Private Sub Game_Loop()
    88.     Do While Running = True
    89.  
    90.         'Game code goes here
    91.  
    92.         Select Case Status
    93.             Case INTRO
    94.                 'Intro_Loop
    95.             Case TITLE_SCREEN
    96.                 'Title_Screen_Loop
    97.             Case LOAD_SCREEN
    98.                 'Load_Screen_Loop
    99.             Case GAME_WORLD
    100.                 'Game_World_Loop
    101.             Case ENDING
    102.                 'Ending_Loop
    103.         End Select
    104.  
    105.  
    106.         Me.Caption = Get_FPS
    107.         Lock_Framerate 60
    108.         DoEvents
    109.     Loop
    110. End Sub
    111.  
    112. Private Sub Form_Load()
    113.     Main
    114. End Sub
    115.  
    116. Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
    117.     If KeyCode = vbKeyEscape Then
    118.         Shutdown
    119.     End If
    120. End Sub
    121.  
    122. Private Sub Form_Unload(Cancel As Integer)
    123.     Shutdown
    124. End Sub

    Another thing is that you shouldn't use BitBlt for making games with as it is a royal pain to work with. Your better off either using TransparentBlt which doesnt require a mask for transparency, or step into the realm of DirectX in VB. With DirectX, you can make beautiful enriched games both in 2D and 3D such as these:





    I have lots and lots of DirectX examples in my signature

  13. #13
    PowerPoster
    Join Date
    Jan 2008
    Posts
    11,074

    Re: BitBlt issue smearing the character on a moving background...

    This simple example shows you how to move an image across a canvas using BitBlt API. This example uses a Picturebox control where you move the image using the command buttons or the up, down, left, and right keyboard keys.

    The basic steps to move an image are:

    1) Save the rectangle area from the Picturebox the size of the rectangle of the original image.

    2) BitBlt the original image from it's source to that area on the Picturebox. It is better to use TransparentBlt instead of BitBlt because it does not require that you use masking to make image transparent.

    3) Restore the area that was saved

    4) Set next position

    5) Save the area that represents the next position you want to move the image to

    6) BitBlt image to next position

    Repeat at Step 3

    The attached project use this method.
    Attached Files Attached Files


    Anything I post is an example only and is not intended to be the only solution, the total solution nor the final solution to your request nor do I claim that it is. If you find it useful then it is entirely up to you to make whatever changes necessary you feel are adequate for your purposes.

  14. #14
    PowerPoster
    Join Date
    Jan 2008
    Posts
    11,074

    Re: BitBlt issue smearing the character on a moving background...

    Here's another example. This one uses BitBlt to move the balls so it requires masking. The balls are moved using the mouse pointer and can be moved anywhere on the screen
    Attached Files Attached Files


    Anything I post is an example only and is not intended to be the only solution, the total solution nor the final solution to your request nor do I claim that it is. If you find it useful then it is entirely up to you to make whatever changes necessary you feel are adequate for your purposes.

  15. #15
    New Member c080's Avatar
    Join Date
    Oct 2013
    Posts
    11

    Re: BitBlt issue smearing the character on a moving background...

    I also recommend using without a timer for drawing. 'Quoting myself
    'See Above.
    My attached Link , shows a thread ' Loop from that post. = Boolean , that is continuous. Until false.
    No Timer.

    Cheers

  16. #16

    Thread Starter
    Addicted Member
    Join Date
    Sep 2013
    Posts
    190

    Re: BitBlt issue smearing the character on a moving background...

    Here is the :::cough:::finished:::cough::: product.

    http://www.vbforums.com/showthread.p...91#post4600591

    Marking this thread as Resolved.

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