- <Storyboard x:Key="walkLeftStoryboard">
- <ObjectAnimationUsingKeyFrames Duration="00:00:00.4" RepeatBehavior="Forever"
- Storyboard.TargetName="marioImage" Storyboard.TargetProperty="CurrentFrame" />
- </Storyboard>
- <game:AnimatedImage x:Name="marioImage" Image="/SuperMario;component/Images/mario.png" CurrentFrame="0, 0, 0.5, 0.5" Width="134" Height="131">
- <game:AnimatedImage.RenderTransform>
- <TranslateTransform x:Name="marioTranslate" X="0" Y="0"/>
- </game:AnimatedImage.RenderTransform>
- </game:AnimatedImage>
复制代码用C#代码添加帧:
- internal static void AddKeyFrames(ObjectAnimationUsingKeyFrames animation, Rect[] frames)
- {
- double percent = 0;
- double pace = 1.0 / frames.Length;
- foreach (var frame in frames)
- {
- animation.KeyFrames.Add(new DiscreteObjectKeyFrame(frame, KeyTime.FromPercent(percent)));
- percent += pace;
- }
- }
复制代码AnimatedImage是一个自定义的控件,控件模板如下:
- <Style TargetType="local:AnimatedImage">
- <Setter Property="Template">
- <Setter.Value>
- <ControlTemplate TargetType="local:AnimatedImage">
- <Border BorderThickness="0">
- <Border.Background>
- <ImageBrush ImageSource="{Binding Path=Image,RelativeSource={RelativeSource TemplatedParent}}"
- Stretch="UniformToFill" AlignmentX="Left" AlignmentY="Top" Viewbox="{Binding Path=CurrentFrame,RelativeSource={RelativeSource TemplatedParent}}"/>
- </Border.Background>
- </Border>
- </ControlTemplate>
- </Setter.Value>
- </Setter>
- </Style>
复制代码后来发现SliverLight里的TileBrush没有ViewBox属性,所以还是无法迁移。
接下来就是在GameLoop中根据键盘按键控制动画的开始和停止,并用marioTranslate来改变人物的位置。
GameLoop可由CompositionTarget.Rendering事件指定:
- GameLoop gameLoop;
- private void Window_Loaded(object sender, RoutedEventArgs e)
- {
- ......
- gameLoop = new GameLoop(player, Scenes.Level1);
- CompositionTarget.Rendering += new EventHandler(CompositionTarget_Rendering);
- }
- void CompositionTarget_Rendering(object sender, EventArgs e)
- {
- gameLoop.ProcessChanges();
- }
复制代码在GameLoop中还需要注意的就是跳跃过程中重力效果的模拟和对物体、台阶、边界的碰撞检查,这个就不多说了,看代码:
- public void ProcessChanges()
- {
- TimeSpan timeSpan = DateTime.Now - lastTime;
- double step = timeSpan.TotalSeconds;
- lastTime = DateTime.Now;
- double x = Sprite.X;
- double y = Sprite.Y;
- double dx = step * Sprite.Speed;
- if (Sprite.IsWalkingLeft)
- {
- x -= dx;
- Scene.ScrollRightt(x, dx);
- }
- else if (Sprite.IsWalkingRight)
- {
- x += dx;
- Scene.ScrollLeft(x, dx);
- }
- if (Map.CanMoveTo(x, Sprite.Y, Sprite.Width, Sprite.Height))
- {
- Sprite.X = x;
- }
- if (Sprite.IsJumping)
- {
- y -= (1 - Sprite.JumpTime) * step * 400;
- if (Sprite.JumpTime < 1 && Map.CanMoveTo(Sprite.X, y, Sprite.Width, Sprite.Height))
- {
- Sprite.Y = y;
- Sprite.JumpTime += step;
- }
- else
- {
- Sprite.IsJumping = false;
- Sprite.IsFalling = true;
- Sprite.JumpTime = 0;
- }
- }
- else if (Sprite.IsFalling)
- {
- y += 800 * Sprite.FallTime * step;
- if (Map.CanMoveTo(Sprite.X, y, Sprite.Width, Sprite.Height))
- {
- Sprite.Y = y;
- Sprite.FallTime += step;
- }
- else
- {
- Sprite.IsFalling = false;
- Sprite.FallTime = 0;
- }
- }
- else
- {
- y += 1;
- if (Map.CanMoveTo(Sprite.X, y, Sprite.Width, Sprite.Height))
- {
- Sprite.Y = y;
- Sprite.IsFalling = true;
- Sprite.FallTime = step;
- }
- }
- }
复制代码 下一步下一步我打算用XAML矢量图来做动画,场景物体等也全都用矢量图,这样的好处一是可以任意放大缩小,二是动画效果会更加流畅一些。(文/
Junfeng Liu)