c# - 如何使 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;
}
解决方案
正如您所注意到的,.net 控件透明度不是真正的透明度,它复制了它的父背景,因此如果您有其他同级控件,则具有较高 Z 索引的控件将遮挡其他控件。
如果你想创建一个避免使用图片框的游戏,有很多选择:使用 Unity 之类的游戏引擎或滚动你自己的引擎。
很容易做的是创建一个位图,在其中渲染你的游戏,然后以你的形式呈现它,但要注意,这可能会很慢。
编辑:正如您所要求的,这里有一个关于如何使用Intersect
Rectangle 结构的函数来确定两个矩形的哪些部分重叠的示例。
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).
推荐阅读
- node.js - npm 路径和包路径不一样
- css - React with Css 模块中的动态样式(非内联样式)
- python - 如何动态加载kedro DataSet对象
- google-cloud-platform - Google Cloud Functions 部署错误:更改了虚拟环境并部署仍然引用旧的虚拟环境
- php - Laravel登录没有在sql server中加密密码
- javascript - 从javascript中的日期中删除GMT-####文本?
- excel - Excel VBA 使用循环函数插入列
- javascript - 在本地主机上开发时,Firebase 分析是否有效?
- reactjs - 在 this.state 中更改标题
- ruby-on-rails - Rails api 控制器不从父类继承方法