制限時間内に指定した画像を見つけ出す脳トレーニングアプリを作ろう
次に、ソリューション・エクスプローラー内のMainWindow.xamlを展開して表示される、MainWindow.xaml.vbをダブルクリックしてリスト2のコードを記述します。
ロジックコードを記述する
リスト2 (MainWindow.xaml.vb)
ImageInfoというクラス内に、「画像名」という数値型のプロパティを定義しておきます。
Public Class ImageInfo Public Property 画像名 As String End Class
‘ 乱数を発生させるための、Randomクラス型のメンバー変数Rndを宣言します
Private Rnd As Random Private mySecond As Integer Private _second As Integer = 0
‘ タイマーを発生させるためのDispacherTimerクラス型のメンバー変数myTimerを宣言します
Private myTimer As DispatcherTimer Private myCount As Integer = 0
‘ 選択された画像を格納する文字列型のメンバー変数SelectImageを宣言します
Private SelectImage As String
‘ 30個の画像に関連付けている画像のURLを格納するメンバー変数_Imageを宣言します。
Private _Image As String
‘ キャラクターに喋らす内容を格納する文字列型のメンバー変数readingTextを宣言します。
Private readingText As String
ランダムな画像を表示する処理
数値型の変数myRndを宣言し0で初期化します。添え字が31の数値型配列変数myArray(31)を宣言します。
ImageInfoクラス型の新しいリストである、myImageInfo変数を宣言します。
まず、最初に、繰り返し変数iで1から31までを繰り返し、配列変数myArrayに格納しておきます。
XElement.Loadメソッドでphotos.xmlを読み込みます。文字列型の変数myImageを宣言します。
繰り返し変数iで1から31までを繰り返し、以下の処理を行います。
新しいRandomのインスタンスRndオブジェクトを作成します。
myRnd = Rnd.Next(i, 31)
で最少がiで最大が31までのランダムな数を生成し、変数myRndに格納します。
このままでは、重複した乱数が表示されるため、myRndで初期化された配列変数myArrayをtemp変数に格納します。myRndを配列に持つmyArrayにmyArray(i)の値を代入します。最後にmyArray(i)にtempの値を代入します。これで、重複しない1から31までの数値が表示されます。
リスト1のXML文書を見るとわかりますが、属性に”番号”を持たせて番号を振っています。この番号の値が、ランダムに表示された数値と合致する画像名要素を選択するクエリを定義します。
クエリ—内を変数resultで操作して、画像名要素の内容を取得しながら、以下の処理を行います。
変数myImageに画像名要素の値を格納します。乱数は31まで生成しますが、画像は30枚しか表示しないので、変数iが31より小さい時だけ、ImageInfoクラスの画像名プロパティに、文字列”ms-appx:///Images/”と変数myImageの格納している画像名を連結して、AddメソッドでmyImageInfoオブジェクトに追加していきます。
画像は30枚しか使用しないので、乱数も30まで生成すればいいように思えますが、それでは必ず決まった画像が最後(30番目)に表示されることになり、これではまずいので、31までの乱数を発生させて、表示は30までの乱数に該当する番号の画像名を表示させていいます。
GridView1のItemsSourceプロパティにmyImageInfoオブジェクトを指定します。これで、ランダムに並んだ画像が表示されます。
Private Sub DataShow() Dim myRnd As Integer = 0 Dim temp As Integer = 0 Dim myArray(31) As Integer Dim myImageInfo As New List(Of ImageInfo) For i As Integer = 1 To 31 myArray(i) = i Next Dim xmldoc As XElement = XElement.Load("photos.xml") Dim myImage As String = String.Empty Dim no As Integer = 1 For i As Integer = 1 To 31 Rnd = New Random myRnd = Rnd.Next(i, 31) temp = myArray(myRnd) myArray(myRnd) = myArray(i) myArray(i) = temp Dim query = From c In xmldoc.Descendants("画像名") Where CInt(c.Attribute("番号").Value).Equals(myArray(no)) For Each result In query myImage = result.Value If i < 31 Then myImageInfo.Add(New ImageInfo With {.画像名 = "ms-appx:///Images/" & myImage}) End If Next no += 1 Next GridView1.ItemsSource = myImageInfo End Sub
秒数を選択した時の処理
ComboBoxから値が選択されている場合は、メンバー変数mySecondにComboBoxより選択された値を格納します。その値をメンバー変数_secondに代入します。
[開始]ボタンの使用を可能にします。
ComboBoxから値が選択されていない場合は、[開始]ボタンの使用は不可とします。
変化する秒数を表示するtimeTextBlockに、残り何秒と表示します。
Private Sub ComboBox1_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles ComboBox1.SelectionChanged If ComboBox1.SelectedIndex >= 0 Then mySecond = DirectCast(ComboBox1.SelectedItem, ComboBoxItem).Content.ToString _second = mySecond StartButton.IsEnabled = True Else mySecond = 0 StartButton.IsEnabled = False End If timeTextBlock.Text = "残り" & mySecond & "秒" End Sub
[開始]ボタンがタップされた時の処理
メッセージを表示させるmessageTextBlockを非表示にします。ComboBoxからの秒数の選択を不可とします。
画像をランダムに表示させるDataShowメソッドを実行します。
画面の右済み下に表示させる、選択元となる画像を表示させるImageShowメソッドを実行します。
[開始]ボタンの使用を不可とします。
新しいDispatcherTimerクラスのインスタンスmyTimerオブジェクトを作成します。Intervalに「1秒」と指定します。
AddHandlerステートメントで、指定したタイマーの間隔が経過し、タイマーが有効である場合に発生するTickイベントに、myTimer_Tickイベントハンドラを指定します。Startメソッドでタイマーを開始します。
Private Sub StartButton_Click(sender As Object, e As RoutedEventArgs) Handles StartButton.Click messageTextBlock.Text = String.Empty messageTextBlock.Visibility = Windows.UI.Xaml.Visibility.Collapsed ComboBox1.IsEnabled = False DataShow() ImageShow() StartButton.IsEnabled = False myTimer = New DispatcherTimer myTimer.Interval = New TimeSpan(0, 0, 1) AddHandler myTimer.Tick, AddressOf myTimer_Tick myTimer.Start() End Sub
画面の右隅下に表示させる選択元となる画像を表示させるメソッド
ここの処理はDataShowメソッドとほとんど同じ処理ですので、解説はそちらを参照してください。異なる点は、DataShowメソッドでは画像をGridView1に表示させていましたが、ここではImage1に表示させている点が異なるだけです。
Private Sub ImageShow() Rnd = New Random Dim myRnd As Integer = 0 Dim temp As Integer = 0 Dim myArray(31) As Integer Dim myImageInfo As New List(Of ImageInfo) For i As Integer = 1 To 31 myArray(i) = i Next Dim xmldoc As XElement = XElement.Load("photos.xml") Dim myImage As String = String.Empty Dim no As Integer = 0 For i As Integer = 1 To 31 no += 1 myRnd = Rnd.Next(i, 31) temp = myArray(myRnd) myArray(myRnd) = myArray(i) myArray(i) = temp If i < 31 Then Dim query = From c In xmldoc.Descendants("画像名") Where CInt(c.Attribute("番号").Value).Equals(myArray(no)) For Each result In query myImage = result.Value Image1.Tag = "ms-appx:///Images/" & myImage Image1.Source = New BitmapImage(New Uri("ms-appx:///Images/" & myImage, UriKind.Absolute)) Next End If Next End Sub
制限時間内に指定した画像を見つけ出す脳トレーニングアプリ
『Windows 8.1+Visual Studio 2013によるWindows ストア・アプリ開発実例集』 第2回のサンプルプログラムです。