使用计时器传递给线程的同步对象

时间:2013-03-22 23:57:36

标签: c# multithreading winforms timer

我之前制作了一个简单的球和桨程序,所有这些都以一种形式运行。现在我试图让球在一个单独的线程上运行,但是在概念上并不完全理解如何让球运行一个单独的线程,同时保持我的程序的其余部分相同。

最初计时器会使球移动,所以我想我可以将该移动线插入我的ballUpdate类。但现在我的问题是,是否有办法使线程工作我的当前计时器实现。

这就是我的form1看起来像

public partial class Form1 : Form
    {
        Graphics paper;
        Paddle paddle = new Paddle();
        Ball ball = new Ball();
        Thread myThread;
        BallUpdate ballUpdate = new BallUpdate();

        public Form1()
        {
            InitializeComponent();
            myThread = new Thread(() => ballUpdate.ballMotion(ball));
            myThread.Start();
        }

        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            paper = e.Graphics;
            paddle.drawPaddle(paper);
            ball.drawBall(paper);

        }
        private void timer1_Tick(object sender, EventArgs e)
        {
            //ball.moveBall();
            ball.collide();
            ball.hitPaddle(paddle.PaddleRec);
            this.Invalidate();
        }

我认为这可能会有所改变,但球根本不动。

class BallUpdate
{
    public BallUpdate(){}

    public void ballMotion(Ball x)
    {
        while(true)
        {
            x.moveBall();
            Thread.Sleep(30);
        }   
    }
}

2 个答案:

答案 0 :(得分:1)

您需要初始化ballUpdate并启动myThread。只有球的逻辑应该在一个单独的线程上。

public partial class Form1 : Form
    {
        Graphics paper;
        Paddle paddle = new Paddle();
        Ball ball = new Ball();
        Thread myThread;
        BallUpdate ballUpdate = new BallUpdate();

        public Form1()
        {
            InitializeComponent();
            myThread = new Thread(() => ballUpdate.ballMotion(ball));
            myThread.Start();
        }

        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            paper = e.Graphics;
            paddle.drawPaddle(paper);
            ball.drawBall(paper);

        }
        private void timer1_Tick(object sender, EventArgs e)
        {
            //ball.moveBall();
            ball.collide();
            ball.hitPaddle(paddle.PaddleRec);
            this.Invalidate();
        }

在BallUpdate中将if(true)更改为while(true)以防止线程退出。加入延迟使你的球不会飞行。

class BallUpdate
{
    public BallUpdate(){}

    public void ballMotion(Ball x)
    {
        while(true)
        {
            x.moveBall();
            Thread.Sleep(10000);
        }   
    }
}

答案 1 :(得分:0)

我建议构建一个循环遍历以下内容的线程方法:

  1. 计算自上次计算以来的时间跨度(以毫秒为单位)
  2. 相应地移动所有对象
  3. 碰撞检查和解决
  4. 调用显示方法以渲染帧
  5. 返回第1步
  6. 请不要在每个框架中创建一个具有极差性能的新线程。另外,不要操作线程中的图形对象。