色ブロックを描画する
色ブロックを描画する
「colorVbWPF」プロジェクトを右クリックして表示されるメニューから「Add」→「New Item...」を選び、「ColorBlock.vb」ファイルを新規作成して追加します。
色ブロックは「ColorBlock」クラスで設計図を書きます。「New」コンストラクタで色ブロックを準備し、「GetImg」関数で画像をファイルから読み込みます(図2)。「Sub」プロシージャは戻り値を返さないメソッドで「Function」プロシージャは戻り値を返すメソッドです。
・サンプルコード「ColorBlock.vb」ファイル
Public Class ColorBlock
Private x, y As Integer
Private vx, vy As Integer
Private img As Image
Private color As Integer
Private Shared ReadOnly rnd As New Random()
Private parent As MainWindow
Public Sub New(imageCanvas As Canvas, col As Integer, p As MainWindow)
parent = p
color = col
img = GetImg(col)
AddHandler img.MouseLeftButtonDown, AddressOf Img_MouseLeftButtonDown
imageCanvas.Children.Add(img)
x = rnd.Next(0, 1700)
y = rnd.Next(0, 800)
vx = rnd.Next(-3, 4)
vy = rnd.Next(-3, 4)
Canvas.SetLeft(img, x)
Canvas.SetTop(img, y)
End Sub
Private Function GetImg(col As Integer) As Image
Dim path As String = System.IO.Path.Combine(
AppDomain.CurrentDomain.BaseDirectory,
"../../../images",
$"{col}.png"
)
Dim bitmap As New BitmapImage()
bitmap.BeginInit()
bitmap.UriSource = New Uri(path, UriKind.Absolute)
bitmap.CacheOption = BitmapCacheOption.OnLoad
bitmap.EndInit()
bitmap.Freeze()
' Imageを作成
Return New Image With {
.Width = 100,
.Height = 100,
.Stretch = Stretch.Uniform,
.Source = bitmap
}
End Function
Private Sub Img_MouseLeftButtonDown(sender As Object, e As MouseButtonEventArgs)
End Sub
End Class【サンプルコードの解説】
ColorBlockクラスで色ブロックの位置(x,y)、移動量(vx,vy)、画像(img)、色(color)、乱数(rnd)、MainWindowクラス自体のインスタンス(parent)を宣言します。
NewコンストラクタでMainWindowクラスのインスタンスと色ブロックの色をセットし、「GetImg」メソッドでcolインデックスの色ブロック画像を読み込みます。色ブロックが左クリックされた時のイベントハンドラをセットし、「ImageCanvas」の子要素に色ブロックを追加します。ランダムに(x,y)と(vx,vy)を決め、imgのあるCanvasにx(SetLeft)、y(SetTop)の位置で配置します。
「GetImg」メソッドは、アプリのexeファイルを書き出したディレクトリからの相対パスで0.png~2.pngの画像をBitmapImageに読み込み、Imageクラスのインスタンスを生成して戻り値として返します。
「Img_MouseLeftButtonDown」は色ブロックがクリックが押された時に呼ばれます。
・サンプルコード「MainWindow.xaml.vb」ファイル
Class MainWindow
Property colors As List(Of ColorBlock) = New List(Of ColorBlock)()
Private WithEvents timer As New DispatcherTimer()
Private stage As Integer = 2
Public Sub New()
InitializeComponent()
End Sub
Private Sub Title_MouseLeftButtonUp(sender As Object, e As MouseButtonEventArgs)
TitleGrid.Visibility = Visibility.Hidden
ImageCanvas.Visibility = Visibility.Visible
Init()
End Sub
Private Sub Init()
ImageCanvas.Children.Clear()
colors.Clear()
For i As Integer = 0 To stage * 3 - 1
colors.Add(New ColorBlock(ImageCanvas, i Mod 3, Me))
Next
End Sub
End Class【サンプルコードの解説】
MainWindowクラスで、「colors」リスト配列に色ブロックを、定期的に呼び出すタイマーを「timer」プロパティに、ステージ(面)の初期値として2を「stage」プロパティにセットします。
「Title_MouseLeftButtonUp」で、タイトル画像のマウスクリックが離されたらタイトルGridを隠してImageCanvasを表示し、「Init」メソッドを呼び出します。
Initメソッドで、ImageCanvasとcolorsをクリアし、colorsにstage×3色(R・G・B)の個数だけ色ブロックを追加します。
色ブロックを移動しゲームオーバーを処理する
今度は色ブロックを20FPSで毎フレーム更新して移動させます。すべての色ブロックが画面外に出たらflgが0になり、ゲームオーバー処理としてタイマーを停止し、タイトルGridを表示してImageCanvasを隠します。ゲームオーバー画面とサウンドは省略しました。
・サンプルコード「ColorBlock.vb」ファイル
Public Class ColorBlock
(中略)
Public Sub New(imageCanvas As Canvas, col As Integer, p As MainWindow)
(中略)
End Sub
Private Function GetImg(col As Integer) As Image
(中略)
End Function
Public Function Update() As Integer
x += vx
y += vy
Canvas.SetLeft(img, x)
Canvas.SetTop(img, y)
If x >= -100 And x <= 1800 And y >= -100 And y <= 900 Then
Return 1
End If
Return 0
End Function
Private Sub Img_MouseLeftButtonDown(sender As Object, e As MouseButtonEventArgs)
End Sub
End Class【サンプルコードの解説】
「Update」メソッドで色ブロックの位置を移動量だけ移動します。
・サンプルコード「MainWindow.xaml.vb」ファイル
Imports System.Windows.Threading
Class MainWindow
(中略)
Public Sub New()
InitializeComponent()
End Sub
Private Sub Window_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
timer.Interval = TimeSpan.FromMilliseconds(50)
End Sub
Private Sub Title_MouseLeftButtonUp(sender As Object, e As MouseButtonEventArgs)
TitleGrid.Visibility = Visibility.Hidden
ImageCanvas.Visibility = Visibility.Visible
Init()
timer.Start()
End Sub
Private Sub Init()
(中略)
End Sub
Private Sub Timer_Tick(sender As Object, e As EventArgs) Handles timer.Tick
Dim flg As Integer = 0
For Each col In colors
flg += col.Update()
Next
If flg = 0 Then
timer.Stop()
TitleGrid.Visibility = Visibility.Visible
ImageCanvas.Visibility = Visibility.Hidden
End If
End Sub
End Class【サンプルコードの解説】
MainWindowクラスでウィンドウの読み込みが完了すると「Window_Loaded」メソッドが呼ばれ、タイマーを50ミリ秒ごとに更新(20FPS)します。
Title_MouseLeftButtonUpメソッドでタイマーをスタートします。
「Timer_Tick」メソッドで色ブロックを移動し、画面内にいたら1ずつ加算します。色ブロックが0個(flg = 0)ならタイマーをストップしてタイトル画面を表示し、ImageCanvasを隠します。
イシュー度、つまり「問題にするほど価値がある題材かが重要だ」と気付かされました。解決策を考えてもイシュー度が低ければ無意味。売れないのに絵本のアイデアを考えているより、絵本以外を見つけるべきかと考えさせられました。
この記事をシェアしてください
