Disable a form's KeyDown after timer.stop() - c#

I just created a letter game. While the timer is on it prints letters to a listbox.
The user must press the correct key. If he does, a label with the mumber of correct presses is updated. If not, a missed label is updated. In both cases, the Total and and accuracy label is updated.
The problem is that after the game is over it still counts.
The thing I want to do is disable keyDown event from happening on the form.
I wrote this code but doesn't work.
timer1.Stop();
Form1 form = new Form1();
form.KeyPreview = false;
Does anyone has a solution?
This is my code. Even if I add a flag, the form, even after the game is over, has keyDown Event enabled. I want to know if there is a way to disable the keyDown event from happening after the game finishes.
namespace TypingGame
{
public partial class Form1 : Form
{
Random random = new Random();
Stats stats = new Stats();
public Form1()
{
InitializeComponent();
}
//Here the game starts
private void timer1_Tick(object sender, EventArgs e)
{
listBox1.Items.Add((Keys) random.Next(65,90));
//If letters missed are more than 7 the game is over
//so I need a way to disable the KeyDown event from happening after the game is over
if (listBox1.Items.Count > 7)
{
listBox1.Items.Clear();
listBox1.Items.Add("Game Over");
timer1.Stop();
}
}
//Here is what happens on KeyDown.
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (listBox1.Items.Contains(e.KeyCode))
{
listBox1.Items.Remove(e.KeyCode);
listBox1.Refresh();
if (timer1.Interval > 400)
{
timer1.Interval -= 10;
}
if (timer1.Interval > 250)
{
timer1.Interval -= 7;
}
if (timer1.Interval > 100)
{
timer1.Interval -= 2;
}
difficultyProgressBar.Value = 800 - timer1.Interval;
stats.Update(true);
}
else
{
stats.Update(false);
}
correctLabel.Text = "Correct: " + stats.Correct;
missedLabel.Text = "Missed: " + stats.Missed;
totalLabel.Text = "Total: " + stats.Total;
accuracyLabel.Text = "Accuracy" + stats.Accuracy + "%";
}
}
}

I have updated the code base on your code.
MSDN Reference - Timer
//Here the game starts (?? game stop?)
private void timer1_Tick(object sender, EventArgs e)
{
listBox1.Items.Add((Keys) random.Next(65,90));
//If letters missed are more than 7 the game is over
//so I need a way to disable the KeyDown event from happening after the game is over
if (listBox1.Items.Count > 7)
{
listBox1.Items.Clear();
listBox1.Items.Add("Game Over");
// timer1.Stop();
// disable the timer to stop
timer1.Enabled = false;
}
}
//Here is what happens on KeyDown.
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
// if timer disabled, do nothing
if (!timer1.Enabled) return;
if (listBox1.Items.Contains(e.KeyCode))
{
listBox1.Items.Remove(e.KeyCode);
listBox1.Refresh();
if (timer1.Interval > 400)
{
timer1.Interval -= 10;
}
if (timer1.Interval > 250)
{
timer1.Interval -= 7;
}
if (timer1.Interval > 100)
{
timer1.Interval -= 2;
}
difficultyProgressBar.Value = 800 - timer1.Interval;
stats.Update(true);
}
else
{
stats.Update(false);
}
correctLabel.Text = "Correct: " + stats.Correct;
missedLabel.Text = "Missed: " + stats.Missed;
totalLabel.Text = "Total: " + stats.Total;
accuracyLabel.Text = "Accuracy" + stats.Accuracy + "%";
}

Related

How to move a winforms tool to the right and then to the left continuously in the forms by using point class and timer tools?

Purpose of this code was to move a title(label) first rightwards until it hits the 600th pixel on the X axis and then leftwards until it hits the 27th pixel on the X axis of the form by using 2 timer tools and the Point class. One timer for going right and the other timer for going left. They should've work by swithing on and off consecutively after one another, however it does not work.
The label is stuck at 600th X location and does not move back to where it was.
The timer interval is 100 so it moves with a decent speed that allows us to see it moving.
namespace AlanCevreHesabiUygulamasi
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
if (label11Point.X == 27)
{
timer2.Stop();
timer1.Start();
}
if (label11Point.X == 599)
{
timer1.Stop();
timer2.Start();
}
}
Point label11Point = new Point(27, 32);
private void timer1_Tick(object sender, EventArgs e)
{
while (label11Point.X <= 600)
{
label12.Text = label11Point.X.ToString();
label11Point.X += 1;
label11.Location = label11Point;
break;
}
}
private void timer2_Tick(object sender, EventArgs e)
{
while (label11Point.X >= 27)
{
label12.Text = label11Point.X.ToString();
label11Point.X -= 1;
label11.Location = label11Point;
break;
}
}
}
}
Label is stuck at 600th pixel of the form, does not move back. How to make it work?
I'm surprised you see movement resulting from a while loop in a timer tick handler. Why have a timer if your are going to do it that way.
In this solution, I have a timer, and the movements happen during a timer tick. I also have three possible directions, Right, Left and Stopped (in case you want to have a start/stop button).
In the Windows Forms designer, I dropped both a label and a timer on the form. I left their properties alone except for the timer's Interval property (that I set to 10 (ms))
Then I added an enum and an instance of the enum as a field to the Form class:
public partial class Form1 : Form
{
private enum Direction { MoveRight, MoveLeft, Stopped }
Direction _direction;
public Form1()
{
InitializeComponent();
}
}
I double-clicked the Caption area of the form in the designer to create a form Load handler, and added a call to start the timer:
private void Form1_Load(object sender, EventArgs e)
{
timer1.Start();
}
Finally, I double-clicked the timer to get a timer Tick handler and added some code:
private void timer1_Tick(object sender, EventArgs e)
{
var curLocation = label1.Location;
if (_direction == Direction.MoveRight && curLocation.X > 600)
{
_direction = Direction.MoveLeft;
}
else if (_direction == Direction.MoveLeft && curLocation.X < 27)
{
_direction = Direction.MoveRight;
}
int offset = _direction switch
{
Direction.MoveRight => 1,
Direction.MoveLeft => -1,
_ => 0,
};
curLocation.X += offset;
label1.Location = curLocation;
}
The _direction field determines if the label is moving to the right or the left.
How can you write the code without a timer?"
You asked "How can you write the code without a timer?" I'm still flabbergasted that your label moves as the result of a while loop in an event handler - something must have changed from my good-old understanding of Win32 processing.
Anyways, I cheat and await a call to Task.Delay instead of using a timer. Take my existing code and do the following:
Add two buttons to your form (One labeled Start (named StartBtn) and the other labeled Stop (named StopBtn).
Add another Direction-typed field to the class: Direction _previousDirection;
Comment out the call to timer1.Start(); in the Form1_Load handler
Comment out all the code in the timer1_Tick method (at this point, you could remove the timer from the form if you want)
Select both buttons (Start and Stop) and press <Enter>. This will bring up click handlers for both buttons.
Change the StopBtn button's handler to look like:
New Stop Button code:
private void StopBtn_Click(object sender, EventArgs e)
{
_previousDirection = _direction;
_direction = Direction.Stopped;
}
Change the StartBtn's handler to look like the following. Note that nearly everything in the while loop (except the call to Task.Delay) is the same as the previous timer tick handler code. Also note that I made the handler async void to allow for the await keyword to do it's magic.
Start Button code:
private async void StartBtn_Click(object sender, EventArgs e)
{
_direction = _previousDirection;
while (_direction != Direction.Stopped)
{
var curLocation = label1.Location;
if (_direction == Direction.MoveRight && curLocation.X > 600)
{
_direction = Direction.MoveLeft;
}
else if (_direction == Direction.MoveLeft && curLocation.X < 27)
{
_direction = Direction.MoveRight;
}
int offset = _direction switch
{
Direction.MoveRight => 1,
Direction.MoveLeft => -1,
_ => 0,
};
curLocation.X += offset;
label1.Location = curLocation;
await Task.Delay(10);
}
}
I solved it, I don't know why but in my opening post the Form1() function only makes one of the if() conditions work. However, putting the if() statements into the timers solved the problem. Now, the title goes back and forth in the specified x axis intervals.
namespace AlanCevreHesabiUygulamasi
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
timer1.Start();
}
Point label11Point = new Point(27, 32);
private void timer1_Tick(object sender, EventArgs e)
{
while (label11Point.X >= 27)
{
label12.Text = label11Point.X.ToString();
label11Point.X += 1;
label11.Location = label11Point;
break;
}
if (label11Point.X == 600)
{
timer2.Start();
timer1.Stop();
}
}
private void timer2_Tick(object sender, EventArgs e)
{
while (label11Point.X <= 600)
{
label12.Text = label11Point.X.ToString();
label11Point.X -= 1;
label11.Location = label11Point;
break;
}
if (label11Point.X == 27)
{
timer1.Start();
timer2.Stop();
}
}

How to make a button that you must click at certain places within a certain time frame in C#

I am trying to create a game in Visual studios using C# where you have rows of sliding boxes that you must press a key in certain locations one after the other, kinda like stacker, before the time runs out.
I am using this as the basis but unsure how to adjust the speed among making it work in the first place since the code apparently runs with no issues but I only got it where the button just gives you a message box.
https://www.youtube.com/watch?v=O78n7apXjG8
Just asking for tips on where to go.
https://files.catbox.moe/x3wx22.zip
additional info for clarification
https://catbox.moe/c/fakpxe
// Project by 124
// Redid:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WinFormsApp1
{
public partial class Form1 : Form
{
private int _ticks;
private object textBox1;
public Form1()
{
InitializeComponent();
timer1.Start();
}
//This should be the part that moves the button back and forth but it's not working
int Left = 140;
private void timer1_tick(object sender, EventArgs e)
{
Left += 10;
if (Left > 430)
{
Left = -138;
Left += Left;
if (Left > 140 )
{
} else
{
button1.Left = Left;
}
}
else
button1.Left = Left;
{
button1.Visible = false;
button2.Visible = true;
}
{
_ticks++;
this.Text = _ticks.ToString();
if (_ticks == 9)
{
this.Text = "Game Over";
timer1.Stop();
}
}
}
private void button1_Click(object sender, EventArgs e)
//since the movement button function is not working so is this one where it's supposed to give you the win but the win is there regardless
{
if (_ticks < 9) ;
{
MessageBox.Show("good job you beat the time");
MessageBox.Show("You are a winner");
}
}
private void button2_Click(object sender, EventArgs e)
{
Application.Restart();
Environment.Exit(0);
}
private void button3_Click(object sender, EventArgs e)
{
Form3 f3 = new Form3();
f3.ShowDialog();
}
}
}
Adjust the speed among making it work:
Left += Convert.ToInt32(label1.Text);
Control speed +1:
private void Button4_Click(object sender, EventArgs e) {
label1.Text = (Convert.ToInt32(label1.Text) + 1).ToString();
}
Control speed -1:
private void Button5_Click(object sender, EventArgs e) {
label1.Text = (Convert.ToInt32(label1.Text) - 1).ToString();
}
Updated:
Write at the top:
You can control the speed and position of the button by modifying the values of'V0' and'a'.
//current position
Left += 20* _ticks+(a* _ticks* _ticks)/2;//s = v0·t + a·t²/2
Set the initial time value outside the timer
private double _ticks = 0;
Set the initial position to 0.
double Left = 0;
Increase by 1 every second. Because internal is 0.2, add 0.2 every time.
_ticks+=0.2;
Modified timer1_tick:
private void timer1_tick(object sender, EventArgs e) {
//Set acceleration
double a = 0.5;
//Increase by 1 every second. Because internal is 0.2, add 0.2 every time.
_ticks += 0.2;
this.Text = _ticks.ToString();
//Time to stop at 9s
if (_ticks == 9) {
this.Text = "Game Over";
timer1.Stop();
MessageBox.Show("Game Over");
button1.Visible = false;
button2.Visible = true;
}
//current position
Left += 20 * _ticks + (a * _ticks * _ticks) / 2;//s = v0·t + a·t²/2
//When the total distance exceeds the set width on the interface, perform operations such as subtraction until the current position is less than the set value.
rtn:
if (Left > 300) {
Left -= 300;
if (Left > 300) {
goto rtn;//Use goto: Perform an iterative operation.
} else {
button1.Left = Convert.ToInt32(Left);//Cast double data type to int
}
} else
button1.Left = Convert.ToInt32(Left);
}
Modified button_Click: Don’t add ‘;’ after ‘if’, it will be useless.
private void button1_Click(object sender, EventArgs e) {
if (_ticks < 9) //Don’t add ‘;’ after ‘if’, it will be useless.
{
timer1.Stop();
button1.Visible = false;
button2.Visible = true;
MessageBox.Show("good job you beat the time");
MessageBox.Show("You are a winner");
}
}
Output:

Smooth Expanding and Collapsing Animation for WinForms

Im trying to get a smooth expanding and collapsing animation for my form. My current animation is really jittery and non consistent. Heres a Gif of the Animation. Is there another way to do this that doesnt freeze the form?
private void ShowHideToggle_CheckStateChanged(object sender, EventArgs e)
{
if (ShowHideToggle.Checked) //checked = expand form
{
ShowHideToggle.Text = "<";
while (Width < originalWidth)
{
Width++;
Application.DoEvents();
}
}
else
{
ShowHideToggle.Text = ">";
while(Width > 24)
{
Width--;
Application.DoEvents();
}
}
}
Create a Timer:
Timer t = new Timer();
t.Interval = 14;
t.Tick += delegate
{
if (ShowHideToggle.Checked)
{
if (this.Width > 30) // Set Form.MinimumSize to this otherwise the Timer will keep going, so it will permanently try to decrease the size.
this.Width -= 10;
else
t.Stop();
}
else
{
if (this.Width < 300)
this.Width += 10;
else
t.Stop();
}
};
And change your code to:
private void ShowHideToggle_CheckStateChanged(object sender, EventArgs e)
{
t.Start();
}

How to reset a picture boxes position back to the left side of the form?

I'm creating a basic racing game in C# for an assignment where two picture boxes race from the left side of the form to the right side. What I am struggling with is resetting the position back to the 1st pixel on the left side of the form once the picture box has reached the end of the form on the right side. At the moment the picture boxes just keep going right and then disappear from the form and never come back.
That is what the layout of the game looks like:
I've tried searching google for snippets of code or even examples on how I might achieve this and have yet to find anything.
Any help would be much appreciated.
public partial class frmRacing : Form
{
public frmRacing()
{
InitializeComponent();
}
//This is the segment of intergers and the randomizer.
Random r = new Random();
int dir = 1;
int min, sec, ms = 0;
private void btnExit_Click(object sender, EventArgs e)
{
this.Close();
}
//This is the timer for "Player One". It moves the players picture box across the form at a random speed between 1-10 and times how long it takes to complete the total laps.
private void tmrOne_Tick(object sender, EventArgs e)
{
dir = r.Next(1, 10);
picStark.Left += dir;
lblTimer1.Text = min + ":" + sec + ":" + ms.ToString();
ms++;
if (ms > 100)
{
sec++;
ms = 0;
}
else
{
ms++;
}
if (sec > 60)
{
min++;
sec = 0;
}
}
//This is the timer for "Player Two". It moves the players picture box across the form at a random speed between 1-10 and times how long it takes to complete the total laps.
private void tmrTwo_Tick(object sender, EventArgs e)
{
dir = r.Next(1, 10);
picLannister.Left += dir;
lblTimer2.Text = min + ":" + sec + ":" + ms.ToString();
ms++;
if (ms > 100)
{
sec++;
ms = 0;
}
else
{
ms++;
}
if (sec > 60)
{
min++;
sec = 0;
}
}
//This is the start button. It enables all the timers and starts the race.
private void btnStart_Click(object sender, EventArgs e)
{
tmrOne.Enabled = true;
tmrTwo.Enabled = true;
tmrThree.Enabled = true;
}
private void hsbLaps_Scroll(object sender, ScrollEventArgs e)
{
lblLaps3.Text = lblLaps3.Text + 1;
}
//This is the overall timer for the race.
private void tmrThree_Tick(object sender, EventArgs e)
{
lblTimer3.Text = min + ":" + sec + ":" + ms.ToString();
ms++;
if (ms > 100)
{
sec++;
ms = 0;
}
else
{
ms++;
}
if (sec > 60)
{
min++;
sec = 0;
}
}
}
You could create a method which you call at the end of your tick events which checks if the Left property is greater than the width of your form.
private void ResetPicture(PictureBox pb)
{
// check if picture box left property is greater than the width
// of your form - the width of your picturebox
if (pb.Left >= this.Width - pb.Width)
{
// the picture has won the game, reset it
pb.Left = 1;
}
}

Countdown after clicking a button that goes from 10 to 0 setting text on a label C#

My problem is very simple but I can't figure it out, so I need your help.
The problem is that I have a button and a label in a form, I simply want to click the button and see the label countdown from 10 to 0 and after that happens the form closes, that simple, can someone help me with this?
BTW, my real app is a form that shows video in real time from my webcam and the idea is to click the button, see the count down and when it finishes the appp saves the current frame as an image.
Thanks in advice!
It sounds like you probably just need three things:
A counter in your class as an instance variable
A timer (System.Windows.Forms.Timer or a DispatcherTimer depending on what UI framework you're using)
A method handling the timer's Tick even which decrements the counter, updates the UI, and stops the timer + takes a snapshot if the counter reaches 0
You can do all of this without any other threads.
Using WindowsFormsApplication u can do it like this:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
timer1.Enabled = false; // Wait for start
timer1.Interval = 1000; // Second
i = 10; // Set CountDown Maximum
label1.Text = "CountDown: " + i; // Show
button1.Text = "Start";
}
public int i;
private void button1_Click(object sender, EventArgs e)
{
// Switch Timer On/Off
if (timer1.Enabled == true)
{ timer1.Enabled = false; button1.Text = "Start"; }
else if (timer1.Enabled == false)
{ timer1.Enabled = true; button1.Text = "Stop"; }
}
private void timer1_Tick(object sender, EventArgs e)
{
if (i > 0)
{
i = i - 1;
label1.Text = "CountDown: " + i;
}
else
{ timer1.Enabled = false; button1.Text = "Start"; }
}
}
You only need a label, a button and a timer.
use this code. put one timer,label and button.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
timer1.Tick += new EventHandler(timer1_Tick);
}
private static int i = 10;
private void button1_Click(object sender, EventArgs e)
{
label1.Text = "10";
timer1.Interval = 1000;
timer1.Start();
}
private void timer1_Tick(object sender, EventArgs e)
{
label1.Text = (i--).ToString();
if (i < 0)
{
timer1.Stop();
}
}
}

Categories