views:

493

answers:

2

With reference to this programming game I am currently building.

I wrote the below method to move (translate) a canvas to a specific distance and according to its current angle:

private void MoveBot(double pix, MoveDirection dir)
    {
        if (dir == MoveDirection.Forward)
        {
            Animator_Body_X.To = Math.Sin(HeadingRadians) * pix;
            Animator_Body_Y.To = ((Math.Cos(HeadingRadians) * pix) * -1);
        }
        else
        {
            Animator_Body_X.To = ((Math.Sin(HeadingRadians) * pix) * -1);
            Animator_Body_Y.To = Math.Cos(HeadingRadians) * pix;
        }

        Animator_Body_X.To += Translate_Body.X;
        Animator_Body_Y.To += Translate_Body.Y;

        Animator_Body_X.From = Translate_Body.X;
        Translate_Body.BeginAnimation(TranslateTransform.XProperty, Animator_Body_X);

        Animator_Body_Y.From = Translate_Body.Y;
        Translate_Body.BeginAnimation(TranslateTransform.YProperty, Animator_Body_Y);

        TriggerCallback();
    }

One of the parameters it accepts is a number of pixels that should be covered when translating.

As regards the above code, Animator_Body_X and Animator_Body_Y are of type DoubleAnimation, which are then applied to the robot's TranslateTransform object: Translate_Body


The problem that I am facing is that the Robot (which is a canvas) is moving at a different speed according to the inputted distance. Thus, the longer the distance, the faster the robot moves! So to put you into perspective, if the inputted distance is 20, the robot moves fairly slow, but if the inputted distance is 800, it literally shoots off the screen.

I need to make this speed constant, irrelevant of the inputted distance.

I think I need to tweak some of the Animator_Body_X and Animator_Body_Y properties in according to the inputted distance, but I don't know what to tweak exactly (I think some Math has to be done as well).

Here is a list of the DoubleAnimation properties that maybe you will want to take a look at to figure this out.

+2  A: 

Is there are reason you're using DoubleAnimation? DoubleAnimation is designed to take a value from A to B over a specific time period using linear interpolation acceleration/deceleration at the start/end of that period if required (which is why it's "faster" for longer distance.. it has further to go in the same time!). By the looks of things what you are trying to do is move something a fixed distance each "frame" depending on what direction it is facing? That doesn't seem to fit to me.

You could calculate the length of the animation, depending on the distance, so the length is longer for longer distances, then the item is always moving at the same "speed". To me, it makes more sense to just move the item yourself though. You can calculate a objects velocity based on your angle criteria, then each "frame" you can manually move the item as far as it needs to go based on that velocity. With this method you could also easily apply friction etc. to the velocity if required.

Steven Robbins
A: 

The math you have to do is: velocity*time=distance

So, to keep the speed constant you have to change the animation's duration:

double pixelsPerSecond = 5;
animation.Duration = TimeSpan.FromSeconds(distance/pixelsPerSecond);

BTW, I don't think animations are the best solution for moving your robots.

Nir
Nir, what do you suggest instead of animations ?Something like incrementing the ticks with a DispatcherTimer ?
Andreas Grech
Maybe, I have experience in simulation (but not under WPF), there are some tricky details you have to get right if you want the movement to look "natural", in Win32 we used WM_PAINT loops I think the Wpf equivalent is CompositionTarget.Rendering (be careful, touching this will effect performance)
Nir