-1

我正在尝试制作一个简单的乒乓球游戏,但遇到了这个问题,如果按下“S”或“W”按钮,每个 timer1 滴答声(间隔设置为 1ms)应该移动 1 个像素的白色桨矩形,这个从理论上讲,我的 400px 高度图片框内的白色矩形应该在 0.4 - 0.8 秒内从 y = 0 移动到 y = 400,但显然它需要超过 4 秒。

我知道如果 cpu 已经很忙或处理速度问题,计时器滴答事件可能会被“跳过”,但我试图让蛇游戏比这 50 行代码更复杂,并且绘制蛇的速度实际上是准确的低时间间隔

为什么需要这么多?

 public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
        pictureBox1.BackColor = Color.Black;

        timer1.Interval = 1;
        timer1.Start();
    }


    private void timer1_Tick(object sender, EventArgs e)
    {
        PongGame.CheckIfMoving();
        PongGame.DrawIt(pictureBox1);
    }

    private void Form1_KeyDown(object sender, KeyEventArgs e)
    {
        if (e.KeyData == Keys.S)
        { PongGame.movesDown = true; }

        if (e.KeyData == Keys.W)
        { PongGame.movesUp = true; }
    }

    private void Form1_KeyUp(object sender, KeyEventArgs e)
    {
        if (e.KeyData == Keys.S)
        { PongGame.movesDown = false; }

        if (e.KeyData == Keys.W)
        { PongGame.movesUp = false; }
    }
}



public class PongGame
{
    public static Rectangle paddle1 = new Rectangle(14, 370, 20, 100);
    public Rectangle paddle2;
    public static bool movesUp;
    public static bool movesDown;
    public static Graphics Draw;

    public static void DrawIt(PictureBox pb1)
    {
        Draw = pb1.CreateGraphics();
        SolidBrush sb = new SolidBrush(Color.White);

        Draw.Clear(Color.Black);
        Draw.FillRectangle(sb, paddle1);
    }

    public static void CheckIfMoving()
    {
        if (movesUp == true)
        {
            paddle1.Y -= 1;
        }

        if (movesDown == true)
        {
            paddle1.Y += 1;
        }
    }
}

提前感谢您的答案(:

4

2 回答 2

0

计时器不保证它会在您指定的时间间隔内触发。事实上,它可以并且确实以比您指定的间隔更长的时间间隔触发。

通常,定时器的实际间隔将与底层系统和硬件有关。Windows 上的计时器触发频率不超过 20Hz 的情况并不少见。

如果您要制作基于计时器的游戏,请使用计时器为您的游戏提供脉冲,即有规律的心跳。当计时器触发时,使用自上次计时器事件以来的时间量来更新状态。您需要使用准确的时间度量。类Stopwatch应该足够了。

您也错误地使用了图片框。这是一个事件驱动的控件。您应该Paint在图片框事件的处理程序中绘制场景。

于 2014-03-17T19:16:51.873 回答
0

首先,在这种情况下,将 Timer 的时间间隔设置为 1 会产生不必要的开销。那是 1000 fps(好吧,如果您真的可以信任 Timer,那就是这样)。

在 DrawIt 中:

Draw = pb1.CreateGraphics();
SolidBrush sb = new SolidBrush(Color.White);

由于 DrawIt 由 Timer 的刻度调用,因此每秒重新创建图形和画笔 1000 次。小心你放在那里的东西。

此外,您不应该使用 Picturebox 的 CreateGraphics 方法。相反,重写其 OnPaint 方法,并对其调用 Refresh。

您可以在Bob Powell 的网站上阅读更多相关信息

于 2014-03-17T19:29:27.373 回答