생애 첫 번째 윈도우 폰 7 애플리케이션 만들기 6회
[애니메이션 효과 주기]
실버라이트에서 스토리보드가 애니메이션이다. 각 스토리보드는 키 프레임을 포함하는 타임라인을 정의한다. 각 키 프레임은 위치, 크기, 회전, 투명도, 그리고 심지어 전경 및 배경 색 같은 컨트롤 속성을 독립적으로 재 정의할 수 있다. 이러한 접근 방법을 사용해 사용자는 모든 단일 프레임을 정의해 애니메이션을 생성할 필요가 없고, 대신에 중요한 속성 변경을 표시하기 위해 타임라인에서 선택된 위치만 제공해야 한다. 실버라이트는 두 개의 인접한 키 프레임간의 애니메이션 속성의 값을 보간해서 중간 프레임을 생성하고 부드러운 전환을 제공한다.
각 스토리보드는 해당 페이지의 코드 숨김에서 사용할 수 있는 메서드와 이벤트를 가진 개체다. 이것은 애니메이션을 Begin, Stop, Pause하는 메서드를 포함한다. 단일 이벤트이벤트인 Completed는 해당 애니메이션 재생이 완료될 때 발생한다.
스토리보드는 XAML 코드로 작성될 수 있고 익스프레션 블렌드로 쉽게 생성한다.
이번 시간에는 사용자가 퍼즐을 성공적으로 풀었을 때 재생할 스토리보드를 생성한다. 해당 애니메이션은 시각적 효과를 만들어 가운데 축을 중심으로 퍼즐의 이미지를 회전하고 점차적으로 희미해져 가는 메시지를 표시한다.
1. 먼저 새로운 Resources 섹션을 아래 보인 강조된 코드를 페이지로 삽입한다.
<phone:PhoneApplicationPage
x:Class="WindowsPhonePuzzle.PuzzlePage" ...>
<phone:PhoneApplicationPage.Resources>
</phone:PhoneApplicationPage.Resources>
...
<Grid x:Name="LayoutRoot" Background="Transparent">
</Grid>
</navigation:PhoneApplicationPage>
2. 다음으로 섹션 Resources 내에 사용자가 퍼즐을 풀 때 발생하는 전환을 위한 애니메이션 스토리보드를 삽입한다. WinTransition 스토리 보드를 정의한 다음의 XAML 마크업을 아래처럼 삽입한다.
...
<phone:PhoneApplicationPage.Resources>
<Storyboard x:Name="WinTransition">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="PreviewImage" Storyboard.TargetProperty="(UIElement.Opacity)">
<EasingDoubleKeyFrame KeyTime="00:00:00" Value="0.2"/>
<EasingDoubleKeyFrame KeyTime="00:00:00.7000000" Value="1"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="border" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)">
<EasingDoubleKeyFrame KeyTime="00:00:00" Value="1"/>
<EasingDoubleKeyFrame KeyTime="00:00:00.7000000" Value="-1">
<EasingDoubleKeyFrame.EasingFunction>
<CubicEase EasingMode="EaseInOut"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
<EasingDoubleKeyFrame KeyTime="00:00:01.7000000" Value="1">
<EasingDoubleKeyFrame.EasingFunction>
<CubicEase EasingMode="EaseInOut"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="CongratsBorder" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)">
<EasingDoubleKeyFrame KeyTime="00:00:00" Value="0"/>
<EasingDoubleKeyFrame KeyTime="00:00:00.7000000" Value="-1">
<EasingDoubleKeyFrame.EasingFunction>
<CubicEase EasingMode="EaseInOut"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
<EasingDoubleKeyFrame KeyTime="00:00:01.7000000" Value="1">
<EasingDoubleKeyFrame.EasingFunction>
<CubicEase EasingMode="EaseInOut"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="CongratsBorder" Storyboard.TargetProperty="(UIElement.Opacity)">
<EasingDoubleKeyFrame KeyTime="00:00:01.2000000" Value="0"/>
<EasingDoubleKeyFrame KeyTime="00:00:01.3000000" Value="0"/>
<EasingDoubleKeyFrame KeyTime="00:00:01.4000000" Value="1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</phone:PhoneApplicationPage.Resources>
3. 마지막으로 게임을 재 시작할 때 마다 발생하는 전환을 위해 해당 스토리보드를 삽입한다.
<phone:PhoneApplicationPage.Resources>
<Storyboard x:Name="WinTransition">
...
</Storyboard>
<Storyboard x:Name="ResetWinTransition">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="CongratsBorder" Storyboard.TargetProperty="(UIElement.Opacity)" Duration="00:00:00.0010000">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="PreviewImage" Storyboard.TargetProperty="(UIElement.Opacity)" Duration="00:00:00.0010000">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="0.20000000298023224"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="GameContainer" Storyboard.TargetProperty="(UIElement.Opacity)">
<EasingDoubleKeyFrame KeyTime="00:00:00" Value="1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</phone:PhoneApplicationPage.Resources>
...
4. [솔루션 탐색기]에서 PuzzlePage.xaml을 오른 클릭해 [View Code]를 선택해 이 페이지에 대한 코드 숨김 파일을 연다.
5. PuzzlePage 클래스의 생성자에서 GameOver 이벤트를 처리하는 익명 함수를 찾아서 메서드의 시작 부분에 다음의 강조된 코드 라인을 삽입한다.
public PuzzlePage()
{
...
this.game.GameOver += delegate
{
this.WinTransition.Begin();
this.TapToContinueTextBlock.Opacity = 1;
this.StatusPanel.Visibility = Visibility.Visible;
this.TotalMovesTextBlock.Text = this.game.TotalMoves.ToString();
};
...
}
6. 여전히 PuzzlePage 클래스의 생성자에서 GameStarted 이벤트에 대한 핸들러를 찾아서 다음의 강조된 코드 라인을 추가한다.
public PuzzlePage()
{
...
this.game.GameStarted += delegate
{
this.ResetWinTransition.Begin();
this.StatusPanel.Visibility = Visibility.Visible;
this.TapToContinueTextBlock.Opacity = 0;
this.TotalMovesTextBlock.Text = this.game.TotalMoves.ToString();
};
...
}
7. [F5]를 눌러 빌드한 후 애플리케이션을 에뮬레이터로 배포하고, 잠깐 기다린 후 [START]을 클릭해 새로운 게임을 시작해본다.
8. 보드의 퍼즐을 드래그해서 풀어보든지 아니면 [SOLVE] 버튼을 눌러 퍼즐을 해결하고 게임을 종료한다. 해당 게임이 종료할 때 해당 애니메이션을 일으키고 중간 축을 중심으로 보드를 회전시키면서 “CONGRATULATIONS" 텍스트를 표시했다가 점차적으로 사라진다.
[그림 17] 축하 메시지를 표시하는 해결된 퍼즐