Results 1 to 12 of 12

Thread: Make for loops wait before they loop again

  1. #1

    Thread Starter
    Registered User
    Join Date
    Aug 2013
    Posts
    3

    Make for loops wait before they loop again

    Hello,
    I have been programming a small game for a while. It involves pictures to be constantly moving across the screen. One way to get something to move is to add a timer, and when it ticks add say 5 pixels to the distance between the pic box and the top of the form. Well, while I have been working on this game i have been adding in a fair few timers and different stuff happening when timers tick, and it all got a bit confusing and not working smoothly so I thought I'd try using a while loop.

    This is just a test to see if it can work.
    Code:
    Public Class Form1
    
        Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
            Dim x As Integer = 0
    
            Do While x = 0
    
                PictureBox1.Top += 10
    
            Loop
    
        End Sub
    End Class
    So as you can see i'm making the picturebox move downwards while x is equal to 0.

    WHAT i want is before it does a loop, it waits a second or however long. If you try this code, you'd see the picturebox moves insanely fast down the form.

    My goal is to have it moving down slower like a tetris piece xD

    Does anyone know how I could just make it wait a bit?

    Cheers, Callum

  2. #2
    PowerPoster Evil_Giraffe's Avatar
    Join Date
    Aug 2002
    Location
    Suffolk, UK
    Posts
    2,555

    Re: Make for loops wait before they loop again

    Nope, that's not going to work. The window isn't going to redraw until the Click event handler has finished running so you won't see it move gradually down the screen, it'll jump there. If you got your delay working then it would just wait longer before jumping to its final position. I would stick to the timer approach, but try and make it all work from a single timer that ticks quite frequently, and only performs the actions relevant at that time.

    In fact, to stop a build up of Timer ticks with a small interval that is shorter than the processing time of the tick handler, I would actually have a timer that doesn't continually fire, and the very last thing in the tick event handler is to set the next tick up.

  3. #3
    Pro Grammar chris128's Avatar
    Join Date
    Jun 2007
    Location
    England
    Posts
    7,604

    Re: Make for loops wait before they loop again

    Yeah I agree you need to use a timer instead of a loop. You could use Thread.Sleep(1000) in the loop to pause it for a second but like Evil_Giraffe pointed out, the UI will just freeze and not redraw until it finishes the loop.

    PS if in future you ever want a loop to run infinitely like it is in your example, you can just do this instead of using a Do While loop:
    Code:
    Do
    
      'do something here
    
    Loop
    Last edited by chris128; Aug 15th, 2013 at 04:21 AM.
    My free .NET Windows API library (Version 2.2 Released 12/06/2011)

    Blog: cjwdev.wordpress.com
    Web: www.cjwdev.co.uk


  4. #4
    New Member
    Join Date
    Mar 2006
    Location
    Toledo OH
    Posts
    9

    Re: Make for loops wait before they loop again

    Code:
    Public Class Form1
        Private m_timer As Timer
        Const constSleepTime As Integer = 500
    
        Public Sub New()
    
            ' This call is required by the designer.
            InitializeComponent()
    
            ' Add any initialization after the InitializeComponent() call.
            m_timer = New Timer With {.Interval = 100}
            AddHandler m_timer.Tick, AddressOf timer_tick
    
        End Sub
        Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
            m_timer.Enabled = True
    
            '...Start Loop logic
            .
            .
            .
            'Pause for 500 milliseconds
            System.Threading.Thread.Sleep(constSleepTime)
            .
            .
            '...End Loop logic
    
            m_timer.Enabled = False
        End Sub
    
        Private Sub timer_tick(sender As Object, e As System.EventArgs)
            Application.DoEvents()
        End Sub
    
    
    End Class
    Last edited by chad101; Aug 15th, 2013 at 07:26 AM.

  5. #5
    PowerPoster Evil_Giraffe's Avatar
    Join Date
    Aug 2002
    Location
    Suffolk, UK
    Posts
    2,555

    Re: Make for loops wait before they loop again

    No, that won't work chad101. Not only would using Application.DoEvents be a bad idea - if the OP is having difficulty handling multiple timers firing, throwing the problems of re-entrancy from a DoEvents call into the mix is going to cause even more problems.

    However, aside from that, it won't work how you've coded it. The timer is started at the beginning of the button click event handler, and is quietly queuing up tick events while the button handler executes. When the button handler finishes executing, the screen can be redrawn, the picturebox jumps to its final position, and then all those tick events are handled and the Application.DoEvents calls are made.

    The point of Application.DoEvents is to allow the processing of other messages in the queue whilst you are in the middle of processing a different one. By putting the call to Application.DoEvents inside the processing of a different message, you don't actually interrupt the processing of the blocking message to let that Application.DoEvents run.

  6. #6
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    39,038

    Re: Make for loops wait before they loop again

    While EG covered this indirectly, let me more explicitly point out that thread.Sleep does just that: It puts the thread to sleep for that duration. Since this is the UI thread, NOTHING will be happening during that interval, including responding to any user input, any events (such as timer ticks), or anything else. Sleep is sleep, and it happens at the OS level, so the app doesn't do any backgroud processing of events.
    My usual boring signature: Nothing

  7. #7

    Thread Starter
    Registered User
    Join Date
    Aug 2013
    Posts
    3

    Re: Make for loops wait before they loop again

    Cheers guys

    Well, thread.sleep was a solution, but as you guys said it freezes the whole program, if in that time i say pressed right to move a picturebox right it wouldn't happen.

    I kinda have another query, if you don't mind me asking. I have sort of fixed up my timers problem, but it has made a new issue.
    In my form I need to know when two pic boxes intersect, to which then a label in the corner of the form goes from it's current position of health which may be 5, and then 1 is taken away. It looks like this. (This part of code is in a sub that occurs every time a timer ticks)

    Code:
        Private Sub Timer1_Tick(sender As System.Object, e As System.EventArgs) Handles Timer1.Tick
    
            If PictureBox1.Bounds.IntersectsWith(PictureBox2.Bounds) Then
                HealthValue -= 1
                Label1.Text = "Health: " & HealthValue.ToString()
    
            End If
    
        End Sub
    The problem is, due to the timers rate of ticking which has to be high so it's always checking, means that when the picture boxes collide the health amount will go down like 5,4,3,2,1 because the timer is still ticking while the 2 picture boxes are still intersecting as both picture boxes are roughly 70 , 20 in size.

    How can i make it so that the very pixel when they first collide, the health is equal to health minus 1 and then even tho the 2 pictureboxes are still intersecting the health doesn't go down by 1?

    Help is much appreciated
    Callum

  8. #8
    Pro Grammar chris128's Avatar
    Join Date
    Jun 2007
    Location
    England
    Posts
    7,604

    Re: Make for loops wait before they loop again

    Just as a side note, it looks like you're making a game - you might want to consider using the XNA framework which is specifically designed for making games (rather than trying to use WinForms to make a game, which really isn't designed to do that). http://msdn.microsoft.com/en-us/library/bb200104.aspx Although I think it only lets you use C#.NET rather than VB.NET
    My free .NET Windows API library (Version 2.2 Released 12/06/2011)

    Blog: cjwdev.wordpress.com
    Web: www.cjwdev.co.uk


  9. #9
    Bad man! ident's Avatar
    Join Date
    Mar 2009
    Location
    Cambridge
    Posts
    5,398

    Re: Make for loops wait before they loop again

    Quote Originally Posted by chris128 View Post
    C#.NET
    c#.net whats that :O

  10. #10
    Pro Grammar chris128's Avatar
    Join Date
    Jun 2007
    Location
    England
    Posts
    7,604

    Re: Make for loops wait before they loop again

    Oh and as for your question, just use a Boolean variable (True/False) to determine whether or not the images have already intersected. Declare this variable at class level rather than inside your timer tick event, then it will keep its value in between timer ticks. The basic logic would be like this:

    IF image 1 intersects with image 2 AND variable is False Then
    set variable to true
    take away health
    End IF

    IF they do not intersect Then
    set variable to false
    End If
    My free .NET Windows API library (Version 2.2 Released 12/06/2011)

    Blog: cjwdev.wordpress.com
    Web: www.cjwdev.co.uk


  11. #11

    Thread Starter
    Registered User
    Join Date
    Aug 2013
    Posts
    3

    Re: Make for loops wait before they loop again

    Chris, you've been really great help, cheers!

    As this is a school project with a due by date, i'll stick to using vb.net for this project as I havn't learnt much off c#. I'll give XNA a go later.

    So if I put the intersects bit of code at a class level, it will keep on checking it? That's pretty cool. When I get up to that part i'll give it a go

    Thanks,
    Callum

  12. #12
    Pro Grammar chris128's Avatar
    Join Date
    Jun 2007
    Location
    England
    Posts
    7,604

    Re: Make for loops wait before they loop again

    Don't put the entire thing at class level, I just meant the Boolean variable I was talking about. You still need everything else in your timer tick event.

    e.g:

    Public Class Form1

    Dim HasIntersected As Boolean

    Sub Timer_Tick
    'Do work here and check/set HasIntersected value as described in my previous post
    End Sub

    End Class
    My free .NET Windows API library (Version 2.2 Released 12/06/2011)

    Blog: cjwdev.wordpress.com
    Web: www.cjwdev.co.uk


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