ゲーム実装で身に付くプログラミング 7

背景色を反映させる

背景色を反映させる

やっと、このゲームの核心である変化する背景色を反映させます(図4)。背景色はRed、Green、Blueの各数値が大きいほど、対応する色が明るくなります。実際には「rgb」配列の3要素に正の整数値を代入したりインクリメントし、その数値を元に背景色を決めているわけです。

また、色ブロックがすべてなくなるとゲームオーバー処理を行い、背景色が真っ白になったらステージクリア処理をします。改造するならゲームオーバー画像やステージクリア画像を表示すると良いでしょう。

図4:背景色を反映

・サンプルコード「Forms1.vb」ファイル

Imports System.Drawing
Imports System.Runtime.Intrinsics
Imports System.Windows.Forms

Partial Public Class Form1
    Inherits Form
    Private timer As New Timer()
    Private sprites As New List(Of Sprite)()
    Private rand As New Random()
    Private rgb(2) As Integer
    Private img(3) As Image
    Private stage As Integer = 2
    Enum GAME_STATE
        TITLE
        MAIN_LOOP
        GAME_OVER
        STAGE_CLEAR
    End Enum
    Private gameState As GAME_STATE

    Public Sub New()
(中略)
    End Sub

    Private Sub title()
(中略)
    End Sub

    Private Sub onClick2Start(sender As Object, e As MouseEventArgs)
(中略)
    End Sub

    Private Sub init()
        gameState = GAME_STATE.MAIN_LOOP
        rgb(0) = 0
        rgb(1) = 0
        rgb(2) = 0
        While rgb(0) = rgb(1)
            rgb(0) = rand.Next(0, stage)
            rgb(1) = rand.Next(0, stage)
            rgb(2) = rand.Next(0, stage)
        End While
        sprites.Clear()
        ' 初期生成
        For i As Integer = 0 To stage * 3 - 1
            sprites.Add(New Sprite(Me.ClientSize, img, i Mod 3))
        Next
    End Sub

    Private Sub update(sender As Object, e As EventArgs)
        For i As Integer = sprites.Count - 1 To 0 Step -1
            If sprites(i).Update(Me.ClientSize) Then
                sprites.RemoveAt(i)
            End If
        Next
        ' ゲームオーバー判定
        If sprites.Count <= 0 Then
            gameState = GAME_STATE.GAME_OVER
            title()
        End If
        ' 背景色セット&ゲームクリア判定
        If bgColor() Then
            gameState = GAME_STATE.STAGE_CLEAR
            stage += 1
            init()
        End If
        Me.Invalidate() ' 再描画
    End Sub

    Private Function bgColor() As Boolean
        Dim indexSorted = rgb.
            Select(Function(v, idx) idx).
            OrderByDescending(Function(idx) rgb(idx)).
            ToArray()
        Dim i As Integer = 255 \ rgb(indexSorted(0))
        Dim r As Integer = i * rgb(0)
        Dim g As Integer = i * rgb(1)
        Dim b As Integer = i * rgb(2)
        Me.BackColor = Color.FromArgb(r, g, b)
        If r = g AndAlso g = b Then
            Return True
        End If
        Return False
    End Function

    Protected Overrides Sub OnPaint(e As PaintEventArgs)
(中略)
    End Sub

    Private Sub onMouseDown(sender As Object, e As MouseEventArgs)
    End Sub

End Class

【サンプルコードの解説】
「init」メソッドでrgb配列の各要素にランダムな値を入れます。ゲーム開始時から背景色の赤緑青が全て同じ数値の白色にならないようにします。
「update」メソッドで「sprites」配列の要素数が0以下になったらゲームオーバーです。「bgColor」メソッドを呼び出し、背景色が真っ白ならステージクリアとなります。
「bgColor」メソッドでは、rgb配列の赤緑青のうち最も大きい要素を最大の明るさとし、他の2色の要素の数値をそれに対する比率で明るさを決めます。赤緑青がすべて同じ数値なら背景色は真っ白になり、戻り値としてTrueを返します。そうでなければFalseを返します。

クリックで色ブロックを消す

最後に仕上げとして、色ブロックをクリックしたら削除する処理をします。その際、クリックした色ブロックの色の値が背景色のRGBの対応する要素にインクリメントされます。今回も解説をシンプルにするためサウンドはありませんが、改造するならサウンドを再生できるようにしても良いでしょう。

・サンプルコード「Sprite.vb」ファイル

Imports System.Drawing
Imports System.Windows.Forms

Public Class Sprite
(中略)
    Public Sub New(clientSize As Size, img() As Image, col As Integer)
(中略)
    End Sub

    Public Function Update(clientSize As Size) As Boolean
(中略)
    End Function

    Public Function Click(e As MouseEventArgs) As Boolean
        Dim rect As New Rectangle(
            CInt(X),
            CInt(Y),
            Img.Width,
            Img.Height
        )
        If rect.Contains(e.Location) Then
            Return True
        End If
        Return False
    End Function
End Class

【サンプルコードの解説】
色ブロックの「Sprite」クラスの「Click」メソッドでは、画像の矩形にマウス座標が含まれていれば戻り値としてTrueを返します。そうでなければFalseを返します。

・サンプルコード「Forms1.vb」ファイル

Imports System.Drawing
Imports System.Runtime.Intrinsics
Imports System.Windows.Forms

Partial Public Class Form1
    Inherits Form
(中略)
    Public Sub New()
(中略)
    End Sub

    Private Sub title()
(中略)
    End Sub

    Private Sub onClick2Start(sender As Object, e As MouseEventArgs)
(中略)
    End Sub

    Private Sub init()
(中略)
    End Sub

    Private Sub update(sender As Object, e As EventArgs)
(中略)
    End Sub

    Private Function bgColor() As Boolean
(中略)
    End Function

    Protected Overrides Sub OnPaint(e As PaintEventArgs)
(中略)
    End Sub

    Private Sub onMouseDown(sender As Object, e As MouseEventArgs)
        For i As Integer = 0 To sprites.Count - 1
            Dim s As Sprite = sprites(i)
            If s.Click(e) Then
                sprites.RemoveAt(i)
                rgb(s.Col) += 1
                Exit For
            End If
        Next
    End Sub
End Class

【サンプルコードの解説】
マウスが押されたら「onMouseDown」メソッドが呼ばれ、マウス座標に色ブロックがあればsprites配列から削除し、その色に対応する背景色の要素に1を加算します。

【コラム】やなせたかし先生

やなせたかしさんが「人生は後半が楽しい」と言っていました。やなせさんは50代でアンパンマンを発表し、70代でアニメ化し、94歳で死ぬまで創作活動を続けました。アンパンマングッズに囲まれた仕事場を見るたびにクリエイターの憧れだと思います。

おわりに

今回は「Visual Studio 2026」のプログラミング言語「Visual Basic.NET」でColorゲームを開発しました。C#とほとんど同じアルゴリズムでしたね。Visual Basic.NETは他にも「WPF(Windows Presentation Foundation)」や「UWP(Universal Windows Platform)」などの機能を使って開発することもできます。

人気記事トップ10

人気記事ランキングをもっと見る

企画広告も役立つ情報バッチリ! Sponsored