当 PictureBox 在另一个 PictureBox 上时,如何使它的透明度正常工作?

How can I make the transparency from a PictureBox work properly when it's over another PictureBox?

我在 Windows Forms 中做一个游戏项目并且真的很喜欢它的结果,除了一件让我烦恼的事情:我添加的新图片框 "eating" 远离一个在它后面,显示它 parent 的背景,而不是像我认为的那样显示他身后的图像。 Apparently 这就是透明度在 Windows Forms 中的工作原理,它基本上复制了他身后的颜色。

This is how it looks,我希望动物能被完整地看到。

我也试过 from another post here, but it turned out like this.

这个可能没法解决,我自己做的这个小游戏还有别的东西。还有另一个带有其他按钮和东西的图片框,代表商店。您还可以在两张图片中看到底部有一个带有一些细节的面板。在那种情况下,我会保持原样,也许下次尝试将其移至 WPF。

=================== 编辑 ===================

接受的答案帮助我从一个带有叠加 PictureBoxes 的游戏切换到一个我 "paint" 游戏的每一帧都在背景上的游戏。查看该答案的评论以获取有关此的更多详细信息:) This 结果如何。

这是专门针对我的代码,其中我有一个静态资源 class。你的看起来可能更干净,也许你有这个 Render 功能,你有所有其他矩形和图像。我希望这对访问此页面的每个人都有帮助:)

    // ================ SOLUTION ================
    public static void Render()
    {
        //draw the background again. This is efficient enough, maybe because the pixels that did not changed won't be redrawn
        grp.DrawImage(Resources.gameBackground, 0, 0);

        //draw the squirrel image on the position and length of the "squirrel" Rectangle
        grp.DrawImage(Resources.currentSquirrelImage, Resources.squirrel.X, Resources.squirrel.Y, Resources.squirrel.Width, Resources.squirrel.Height);

        //after that, draw each projectile (acorns, wallnuts) the same way
        foreach (Projectile projectile in Resources.projectiles)
        {
            grp.DrawImage(projectile.image, projectile.rect.X, projectile.rect.Y, projectile.rect.Width, projectile.rect.Height);
        }

        //then draw each animal
        foreach (Enemy animal in Resources.enemies)
        {
            grp.DrawImage(animal.image, animal.rect.X, animal.rect.Y, animal.rect.Width, animal.rect.Height);
        }

        //and finally, the image that shows where the squirrel is shooting
        grp.DrawImage(Resources.selectionImge, Resources.selection.X, Resources.selection.Y, Resources.Selection.Width, Resources.Selection.Height);

        //update the image of the game picturebox
        form.TheGame.Image = bmp;
    }

如您所见,.net 控件透明度不是真正的透明度,它会复制其父背景,因此如果您有其他同级控件,Z 索引较高的控件会遮挡其他控件。

如果你想创建一个游戏,避免使用图片框,有很多选择:使用像 Unity 这样的游戏引擎或者你自己的。

创建一个位图很容易,在其中渲染您的游戏,然后将其呈现在您的表单中,但要注意,这可能会很慢。

编辑:正如您所要求的,这里有一个关于如何使用 Rectangle 结构的 Intersect 函数来确定两个矩形重叠的部分的示例。

Rectangle R1 = new Rectangle (0,0,32,32);
Rectangle R2 = new Rectangle (16,16,32,32);

//To test if a rectangle intersects with another...
bool intersects = R1.IntersectsWith(R2); //If does not intersect then there's nothing to update

//To determine the area that two rectangles intersect
Rectangle intersection = Rectangle.Intersect(R1, R2); //In this example that would return a rectangle with (16,16,16,16).