具有透明度的分层图形
Layering graphics with transparency
正在制作一个小游戏,想在顶部放置我的暂停菜单。
计时器负责游戏循环。当它暂停时,它会调用一个单独的函数来绘制暂停菜单。现在我正在画一个小的居中矩形。然而矩形不是透明的,即使我清除它是透明的。
有什么办法可以做到吗?
这是我的游戏循环代码,它更新状态并基于它们绘制。如您所见,当游戏暂停时,它会调用一个单独的方法。
private void tmrGameLoop_Tick(object sender, EventArgs e)
{
if (Paused)
{
Pause();
return;
}
using (Graphics gr = CreateGraphics())
{
using (BufferedGraphicsContext bgc = new BufferedGraphicsContext())
{
using (BufferedGraphics bg = bgc.Allocate(gr, DisplayRectangle))
{
bg.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
bg.Graphics.Clear(Color.Transparent);
// draw the stuff
bg.Render();
}
}
}
}
这是暂停()。它按预期在顶部绘制,但因为它是一个单独的图形对象,所以它在顶部绘制并且不像我预期的那样透明。
private void Pause()
{
using (Graphics gr = CreateGraphics())
{
using (BufferedGraphicsContext bgc = new BufferedGraphicsContext())
{
using (BufferedGraphics bg = bgc.Allocate(gr, m_menu))
{
bg.Graphics.Clear(Color.Transparent);
// draw pause menu
bg.Render();
}
}
}
}
有什么方法可以做到透明吗?
您似乎相信 Graphics.Clear(Color.Transparent)
会创建一个透明的 canvas。
好吧,只有将它应用于 Bitmap
时才会如此。对于 controls
,它让 Parent
的 BackColor
发光,而对于 Forms
,它没有 Parent
,它使 Form
看黑色.
它还重置 Graphics
对象,这可能也不是您想要的..
以下是在 Form
上绘制半透明覆盖层的方法:
using (SolidBrush br = new SolidBrush(Color.FromArgb(192, Color.Silver)))
g.FillRectangle(br, ClientRectangle);
StringFormat fmt = new StringFormat()
{ Alignment = StringAlignment.Center,
LineAlignment = StringAlignment.Center };
using (SolidBrush br = new SolidBrush(Color.FromArgb(128, Color.Tomato)))
using (Font f = new Font("Consolas", 40f))
g.DrawString("PAUSED",f, br, ClientRectangle, fmt);
结果:
将您的数字用于叠加层和(可能)文本的 alpha 值!
通常要使用的 Graphics
对象应该是 Form
的 Paint
事件中的 e.Graphics
。
但是由于您似乎是从 Timer.Tick
开始绘制所有内容,因此您可能会使用 CreateGraphics
创建它,但通常不推荐这样做,因为结果是 非持久性..
正在制作一个小游戏,想在顶部放置我的暂停菜单。
计时器负责游戏循环。当它暂停时,它会调用一个单独的函数来绘制暂停菜单。现在我正在画一个小的居中矩形。然而矩形不是透明的,即使我清除它是透明的。
有什么办法可以做到吗?
这是我的游戏循环代码,它更新状态并基于它们绘制。如您所见,当游戏暂停时,它会调用一个单独的方法。
private void tmrGameLoop_Tick(object sender, EventArgs e)
{
if (Paused)
{
Pause();
return;
}
using (Graphics gr = CreateGraphics())
{
using (BufferedGraphicsContext bgc = new BufferedGraphicsContext())
{
using (BufferedGraphics bg = bgc.Allocate(gr, DisplayRectangle))
{
bg.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
bg.Graphics.Clear(Color.Transparent);
// draw the stuff
bg.Render();
}
}
}
}
这是暂停()。它按预期在顶部绘制,但因为它是一个单独的图形对象,所以它在顶部绘制并且不像我预期的那样透明。
private void Pause()
{
using (Graphics gr = CreateGraphics())
{
using (BufferedGraphicsContext bgc = new BufferedGraphicsContext())
{
using (BufferedGraphics bg = bgc.Allocate(gr, m_menu))
{
bg.Graphics.Clear(Color.Transparent);
// draw pause menu
bg.Render();
}
}
}
}
有什么方法可以做到透明吗?
您似乎相信 Graphics.Clear(Color.Transparent)
会创建一个透明的 canvas。
好吧,只有将它应用于 Bitmap
时才会如此。对于 controls
,它让 Parent
的 BackColor
发光,而对于 Forms
,它没有 Parent
,它使 Form
看黑色.
它还重置 Graphics
对象,这可能也不是您想要的..
以下是在 Form
上绘制半透明覆盖层的方法:
using (SolidBrush br = new SolidBrush(Color.FromArgb(192, Color.Silver)))
g.FillRectangle(br, ClientRectangle);
StringFormat fmt = new StringFormat()
{ Alignment = StringAlignment.Center,
LineAlignment = StringAlignment.Center };
using (SolidBrush br = new SolidBrush(Color.FromArgb(128, Color.Tomato)))
using (Font f = new Font("Consolas", 40f))
g.DrawString("PAUSED",f, br, ClientRectangle, fmt);
结果:
将您的数字用于叠加层和(可能)文本的 alpha 值!
通常要使用的 Graphics
对象应该是 Form
的 Paint
事件中的 e.Graphics
。
但是由于您似乎是从 Timer.Tick
开始绘制所有内容,因此您可能会使用 CreateGraphics
创建它,但通常不推荐这样做,因为结果是 非持久性..