当 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).
我在 Windows Forms 中做一个游戏项目并且真的很喜欢它的结果,除了一件让我烦恼的事情:我添加的新图片框 "eating" 远离一个在它后面,显示它 parent 的背景,而不是像我认为的那样显示他身后的图像。 Apparently 这就是透明度在 Windows Forms 中的工作原理,它基本上复制了他身后的颜色。
This is how it looks,我希望动物能被完整地看到。
我也试过
这个可能没法解决,我自己做的这个小游戏还有别的东西。还有另一个带有其他按钮和东西的图片框,代表商店。您还可以在两张图片中看到底部有一个带有一些细节的面板。在那种情况下,我会保持原样,也许下次尝试将其移至 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).