none
Bad Flickering in Game RRS feed

  • Question

  • Hello,

    I am somewhat new to Visual Basic and am trying to code a game. The title screen contains a animation. Once the user presses enter, refreshes and paints the next level's background. Then it paints the player's sprite. Once it paints the sprite, it starts flickering badly. If I try to move the player using WASD, the player disappears completely. Here is some of the code for the game:

        Private Sub GlooberForm_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
            Dim startFont As Font = New Font("04b", 30, FontStyle.Bold, GraphicsUnit.Pixel)
            Dim whiteBrush As New SolidBrush(Color.White)
            Dim myGraphics As Graphics = e.Graphics
            If gameStarted = False Then
                myGraphics.DrawString("PRESS ENTER TO START", startFont, whiteBrush, 75, 300)
                myGraphics.DrawImage(gloobers(startFrame), logoPoint)
            End If
            If gameStarted = True Then
                Select Case currentKey
                    Case "w"
                        ' paint, and then invalidate? integer for invalidated? need to only invalidate once. use update? just need to stop flickering'
                        If keyPressed = True Then
                            playerSprite.Size.X = 55
                            playerSprite.Size.Y = 55
                            playerSprite.PaintImage(myGraphics, DoubleBuffered)
                            Invalidate()
                            Invalidated = 1
                        End If
                    Case "s"
                        If keyPressed = True Then
                            Invalidate()
                            playerSprite.Size.X = 55
                            playerSprite.Size.Y = 55
                            playerSprite.PaintImage(myGraphics, DoubleBuffered)
                        End If
                    Case "a"
                        If keyPressed = True Then
                            Invalidate()
                            playerSprite.Size.X = 55
                            playerSprite.Size.Y = 55
                            playerSprite.PaintImage(myGraphics, DoubleBuffered)
                        End If
                End Select
                Select Case currentLevel
                    Case 1
                        Refresh()
                        myGraphics.DrawImage(level(0), 0, 0)
                        playerSprite.SetImageResource(My.Resources.playerright__2_)
                        If keyPressed = False Then
                            playerSprite.Size.X = 55
                            playerSprite.Size.Y = 55
                            playerSprite.UpperLeft.X = 240
                            playerSprite.UpperLeft.Y = 100
                            playerSprite.PaintImage(myGraphics, DoubleBuffered)
                            Refresh()
                        End If
                End Select
            End If
        End Sub

    Does anyone know what my problem is? I believe it may be that Invalidate() won't stop. Am I right?

    Thanks,

    The Visual Basic Noob

    Monday, January 8, 2018 11:31 PM

Answers

  • Try this in the form load.

    Me.doublebuffer = true

    PS You should not put invalidate or refresh in a paint event unless you want an infinite loop.


    Monday, January 8, 2018 11:49 PM

All replies

  • Try this in the form load.

    Me.doublebuffer = true

    PS You should not put invalidate or refresh in a paint event unless you want an infinite loop.


    Monday, January 8, 2018 11:49 PM
  • Did you set the Form's DoubBuffered property to true?  You'll need to do so if not.  In the Form.Load event handler set Me.DoubleBuffered = True.

    The next question would be what does the method playerSprite.PaintImage(myGraphics, DoubleBuffered) do?  The issue may arise from code in that method.

    Finally, how does the form get invalidated to cause the paint event?  The method you are using there may play into it as well.

    For what it's worth I'm working on a simple game engine for Windows Forms that you may want to review; here's a link to the thread about it.


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    Monday, January 8, 2018 11:53 PM
    Moderator
  • Hi

    You appear to have a lot of code in the Paint event that should really be elsewhere.  You are using Invalidate (and Refresh) within the code block that is called by the Invalidate (the Paint event). All of the key handling code could probably be dealt with elsewhere (in the Key event handlers perhaps). Probably, the 'playerSprite' properties could be elsewhere too.

    *

    Although you would need some other code within the Paint event handler, that handler should really be restricted as much as possible to the Graphics methods etc.


    *

    The more code you have in the Paint event, the more you risk slowing things down dramatically.

    *

    Do you have  DoubleBuffered set to True (say in the Form load event?

    *

    It is also a possibility that the recent post by Reed Kimble could help you also.

    EDIT: ha ha Reed, I was just composing this when you posted your reply.


    Regards Les, Livingston, Scotland


    • Edited by leshay Monday, January 8, 2018 11:59 PM
    Monday, January 8, 2018 11:57 PM
  •  Well,  you are calling the Invalidate method and the Refresh method inside the Paint event.  That should not be required and is probably a good reason for the flickering.

     The Refresh method will postpone all other messages that the form has in it's message queue and immediately force the form to paint itself again.  So,  if the currentLevel is 1, and keyPressed is False,  you pretty much have an infinite loop where the form will just keep painting itself over and over again.

     The Invalidate method will allow the form to process any messages in it's message queue and then repaint the form when it has the chance.  However,  you can specify parameters in the Invalidate method to tell it to only repaint a certain rectangle area in the form and/or tell it not to repaint any child controls that may be on the form.

     As i said though,  you should not be calling either of those methods inside the Paint event.  All the processing of positions and visibility of text or characters should be done outside the paint event,  in a game loop or even a Timer Tick event.  After all these things are set,  you would then call the Invalidate or Refresh method just once to update the changes.

     Also,  if you are drawing all this stuff on the Form,  you should have the Form's DoubleBuffered property set to True.  I think you probably have more of a problem with the way you are calling Invalidate and Refresh inside the Paint event though.

    PS - You should be calling the Dispose method on the New Font and New SolidBrush at the end of your Paint event sub.  Don't forget to do that.  It might be better to just create them at a Class scope,  initialize them when the form Loads and Dispose them when the Form is Closing.

    EDIT - Man i am a slow poster... There was not even one reply when i started posting,  so sorry if i have repeated anything that has already been said.  8)


    If you say it can`t be done then i`ll try it


    • Edited by IronRazerz Tuesday, January 9, 2018 12:16 AM
    Tuesday, January 9, 2018 12:03 AM

  • EDIT - Man i am a slow poster... There was not even one reply when i started posting,  so sorry if i have repeated anything that has already been said.  8)


    If you say it can`t be done then i`ll try it


    Hi

    It happens to everyone. No way of knowing others are beavering away composing/posting behind your back :) Happens to me a lot.


    Regards Les, Livingston, Scotland

    Tuesday, January 9, 2018 1:01 AM
  • LOL yeah, it appears we all hit this one around the same time. :)

    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    Tuesday, January 9, 2018 1:29 AM
    Moderator