再直し
またまた、いろいろとご指摘を受けたり
ちょっと根本的によくわかってなかったり
おっ、なるほどというようなことがあったので、直しました。
まず、OnPaint() 内で値をいじらないという部分で
ここ以外でもう1回 foreach をぐるぐる回すのが効率よくないとか思っていましたが、
それよりも OnPaint() 内で値をいじらない方がよさそうです。
あと、無駄な変数多すぎ。
でも、実は高田馬場の勉強会のときのものは、
もっとグチャグチャで、それを直したのが、2つ前のエントリのだったりします。
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; namespace WindowsFormsApplication1 { public partial class Form1 : Form { public Form1() { Text = "アプリ"; Size = new Size(240, 320); MinimizeBox = false; SuspendLayout(); AutoScaleDimensions = new SizeF(96, 96); AutoScaleMode = AutoScaleMode.Dpi; Menu = new MainMenu(); InitializeComponent(); ResumeLayout(false); } // x,y はボールの座標、xx,yy はボールをクリックしたときの座標 private int x = 0; private int y = 0; // list は画面表示のときに作成したボールをすべて描画するためのリスト private List<Point> list = new List<Point>(); // タイマーを作成 private void InitializeComponent() { var timer = new Timer(); timer.Interval = 50; timer.Tick += new EventHandler(timer_Trick); timer.Enabled = true; } void timer_Trick(object sender, EventArgs e) { // y 座標(縦)に4ずつ動く、下まで行ったら上から(全体の長さで割った余りにすると最初の位置に戻る) y += 4; y %= ClientSize.Height; // listに入ってるものすべてを移動 for (int i = 0; i < list.Count; i++) { var p = list[i]; // listの中身i番目の(X,Y)のXを3つ進めて p.X += 3; // 端っこまで行ったら元の位置に戻す(全体の長さで割った余りにすると最初の位置に戻る) p.X %= ClientSize.Width; //listの中身i番目に戻す list[i] = p; } Invalidate(); } // マウスをクリックした場所がボールの辺りだったらリスト list に座標を追加(x=0のまま) protected override void OnMouseDown(MouseEventArgs e) { base.OnMouseDown(e); if (x <= e.X && e.X <= x + 16 && y <= e.Y && e.Y <= y + 16) { list.Add(new Point(x, y)); } } // 描画するとこ protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); // listに入ってるものすべてを描画 using (var brush = new SolidBrush(Color.Purple)) { foreach (var p in list) { e.Graphics.FillEllipse(brush, p.X, p.Y, 16, 16); } } // 最初から縦に動いているものを描画 using (var brush = new SolidBrush(Color.Red)) { e.Graphics.FillEllipse(brush, x, y, 16, 16); } } } }