Windows Phone 8:アプリケーションを作成します。 マトリックス パート2
Windows Phone 8:アプリケーションを作成します。 マトリックス パート3. MVVM
コンテスト用のアプリケーションを作成すると、Windows Phone 8用のアプリケーションの作成に関する情報を見つけるのに苦労したため、同じアイデアが作成プロセスを共有するようになりました。なぜ「マトリックス」なのでしょうか? 映画のリリース以来、私を魅了したからです。 それから彼はスクリーンセーバーを見つけました。 彼は何時間も彼女を見ることができた。 そして今、私はそれを電話に転送することにしました。 それでは始めましょう。
Lumia 520の画面から画面を印刷する
約2年前、すでに似たようなものを作成しましたが、JQueryで作成しました。 ただし、完全な値を除いてすべてが判明しました。「スローダウン」しないマトリックスの最大サイズは約15 X 20セルであり、これは最新のFULL HDモニターでは明らかに小さいです。 この動作の理由を見つけると、すべてが1コアのみをロードし、理解したように、1スレッドのみであることがわかりました(間違っている可能性がありますが、このトピックに関する詳細な説明は行いませんでした)。 はい。このJSフレームワークに慣れるという目的でのみ作成されました。 C#にはこれらの欠点がありません。また、現代のスマートフォンの能力は、多数の要素とそのような各要素の多くの乱数を処理するのに十分なはずです。 将来的には、弱いLumia 520でテストするとき、私の期待はすべて実現したと言います。
まず、作成するものを正確に決定しましょう
- ヘビの始点の座標がランダムに選択されるセルのグリッド
- ヘビの長さはランダムに異なります。
- ヘビの各セルでは、要素がランダムな回数ランダムに変化します
- 色あせ効果があります。 ヘビの各成分の明るさは、その長さに依存します
アプリケーションの作成に使用したもの
- Windows 8 Pro x64(RU)
- VS 2012 SP1(RU)
- Windows Phone SDK 8.0(RU)
- VSに含まれる標準アイテムのみ
- WVGA 512 MB設定(RU)のエミュレーターでテスト済み
テストに関するいくつかの言葉。 エミュレーターでは、結果はあまり妥当ではありません。 多数のヘビを起動すると、彼は実際の携帯電話よりも多くのFPSを示しました。 電話でデバッグするとき-電話はひどく遅くなります。 ただし、デバッグを停止して単純にアプリケーションを起動した後、パフォーマンスは十分でした。
Visual Studioで作業を始めましょう
プロジェクトを作成します:テンプレート-Visual C#-Windows Phone-Windows Phoneアプリケーション。
.NET Framework 4.5を選択します。
プロジェクトの名前はSE_Matrix_2d_v_1です。 名前空間にもなります。
Windows Phone OS 8.0を選択します。
MainPage.xaml
次に、XAMLコードを編集します。 LayoutRootという名前のグリッドと、Event_Grid_Tap_LayoutRootを押すイベント(タップ)のみが必要です。これに、画面の拡張に応じて、必要な数のTextBlockセルを動的に入力します。 私たちは見ます:
<phone:PhoneApplicationPage x:Class="SE_Matrix_2d_v_1.MainPage" x:Name="SE_Matrix_2d_v_1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone" xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" FontFamily="{StaticResource PhoneFontFamilyNormal}" FontSize="{StaticResource PhoneFontSizeNormal}" Foreground="{StaticResource PhoneForegroundBrush}" SupportedOrientations="Portrait" Orientation="Portrait" shell:SystemTray.IsVisible="True"> <!--LayoutRoot , --> <Grid x:Name="LayoutRoot" Background="Transparent" Tap="Event_Grid_Tap_LayoutRoot"> </Grid> </phone:PhoneApplicationPage>
エミュレータを起動します。 それはただ黒い画面であるべきです。
MainPage.xaml.cs
必要なライブラリをすぐに接続します。
using System.Windows.Media; // using System.Threading.Tasks; // using System.Diagnostics; // . Debug.WriteLine( SomethingYouNeedToSee);
コンストラクターで、CreateElementメソッドを呼び出します。これにより、要素のマトリックスが作成され、さらにすべてのアクションが実行されます。
// public MainPage() { InitializeComponent(); CreateElement(); }
マトリックスを作成するには、画面の拡張子を決定する必要があります。 ScreenWidthおよびScreenHeightプロパティをMainPageクラスに追加します。
public partial class MainPage : PhoneApplicationPage { // double ScreenWidth = System.Windows.Application.Current.Host.Content.ActualWidth; double ScreenHeight = System.Windows.Application.Current.Host.Content.ActualHeight; ...
CreateElementメソッドの作成を始めましょう。
まず、作成するマトリックスの行と列の数を決定する必要があります。
// countWidth = (int)Math.Round(ScreenWidth / 50); countHeight = (int)Math.Round(ScreenHeight / 50);
他の言語を習得した後にC#の学習を開始した場合、より明確になるでしょう。
// countWidth = (int)Math.Round(this.ScreenWidth / 50); countHeight = (int)Math.Round(this.ScreenHeight / 50);
(これを使用して)クラスのプロパティを参照する必要があることを明確に示します。
これが使用されていない場合、まずその名前の変数がメソッド内で検索され、使用されていない場合、クラスのプロパティで検索が続行されます。
行と列の数がわかったら、通常の列挙(ループの場合は2)を使用して、必要な初期設定で必要な数のTextBlock要素を作成します。
// for (i = 0; i < countWidth; i++) { for (j = 0; j < countHeight; j++) { // TextBlock TextBlock element = new TextBlock(); // TextBlock element.Name = "TB_" + i + "_" + j; // //element.Text = char.ConvertFromUtf32(random.Next(0x4E00, 0x4FFF)); // element.Text = ""; // // TextBlock int wx = i * 50; int wy = j * 50; element.Margin = new Thickness(wx, wy, 0, 0); // element.Foreground = new SolidColorBrush(Colors.Green); // element.FontSize = 36; // Grid LayoutRoot.Children.Add(element); } }
マージンは、それらがすべて重なり合っていないことを確認するように求められます。
各TextBlockの名前は、XおよびY座標の参加によって形成され、それらへの後続のアクセスと、蛇の始点の座標をランダムに設定する機能を容易にします。
このメソッドにBorder要素を追加すると、セルのサイズと位置を視覚的に評価できます。 私たちは見ます:
// , public void CreateElement() { int i, j, countWidth, countHeight; // countWidth = (int)Math.Round(this.ScreenWidth / 50); countHeight = (int)Math.Round(this.ScreenHeight / 50); // for (i = 0; i < countWidth; i++) { for (j = 0; j < countHeight; j++) { // TextBlock TextBlock element = new TextBlock(); // Border Border elementBorder = new Border(); // TextBlock elementBorder.Name = "B_" + i + "_" + j; // TextBlock element.Name = "TB_" + i + "_" + j; // //element.Text = char.ConvertFromUtf32(random.Next(0x4E00, 0x4FFF)); // element.Text = ""; // // TextBlock int wx = i * 50; int wy = j * 50; element.Margin = new Thickness(wx, wy, 0, 0); // element.Foreground = new SolidColorBrush(Colors.Green); // element.FontSize = 36; // Border elementBorder.Margin = new Thickness(wx, wy, 0, 0); // elementBorder.BorderThickness = new Thickness(1); // elementBorder.BorderBrush = new SolidColorBrush(Colors.Green); // TextBlock Border elementBorder.Child = element; // Grid LayoutRoot.Children.Add(elementBorder); } } }
この場合、グリッドにBorder要素(LayoutRoot.Children.Add(elementBorder);)を追加します。目的の要素の境界線を表示するには、Borderタグで囲む必要があるためです。
<Border BorderThickness="1" BorderBrush="Black" Background="Green" CornerRadius="5"> <TextBlock Text="Description"/> </Border>
次に、ボーダーなしで最初のオプションを引き続き使用します。
マトリックスができたので、巻き込まれるヘビの作成を開始できます。 最初に、グリッド要素をクリックするためのイベントハンドラーを作成します。これは、単にStartメソッドを呼び出します。
// Grid ( ) private void Event_Grid_Tap_LayoutRoot(object sender, System.Windows.Input.GestureEventArgs e) { Start(); }
ループ内のこのループでStartメソッドを呼び出すと、複数のヘビが同時に取得されます。 しかし、これは少し後です。
Startメソッドは、蛇の開始のX座標とY座標、蛇の長さ、各TextBlockセルのキャラクターの変化速度など、蛇の初期設定を決定します。ランダムに、キュー内の画面をクリックした後の蛇の数:
// public async void Start() { int count, iteration; // iteration = 1; count = 0; // while (count < iteration) { // int ranX = random.Next(0, 10); // int ranY = random.Next(0, 20); // int length = random.Next(3, 7); // int time = random.Next(30, 70); await Task.Delay(1); // await RandomElementQ_Async(ranX, ranY, length, time); count++; } }
それで、アプリケーションの「中心」であるRandomElementQ_Asyncメソッドに到達しました。 彼は、目的の要素をキャプチャし、その色を決定し、落下の効果を作り出し、ヘビがマトリックスからはみ出さないようにする責任があります。 そして今、より詳細に:
// , public async Task RandomElementQ_Async(int x, int y, int length, int timeOut) { // , . Dictionary<int, TextBlock> dicElem = new Dictionary<int, TextBlock>(); // , , if ((y + i) < countHeight && (y + i) >= 0). 4 . int count = 0; // length for (int i = 0; i < length; i++) { // , // int countHeight = (int)Math.Round(ScreenHeight / 50); // , , if ((y + i) < countHeight) { // , string elementName = "TB_" + x + "_" + (y + i); // object wantedNode = LayoutRoot.FindName(elementName); TextBlock element = (TextBlock)wantedNode; // , "" "" dicElem[count] = (element); // . ( ) - , - . // 1, , 255 . int rf = (int)Math.Round(255 / (double)(i + 1)) - 1; // , . . await Change(element, timeOut, 255); // , . , . for (int k = 0; k <= i; k++) { // "" (, y = -5) if (dicElem.ContainsKey(k)) { // , . "" TextBlock previousElement = dicElem[k]; // // (rf * (k + 1)) - 20 , // ( ) Task dsvv = Change(previousElement, timeOut, (rf * (k + 1)) - 20); } } count++; } } }
最後の簡単な方法は、適切なセルの文字と色を適切な回数変更することです。
// public async Task Change(TextBlock txt, int timeOut, int Opacity) { // SolidColorBrush NewColor = new SolidColorBrush(new Color() { A = (byte)(255) /*Opacity*/, R = (byte)(0) /*Red*/, G = (byte)(Opacity) /*Green*/, B = (byte)(0) /*Blue*/ }); // "" 1 "" txt.Foreground = NewColor; // for (int i = 0; i < 5; i++) { // txt.Text = char.ConvertFromUtf32(random.Next(0x4E00, 0x4FFF)); // await Task.Delay(timeOut); } }
MainPage.xaml.csファイルコードの実行
using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Media; using System.Windows.Navigation; using Microsoft.Phone.Controls; using Microsoft.Phone.Shell; using System.Threading.Tasks; using System.Diagnostics; namespace SE_Matrix_2d_v_1 { public partial class MainPage : PhoneApplicationPage { // Random random = new Random(); // double ScreenWidth = System.Windows.Application.Current.Host.Content.ActualWidth; double ScreenHeight = System.Windows.Application.Current.Host.Content.ActualHeight; // public MainPage() { InitializeComponent(); CreateElement(); } // , public void CreateElement() { int i, j, countWidth, countHeight; // countWidth = (int)Math.Round(this.ScreenWidth / 50); countHeight = (int)Math.Round(this.ScreenHeight / 50); // for (i = 0; i < countWidth; i++) { for (j = 0; j < countHeight; j++) { // TextBlock TextBlock element = new TextBlock(); // TextBlock element.Name = "TB_" + i + "_" + j; // //element.Text = char.ConvertFromUtf32(random.Next(0x4E00, 0x4FFF)); // element.Text = ""; // // TextBlock int wx = i * 50; int wy = j * 50; element.Margin = new Thickness(wx, wy, 0, 0); // element.Foreground = new SolidColorBrush(Colors.Green); // element.FontSize = 36; // Grid LayoutRoot.Children.Add(element); } } } // Grid ( ) private void Event_Grid_Tap_LayoutRoot(object sender, System.Windows.Input.GestureEventArgs e) { Start(); } // public async void Start() { int count, iteration; // iteration = 1; count = 0; // while (count < iteration) { // int ranX = random.Next(0, 10); // int ranY = random.Next(0, 20); // int length = random.Next(3, 7); // int time = random.Next(30, 70); await Task.Delay(1); // await RandomElementQ_Async(ranX, ranY, length, time); count++; } } // , public async Task RandomElementQ_Async(int x, int y, int length, int timeOut) { // , . Dictionary<int, TextBlock> dicElem = new Dictionary<int, TextBlock>(); // , , if ((y + i) < countHeight && (y + i) >= 0). 4 . int count = 0; // length for (int i = 0; i < length; i++) { // , // int countHeight = (int)Math.Round(ScreenHeight / 50); // , , if ((y + i) < countHeight) { // , string elementName = "TB_" + x + "_" + (y + i); // object wantedNode = LayoutRoot.FindName(elementName); TextBlock element = (TextBlock)wantedNode; // , "" "" dicElem[count] = (element); // . ( ) - , - . // 1, , 255 . int rf = (int)Math.Round(255 / (double)(i + 1)) - 1; // , . . await Change(element, timeOut, 255); // , . , . for (int k = 0; k <= i; k++) { // "" (, y = -5) if (dicElem.ContainsKey(k)) { // , . "" TextBlock previousElement = dicElem[k]; // // (rf * (k + 1)) - 20 , // ( ) Task dsvv = Change(previousElement, timeOut, (rf * (k + 1)) - 20); } } count++; } } } // public async Task Change(TextBlock element, int timeOut, int Opacity) { // SolidColorBrush NewColor = new SolidColorBrush(new Color() { A = (byte)(255) /*Opacity*/, R = (byte)(0) /*Red*/, G = (byte)(Opacity) /*Green*/, B = (byte)(0) /*Blue*/ }); // "" 1 "" element.Foreground = NewColor; // for (int i = 0; i < 5; i++) { // element.Text = char.ConvertFromUtf32(random.Next(0x4E00, 0x4FFF)); // await Task.Delay(timeOut); } } // ApplicationBar //private void BuildLocalizedApplicationBar() //{ // // ApplicationBar ApplicationBar. // ApplicationBar = new ApplicationBar(); // // AppResources. // ApplicationBarIconButton appBarButton = new ApplicationBarIconButton(new Uri("/Assets/AppBar/appbar.add.rest.png", UriKind.Relative)); // appBarButton.Text = AppResources.AppBarButtonText; // ApplicationBar.Buttons.Add(appBarButton); // // AppResources. // ApplicationBarMenuItem appBarMenuItem = new ApplicationBarMenuItem(AppResources.AppBarMenuItemText); // ApplicationBar.MenuItems.Add(appBarMenuItem); //} } }
さて、アプリケーションの最初の部分は準備ができています。 バックボーン。
次の部分では、アプリケーションを「パノラマ付きWindows Phoneアプリ」テンプレートに転送し、さまざまなマトリックス設定を追加してアプリケーションの機能を拡張します。その変更はスマートフォンの画面にすぐに表示されます。
追伸 WP8を学習し始めた人々にとって、アプリケーションがブラックボックスのように見えないように、考えのシーケンスを可能な限り伝えようとしました。 コードを可能な限り簡素化するとともに、次の部分の複雑さを徐々に増やしていきます。 理解できない瞬間がある場合-聞いてください。