C#如何沿矩形路径移动圆

时间:2016-02-29 03:00:51

标签: c# winforms input path

我需要按一个按钮的命令沿矩形路径移动一个点。我希望它从矩形路径的右上角开始,但我不知道如何让它一直绕着路径前进并停在原点。屏幕以用户在输入框中提供的速度刷新。提前谢谢!

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Timers;
namespace Assignment_2
{

    public partial class Form1 : Form
    {
        private const int formwidth = 1280;
        private const int formheight = 720;
        private const int ball_a_radius = 10;
        private const int horizontaladjustment = 8;
        private const double ball_a_distance_moved_per_refresh = 1.6;
        private double ball_a_real_coord_x = 515;
        private double ball_a_real_coord_y = 40;
        private int ball_a_int_coord_x;
        private int ball_a_int_coord_y;

        private const double graphicrefreshrate = 30.0;

        private static System.Timers.Timer graphic_area_refresh_clock = new System.Timers.Timer();

        private static System.Timers.Timer ball_a_control_clock = new System.Timers.Timer();
        private bool ball_a_clock_active = false;

        public double speed = 0;

        public Form1()
        {

            InitializeComponent();
            ball_a_int_coord_x = (int)(ball_a_real_coord_x);
            ball_a_int_coord_y = (int)(ball_a_real_coord_y);
            System.Console.WriteLine("Initial coordinates: ball_a_int_coord_x = {0}. ball_a_int_coord_y = {1}.",
                               ball_a_int_coord_x, ball_a_int_coord_y);

            graphic_area_refresh_clock.Enabled = false;  
            graphic_area_refresh_clock.Elapsed += new ElapsedEventHandler(Updatedisplay);


            ball_a_control_clock.Enabled = false; 
            ball_a_control_clock.Elapsed += new ElapsedEventHandler(Updateballa);

            Startgraphicclock(graphicrefreshrate); 
            Startballaclock(speed);    
        }
        public class NumericTextBox : TextBox
        {
        }

            private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void panel2_Paint(object sender, PaintEventArgs e)
        {

        }

        private void panel2_Paint_1(object sender, PaintEventArgs e)
        {
            //Create pen
            Pen blackPen = new Pen(Color.Black, 1);

            //Create rectangle
            Rectangle rect = new Rectangle(125, 50, 400, 400);

            //Draw rectangle to screen
            e.Graphics.DrawRectangle(blackPen, rect);

            Graphics graph = e.Graphics;
            graph.FillEllipse(Brushes.Green, ball_a_int_coord_x, ball_a_int_coord_y, 2 * ball_a_radius, 2 * ball_a_radius);
            base.OnPaint(e);
        }

        public void button7_Click(object sender, EventArgs e)
        {
           speed = Convert.ToInt32(textBox3.Text);

        }

        private void textBox3_TextChanged(object sender, EventArgs e)
        {

        }

        protected void Startgraphicclock(double refreshrate)
        {
            double elapsedtimebetweentics;
            if (refreshrate < 1.0) refreshrate = 1.0;  
            elapsedtimebetweentics = 1000.0 / refreshrate; 
            graphic_area_refresh_clock.Interval = (int)System.Math.Round(elapsedtimebetweentics);
            graphic_area_refresh_clock.Enabled = true;  
        }

        protected void Startballaclock(double updaterate)
        {
            double elapsedtimebetweenballmoves;
            if (updaterate < 1.0) updaterate = 1.0; 
            elapsedtimebetweenballmoves = 1000.0 / updaterate; 
            ball_a_control_clock.Interval = (int)System.Math.Round(elapsedtimebetweenballmoves);
            ball_a_control_clock.Enabled = true;   
            ball_a_clock_active = true;
        }

        protected void Updatedisplay(System.Object sender, ElapsedEventArgs evt)
        {
            Invalidate();  
            if (!(ball_a_clock_active))
            {
                graphic_area_refresh_clock.Enabled = false;
                System.Console.WriteLine("The graphical area is no longer refreshing.  You may close the window.");
            }
        }

        protected void Updateballa(System.Object sender, ElapsedEventArgs evt)
        {
            ball_a_real_coord_x = ball_a_real_coord_x - 5;

            ball_a_real_coord_y = ball_a_real_coord_y - 5;
            ball_a_int_coord_x = (int)System.Math.Round(ball_a_real_coord_x);
            ball_a_int_coord_y = (int)System.Math.Round(ball_a_real_coord_y);


            if (ball_a_int_coord_x >= formwidth || ball_a_int_coord_y + 2 * ball_a_radius <= 0 || ball_a_int_coord_y >= formheight)
            {
                ball_a_clock_active = false;
                ball_a_control_clock.Enabled = false;
                System.Console.WriteLine("The clock controlling ball a has stopped.");
            }

        }

        private void button4_Click(object sender, EventArgs e)
        {
            ball_a_control_clock.Enabled = true;

        }
    }

}

1 个答案:

答案 0 :(得分:0)

我有一种更直接的方式来移动圆圈。您的代码太长,我无法阅读。看看你是否喜欢这个!

如果我是你,我会使用PictureBox。我首先创建一个圆形图像,然后将该图像放在PictureBox中。然后你可以使用计时器来改变PictureBox的位置。

您应该将计时器的Interval设置为33 ms,大约为30 fps。这是你对计时器进行编程的方法:

保留一个计数器以指示圆圈移动了多少像素。假设您希望它在100px x 50px矩形路径中移动。

For every 33ms,
    If the counter is less than 100, 
        increase the X position and the counter by 1, 
    if the counter is between 101 and 150, 
        increase the Y position and the counter by 1, 
    if the counter is between 151 and 250, 
        decrease the X position by 1 and increment the counter
    if the counter is between 251 and 300,
        decrease the Y position by 1 and increment the counter
    if the counter is greater than 300,
        stop the timer

我真的不喜欢使用OnPaint事件在屏幕上绘制内容。我的意思是,你移动一个球!人们认为这是改变球的x和y位置,而不是在前一个位置删除球并将其拉到新位置。改变图片框的位置只会让LOTS更有意义,你不这么认为吗?