東京工芸大学 工学部  電子機械学科 2年 後期 

応用プログラミング 第11回
 2017.12.5
藤木 文彦

http://fujiki.tv/t-kougei/ouyouprog/
fujiki.kougei@gmail.com
 ■ 1   ■ 2   ■ 3   ■ 4  ■5   ■6         ■ 9  ■10   ■11  ■12   ■ 3   ■ 4      

インデックスに戻る


先週の後半問題を行っていない人は、まず、以下の、「10回目分問題」から始めてください。
途中の人は、続きから始めてください。
終わってる人は、「11回目分問題」から始めてください。

 10回目分問題 1.マウス位置の取得・表示


 プロジェクト名: Project1001
 csファイル名:  MouseMove1


 こんなのを作ってください。




  public Form1()
{
InitializeComponent();
pictureBox1.MouseDown += new MouseEventHandler(fm_MouseDown);
pictureBox1.MouseMove += new MouseEventHandler(fm_MouseMove);
}
public void fm_MouseMove(Object sender, MouseEventArgs e)
{
Point p1 = new Point();
p1.X = e.X;
p1.Y = e.Y;
this.textBox1.Text = p1.X.ToString();
this.textBox2.Text = p1.Y.ToString();

}
public void fm_MouseDown(Object sender, MouseEventArgs e)
{
Point p2 = new Point();
p2.X = e.X;
p2.Y = e.Y;
this.textBox3.Text = p2.X.ToString();
this.textBox4.Text = p2.Y.ToString();

}


【提出物1】 上記のような画像ファイルを表示した画面のスクリーンショットをプリントして提出物1としなさい。

(表示される数値は、こことは違うものになっているように。)

 10回目分問題 2.マウスの軌跡の描画と、クリックした場所の表示


 プロジェクト名: Project1002
 csファイル名:  MouseMove2


 次は、少し改造して、次のようなものを作ってください。
 マウスが動いた後に、ドットを描いていき、クリックしたところに大きな丸を付けます。



 ヒントは、以下を見てください。(スペース部分が ・・・ になっていますが、これは、何も入れない空白を見えるように書いただけです。)





【提出物2】 上記のような画像ファイルを表示した画面のスクリーンショットをプリントして提出物2としなさい。

(表示される数値は、こことは違うものになっているように。)


 10回目分問題 3.タイマーを用いた、動くグラフィックス


 赤いボールが pictureBox 内を飛び回るプログラムを作成します。
 タイマーを用いて、黙っていても、少しずつ動き、画像枠の端まで来たら跳ね返ります。


 プロジェクト名: Project1003
 csファイル名:  MouseMove3

 タイマーの時間設定は、

 timer1.Interval=200;

としてありますが、これは、 「200ミリ秒に1回動かす」ということです。この値を小さくすると早く動きます。

 その他、今までには無かった 「Ball 型クラスの設定」など、いくつか新しい事項がありますが、以下のプログラムを参照して作成してください。




【明確なエラーが無いのに動かないときのチェック事項】
 MouseMove と MouseDown を間違えていないか。
 変数名の、 x1,y1,p1,p2 などのチェック
 ボタンを押して起動されるものの場合、自分で書いたのではなく、ボタンを押して書いたものでないとならない。
 自分で書いたのなら、ボタンを押してできたところにコピー。
 (現状では、 public でも private でも動く。あまりよくはないが。)
 自分で書いたものなら、 Form1 の検索イベントに、 += で追加されているか。


【注意】
 以下のプログラム入力時に、あらかじめ、
 ボタンをクリックして、その時に表示された button1_Click() の中にプログラムを組み込まないと、正常に動作しません。
 自分で、全部書いたのではだめです。
 これは、button1_Click というイベントが、毎回のループで探されるイベントに、登録されないからです。
 ボタンを押してプログラムを書いた時には自動的に登録されています。
 自分で作った時には、自分で登録しないといけません。他にも、自分で作ったものに関しては、

 += で、イベントハンドラに追加して、初めて意味があるものとなったはずです。

 namespace Project1003
{


public partial class Form1 : Form
{
private Ball a1;
private int x1=10, y1=10;
public Form1()
{
InitializeComponent();
}

public void button1_Click(object sender, EventArgs e)
{
a1 = new Ball();
Point p = new Point(0, 0);
Color c = Color.Red;
Timer timer1 = new Timer();
timer1.Interval = 200;
timer1.Start();
pictureBox1.Paint += new PaintEventHandler(fm_Paint);
timer1.Tick += new EventHandler(timer1_Tick);
}
public void fm_Paint(Object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
Point p = a1.Point;
Color c = Color.Red;
SolidBrush brush1 = new SolidBrush(c);
int x1 = p.X;
int y1 = p.Y;
g.FillEllipse(brush1, x1, y1, 10, 10);
}
public void timer1_Tick(Object sender,EventArgs e)
{Point p=a1.Point;
if(p.X<0||p.X>pictureBox1.ClientSize.Width-10) x1=-x1;
if(p.Y<0||p.Y>pictureBox1.ClientSize.Height-10) y1=-y1;
p.X=p.X+x1;
p.Y=p.Y+y1;
a1.Point=p;
pictureBox1.Invalidate();

}
private void pictureBox1_Click(object sender, EventArgs e)
{

}

private void button2_Click(object sender, EventArgs e)
{
Application.Exit();
}
}
//  以下の部分を付け加えるのを忘れないように。付け加える場所に注意!
public partial class Ball
{
public Color Color;
public Point Point;
}



}


【提出物3】 上記のような画像ファイルを表示した画面のスクリーンショットをプリントして提出物3としなさい。




以下本日分(11回目分)です。

 1.マウス位置への直線の描画


 プロジェクト名: Project1101
 csファイル名:  DrawLine1


 まずこんな画面を作ってください。






 次に、ピクチャーボックスをクリックします。
 右のプロパティボックスの上の、下図のマークの位置をクリックします。



 これは、マウスが移動するなどの「イベント」が発生したときに、どういう動作をするか記述する状態にする、という意味です。

 先週は、マウスの移動などは、直接プログラム中に自分で書きましたがこのようにすると、マウスの移動の際の処理も、半自動的に書くことができます。

 下図のような表示になりますので、「MouseMove」を選び、次のように項目を設定します。




 この項目をダブルクリックすると、 cs プログラム編集画面に移動します。
 そこで、次のようなプログラムを入力してください。


 なお、今回は、ペンの色を、RGBの配合で表示する方法を入れました。

 Color.FromArgb( R, G, B)

 の部分です。 R,G,B は、 Red, Green, Blue の色の3原色で、
 0≦R,G,B≦255
 の値で指定します。値が大きいほどその色の発色が強くなるので、

 真っ赤なら R=255, G=0, B=0
 真っ白なら R=255, G=255, B=255
 黄色なら    R=255, G=255, B=0

などです。もちろん、途中の値を微妙に変えると色加減も変わります。
(プログラム中で色を入力する方法はこの後示します。)


 実行してマウスを動かすと次のようになります。





 【演習問題1】 

 授業の説明に従って、"Project1101"を作成し、画面プリントと、メールを提出しなさい。
cs ファイルの名前は、drawLine1.cs になっている場合は、それを添付。

【提出物1】 上記のような画像ファイルを表示した画面のスクリーンショットをプリントして提出物1としなさい。

  public Form1()
{
InitializeComponent();
}
//全体で使う変数の宣言
Point p0 = new Point(100, 100);

private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
Graphics g1 = pictureBox1.CreateGraphics();

Pen myPen = new Pen(Color.FromArgb(100, 200, 50));

p1.X = e.X;
p1.Y = e.Y;
this.textBox1.Text = p1.X.ToString();
this.textBox2.Text = p1.Y.ToString();
g1.DrawLine(myPen, p0, p1);
}

 2.前に描いた線を消して新しい線を描く


 プロジェクト名: Project1102
 csファイル名:  DrawLine2


 前に作ったプロジェクトの画面をコピーしたい場合は、次の項目を参考にしてください。
ただし、コピー後の設定が難しいので、コピーせず最初から作ることを推奨します。

 新しいプロジェクトへの以前のプロジェクトのコピー方法




 Project1101では、マウスが動いた場所に全部線が描かれてしまいましたので、今のマウスの位置がわかりにくいですね。
 そこで、マウスの位置だけに線を引くようにします。
 そのためには、
 
「直前に描いた線を、背景色で塗りつぶしてから新しい線を描く」という方法をとります。


 ポイントを示す変数名

p1 などが、
pold
pnew

などに変わっているので注意してください。
また、この変数の宣言場所にも注意してください。






  //全体で使う変数の宣言
Point p0 = new Point(100, 100);
Point pold = new Point();
Point pnew = new Point();


private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
Graphics g1 = pictureBox1.CreateGraphics();

Pen erasePen = new Pen(pictureBox1.BackColor);
Pen myPen = new Pen(Color.FromArgb(100, 200, 50));

pnew.X = e.X;
pnew.Y = e.Y;
this.textBox1.Text = pnew.X.ToString();
this.textBox2.Text = pnew.Y.ToString();
g1.DrawLine(erasePen, p0, pold);
g1.DrawLine(myPen, p0, pnew);
pold= pnew;
}

 【演習問題2】 

 授業の説明に従って、"Project1102"を作成し、画面プリントと、メールを提出しなさい。

【提出物2】 上記のような画像ファイルを表示した画面のスクリーンショットをプリントして提出物2としなさい。
cs ファイルの名前は、drawLine2.cs になっている場合は、それを添付。



 3.色を指定する方法


 プロジェクト名: Project1103
 csファイル名:  Color1

 次に、色指定を、一覧から行うモードと、直接数値で行うモードを準備します。
 次のように各種部品を用意してください。

 一番下は、 colorDialog というコンポーネントです。ツールボックスから選択して、画面上の適当な場所に置きます。

デザイン画面はこんな感じ。




実行するとこんな感じになります。まだ途中段階です。(数値の範囲 0〜255 以外の範囲をいれるとエラー終了してしまいますから注意が必要です。)




プログラムの主要部分は次のような感じです。(まだ途中段階ですが、一度に全部作るのは大変なので、色選択画面が出るのと、数値入力で色を指定するところまで作ります。)





  public partial class Form1 : Form
{
Pen myPen = new Pen(Color.FromArgb(100, 200, 50));


public Form1()
{
InitializeComponent();
textBox3.Text = "100";
textBox4.Text = "100";
textBox5.Text = "100";
}

private void button1_Click(object sender, EventArgs e)
{
DialogResult ret;
ret = colorDialog1.ShowDialog();
if (ret == DialogResult.OK)
{
myPen.Color = this.colorDialog1.Color;
this.pictureBox1.BackColor = myPen.Color;

textBox3.Text = colorDialog1.Color.R.ToString();
textBox4.Text = colorDialog1.Color.G.ToString();
textBox5.Text = colorDialog1.Color.B.ToString();
}
}
private void button2_Click(object sender, EventArgs e)
{
myPen.Color = Color.FromArgb(
int.Parse(textBox3.Text),
int.Parse(textBox4.Text),
int.Parse(textBox5.Text));
this.pictureBox1.BackColor = myPen.Color;

}


 数値で入力して「色選択(RGB)」を押すことでも色が選択できます。(数値範囲 0〜255 以外をいれるとエラーになります。このエラーを回避する方法については面倒になるので、今回は行いません。)


 【演習問題3】 

 授業の説明に従って、"Project1103"を作成し、画面プリントと、メールを提出しなさい。

【提出物3】 上記のような画像ファイルを表示した画面のスクリーンショットをプリントして提出物3としなさい。
(白黒で良い)cs ファイルの名前は、Color1.cs になっている場合は、それを添付。



 4.いろいろな色の●を描く


 プロジェクト名: Project1103 の続きで良い。
 csファイル名:  Color2

 色を指定してマウスをクリックするとその位置に●が描かれるようにプログラムを付け加えます。




下のプログラムは、 pictureBox2 を選択した状態で、 イベントマーク(雷印) をクリックし、MouseDown を選んでダブルクリックされる、下記の部分に作成します。




  private void pictureBox2_MouseDown(object sender, MouseEventArgs e)
{
Graphics gp = pictureBox2.CreateGraphics();
Brush brushRed = new SolidBrush(myPen.Color);
int r1 = 30;
Point p = new Point(100, 100);
p.X = e.X;
p.Y = e.Y;
textBox1.Text = p.X.ToString();
textBox2.Text = p.Y.ToString();
gp.FillEllipse(brushRed,p.X,p.Y,r1,r1);
}

 【演習問題4】 

 授業の説明に従って、"Project1103"の続きを作成し、画面プリントと、メールを提出しなさい。

注意: メールのタイトルは、Project1104  とするが、添付するCSファイルは、前の続きなので、新しい、 Project1103.cs を添付する。

【提出物4】 上記のような画像ファイルを表示した画面のスクリーンショットをプリントして提出物4としなさい。
(白黒で良い)cs ファイルの名前は、Color2.cs になっている場合は、それを添付。



 4b.応用課題



 このプログラムで描かれる●印は、マウスのクリックした位置とずれているようにみえます。
 これは、マウスで指定した位置が、● を含む枠の ■ の 左上の位置だからです。

 マウスを押した位置が、円の中心になるように、プログラムを改良しなさい。

 【応用演習問題4b】 

メールと画面プリントを提出しなさい。

【提出物4b】 上記のような画像ファイルを表示した画面のスクリーンショットをプリントして提出物4bとしなさい。
(白黒で良い) 

注意: メールのタイトルは、Project1104b  とするが、添付するCSファイルは、前の続きなので、新しい、 Project1103.cs を添付する。



 5.乱数発生

Project1105
Game2

 こういうのができるようにします。
 ボタンを押すごとに発生させた乱数によって、指定位置に印をつけていきます。


 これも、最初の宣言の位置に注意してください。
 なお、 Graphics の宣言の位置が、 pictureBox1 の中にありません。
 しかし、 pictureBox1 がないと、エラーが起きますので、プログラム時に、pictureBox1 をダブルクリックして、中身が空でもいいので、プログラムに挿入されるようにしておいてください。




下記では、プロジェクト番号が違っているが、プログラムはそのままで動作するはずである。なお、プログラム中の ・・・ は、
空白の部分が表示されたものであるので、ここは、何も入力しない。

  public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
Random rnd1=new Random();
Point p1 = new Point();
Pen myPen = new Pen(Color.FromArgb(200, 50, 0),3);


private void button1_Click(object sender, EventArgs e)
{
p1.X=rnd1.Next(100);
p1.Y = rnd1.Next(100);
this.textBox1.Text = p1.X.ToString();
this.textBox2.Text = p1.Y.ToString();
Graphics g = pictureBox1.CreateGraphics();
g.DrawEllipse(myPen, p1.X, p1.Y, 5, 5);
}

private void pictureBox1_Click(object sender, EventArgs e)
{

}


}


 【演習問題5】 

 授業の説明に従って、"Project1105"を作成し、画面プリントと、メールを提出しなさい。
cs ファイルの名前は、Game2.cs になっている場合は、それを添付。

【提出物5】 上記のような画像ファイルを表示した画面のスクリーンショットをプリントして提出物5としなさい。



 6.座標位置の pictureBox 内への文字表示

 プロジェクトは新規に作成せず、前のプロジェクトに続けます。

 下のように、pictureBox 内に文字を表示します。




 【演習問題6】 

 授業の説明に従って、"Project1105"の続きを作成し、画面プリントと、メールを提出しなさい。
注意:メールのタイトルは Project1106 とするが、添付するCS ファイルは、 Project1105.cs とする。

cs ファイルの名前は、Game2.cs になっている場合は、それを添付。

【提出物6】 上記のような画像ファイルを表示した画面のスクリーンショットをプリントして提出物6としなさい。

  public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
Random rnd1=new Random();
Point p1 = new Point();
Pen myPen = new Pen(Color.FromArgb(200, 50, 0),3);
Font font1 = new Font("MS UI Gothic", 10);
Brush brush1 = new SolidBrush(Color.Black);

private void button1_Click(object sender, EventArgs e)
{
p1.X=rnd1.Next(100);
p1.Y = rnd1.Next(100);
this.textBox1.Text = p1.X.ToString();
this.textBox2.Text = p1.Y.ToString();
Graphics g = pictureBox1.CreateGraphics();
g.DrawEllipse(myPen, p1.X, p1.Y, 5, 5);
g.DrawString("座標 "+p1.X.ToString()+" "+p1.Y.ToString(), font1, brush1, p1.X+10, p1.Y+10);
}

private void pictureBox1_Click(object sender, EventArgs e)
{

}


}