winforms 有背景图像时Windows窗体运行缓慢

5jvtdoz2  于 2023-02-24  发布在  Windows
关注(0)|答案(1)|浏览(138)

你好,我正在做一个简单的突破游戏与windows窗体在visual studio中。我注意到游戏运行很糟糕,当游戏计时器设置在20以下,当一个背景图像被添加,它降低了性能,甚至移动。移动对象口吃,当2个对象同时移动,他们都慢下来。
我试过多个图像,图像越大,性能下降越大
下面是我的代码

// Variables
int playerSpeed;
int score;
bool moveLeft;
bool moveRight;
int deflection;
int ballBaseSpeed;
int ballXSpeed;
int ballYSpeed;
int difficulty = 1;

public Form2()
{
    InitializeComponent();
}

private void setupGame()
{
    playerSpeed = 7 * difficulty;
    score = 0;
    moveLeft = false;
    moveRight = false;
    deflection = 0;
    ballBaseSpeed = 5 * difficulty;
    ballXSpeed = ballBaseSpeed;
    ballYSpeed = ballBaseSpeed;
    gameTimer.Start();
}

private void gamerTimerEvent(object sender, EventArgs e)
{
    // Player Move
    if (moveRight & player.Left < 784 - player.Width)
    {
        player.Left += playerSpeed;
    }
    if (moveLeft & player.Left > 0)
    {
        player.Left -= playerSpeed;
    }
    // Ball Collisions
    if (ball.Top < 0)
    {
        ballYSpeed *= -1;
        ball.Top = 0;
    } else if (ball.Top > 461 - ball.Height)
    {
        gameTimer.Stop();
    }
    if (ball.Left < 0) 
    {
        ballXSpeed *= -1;
        ball.Left = 0;
    } else if (ball.Left > 784 - ball.Width)
    {
        ballXSpeed *= -1;
        ball.Left = 784 - ball.Width;
    }
    if (ball.Bounds.IntersectsWith(player.Bounds))
    {
        // Calculates how much extra speed to add depending on where the ball lands on the paddle
        deflection = ((((player.Left + (player.Width / 2) - ball.Width / 2) - ball.Left) * -1) / 10);
        // If ball is on right side and travelling left then the ball direction swaps
        if (deflection > 0 & ballXSpeed < 0) 
        {
            ballXSpeed *= -1;
        // If ball is on left side and travelling right then the ball direction swaps
        } else if (deflection < 0 & ballXSpeed > 0)
        {
            ballXSpeed *= -1;
        }
        ballYSpeed *= -1;
        // Resets ball speed to minimum and calculates the extra speed needed due to paddle position
        if (ballXSpeed > 0)
        {
            ballXSpeed = ballBaseSpeed + deflection;
        } else if (ballXSpeed < 0)
        {
            ballXSpeed = (ballBaseSpeed * -1) + deflection;
        }
    }
    // Ball Movement
    ball.Left += ballXSpeed;
    ball.Top -= ballYSpeed;

    // Blocks Collisions
    foreach(Control x in this.Controls)
    {
        if (x is PictureBox && (string)x.Tag == "blocks")
        {
            if (ball.Bounds.IntersectsWith(x.Bounds)) {
                this.Controls.Remove(x);
                ballYSpeed *= -1;
                score += 1;
            }
        }
    }

    // Display and updating text
    scoreLabel.Text = ("Score: " + score.ToString());

}

private void keyIsDown(object sender, KeyEventArgs e)
{
    // Player Controls
    if (e.KeyCode == Keys.Right)
    {
        moveRight = true;
    }
    if (e.KeyCode == Keys.Left)
    {
        moveLeft = true;
    }
}

private void keyIsUp(object sender, KeyEventArgs e)
{
    // Player Controls
    if (e.KeyCode == Keys.Right)
    {
        moveRight = false;
    }
    if (e.KeyCode == Keys.Left)
    {
        moveLeft = false;
    }
}

private void startButton_Click(object sender, EventArgs e)
{
    setupGame();
    startButton.Hide();
    easyButton.Hide();
    hardButton.Hide();
    startButton.Enabled = false;
    easyButton.Enabled = false;
    hardButton.Enabled = false;
}

private void hardButton_Click(object sender, EventArgs e)
{
    difficulty = 2;
}

private void easyButton_Click(object sender, EventArgs e)
{
    difficulty = 1;
}
mzsu5hc0

mzsu5hc01#

我觉得这个问题还有些地方漏了,因为性能问题很可能不是来自移动计算,而是来自游戏元素的绘制。不过,我想我可以有根据地猜一猜这是怎么回事。
在我看来,你似乎是在用图片框来画方块,可能也是在画球。这就是问题所在-- Winforms并没有针对在一个窗体中绘制大量重叠的控件进行优化,尤其是当控件改变位置时。有了背景图片,你会得到大量的重叠。球的任何重新定位都可能导致所有控件的重绘-这是相当缓慢的。
对于这样的游戏,我建议不要使用图片框或其他标准控件。最好在窗体的OnPaint事件或属于窗体的面板中实现您自己的元素绘制。这样可以让您完全控制哪些元素需要重绘,哪些元素不需要重绘,并且当您不引入任何严重错误时,这应该可以解决您的性能问题。

相关问题