C# 如何使用WinForms绘制在面板中移动的球?
我有一个代码,当我在面板中单击鼠标时,它会画一个球。现在,我想要的是,当我点击面板时,不仅会出现一个球,而且会以一定的速度移动。现在我真的不在乎球是否越过了面板的边界。我该怎么做C# 如何使用WinForms绘制在面板中移动的球?,c#,winforms,C#,Winforms,我有一个代码,当我在面板中单击鼠标时,它会画一个球。现在,我想要的是,当我点击面板时,不仅会出现一个球,而且会以一定的速度移动。现在我真的不在乎球是否越过了面板的边界。我该怎么做 public partial class Form1 : Form { ArrayList dotPts = new ArrayList(); public Form1() { InitializeComponent(); } private void mai
public partial class Form1 : Form
{
ArrayList dotPts = new ArrayList();
public Form1()
{
InitializeComponent();
}
private void mainPanel_Paint(object sender, PaintEventArgs e)
{
foreach (Point p in dotPts)
{
e.Graphics.FillEllipse(Brushes.Black, p.X, p.Y, 20, 20);
}
}
private void mainPanel_MouseUp(object sender, MouseEventArgs e)
{
Graphics g = Graphics.FromHwnd(this.Handle);
dotPts.Add(new Point(e.X - 10, e.Y - 10));
mainPanel.Invalidate();
}
}
InitializeComponent():
要使某个物体随时间平滑移动,一般的解决方案是使计时器对象在每次滴答声中通过速度(或其一部分)改变球的位置:
ball.x += xVelocity;
ball.y += yVelocity;
我有一个例子(快速和肮脏的)代码,我试图给你一个想法。。(在LINQPAD中运行)
你需要一个计时器。在Tick事件处理程序中,计算对象的新位置并调用面板的Invalidate()方法,以便重新绘制。如果闪烁变得太明显,可以使用PictureBox代替面板
也要处理ArrayList。这需要成为一个
列表,其中Ball类存储位置和速度向量。再加上你将来要添加的其他属性,如颜色或半径。以与什么相同的速度移动?我猜你是指恒定速度?您可以使用计时器
为球的运动“设置动画”。您还应该指定球的移动方式(从左到右、随机、反弹等)。现在可以使用常量。在winforms中执行时,比约纳斯建议的方法是平滑的。我自己喜欢使用wpf和可以使用的动画。从线程池线程调用Invalidate()是不合法的。tmr.appead
和gmlp.appead
都是在线程池中调用的。
ball.x += xVelocity;
ball.y += yVelocity;
void Main()
{
Application.Run(new Form1());
}
public class Form1 :Form
{
float time3 =0, time =0,time2=1000000,height=20,width=20;int a = -1;
PointF Location = new PointF(0,0);
PointF Velocity = new PointF(50,50);
DateTime dt;
float x=0;
System.Timers.Timer tmr = new System.Timers.Timer();
System.Timers.Timer gmlp = new System.Timers.Timer();
public Form1()
{
this.Size = new Size(700,700);
Label lb = new Label();
tmr.Interval =20;
tmr.Elapsed += (s,e) => {
//if(Location.X >= 500) Velocity.X *= a;
//if(time3 >= 1000) time=0; else
time3 +=20;// (DateTime.Now.Ticks - dt.Ticks)/10000;
Location.X = Velocity.X * (time3/1000);
Location.Y = Velocity.Y * (time3/1000);
this.Invalidate();
if(time >= time2) {tmr.Stop(); tmr.Enabled = false; gmlp.Stop(); gmlp.Enabled = false;}
};
this.DoubleBuffered =true;
gmlp.Interval = 1000;
gmlp.Elapsed += (s,e) => {
//dt = dt.AddSeconds(1);
lb.Text =
"time: " + time +
"\ntime2: " + time2 +
"\ntime3: " +time3 +
"\nlocx: " +Location.X +
"\ntimespan: " + (DateTime.Now.Ticks - dt.Ticks)/10000 +
"\nx moved: " + (Location.X - x);
};
gmlp.Enabled = true;
gmlp.Start();
tmr.Enabled =true;
tmr.Start();
lb.Location = new Point(20,20);
lb.Size = new Size(80,200);
this.Controls.Add(lb);
dt = DateTime.Now;
}
protected override void OnPaint(PaintEventArgs pe)
{
base.OnPaint(pe);
pe.Graphics.FillEllipse(Brushes.Tomato, new Rectangle((int)Location.X,(int)Location.Y,(int)height,(int)width));
}
}