I am trying to create a game in C#, using winforms, where shapes randomly appears and you have to click the shapes (one at a time) as quickly as possible.
When the shape is created, a timer starts, this timer counts how long it took you to click the shape, then once clicked, the shape deletes. I am having trouble with the shape deleting part. I have the timer, and I have it waiting for the timer to be stopped, but whenever I try to delete the shape I get the following error at the line: g.clear(Color.black).
System.ArgumentException: 'Parameter is not valid.'
The full error trace is:
System.ArgumentException
HResult=0x80070057
Message=Parameter is not valid.
Source=System.Drawing
StackTrace:
at System.Drawing.Graphics.Clear(Color color)
at NumbersGame.ShapesRound.<ShapesWindow_Paint>d__9.MoveNext() in
C:\Users\Matthew\Desktop\AHProject\NumbersGame\NumbersGame\ShapesRound.cs:line 92
This is all of my code for the game:
namespace NumbersGame
{
public partial class ShapesRound : UserControl
{
public ShapesRound()
{
InitializeComponent();
}
public bool GameStarted = false;
public GraphicsPath path;
public Rectangle currentShape = new Rectangle();
Stopwatch timer = new Stopwatch();
public bool timerIsRunning = false;
public bool ShapeClicked(Point location)
{
bool clicked = false;
if (currentShape.Contains(location))
{
clicked = true;
}
return clicked;
}
private void ShapesRound_Load(object sender, EventArgs e)
{
path = new GraphicsPath();
nameBox.Text = "Matthew";
// nameBox.Text = Welcome.name;
scoreBox.Text = Welcome.totalScore.ToString();
}
private void ShapesRound_MouseDown(object sender, MouseEventArgs e)
{
if (ShapeClicked(e.Location))
{
// MessageBox.Show("CLICKED");
//end timer
timer.Stop();
var timeP = timer.ElapsedMilliseconds / 1000;
// MessageBox.Show(timeP.ToString() + " SECONDS");
}
}
private async void ShapesWindow_Paint(object sender, PaintEventArgs e)
{
if (GameStarted == false) { return; } //if the game hasnt started (ie the start button has not been clicked), do nothing
else
{
using (Graphics g = e.Graphics)
{
g.SmoothingMode = SmoothingMode.AntiAlias;
currentShape = new Rectangle(10, 100, 75, 75); //assign coordinates to the global CurrentShape variable
g.FillEllipse(new SolidBrush(Color.Black), currentShape);
//INVALID PAARAM?//fill the currentshape on screen
//start a timer
timer.Start(); //start a timer
while (timer.IsRunning) //while the timer is running (ie shape isnt clicked) wait
{
await Task.Delay(500);
}
g.Clear(Color.Black);
// currentShape = null;
// MessageBox.Show("DELETING");
var bckCol = ShapesWindow.BackColor;
// e.Graphics.FillEllipse(new SolidBrush(bckCol), currentShape);
// e.Graphics.Clear(Color.Black); //INVALID PAARAM?
ShapesWindow.Refresh();
}
}
}
private void StartButton_Click(object sender, EventArgs e)
{
GameStarted = true;
ShapesWindow.Paint += new PaintEventHandler(ShapesWindow_Paint);
ShapesWindow.Refresh();
}
}
}
If I understand correctly, you are drawing a shape. Then when that shape is clicked, you want to delete that shape and draw a new one, and the process repeats.
If I'm correct, then reverse your logic. Right now, you are drawing a shape, waiting, then trying to clear. But you can clear first, then draw the shape. That way, when you detect a click, you just trigger a refresh.
If there's ever a time you don't want to draw a new shape, then declare a
boolvalue that will tell it to not draw a new shape. Set that whenever you don't want to draw a new value, and check that in your paint event after you clear, like: