Анимация Silverlight, не гладкая

При попытке ко времени/кадру одушевленных объектов, базирующемуся в Silverlight (в отличие от использования чего-то как DoubleAnimation или Раскадровка, которая не подходит, например, для быстрых измеренных шагами игр), например, перемещая космический корабль в конкретное направление каждый кадр, перемещение является нервным и не действительно гладким. Экран даже, кажется, рвется.

Кажется, нет никакого различия между CompositionTarget и DistpatcherTimer. Я использую следующий подход (в псевдокоде):

Register Handler to Tick-Event of a DispatcherTimer
In each Tick:
Compute the elapsed time from the last frame in milliseconds
Object.X += movementSpeed * ellapsedMilliseconds

Это должно привести к гладкому перемещению, правильно? Но это не делает. Вот пример (Средства управления: WASD и Мышь): Игра Silverlight. Хотя эффект, который я описал, не слишком распространен в этом образце, я могу уверить Вас, который, даже перемещая единственный прямоугольник через холст производит нервную анимацию.

Делает у кого-то есть идея, как минимизировать это. Там другие подходы к к покадровой анимации кроме использования Storyboards/DoubleAnimations, который мог решить это?

Править: Здесь быстрый и грязный подход, анимируя прямоугольник с минимальным кодом (Средства управления: A и D) Образец Анимации

Xaml:

 
    
        
    

C#:

private bool isLeft = false;
    private bool isRight = false;
    private DispatcherTimer timer = new DispatcherTimer();
    private double lastUpdate;

    public Page()
    {
        InitializeComponent();

        timer.Interval = TimeSpan.FromMilliseconds(1);
        timer.Tick += OnTick;

        lastUpdate = Environment.TickCount;
        timer.Start();
    }

    private void OnTick(object sender, EventArgs e)
    {
        double diff = Environment.TickCount - lastUpdate;

        double x = Canvas.GetLeft(rect);

        if (isRight)
            x += 1 * diff;
        else if (isLeft)
            x -= 1 * diff;

        Canvas.SetLeft(rect, x);

        lastUpdate = Environment.TickCount;
    }

    private void UserControl_KeyDown(object sender, KeyEventArgs e)
    {
        if (e.Key == Key.D)
            isRight = true;

        if (e.Key == Key.A)
            isLeft = true;
    }

    private void UserControl_KeyUp(object sender, KeyEventArgs e)
    {
        if (e.Key == Key.D)
            isRight = false;

        if (e.Key == Key.A)
            isLeft = false;
    }

Спасибо! Andrej

6
задан Andrej 30 June 2009 в 16:03
поделиться

1 ответ

Обновление позиции каждые 1 миллисекунду - это излишество, потому что silverlight просто не будет обновлять экран так быстро. Когда вы изменяете положение объекта подобным образом (или любое другое обновление пользовательского интерфейса), silverlight помечает фреймбуфер как грязный и в конечном итоге перерисовывает экран, однако он не будет перерисовывать экран чаще, чем MaxFrameRate.

Чтобы установить MaxFrameRate, просто:

Application.Current.Host.Settings.MaxFrameRate = 60;

Это ограничит ваше приложение 60 кадрами в секунду, что должно быть более чем достаточно.

3
ответ дан 17 December 2019 в 18:19
поделиться
Другие вопросы по тегам:

Похожие вопросы: