タイマーの仕組みを知る
この節ではタイマーについて紹介しましょう。タイマーは、指定間隔ごとにTickイベントと呼ばれるイベントを発生させるクラスです。
このクラスのイベントを利用すると、一定時間ごとにTickイベントが発生し、このイベントを処理するために登録されたイベントハンドラが呼び出されるようになります。つまり、一定時間ごとに画像を動かしたりするなどといった処理ができるようになります。
アニメーションを行う
タイマーと画像を使うとアニメーションをすることができます。さっそくコードを見ていきましょう。
//sample7.cs
using System;
using System.Windows.Forms;
using System.Drawing;
using System.Collections.Generic;
namespace lesson8
{
class sample7 : Form
{
private Ball bl;
private int x, y;
static void Main(string[] args)
{
Application.Run(new sample7());
}
public sample7()
{
this.Text = "lesson8";this.ClientSize = new Size(200, 100);
bl = new Ball();
Point p = new Point(0,0);
Color c = Color.Blue;
bl.Point = p; bl.Color = c;
x = 2; y = 2;
Timer tm = new Timer();//タイマーオブジェクトを作成します
tm.Interval = 100;//間隔をミリ秒で指定します
tm.Start();//タイマーを開始します
this.Paint += new PaintEventHandler(fm_Paint);
tm.Tick += new EventHandler(tm_Tick);//イベントハンドラを登録します
}
public void fm_Paint(Object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
Point p = bl.Point;
Color c = bl.Color;
SolidBrush br = new SolidBrush(c);
int x = p.X;
int y = p.Y;
g.FillEllipse(br, x, y, 100, 100);
}
//指定ミリ秒ごとにイベントハンドラが処理されます
public void tm_Tick(Object sender, EventArgs e)
{
Point p = bl.Point;
//壁にあたったら反転させます
if (p.X < 0 || p.X > this.ClientSize.Width - 10) x = -x;
if (p.Y < 0 || p.Y > this.ClientSize.Height - 10) y = -y;
p.X = p.X + x; //移動させます
p.Y = p.Y + y; //移動させます
bl.Point = p;
this.Invalidate(); //再描画させます
}
}
class Ball
{
public Color Color;
public Point Point;
}
}
タイマーイベントを利用する方法もこれまでのイベント処理の仕組みと同じです。まず、Timerクラスからオブジェクト作成します。そして、このTickイベントを処理するためのイベントハンドラを設計して登録します。
イベントハンドラ内では、ボールの位置を移動させる処理を記述します。そして描画するInvalidate()を記述するのです。イベントハンドラ内ではボールを描画処理を記述しましょう。
さて、プログラムが実行され、タイマーオブジェクトのStart()メソッドが処理されると、一定時間ごとにTickイベントが発生します。そのたびにボールの位置が変わり、フォームの再描画が行われます。この結果、ボールがアニメーションするプログラムとなるのです。
なお、Tickイベントの発声間隔はタイマークラスのIntervalプロパティでミリ秒単位で設定することができます。この値を変えることによって速度を変化させることができますので、確認してみると良いでしょう。
tm.Interval = 100;//間隔をミリ秒で指定します
クラス | 説明 |
---|---|
System.Windows.Forms.Timerクラス | |
Timer()コンストラクタ | タイマーを作成する |
void Start()メソッド | タイマーをスタートする |
Intervalプロパティ | タイマーイベントの発生間隔を設定する |
System.Windows.Forms.Controlクラス | |
ClientSizeプロパティ | クライアント領域のサイズを設定・取得する |
System.Drawing.Sizeクラス | |
Widthプロパティ | 幅を設定・取得する |
Heightプロパティ | 高さを設定・取得する |
タイマーは一定時間ごとにイベントを発生する。
画像を使ったアニメーション
画像を使って別のアニメーションを作ることもできます。今度は横から少しずつスライドさせて表示させれる画像アニメーション作成しましょう。
//sample8.cs
using System;
using System.Windows.Forms;
using System.Drawing;
using System.Collections.Generic;
namespace lesson8
{
class sample8 : Form
{
private Image img;
private int i;
static void Main(string[] args)
{
Application.Run(new sample8());
}
public sample8()
{
this.Text = "lesson8"; this.Width = 400; this.Height = 300;
this.DoubleBuffered = true; //ダブルバッファを利用します
img = Image.FromFile("E:\\099_Technology\\C#\\csharp\\csharp_train\\lesson2\\google.JPG");
i = 0;
Timer tm = new Timer();//タイマーオブジェクトを作成します
//tm.Interval = 100;
tm.Start();//タイマーを開始します
tm.Tick += new EventHandler(tm_Tick);//イベントハンドラを登録します
this.Paint += new PaintEventHandler(fm_Paint);
}
public void tm_Tick(Object sender, EventArgs e)
{
if (i > img.Width + 200)
{
i = 0; //全部描画されたら描画幅を0に戻します
}
else
{
i = i + 10; //描画されるイメージの幅を大きくします
}
this.Invalidate(); //再描画させます
}
public void fm_Paint(Object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
//指定幅だけ描画します
g.DrawImage(img, new Rectangle(0, 0, i, img.Height), 0, 0, i, img.Height, GraphicsUnit.Pixel);
}
}
}
今度は画像中の指定された矩形範囲を描画しています。この矩形範囲をタイマーイベントが発生するたびに大きくすることで、少しずつ画像が大きくなるように画像を表示しているのです。
なお、このようなアニメーションをそのまま処理すると、描画の際にフォームの背景色が塗りなおされるため、画面にちらつき生じます。このようなとき、描画されるコントロールにダブルバッファ(DoubleBuffered)を使用するように指定します。この設定を行うとちらつきが少なくなります。
クラス | 説明 |
---|---|
System.Drawing.Graphicsクラス | |
DrawImage(Image i, Rectangle r, int x, int y, int w, int y, GraphicsUnit u)メソッド | 指定位置に指定幅・高さで指定矩形範囲の画像を描画する |
System.Windows.Forms.Formクラス | |
DoubleBuffered プロパティ | ダブルバッファを設定する |
デジタル時計を作成する
最後に、タイマーとラベルを使ってデジタル時計を作成してみましょう。ラベルを使って1秒ごとに時刻を変更しますので、Intervalは1000設定します。
//sample9.cs
using System;
using System.Windows.Forms;
using System.Drawing;
using System.Collections.Generic;
namespace lesson8
{
class sample9 : Form
{
private Label lb;
static void Main(string[] args)
{
Application.Run(new sample9());
}
public sample9()
{
this.Text = "lesson8 Clock"; this.Width = 200; this.Height = 100;
Timer tm = new Timer();
tm.Interval = 1000;
tm.Start();
lb = new Label();
lb.Font = new Font("Courier", 20, FontStyle.Regular);
lb.Dock = DockStyle.Fill;
lb.Parent = this;
tm.Tick += new EventHandler(tm_Tick);
}
public void tm_Tick(Object sender, EventArgs e)
{
DateTime dt = DateTime.Now;
lb.Text = dt.ToLongTimeString();
}
}
}
DateTime構造体のNowプロパティによって、現在の時刻を取得できます。このToLongTimeString()メソッドによって「時:分:秒」の形式にし、ラベルのテキストとして設定します。1秒ごとに表示が変更されるので、デジタル時計として表示されることになります。
なお、DateTime構造体では、次の表のようなさまざまなプロパティが利用できるようになっています。NowとTodayは静的な(Static)プロパティです。なお、この構造体には日付どうしの計算を行うメソッドも用意されています。
プロパティ | 説明 |
---|---|
(static)Now | 現在の時刻 |
(static)Today | 現在の日付 |
Year | 年を設定・取得する |
Month | 月を設定・取得する |
Day | 日を設定・取得する |
Hour | 時を設定・取得する |
Minute | 分を設定・取得する |
Second | 秒を設定・取得する |
クラス | 説明 |
---|---|
System.DateTime構造体 | |
Nowプロパティ | 現在の時刻を取得する |
string ToLongTimeString()メソッド | 時刻を長い書式で取得する |
コメント