Быстро движущееся растровое изображение Silverlight не обновляется плавно
Когда я перемещаю заполненный растровым путем путь в Silverlight, обновляя его RenderTransform, изображение обновляется с заиканием / дрожанием примерно каждые полсекунды.
Путь использует BitmapCache, и аппаратное ускорение включено. Аппаратное ускорение проверяется с помощью параметра EnableCacheVisualization и наблюдения за высокой частотой кадров ~ 60 кадров в секунду.
Вы можете видеть то, о чем я говорю здесь. Это работающее приложение Silverlight, демонстрирующее поведение при заикании. (Вы можете представить, какую игру я пытаюсь сделать, когда увидите изображение...)
http://glerok.com/smb/index.html
Вы заметите, что растровое изображение плавно прокручивается, но каждые 0,5-1 секунды оно останавливается, как будто некоторые кадры пропускаются. Я проверил это на двух разных ПК.
Это ожидаемое поведение в Silverlight, или я делаю что-то не так, вручную обновляя RenderTransform объекта? (Пожалуйста, не принимайте это как возможность унижать Silverlight...)
Заранее спасибо!!!
Вот код, который я использую для генерации пути:
RectangleGeometry rg = new RectangleGeometry();
BitmapImage bi = new BitmapImage(new Uri("world.png", UriKind.Relative));
int WorldWidth = 703;
int WorldHeight = 240;
rg.Rect = new Rect(WorldTilePosition, 0, WorldWidth * Scale, WorldHeight * Scale);
Path p = new Path { RenderTransform = new TranslateTransform { X = 0, Y = 0 } };
p.Data = rg;
p.CacheMode = new BitmapCache();
p.Fill = new ImageBrush { ImageSource = bi };
canvas.Children.Add(p);
А вот код, который обновляет положение пути:
WorldTilePosition-=10;
TranslateTransform tt = WorldPath.RenderTransform as TranslateTransform;
tt.X = -WorldTilePosition;
if (WorldTilePosition < -1000) WorldTilePosition = 1000;
Я наблюдал заикание / дрожание в Silverlight даже для объекта, который анимирован с раскадровкой. Я полагаю, это происходит из-за того, что в Silverlight в настоящее время нет никакой обратной буферизации, что делает его в настоящее время непригодным даже для простых игр на основе спрайтов на ПК? Обратите внимание, что общая частота обновления экрана по-прежнему составляет 60 кадров в секунду.
Код ниже генерирует анимированный прямоугольник, который мерцает во время обновления экрана. Вертикальные объекты лучше показывают полосы во время обновления, по крайней мере, на моем ноутбуке.
<Canvas x:Name="LayoutRoot2" Background="White">
<Rectangle x:Name="myRect" Fill="Red" Width="100" Height="500" CacheMode="BitmapCache" >
<Rectangle.RenderTransform>
<TranslateTransform x:Name="myRectTransform" X="0" />
</Rectangle.RenderTransform>
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Rectangle.Loaded">
<BeginStoryboard>
<Storyboard x:Name="myStoryboard" >
<DoubleAnimation
From="0"
To="1000"
Storyboard.TargetName="myRectTransform"
Storyboard.TargetProperty="X"
Duration="0:0:1"
AutoReverse="True"
RepeatBehavior="Forever"
/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
</Canvas>
1 ответ
Не могу заметить никакого заикания на моем ПК (Core 2 Quad 3 ГГц, Win7 x64, IE9).
Специально для такой игры на основе плитки со спрайтами низкого разрешения и т. Д. Я бы подумал об использовании WriteableBitmap
(хорошая расширенная версия может быть найдена в Codeplex), а затем обновите / отобразите только эту. Это также решает отсутствующий буфер.
Также, чтобы избежать заметного заикания, постарайтесь сохранить игровую логику независимой от частоты кадров (используя таймер или определяя количество миллисекунд, прошедших с последнего кадра). Пропущенные кадры не должны быть такими заметными.
Также попробуйте нарисовать только видимую часть ландшафта (не уверен, что отсечения достаточно; не пробовал).