Just making a little game and want to layer my pause menu over top.
A timer is responsible for the game loop. When it's paused, it calls a separate function that draws the pause menu. Right now I am drawing a small centred rectangle. The rectangle however isn't transparent, even though I clear it to be transparent.
Is there any way I can do that?
Here's the code for my game loop that updates the states and draws based on them. As you can see, when the game is paused, it calls a separate method.
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();
}
}
}
}
This is Pause(). It draws over top as expected, but because it's a separate graphics object, it draws over and isn't transparent as I expected it to be.
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();
}
}
}
}
Is there any way to do this so that it is transparent?
You seem to believe that Graphics.Clear(Color.Transparent)
would create a transparent canvas.
Well, this only true if you apply it to a Bitmap
. For controls
it lets the BackColor
of the Parent
shine through and for Forms
, which don't have a Parent
it makes the Form
look black.
It also resets the Graphics
object, which may also not be what you want..
Here is how to draw a semi-transparent overlay over a 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);
Result:
Use your numbers for the alpha values of the overlay and (maybe) the text!
Usually the Graphics
object to use should be the e.Graphics
from the Form
's Paint
event.
But since you seem to do all your drawing from a Timer.Tick
you might get away with creating it using CreateGraphics
, which is usually not recommended, as the result is non-persistent..