背景色を反映させる
背景色を反映させる
このゲームの肝である背景色を反映させます(図4)。背景色はRとGとBのそれぞれの数値が他より大きいほど赤緑青のそれぞれの色が明るくなります。背景色は「rgb」配列の3要素に正の整数値が代入され、その数値を元に決めているだけです。
また背景色が真っ白になったらステージクリア処理をし、色ブロックが全てなくなるとゲームオーバー処理します。改造するならステージクリア画像とゲームオーバー画像を表示するとよいでしょう。
・サンプルコード「Forms1.cs」ファイル
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
namespace colorCSForms
{
public partial class Form1 : Form
{
System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
List<Sprite> sprites = new List<Sprite>();
Random rand = new Random();
Image[] img = new Image[4];
int[] rgb = new int[3];
int stage = 2;
enum GAME_STATE {TITLE,MAIN_LOOP,GAME_OVER,STAGE_CLEAR};
GAME_STATE gameState;
public Form1()
{
(中略)
}
void title()
{
(中略)
}
void onClick2Start(object sender, MouseEventArgs e)
{
(中略)
}
void 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);
}
sprites.Clear();
// 初期生成
for (int i = 0; i < stage*3; i++) sprites.Add(new Sprite(this.ClientSize,img,i%3));
}
void update(object sender, EventArgs e)
{
for (int i = sprites.Count - 1; i >= 0; i--) if ( sprites[i].Update(this.ClientSize) ) sprites.RemoveAt(i);
// ゲームオーバー判定
if (sprites.Count <= 0)
{
gameState = GAME_STATE.GAME_OVER;
title();
}
// 背景色セット&ゲームクリア判定
if (bgColor())
{
gameState = GAME_STATE.STAGE_CLEAR;
stage++;
init();
}
this.Invalidate(); // 再描画
}
bool bgColor()
{
int max = rgb[0] < rgb[1] ? (rgb[1] < rgb[2] ? 2 : 1) : (rgb[0] < rgb[2] ? 2 : 0);
int i = 255 / rgb[max];
int r = i * rgb[0];
int g = i * rgb[1];
int b = i * rgb[2];
this.BackColor = Color.FromArgb(r, g, b);
if (r == g && g == b) return true;
return false;
}
protected override void OnPaint(PaintEventArgs e)
{
(中略)
}
void onMouseDown(object sender, MouseEventArgs e)
{
}
}
}【サンプルコードの解説】
「init」メソッドでrgb配列の各要素にランダムな値を入れます。この時に赤緑青が全て同じ数値で白色にならないようにします。
「update」メソッドで「sprites」配列の要素数が0以下になったらゲームオーバー、「bgColor」メソッドを呼び出して背景色が真っ白になったらステージクリアです。
「bgColor」メソッドではrgb配列の赤緑青のうち最も大きい要素を最大の明るさとし、他の2色の要素の数値をそれに対する割合の明るさにします。赤緑青がすべて同じ数値なら背景色は真っ白になり、戻り値としてtrueを返します。
クリックで色ブロックを消す
仕上げとして、色ブロックをクリックしたら消す処理をします。その際、その色の値が背景色のRGBにインクリメントされます。今回もサウンドはありませんが、改造するならサウンドを再生できるようにしてもよいでしょう。
・サンプルコード「Sprite.cs」ファイル
using System.Reflection.Metadata;
namespace colorCSForms
{
public class Sprite
{
(中略)
public Sprite(Size clientSize,Image[] img,int col)
{
(中略)
}
public bool Update(Size clientSize)
{
(中略)
}
public bool Click(MouseEventArgs e)
{
Rectangle rect = new Rectangle(
(int)X,
(int)Y,
Img.Width,
Img.Height
);
if (rect.Contains(e.Location)) return true;
return false;
}
}
}【サンプルコードの解説】
色ブロックの「Sprite」クラスの「Click」メソッドでは、画像の矩形にマウス座標が含まれていれば戻り値としてtrueを返します。
・サンプルコード「Forms1.cs」ファイル
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
namespace colorCSForms
{
public partial class Form1 : Form
{
(中略)
public Form1()
{
(中略)
}
void title()
{
(中略)
}
void onClick2Start(object sender, MouseEventArgs e)
{
(中略)
}
void init()
{
(中略)
}
void update(object sender, EventArgs e)
{
(中略)
}
bool bgColor()
{
(中略)
}
protected override void OnPaint(PaintEventArgs e)
{
(中略)
}
void onMouseDown(object sender, MouseEventArgs e)
{
for (int i = 0; i < sprites.Count; i++)
{
Sprite s = sprites[i];
if ( s.Click(e) )
{
sprites.RemoveAt(i);
rgb[s.Col]++;
break;
}
}
}
}
}【サンプルコードの解説】
マウスが押されたら「onMouseDown」メソッドが呼ばれ、各色ブロックがクリックされていたらsprites配列から削除し、その色の値を背景色に加算します。
ある成功者に「ビジネスで失敗するのが心配じゃないですか?」と聞いたら「死ぬわけじゃない」と言っていました。僕はお金をあまり使わないのに、金額に関係なく1番不正アクセスのことが心配で凹みます…。「死ぬわけじゃない」と思いたいです。
おわりに
今回は「Visual Studio 2026」のプログラミング言語「C#」でColorゲームを開発しました。C#は他にも「WPF(Windows Presentation Foundation)」や「UWP(Universal Windows Platform)」などの機能を使って開発することもできます。
