テキスト篇:p.291「clock01.cs」から
ゲーム開発演習:線の描画(続き)、矩形や円の描画、文字の描画、画面遷移 など
p.292(Consoleクラスの静的プロパティと静的メソッド)
・すでに学習した静的メソッドWrite、WriteLine、ReadLineに加えて便利な静的メソッド、静的プロパティが多数提供されており、 コンソールを疑似的な実行ウインドウにすることができる ・bool CursorVisible静的プロパティ:falseを設定するとカーソルが見えなくなる。チラつき防止に便利。 ・string Title静的プロパティ:コンソール名を設定できる。 ・void SetWindowsSize(int,int)静的メソッド:ウィンドウの幅と高さを文字数で指定できる ・ConsoleColor BackgroundColor静的プロパティ:ConsoleColor列挙型で背景色を指定できる。例:ConsoleColor.Yellow ・ConsoleColor ForegroundColor静的プロパティ:ConsoleColor列挙型で文字色を指定できる。 ・void Clear()静的メソッド:再描画して設定を反映する(※実行すると文字色・背景色の変更が有効になる) ・void SetCursolPosition(int,int)静的メソッド:カーソルの位置を変える。移動先は文字数。 ・bool KeyAvailable静的プロパティ:キーが押されているとtrueになる
p.291 clock01.cs
//p.291 clock01.cs
using System;
class clock01 {
public static void Main() {
int oldsecond = 0; //秒が変わった時に書き換えたいので現在の秒を残しておく変数
Console.CursorVisible = false; //カーソルを消す
Console.Title = "時計"; //コンソールのタイトルを指定
Console.SetWindowSize(12, 3); //表示ウィンドウの大きさを指定
Console.BackgroundColor = ConsoleColor.Yellow; //背景色を黄色に
Console.ForegroundColor = ConsoleColor.Black; //文字色を黒に
Console.Clear(); //背景色を反映
DateTime mt; //日付時刻構造体の生成
while (true) { //無限ループ
mt = DateTime.Now; //現在の日付時刻を得る
if (mt.Second == oldsecond) { //秒が変わっていない?
continue; //以下をスキップして繰り返しを続行
} else {
oldsecond = mt.Second; //秒が変わっているので更新
}
Console.SetCursorPosition(2, 1); //カーソル位置(表示開始位置)を変更
Console.Write("{0:00}:{1:00}:{2:00}", mt.Hour, mt.Minute, mt.Second); //時分秒を表示
if (Console.KeyAvailable) { //なにかキーが押されていたら
break; //ループを抜ける
}
}
}
}
アレンジ演習:p.291 clock01.cs
・ストップウォッチにしよう ・実行すると「00:00:00」を表示してカウントを開始するようにしたい ・現在時刻ではなく、時刻を表す1000万分の1秒刻みのカウンタを返すDateTime構造体ののTicksプロパティ(long型)を用いよう ・起動時のTicksを確保しておいて、最新のTicksとの差を用いる ・この差を1000万倍すると秒になるので、さらに3600で割ると時間、60で割って60で割ったあまりで分、60で割った余りで秒が得られる
作成例
//アレンジ演習:p.291 clock01.cs
using System;
class clock01 {
public static void Main() {
int oldsecond = 0; //秒が変わった時に書き換えたいので現在の秒を残しておく変数
Console.CursorVisible = false; //カーソルを消す
Console.Title = "時計"; //コンソールのタイトルを指定
Console.SetWindowSize(12, 3); //表示ウィンドウの大きさを指定
Console.BackgroundColor = ConsoleColor.Yellow; //背景色を黄色に
Console.ForegroundColor = ConsoleColor.Black; //文字色を黒に
Console.Clear(); //背景色を反映
DateTime st = DateTime.Now; //【追加】日付時刻構造体を生成し開始時の時刻を確保
DateTime mt; //日付時刻構造体の生成
while (true) { //無限ループ
mt = DateTime.Now; //現在の日付時刻を得る
int lap = (int)((mt.Ticks - st.Ticks) / 10000000L); //【追加】経過時間を得て秒単位にする
int Hour = lap / 3600; //【追加】時を得る
int Minute = lap / 60 % 60; //【追加】分を得る
int Second = lap % 60; //【追加】秒を得る
if (Second == oldsecond) { //【変更】秒が変わっていない?
continue; //以下をスキップして繰り返しを続行
} else {
oldsecond = Second; //【変更】秒が変わっているので更新
}
Console.SetCursorPosition(2, 1); //カーソル位置(表示開始位置)を変更
Console.Write("{0:00}:{1:00}:{2:00}", Hour, Minute, Second); //【変更】時分秒を表示
if (Console.KeyAvailable) { //なにかキーが押されていたら
break; //ループを抜ける
}
}
}
}
アレンジ演習:p.291 clock01.cs 続き
・ミリ秒までのストップウォッチにしよう ・実行すると「00:00:00.000」を表示してカウントを開始するようにしたい ・起動時のTicksとTicksとの差を1万倍するとミリ秒になるので、さらに3600000で割ると時間、60000で割って60で割った余りで分、 1000で割って60で割った余りで秒が、1000で割った余りでミリ秒が得られる
作成例
//アレンジ演習:p.291 clock01.cs
using System;
class clock01 {
public static void Main() {
int oldmsecond = 0; //【変更】ミリ秒が変わった時に書き換えたいので現在のミリ秒を残しておく変数
Console.CursorVisible = false; //カーソルを消す
Console.Title = "時計"; //コンソールのタイトルを指定
Console.SetWindowSize(16, 3); //【変更】表示ウィンドウの大きさを指定
Console.BackgroundColor = ConsoleColor.Yellow; //背景色を黄色に
Console.ForegroundColor = ConsoleColor.Black; //文字色を黒に
Console.Clear(); //背景色を反映
DateTime st = DateTime.Now; //日付時刻構造体を生成し開始時の時刻を確保
DateTime mt; //日付時刻構造体の生成
while (true) { //無限ループ
mt = DateTime.Now; //現在の日付時刻を得る
int lap = (int)((mt.Ticks - st.Ticks) / 10000L); //【変更】経過時間を得てミリ秒単位にする
int Hour = lap / 3600000; //【変更】時を得る
int Minute = lap / 60000 % 60; //【変更】分を得る
int Second = lap / 1000 % 60; //【変更】秒を得る
int MSecond = lap % 1000; //【追加】ミリ秒を得る
if (MSecond == oldmsecond) { //【変更】ミリ秒が変わっていない?
continue; //以下をスキップして繰り返しを続行
} else {
oldmsecond = MSecond; //【変更】ミリ秒が変わっているので更新
}
Console.SetCursorPosition(2, 1); //カーソル位置(表示開始位置)を変更
Console.Write("{0:00}:{1:00}:{2:00}.{3:000}", Hour, Minute, Second, MSecond); //【変更】時分秒ミリ秒を表示
if (Console.KeyAvailable) { //なにかキーが押されていたら
break; //ループを抜ける
}
}
}
}
p.294 練習問題 ヒント
・プロパティによる制限なので、クラス内でのエラー表示は不要(するならmain側で) ・偶数は正の整数なので、構造体のデータメンバの型をuint型にすると良い ・偶数しか保持できないようにするには、データメンバへの直接アクセスを禁止するためprivateにする ・このデータメンバを扱うプロパティを定義し、setにおいてvalueの値が偶数かチェックしてから代入する ・getは通常形式で良い
作成例
//p.294 練習問題
using System;
struct MyStruct { //構造体の定義
private uint x; //偶数しか保持できないようにするために直接利用を禁止
public uint X { //プロパティ
get { return x; }
set { if (value % 2 == 0) x = value; } //偶数なら格納できる
}
}
class ex11 {
public static void Main() {
MyStruct ms = new MyStruct(); //構造体変数の宣言と構造体オブジェクトの生成(new不要)
Console.Write("正の数:"); uint n = uint.Parse(Console.ReadLine());
ms.X = n; //プロパティ経由で代入
Console.WriteLine((n == ms.X) ? "格納できました" : "格納できません"); //プロパティ経由で得て比較
}
}