VB.NET 2003 Winforms  Animation - movement of an image on the screen between 2 points.

hagoog
hagoog used Ask the Experts™
on
THIS IS VB.NET 2003 DESKTOP APP WINFORMS  not asp!
I have 3 picture boxes in VB.net
pic box A
Pic Box 1
Pic Box 2

in the set up phase of the program
Pic box 1 and 2 can be moved around the screen.   (this is complete)

The start mode:
when in start mode pic box needs to fly back and forth between Pic Box 1 and pic box 2

To start:
Pic box 0 appears at pic box 1 location
Pic box 0 then needs to calculate how to fly to pic box 2 location and then fly there using a timer tick event.. flys a little at each tick to control speed
So it flys to and lands on top of pic box 2
Pic box 0 then needs to calculate how to fly to pic box 1 location and then fly there using a timer tick event.. flys a little at each tick to control speed

How best to do this for the smoothest motion?

See code below.  It does move, but it is a little jerky and the X Y motion is not straight and smooth

I am open to changing how it is done to make the motion smoother
CURRENT CODE to calculate movement
                FromX = Me.p1.Left
                ToX = Me.p2.Left
 
                FromY = Me.p1.Top
                ToY = Me.p2.Top
 
                Dx = ToX - FromX
                Dy = ToY - FromY
 
                DistanceToMove = System.Math.Sqrt(Dx * Dx + Dy * Dy)
 
                Dx = Dx / DistanceToMove * 24
                Dy = Dy / DistanceToMove * 24
 
                Me.p0.Left = Me.p1.Left
                Me.p0.Top = Me.p1.Top
 
 
TIMER EVENT
 
 Private Sub Timer2_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer2.Tick
 
 
        DistanceToMove = DistanceToMove - 24
 
 
        If DistanceToMove <= 0 Then
 
            Me.p0.Left = ToX
            Me.p0.Top = ToY
            Timer2.Stop()
            CalcNextPosition()
        Else
 
 
            If Me.p0.Left = ToX Then
 
            Else
                Me.p0.Left = Me.p0.Left + Dx
                '     If Me.p0.Left > ToX Then Me.p0.Left = ToX
            End If
 
 
 
            If Me.p0.Top = ToY Then
 
            Else
                Me.p0.Top = Me.p0.Top + Dy
                '   If Me.p0.Top > ToY Then Me.p0.Top = ToY
            End If
 
 
        End If

Open in new window

Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Mike TomlinsonHigh School Computer Science, Computer Applications, Digital Design, and Mathematics Teacher
Top Expert 2009

Commented:
Does this work any better?
Public Class Form1
 
    Private dir As Integer = 1
    Private Pos As Integer = 0
    Private Jumps As Integer = 100 ' adjust to your liking in conjunction with Timer1.Interval below
    Private dX, dY As Integer
 
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Timer1.Interval = 50 ' adjust to your liking in conjunction with "Jumps" above
        Timer1.Enabled = False
 
        Reset() ' <-- call this after initial positioning of p1 and p2 by the user
    End Sub
 
    Private Sub Reset()
        p0.Location = p1.Location
        dir = 1
        Pos = 0
        dX = p2.Location.X - p1.Location.X
        dY = p2.Location.Y - p1.Location.Y
    End Sub
 
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Timer1.Enabled = Not Timer1.Enabled
    End Sub
 
    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        p0.Location = New Point(p1.Location.X + (Pos / Jumps) * dX, p1.Location.Y + (Pos / Jumps) * dY)
 
        Pos = Pos + dir
        If dir = 1 AndAlso Pos > Jumps Then
            Pos = Jumps
            dir = -1
        ElseIf dir = -1 AndAlso Pos < 0 Then
            Pos = 0
            dir = 1
        End If
    End Sub
 
End Class

Open in new window

Author

Commented:
That is muh smoother!.  One more thing.  I now have to make it work with 3 pictures  instead of 2.
So now there is a p1, p2 and p3.  How would that change this?  I have been playing with it, but with sometime weird results.

THANKS!
Mike TomlinsonHigh School Computer Science, Computer Applications, Digital Design, and Mathematics Teacher
Top Expert 2009

Commented:
Could you explain more about what ALL the different PictureBoxes should be doing?...  =)
OWASP: Threats Fundamentals

Learn the top ten threats that are present in modern web-application development and how to protect your business from them.

Author

Commented:
The idea is that there are either 2 or 3  (p1 p2 p3) picture boxes on the screen.  The user positions them by dragging them to the desired location.  Then when it runs p0 moves from pic to pic in order  1,2,3,1,2,3 etc  or 1,2,1,2 etc    I use a select case to determine whether there are 2 or 3 in the setup so it knows whether p0 needs to go back to 1 or go to 3  depending on whether there are 2 or 3.


So the question is about since I have to do the 3 now  (which I was doing the old way - I thought I could get out of doing 3 and just do 2..)    

High School Computer Science, Computer Applications, Digital Design, and Mathematics Teacher
Top Expert 2009
Commented:
Well...here's one way to do it...
(My form had p0, p1, p2, p3, Timer1, Button1 & Button2)
Public Class Form1
 
    Private leg As Integer
    Private Pos As Integer = 0
    Private Jumps As Integer = 50 ' adjust to your liking in conjunction with Timer1.Interval below
    Private dX, dY As Integer
    Private startX, startY As Integer
    Private PBs As New ArrayList
    Private pbCount As Integer
 
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        PBs.Add(p1)
        PBs.Add(p2)
        PBs.Add(p3)
 
        p0.Visible = False
        p0.BringToFront()
        Timer1.Interval = 50 ' adjust to your liking in conjunction with "Jumps" above
        Timer1.Enabled = False
 
        Reset() ' <-- call this after initial positioning of p1 and p2 by the user
    End Sub
 
    Private Sub Reset()
        p0.Location = PBs(0).Location
        leg = 0
        Pos = 0
        dX = PBs(1).Location.X - PBs(0).Location.X
        dY = PBs(1).Location.Y - PBs(0).Location.Y
        pbCount = IIf(p3.Visible, 3, 2)
    End Sub
 
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Timer1.Enabled = Not Timer1.Enabled
        p0.Visible = Timer1.Enabled
    End Sub
 
    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        If Not Timer1.Enabled Then
            p3.Visible = Not p3.Visible
            Reset()
        End If
    End Sub
 
    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        Dim pb As PictureBox = PBs(leg)
        p0.Location = New Point(pb.Location.X + (Pos / Jumps) * dX, pb.Location.Y + (Pos / Jumps) * dY)
 
        Pos = Pos + 1
        If Pos > Jumps Then
            Pos = 0
            leg = leg + 1
            If leg = pbCount Then
                leg = 0
                dX = PBs(1).Location.X - PBs(0).Location.X
                dY = PBs(1).Location.Y - PBs(0).Location.Y
            ElseIf leg < pbCount - 1 Then
                dX = PBs(leg + 1).Location.X - PBs(leg).Location.X
                dY = PBs(leg + 1).Location.Y - PBs(leg).Location.Y
            Else
                dX = PBs(0).Location.X - PBs(pbCount - 1).Location.X
                dY = PBs(0).Location.Y - PBs(pbCount - 1).Location.Y
            End If
        End If
    End Sub
 
    Private Sub PB_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles p1.MouseDown, p2.MouseDown, p3.MouseDown
        If Not Timer1.Enabled AndAlso e.Button = Windows.Forms.MouseButtons.Left Then
            startX = e.X
            startY = e.Y
        End If
    End Sub
 
    Private Sub PB_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles p1.MouseMove, p2.MouseMove, p3.MouseMove
        If Not Timer1.Enabled AndAlso e.Button = Windows.Forms.MouseButtons.Left Then
            Dim pb As PictureBox = sender
            pb.Location = New Point(pb.Location.X + (e.X - startX), pb.Location.Y + (e.Y - startY))
            Reset()
        End If
    End Sub
 
    Private Sub PB_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles p1.Paint, p2.Paint, p3.Paint
        Dim pb As PictureBox = sender
        Static sf As New StringFormat()
        sf.Alignment = StringAlignment.Center
        sf.LineAlignment = StringAlignment.Center
        e.Graphics.DrawString(pb.Name, Me.Font, Brushes.Black, New RectangleF(0, 0, pb.Width, pb.Height), sf)
    End Sub
 
End Class

Open in new window

PB-Animation.jpg
You could also try using a library I have written called Transitions. It is for just these sorts of animated transitions of multiple UI objects.
http://code.google.com/p/dot-net-transitions/

Mike TomlinsonHigh School Computer Science, Computer Applications, Digital Design, and Mathematics Teacher
Top Expert 2009

Commented:
...but...that would be too...easy!  ;)

Just kidding...thanx for posting Richard.  Will have to try out your Library soon...  =)

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial