![]() |
Platforms, Frameworks & Libraries »
Game Development »
Games
Intermediate
Simon: memory game from the eightiesBy Mike KitchenSimple memory game that uses shaped buttons |
C# 2.0, Windows, .NET 2.0, Visual Studio, GDI+, WinForms, Dev
|
|
Advanced Search Add to IE Search |
|
|
|
||||||||||||||||
I wanted to be able to create non-rectangular buttons, just out of interest more than anything else. I had seen several complex versions on the web, but I thought I could come up with something simpler. Whilst trawling the web, I came across a flash version of Simon, which I enjoyed playing, so here is a recreation of it with my shaped buttons.
There is no sound, but if someone wants to add it, then please send me a copy of the updated code.
This was achieved using the following steps:
UserControl to your application.UserControl to Button.
public partial class simonButton : Button
{
public simonButton()
{
InitializeComponent();
}
} GraphicsPath objects. Declare these in the top of the button class.
public partial class simonButton : Button
{
private GraphicsPath path;
private GraphicsPath innerPath;
...
The path denotes the outline of the button, while the innerPath denotes the shape of the flat surface of the button. OnPaint method of the button, to take care of the drawing, so that is looks like the following code.
protected override void OnPaint(PaintEventArgs pevent)
{
Graphics g = pevent.Graphics;
g.SmoothingMode = SmoothingMode.AntiAlias;
}
So that we do not get jagged curves, set the SmoothingMode to AntiAlias.path object is filled with a LinearGradientBrush. This is simple to achieve by supplying a rectangle and a new LinearGradientBrush.
// Create Rectangle To Limit brush area.
Rectangle rect = new Rectangle(0, 0, 150, 150);
LinearGradientBrush linearBrush =
new LinearGradientBrush(rect,
Color.FromArgb(40,40,40),
this.ForeColor,
225);
Next we instantiate the path object.
path = new GraphicsPath();
Add items to the path object to create the required shape.
path.AddArc(0, 0, 270, 270, 180, 90);
path.AddArc(120, 0, 30, 30, 270, 90);
path.AddLine(150, 0, 150, 85);
path.AddArc(100, 100, 100, 100, -90, -90);
path.AddLine(100, 150, 0, 150);
path.AddArc(0, 120, 30, 30, 90, 90);
path.AddArc(0, 0, 270, 270, 180, 90);
Fill the path.
g.FillPath(linearBrush, path);
Finally, dispose of the brush to free memory.
linearBrush.Dispose();innerPath object is filled with a SolidBrush.
Brush b = new SolidBrush(this.ForeColor);
Next we instantiate the innerPath object.
innerPath = new GraphicsPath();
Add items to the innerPath object to create the required shape.
innerPath.AddArc(10, 10, 250, 250, 180, 90);
innerPath.AddArc(130, 10, 10, 10, 270, 90);
innerPath.AddLine(140, 0, 140, 90);
innerPath.AddArc(90, 90, 100, 100, -90, -90);
innerPath.AddLine(90, 140, 10, 140);
innerPath.AddArc(10, 130, 10, 10, 90, 90);
Fill the innerPath.
g.FillPath(b, innerPath);
Finally, dispose of the brush to free memory.
b.Dispose();Region property of the button to path.
this.Region = new Region(path);
The button will now only accept clicks within the region of the shape.OnMouseEnter and OnMouseLeave methods and change the cursor within them.
protected override void OnMouseEnter(EventArgs e)
{
this.Cursor = Cursors.Hand;
base.OnMouseEnter(e);
}
protected override void OnMouseLeave(EventArgs e)
{
this.Cursor = Cursors.Arrow;
base.OnMouseLeave(e);
}private bool _clicked = false;
public bool Clicked
{
get { return _clicked; }
set
{
_clicked = value;
Invalidate();
}
}
Now override the OnMouseDown and OnMouseUp to set the Clicked state accordingly.
protected override void OnMouseDown(MouseEventArgs mevent)
{
_clicked = true;
base.OnMouseDown(mevent);
}
protected override void OnMouseUp(MouseEventArgs mevent)
{
_clicked = false;
base.OnMouseUp(mevent);
}
Add a new brush.
PathGradientBrush pgbrush = new PathGradientBrush(innerPath);
pgbrush.CenterPoint = new Point(75, 75);
pgbrush.CenterColor = Color.White;
pgbrush.SurroundColors = new Color[] { this.ForeColor };
Redraw the button according to the Clicked state.
if (_clicked == false)
{
g.FillPath(linearBrush, path);
g.FillPath(b, innerPath);
}
else
{
g.FillPath(linearBrush, path);
g.FillPath(pgbrush, innerPath);
}
Remember to dispose of the brush correctly.Once you have built the application, just drop the control on a form. The buttons are a fixed size, so they are not scaleable. Again, if someone wants to improve on this please send me a copy of the code.
The game logic is fairly simple, so I will not write about that here, except to say that only sequences of 1000 are generated. My best score so far is 18, so I think 1000 is reasonable.
Have fun.
| You must Sign In to use this message board. | |||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||
General
News
Question
Answer
Joke
Rant
Admin
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 11 May 2007 Editor: Genevieve Sovereign |
Copyright 2007 by Mike Kitchen Everything else Copyright © CodeProject, 1999-2009 Web21 | Advertise on the Code Project |