同步对象通过计时器传递给线程

本文关键字:线程 计时器 对象 同步 | 更新日期: 2023-09-27 18:05:18

我以前做了一个简单的球和桨程序,它们都以一种形式运行。现在我正试图让球在一个单独的线程上运行,但是从概念上不太理解如何让球在一个单独的线程上运行,同时保持程序的其余部分不变。

最初计时器会使球移动,所以我认为我可以将移动行插入到我的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);
        }   
    }
}

同步对象通过计时器传递给线程

您需要初始化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. 计算自上次计算以来的时间间隔(以毫秒为单位)
  2. 相应移动所有对象
  3. 碰撞检查和解决
  4. 调用显示方法来呈现帧
  5. 返回步骤1

请不要在每一帧中创建一个新的线程,这会导致糟糕的性能。另外,不要在线程中操作图形对象。