Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/283.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用WinForms绘制在面板中移动的球?_C#_Winforms - Fatal编程技术网

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));     
    }
}