この記事では、Silverlightでのゲームループの使用について説明します。 アニメーションを操作し、アニメーションに影響するユーザーアクションを処理するためのすべてのロジックを含む関数。 機械制御の例。
Silverlightは優れたアニメーションをサポートしています。 Blendでプロパティを取得し、キーを配置します。 そしてすべてが機能し、コントロールはユーザーのアクションに応答します。 プログラム的に、
ストーリーボードを介して、プロパティを状態Aから状態Bに変更するアニメーションも、途中で問題なく簡単に行えます。 しかし、複雑なアニメーション(物理、衝突計算、アニメーションカーブの動的な変更)に関しては、
ストーリーボードを介したアニメーションの実装はコードを大幅に複雑にするか、まったく不可能です。
この問題における古典的なアプローチは、タイマーを作成し、更新されるたびにアニメーションロジックを再カウントすることです。
Silverlightでは、これらはタイマーになります。
- System.Windows.Threading.DispatcherTime r-UIスレッドでの作業
- System.Threading.Timer-別のスレッドで動作します。
しかし、Silverlightでプログラムアニメーションを実装するのにより適切なのは、グローバル
Renderingイベントである静的クラス
System.Windows.Media.CompositionTargetを使用することです。
サンプルコード、単純なゲームループ:
frameTime変数には、最後の再描画以降に経過した時間が含まれます。 この時間は大きく異なる可能性があることを考慮する価値があります。 フレーム間の急激な動きを避けるには、この時間に依存する可変プロパティを作成する必要があります。 60に等しいfps(1秒あたりのフレームレート)は、16ミリ秒後にすべてのフレームが表示されることを意味しないことを理解することが重要です。
原則として、それだけです。残っているのは、独自のアニメーションロジックを記述することだけです。 なぜなら Silverlight自体がオブジェクトの再描画を担当します。プロパティに値を入力するだけで、残りは心配する必要はありません。
生きている例
たとえば、「ゲーム」というマシンを箱の中に作成します。 キーボードの矢印は車を制御します。 左、右、ガス、リバース/ブレーキ、すべてが他のどこにでも似ています。
新しいSilverlightプロジェクトを作成します。 「MainPage.xaml」を開きます。 「LayoutRoot」という名前のメイングリッドに、次を配置します。
<Grid Margin="12" Background="#FF084E0F"/> <Viewbox IsHitTestVisible="False" Margin="12"> <TextBlock TextWrapping="Wrap" Text=" " Foreground="#FF00228D" RenderTransformOrigin="0.5,0.5" Margin="10,0" Width="129" Height="16"> <TextBlock.RenderTransform> <CompositeTransform Rotation="-35"/> </TextBlock.RenderTransform> </TextBlock> </Viewbox> <Canvas x:Name="ContentPanel" Margin="12"> <TextBlock x:Name="tbInfo" Text="TextBlock" Foreground="White" FontSize="16" /> <Image x:Name="car" Width="70" Source="car.png" Height="35" /> </Canvas>
写真「car.png」を自分またはこれで使用できます。
主なことは、車の鼻が右に見えることです。
アニメーション中のサイズ変更の問題。
アニメーション化されたオブジェクトのサイズが原因で、アニメーションを操作するときに発生する可能性のある問題がいくつかあります。
- Autoで幅または高さの寸法を設定すると、回転中心の変化はそれぞれ考慮されず、回転のアニメーションに問題がある可能性があります。 絶対単位の次元。
- 開始時、 ActualWidthとActualHeightはゼロです。 複数のオブジェクトがまだ描画されていません。 計算でこれを考慮してください。
ゲームワールドが作成されました。 ロジックを追加します。
キーストローク処理
キーはそれほど単純ではありません。 最初は、Silverlightは同時に押されるキーの定義をサポートせず、修飾キー(Ctrl、Shift、Alt)をカウントしません。 KeyDownイベントは、最後に押されたキーのみを処理します。 つまり 一度に1つのキーを押す必要があります。 例えば、彼らはガスを絞った、そしてガスの間、左に曲がらない。 解決策として、Ctrl / Shiftにガス/ブレーキをかけ、両手で操縦します。 不便です...
しかし、すべてがそれほど悪いわけではありませんが、良いことさえあります。 インターネット(
Silverlightで複数のキー入力を検出 )で、この問題を解決し、ゲームループ内でキーストロークを処理できるクラスが見つかりました。これは、KeyDownハンドラー内よりもはるかに便利です。
プロジェクトにクラスを追加します。
アニメーション
次のグローバル変数をMainPage.xaml.csに追加します。
RenderTransformプロパティを介して車のアニメーションを
作成します。 移動、回転などを担当します。
なぜなら 変換は、開始位置を基準にしてオブジェクトをアニメーション化します。 Canvas.TopとCanvas.Leftが 車オブジェクト(私たちの車)に設定されていないことを確認してください。
メインウィンドウのコンストラクターに入力します。
public MainPage(){ InitializeComponent(); this.Loaded += MainPage_Loaded;
マウスクリック処理機能は、ほとんどの場合、マシンがマウスからのイベントをキャッチすることを示す必要があります。
ウィンドウが表示されたら、Silverlightプラグインにフォーカスを設定します。そうしないと、キーストロークをキャッチしません。 一部のブラウザではこれは役に立たないため、フォーカスを手動に設定する必要があります。 おもちゃをクリックしてください。 また、ゲームサイクルを準備します。
private void MainPage_Loaded(object sender, RoutedEventArgs e){
アニメーションで使用されるグローバル変数を追加します。
車を動かすアニメーションによって。 方向ベクトル(単位ベクトル)を原点の周りで回転させ、ベクトルのコンポーネントに速度を掛けて、車が存在する場所を取得します。 同時に、結果の角度は機械の回転角度になります。
マシンとコンテナの境界線の交差点を計算するには、車両の方向転換の角度を考慮して、マシンを囲む長方形を計算します。
ゲームの中心であるゲームサイクルの機能に移りましょう。
private void _gameLoopUpdate(object sender, EventArgs e){ int currentTime = Environment.TickCount; int frameTime = currentTime - _lastTime; _lastTime = currentTime;
ループ機能は、次の手順で構成されます。
- マシンの現在の位置を取得する
- 押されたキーに応じて変更を設定します
- 速度を常に0にリセットします。これにより、加速アニメーションがそれほど線形ではなくなります。
- 車が箱から出たかどうかを確認します
- 受け取った変更を適用します。
すべての変更について、前のフレームからの経過時間(
delta )を考慮します。 認識しやすくするため、速度は1秒あたりの単位で測定されます。 回転角は車の速度とともに増加します。
キーストロークの処理に注目する価値があります。 なぜなら ゲームサイクルで処理されるため、変更を個別に同期する必要はありません。 また、速度と回転角度を変更するコードがKeyDownハンドラーから呼び出された場合、このような問題が発生していました。
まとめ
車は、多かれ少なかれ複雑なアルゴリズムに従って運転、加速します。 もちろん、加速と回転のより自然なアニメーション、横滑りの効果、道路を横断する老婦人との衝突の誤算...を作成できますが、見るのに十分実装されています:複雑なアニメーション、ゲームループで行うことをお勧めします。
ゲームサイクルにはアーキテクチャ上の利点があり、現時点で発生しているすべてが1か所に集められ、それに影響する要因もあります。
Storyboardを介したアニメーションと比較すると、デバッグが容易であり、非同期性はありません(
Storyboardでは、アニメーションの次の段階を開始するために、アニメーションの終わりをキャッチするのに手間がかかります)。
さらに、額にすべてを実装する必要はありません。 上記の例は
Behaviorで書き直すのは簡単です。 このビヘイビアをBlendのボタンにアタッチすると、画面上を移動します(必要な理由は明確ではありませんが、可能です)。 以下のリソースでは、物理ライブラリのラッパーへのリンクがあります。これは基本的に同じです。Blendでは、オブジェクトにマークを付け、物理法則に敏感になります。
「車の中の車」のソースコードは、
ここまたはサンプルページ
からダウンロードでき
ます 。
リソース:
- Blend、Silverlight、WP7、およびFarseerの物理ヘルパー-Farseer物理エンジン物理ライブラリ(http://farseerphysics.codeplex.com/)のSilverlightラッパー。 彼女のコードで、Silverlightで複雑なアニメーションがどのように処理されるかを見つけました。
- Silverlightのカスタムアニメーション -振り子の例を使用したゲームループの使用。 記事は英語です。