问题
When I move a bitmap-filled path in Silverlight by updating its RenderTransform, the image updates with a stutter/jitter about every half-second.
The Path uses a BitmapCache, and Hardware Acceleration is turned on. The hardware acceleration is verified using the EnableCacheVisualization option, and by observing that the frame rate is high ~ 60 fps.
You can see what I am talking about here. It is a working silverlight app showing the stuttering behavior. (You might imagine what game I am trying to make when you see the image...)
http://glerok.com/smb/index.html
You will notice that the bitmap scrolls smoothly, but every 0.5 to 1 seconds, it stutters, as if some frames were skipped. I verified this on two different PCs.
Is this expected behavior in silverlight, or am I doing something wrong by manually updating the RenderTransform of the object? (Please don't take this as an opportunity to disparage Silverlight...)
Thanks in advance!!!
Here is the code I am using to generate the path:
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);
And here is the code that update the path position:
WorldTilePosition-=10;
TranslateTransform tt = WorldPath.RenderTransform as TranslateTransform;
tt.X = -WorldTilePosition;
if (WorldTilePosition < -1000) WorldTilePosition = 1000;
I observed the stuttering/jittering in Silverlight even for an object that is animated with a storyboard. I guess this happens because there is currently no back-buffering in silverlight, making it currently unsuitable for even simple sprite-based games on PC? Note that the overall screen refresh rate is still reported to be 60 fps.
The code below generates an animated rectangle that flickers during the screen refresh. Vertical objects show better the banding during the refresh rate, at least on my laptop.
<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:
Can't notice any stuttering on my PC (Core 2 Quad 3 GHz, Win7 x64, IE9).
Especially for such a tile based game with low resolution sprites etc. I'd consider using a WriteableBitmap
(a nice extended version can be found on Codeplex) and then update/display that one only. This also solves the missing backbuffer.
Also, to avoid noticeable stuttering, try to keep your game logic independent of framerate (using a timer or detecting the number of milliseconds passed since last frame). Skipped frames shouldn't be as noticeable then as well.
Also try to draw the visible part of the landscape only (not sure if clipping is enough; didn't try it).
来源:https://stackoverflow.com/questions/5319562/silverlight-fast-moving-bitmap-does-not-update-smoothly