locked
Super Fast Movement Help RRS feed

  • Question

  • Ive never had this sisue before but I really need some help here. I need to slow down my barrel movment. Its moving super fast. here is my code:

    Public Class Screen_1
        Private Storage As New Storage
    
        Private Sub DonkeyKong_Timer_Tick(sender As System.Object, e As System.EventArgs) Handles DonkeyKong_Timer.Tick
            Select Case Storage.DonkeyKong
                Case 1
                    DonkeyKong_Timer.Interval = Storage.DonkeyKongspeed
                    pbDonkeyKong.BackgroundImage = My.Resources.Donkey_Kong_1
                    Storage.DonkeyKong += 1
                Case 2
                    pbDonkeyKong.BackgroundImage = My.Resources.Donkey_Kong_2
                    Storage.DonkeyKong += 1
                Case 3
                    pbDonkeyKong.BackgroundImage = My.Resources.Donkey_Kong_3
                    Storage.DonkeyKong += 1
                Case 4
                    pbDonkeyKong.BackgroundImage = My.Resources.Donkey_Kong_4
                    If Storage.BarrelMoving = False Then
                        Storage.BarrelPath = 1
                        Storage.BarrelCase = 1
                        BarrelTimer.Start()
                    End If
                    Storage.DonkeyKong = 1
            End Select
        End Sub
    
        Private Sub Screen_1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
            'Speedup When Pissed Off Lol
            Storage.DonkeyKongspeed = 500
            DonkeyKong_Timer.Start()
        End Sub
    
        Private Sub BarrelTimer_Tick(sender As System.Object, e As System.EventArgs) Handles BarrelTimer.Tick
            Dim Tick As Integer = 0
    
            If Storage.BarrelPath = 1 Then
                Select Case Storage.BarrelCase
                    Case 1
                        Storage.BarrelSpeed = 800
                        BarrelTimer.Interval = Storage.BarrelSpeed
                        pbBarrel.Location = New Point(252, 177)
                        Storage.BarrelMoving = True
                        'Rolling Barrel
                        'Start Location: 252, 177 - Move Left To Location: 69, 177
                        Do Until Tick = 183
                            pbBarrel.Visible = True
                            pbBarrel.Left += 1
                            Tick += 1
                        Loop
                        If Tick >= 183 Then
                            Tick = 0
                            Storage.BarrelCase += 1
                        End If
                    Case 2
                        'Drop Barrel
                        'Start Location: 69, 177 - Move Left To Location: 69, 540
                        Do Until Tick = 363
                            pbBarrel.Visible = True
                            pbBarrel.Top += 1
                            Tick += 1
                        Loop
                        If Tick >= 363 Then
                            Tick = 0
                            Storage.BarrelCase += 1
                        End If
                    Case 3
                        'Rolling Barrel
                        'Start Location: 69, 540 - Move Left To Location: 585, 540
                        Do Until Tick = 516
                            pbBarrel.Visible = True
                            pbBarrel.Left += 1
                            Tick += 1
                        Loop
                        If Tick >= 516 Then
                            Tick = 0
                            Storage.BarrelCase += 1
                        End If
                    Case 4
                        'Drop Barrel
                        'Start Location: 585, 540 - Move Left To Location: 585, 661
                        Do Until Tick = 121
                            pbBarrel.Visible = True
                            pbBarrel.Top += 1
                            Tick += 1
                        Loop
                        If Tick >= 121 Then
                            Tick = 0
                            Storage.BarrelCase += 1
                        End If
                    Case 5
                        'Rolling Barrel
                        'Start Location: 585, 661 - Move Left To Location: 1002, 661
                        Do Until Tick = 417
                            pbBarrel.Visible = True
                            pbBarrel.Left += 1
                            Tick += 1
                        Loop
                        If Tick >= 417 Then
                            BarrelTimer.Stop()
                            Tick = 0
                            Storage.BarrelCase = 0
                            pbBarrel.Visible = False
                            Storage.BarrelMoving = True
                        End If
                End Select
            End If
        End Sub
    End Class

    Wednesday, June 13, 2012 11:30 PM

Answers

  • You can't use code like this:

                        Do Until Tick = 516
                            pbBarrel
    .Visible = True
                            pbBarrel
    .Left += 1
                            Tick
    += 1
                       
    Loop
    and expect to be able to properly control the speed of movement.  You need to use the same technique for barrels that you are using for monkeys - set up a timer and move the barrel in the timer tick event. You already have a timer for barrels, but you are assuming that the barrel state changes on every timer tick.  It should be the barrel position that changes on each tick (according to the current state) and the state changes when the position reaches the limit for that movement.

    • Marked as answer by mholmes_3038 Thursday, June 14, 2012 3:40 PM
    Thursday, June 14, 2012 2:40 AM

All replies

  • Ive tried using a sleep in the thread but that just freezes up the entire game. Suggestions?
    Thursday, June 14, 2012 1:24 AM
  • I read it a while ago, but for me it's hard to say from here. You mean the timer is ticking too fast? Then you should look where you set the interval. Or are the steps with every movement too big? You also didn't provide sufficient information. I guess your barrell is a picurebox? And it's named pbBarrel?

    No, let me start again asking..: You seem to move controls within a loop. That's not a good approach because the UI doesn't have time to update. Instead, you should use a timer and update positions with every timer tick. Use a Stopwatch as the reference time for animations because timer tick's are not guaranteed to be exact. Controls are very bad for animation anyway. Instead you should use only one control and paint all objects in it's paint event (double buffered).

    EDIT:
    A "real" game loop looks something like this:

    Do
        Render
        Process Input
        Animate
    Loop

    And, I really say this, the loop also contains a call to Application.DoEvents - which is the one and only exception to use it since fluid animation and rendering is most important. So, a timer-based approach has it's limits if performance matters.


    Armin

    Thursday, June 14, 2012 2:14 AM
  • Hmm not sure I 100% follow. I know what your saying but its not sinking in. The problem is that its not moving in intervals set. It moves like super fast no matter what I set intervals too. I tried using system.threading.thread.sleep(storage.barrelspeed) and it still moves extremely fast. But I think I agree with you on the moving the loop out of the timer and into a sub. I orginaly had it setup that way but I thought for some reason I had to have it in the timer. Is that true? I dont have to have it in the timer do I? I think I really need a better approach to this. I'm simply trying to remake Dokey Kong the Atrari version. This timer is for the barrels that "roll". i want the barrels to follow a set path. It will randomly choose a path to follow. So I hope that explains a little better. thanks for helping in advance. the ultimate goal is to convert this to XNa VB at some point.
    Thursday, June 14, 2012 2:39 AM
  • You can't use code like this:

                        Do Until Tick = 516
                            pbBarrel
    .Visible = True
                            pbBarrel
    .Left += 1
                            Tick
    += 1
                       
    Loop
    and expect to be able to properly control the speed of movement.  You need to use the same technique for barrels that you are using for monkeys - set up a timer and move the barrel in the timer tick event. You already have a timer for barrels, but you are assuming that the barrel state changes on every timer tick.  It should be the barrel position that changes on each tick (according to the current state) and the state changes when the position reaches the limit for that movement.

    • Marked as answer by mholmes_3038 Thursday, June 14, 2012 3:40 PM
    Thursday, June 14, 2012 2:40 AM
  • Right but I need a loop to move the barrels right or somethig to control the ticks for movment. So what or how do you suggest I set it up then? Sorry i'm confussed.
    Thursday, June 14, 2012 2:45 AM
  • The problem is that its not moving in intervals set. It moves like super fast no matter what I set intervals too.

    In this loop, I do not see an interval, so it's moving as quick as the CPU can:

                       Do Until Tick = 121
                            pbBarrel.Visible = True
                            pbBarrel.Top += 1
                            Tick += 1
                        Loop

    You would have to make the move Timer controled, too.

     I tried using system.threading.thread.sleep(storage.barrelspeed) and it still moves extremely fast. But I think I agree with you on the moving the loop out of the timer and into a sub. I orginaly had it setup that way but I thought for some reason I had to have it in the timer. Is that true? I dont have to have it in the timer do I? 

    In short: Do not move the same object several times within one timer tick. Move it only once each time.

    I think I really need a better approach to this. I'm simply trying to remake Dokey Kong the Atrari version. This timer is for the barrels that "roll". i want the barrels to follow a set path. It will randomly choose a path to follow. So I hope that explains a little better. thanks for helping in advance. the ultimate goal is to convert this to XNa VB at some point.

    Aha, that's a good plan. Though I'd prefer SlimDX.

    EDIT: GDI is also not bad for animations. Depends on complexity. For the purpose you're describing it should be completely sufficient.


    Armin



    Thursday, June 14, 2012 2:47 AM
  • OOOOOOhh ok I think I see now. So no loop method for movment, that what your suggesting? Basicly I need to dumb down my method and not use a loop since i cant control its intervals?
    Thursday, June 14, 2012 2:51 AM
  • Right but I need a loop to move the barrels right or somethig to control the ticks for movment. So what or how do you suggest I set it up then? Sorry i'm confussed.

    Quick & dirty example:

    Public Class Form1
    
       Private WithEvents button As New Button With {.Text = "start", .Parent = Me}
       Private barrel As New PictureBox With {.BackColor = Color.Blue, .Parent = Me, .Top = 50, .Size = New Size(20, 20)}
       Private WithEvents timer As New Timer With {.Interval = 10}
       Private watch As Stopwatch
       Private lastelapsed As TimeSpan
    
    
       Private Sub timer_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles timer.Tick
    
          Dim now = watch.Elapsed
          Dim passed = now - lastelapsed
    
          lastelapsed = now
    
          barrel.Top = CInt(barrel.Top + passed.TotalSeconds * 100)
    
          If barrel.Top > ClientSize.Height Then
             timer.Stop()
             button.Enabled = True
             barrel.Top = 50
          End If
    
       End Sub
    
       Private Sub button_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles button.Click
          watch = Stopwatch.StartNew
          lastelapsed = TimeSpan.Zero
          timer.Start()
          button.Enabled = False
       End Sub
    End Class
    


    Armin



    • Edited by Armin Zingler Thursday, June 14, 2012 3:00 AM code corrected
    Thursday, June 14, 2012 2:58 AM
  • Ahh now i'm super lost. I guess I just need to play with the previous suggestions. thanks guys I'll post results later and see if we can find a better way maybe in the near future.
    Thursday, June 14, 2012 3:10 AM
  • When the barrel movement timer ticks, look up the state of the barrel (as you are now doing).

    If the state is 1, the barrel is rolling.  Add 1 to the PB location (like you are now doing in that loop).   Check if it has reached its limit.  If it has ( the equivalent Tick >= 183 - I can't work out the actual values as your comments disagree with your code) then change its state to 2 (like you are now doing) and wait for the next tick. 


    • Edited by Acamar Thursday, June 14, 2012 3:55 AM sp
    Thursday, June 14, 2012 3:53 AM
  • Mholmes,

    If I use a timer like you do, then the first thing I do is to disable it at the start of the method which handles the tick event and to enable it again at the end of that.

    Otherwise there is a chance the next tick is again handled inside the tick handling which is busy.


    Success
    Cor

    Thursday, June 14, 2012 8:29 AM
  • Otherwise there is a chance the next tick is again handled inside the tick handling which is busy.

    Hi Cor,

    wasn't there a discussion about it lately? :) The Tick event is from the winforms timer, so it can't tick again during execution of the tick handler.


    Armin

    Thursday, June 14, 2012 12:11 PM
  • Yea I know that discussion, however I thought I was not in that discussion.

    I use often the windows forms timer and get to often the message that it is running in a different thread.

    But I've not yet my hands behind it to discuss it.

    Be aware I get the same message from the WPF dispatcher timer.


    Success
    Cor


    Thursday, June 14, 2012 1:50 PM
  • Yes, I saw it, but it looked like Winforms. :)

    Armin

    Thursday, June 14, 2012 2:00 PM
  • Don't use timers; create a single, continuous game loop and have it control everything.

    This is another example of why games aren't made this way...


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

    Thursday, June 14, 2012 3:07 PM
  • Also, the loop would not need DoEvents if it was in another thread such as on a BackgroundWorker.


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

    Thursday, June 14, 2012 3:08 PM
  • Also, the loop would not need DoEvents if it was in another thread such as on a BackgroundWorker.

    The game loop is usually performed in the UI thread since it also contains rendering. Sure, you are free to use another approach (e.g. because Creategraphics can also be call from a different thrread), but it's not common.

    Armin

    Thursday, June 14, 2012 3:22 PM
  • ...about to write a "little" example (anyone remembers Arkanoid?) but as I fail doing things q&d, it will take some days. lol

    Armin

    Thursday, June 14, 2012 3:26 PM
  • Thansk guys, I found the solution. Here it is in case some one else wants or needs it. I'll likely add more 1 later.

    Public Class Screen_1
        Private Storage As New Storage
        Dim Tick As Integer
    
        Private Sub DonkeyKong_Timer_Tick(sender As System.Object, e As System.EventArgs) Handles DonkeyKong_Timer.Tick
            Select Case Storage.DonkeyKong
                Case 1
                    DonkeyKong_Timer.Interval = Storage.DonkeyKongspeed
                    pbDonkeyKong.BackgroundImage = My.Resources.Donkey_Kong_1
                    Storage.DonkeyKong += 1
                Case 2
                    pbDonkeyKong.BackgroundImage = My.Resources.Donkey_Kong_2
                    Storage.DonkeyKong += 1
                Case 3
                    pbDonkeyKong.BackgroundImage = My.Resources.Donkey_Kong_3
                    Storage.DonkeyKong += 1
                Case 4
                    pbDonkeyKong.BackgroundImage = My.Resources.Donkey_Kong_4
                    If Storage.BarrelMoving = False Then
                        'Change me Later
                        Storage.BarrelPath = 1
                        LoadPath()
                        BarrelTimer.Start()
                    End If
                    Storage.DonkeyKong = 1
            End Select
        End Sub
    
        Private Sub Screen_1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
            'Speedup When Pissed Off Lol
            Storage.DonkeyKongspeed = 500
            DonkeyKong_Timer.Start()
        End Sub
    
        Public Sub LoadPath()
            If Storage.BarrelPath = 1 Then
                pbBarrel.Visible = True
                Storage.BarrelSpeed = 50
                BarrelTimer.Interval = Storage.BarrelSpeed
                pbBarrel.Location = New Point(252, 177)
                Storage.BarrelMoving = True
                Storage.BarrelCase = 1
            End If
        End Sub
    
        Private Sub BarrelTimer_Tick(sender As System.Object, e As System.EventArgs) Handles BarrelTimer.Tick
            If Storage.BarrelPath = 1 Then
                Select Case Storage.BarrelCase
                    Case 1
                        If Tick = 183 Then
                            Tick = 0
                            Storage.BarrelCase = 5
                        Else
                            pbBarrel.BackgroundImage = My.Resources.Barrel_Roll_1
                            pbBarrel.Left -= 1
                            Tick += 1
                            Storage.BarrelCase += 1
                        End If
                    Case 2
                        If Tick = 183 Then
                            Tick = 0
                            Storage.BarrelCase = 5
                        Else
                            pbBarrel.BackgroundImage = My.Resources.Barrel_Roll_2
                            pbBarrel.Left -= 1
                            Tick += 1
                            Storage.BarrelCase += 1
                        End If
                    Case 3
                        If Tick = 183 Then
                            Tick = 0
                            Storage.BarrelCase = 5
                        Else
                            pbBarrel.BackgroundImage = My.Resources.Barrel_Roll_3
                            pbBarrel.Left -= 1
                            Tick += 1
                            Storage.BarrelCase += 1
                        End If
                    Case 4
                        If Tick = 183 Then
                            Tick = 0
                            Storage.BarrelCase = 5
                        Else
                            pbBarrel.BackgroundImage = My.Resources.Barrel_Roll_4
                            pbBarrel.Left -= 1
                            Tick += 1
                            Storage.BarrelCase = 1
                        End If
                    Case 5
                        If Tick = 363 Then
                            Tick = 0
                            Storage.BarrelCase = 9
                        Else
                            pbBarrel.BackgroundImage = My.Resources.Barrel_Roll_1
                            pbBarrel.Top += 1
                            Tick += 1
                            Storage.BarrelCase += 1
                        End If
                    Case 6
                        If Tick = 363 Then
                            Tick = 0
                            Storage.BarrelCase = 9
                        Else
                            pbBarrel.BackgroundImage = My.Resources.Barrel_Roll_2
                            pbBarrel.Top += 1
                            Tick += 1
                            Storage.BarrelCase += 1
                        End If
                    Case 7
                        If Tick = 363 Then
                            Tick = 0
                            Storage.BarrelCase = 9
                        Else
                            pbBarrel.BackgroundImage = My.Resources.Barrel_Roll_3
                            pbBarrel.Top += 1
                            Tick += 1
                            Storage.BarrelCase += 1
                        End If
                    Case 8
                        If Tick = 363 Then
                            Tick = 0
                            Storage.BarrelCase = 9
                        Else
                            pbBarrel.BackgroundImage = My.Resources.Barrel_Roll_4
                            pbBarrel.Top += 1
                            Tick += 1
                            Storage.BarrelCase = 5
                        End If
                    Case 9
                        If Tick = 516 Then
                            Tick = 0
                            Storage.BarrelCase = 13
                        Else
                            pbBarrel.BackgroundImage = My.Resources.Barrel_Roll_1
                            pbBarrel.Left += 1
                            Tick += 1
                            Storage.BarrelCase += 1
                        End If
                    Case 10
                        If Tick = 516 Then
                            Tick = 0
                            Storage.BarrelCase = 13
                        Else
                            pbBarrel.BackgroundImage = My.Resources.Barrel_Roll_2
                            pbBarrel.Left += 1
                            Tick += 1
                            Storage.BarrelCase += 1
                        End If
                    Case 11
                        If Tick = 516 Then
                            Tick = 0
                            Storage.BarrelCase = 13
                        Else
                            pbBarrel.BackgroundImage = My.Resources.Barrel_Roll_3
                            pbBarrel.Left += 1
                            Tick += 1
                            Storage.BarrelCase += 1
                        End If
                    Case 12
                        If Tick = 516 Then
                            Tick = 0
                            Storage.BarrelCase = 13
                        Else
                            pbBarrel.BackgroundImage = My.Resources.Barrel_Roll_4
                            pbBarrel.Left += 1
                            Tick += 1
                            Storage.BarrelCase = 9
                        End If
                    Case 13
                        If Tick = 121 Then
                            Tick = 0
                            Storage.BarrelCase = 17
                        Else
                            pbBarrel.BackgroundImage = My.Resources.Barrel_Roll_1
                            pbBarrel.Top += 1
                            Tick += 1
                            Storage.BarrelCase += 1
                        End If
                    Case 14
                        If Tick = 121 Then
                            Tick = 0
                            Storage.BarrelCase = 17
                        Else
                            pbBarrel.BackgroundImage = My.Resources.Barrel_Roll_2
                            pbBarrel.Top += 1
                            Tick += 1
                            Storage.BarrelCase += 1
                        End If
                    Case 15
                        If Tick = 121 Then
                            Tick = 0
                            Storage.BarrelCase = 17
                        Else
                            pbBarrel.BackgroundImage = My.Resources.Barrel_Roll_3
                            pbBarrel.Top += 1
                            Tick += 1
                            Storage.BarrelCase += 1
                        End If
                    Case 16
                        If Tick = 121 Then
                            Tick = 0
                            Storage.BarrelCase = 17
    
                        Else
                            pbBarrel.BackgroundImage = My.Resources.Barrel_Roll_4
                            pbBarrel.Top += 1
                            Tick += 1
                            Storage.BarrelCase = 13
                        End If
                    Case 17
                        If Tick = 417 Then
                            BarrelTimer.Stop()
                            Tick = 0
                            Storage.BarrelCase = 1
                            pbBarrel.Visible = False
                            Storage.BarrelMoving = False
                        Else
                            pbBarrel.BackgroundImage = My.Resources.Barrel_Roll_1
                            pbBarrel.Left += 1
                            Tick += 1
                            Storage.BarrelCase += 1
                        End If
                    Case 18
                        If Tick = 417 Then
                            BarrelTimer.Stop()
                            Tick = 0
                            Storage.BarrelCase = 1
                            pbBarrel.Visible = False
                            Storage.BarrelMoving = False
                        Else
                            pbBarrel.BackgroundImage = My.Resources.Barrel_Roll_2
                            pbBarrel.Left += 1
                            Tick += 1
                            Storage.BarrelCase += 1
                        End If
                    Case 19
                        If Tick = 417 Then
                            BarrelTimer.Stop()
                            Tick = 0
                            Storage.BarrelCase = 1
                            pbBarrel.Visible = False
                            Storage.BarrelMoving = False
                        Else
                            pbBarrel.BackgroundImage = My.Resources.Barrel_Roll_3
                            pbBarrel.Left += 1
                            Tick += 1
                            Storage.BarrelCase += 1
                        End If
                    Case 20
                        If Tick = 417 Then
                            BarrelTimer.Stop()
                            Tick = 0
                            Storage.BarrelCase = 1
                            pbBarrel.Visible = False
                            Storage.BarrelMoving = False
                        Else
                            pbBarrel.BackgroundImage = My.Resources.Barrel_Roll_4
                            pbBarrel.Left += 1
                            Tick += 1
                            Storage.BarrelCase = 17
                        End If
                End Select
            End If
        End Sub
    End Class

    Thursday, June 14, 2012 4:16 PM