首页 > 解决方案 > 如何使 PictureBox 的透明度在另一个 PictureBox 上方时正常工作?

问题描述

我在 Windows 窗体中做一个游戏项目,真的很喜欢它的结果,除了一件让我烦恼的事情:我添加的新图片框正在“吃”远离它后面的那个,显示其父级的背景和没有像我想的那样显示他身后的图像。显然这就是 Windows 窗体中透明度的工作原理,它基本上复制了他背后的颜色。

这就是它的外观,我希望能充分看到动物。

我也在这里的另一篇文章中尝试过这个,但结果是这样的。

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

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

接受的答案帮助我从覆盖 PictureBoxes 的游戏切换到我在背景上“绘制”游戏的每一帧的游戏。检查该答案的评论以获取有关此的更多详细信息:)结果就是这样。

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

    // ================ 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;
    }

标签: c#.netwinformspicturebox

解决方案


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

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

很容易做的是创建一个位图,在其中渲染你的游戏,然后以你的形式呈现它,但要注意,这可能会很慢。

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

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).

推荐阅读