C# - How to create a pop up message once timer reaches zero - c#

I am creating a game in visual studio using c sharp and want to add a pop up message saying 'game Over' once the timer reaches 0. Currently the countdown timer goes to negative seconds and the game keeps going. Currently attempt is below and any help is apricated.
public MainPage()
{
InitializeComponent();
_random = new Random(); // r is my random number generator
_countDown = 30;
SetUpMyTimers();// method for my timer
endGame();
}
private void endGame()
{
throw new NotImplementedException();
}
private void SetUpMyTimers() // calling my method
{
// start a timer to run a method every 1000ms
// that method is "TimerFunctions" that runs on the UI thread
Device.StartTimer(TimeSpan.FromMilliseconds(1000), () =>
{
Device.BeginInvokeOnMainThread(() =>
{ TimerFunctions(); });
return true;
});
}
private void TimerFunctions()
{
// change the countdown.
_countDown--;
LblCountdown.Text = _countDown.ToString();
}

The countdown is over to call the function.Use winform timer control to implement countdown function
public partial class Form1 : Form
{
TimeSpan Span = new TimeSpan(0, 0, 10);
public Form1()
{
InitializeComponent();
}
private void timer1_Tick(object sender, EventArgs e)
{
Span = Span.Subtract(new TimeSpan(0, 0, 1));
label1.Text = Span.Hours.ToString() + ":" + Span.Minutes.ToString() + ":" + Span.Seconds.ToString();//时间格式0:0:10
if (Span.TotalSeconds < 0.0)//when the countdown is over
{
timer1.Enabled = false;
MessageBox.Show("game over");
}
}
private void button1_Click(object sender, EventArgs e)
{
timer1.Interval = 1000;//Set every interval to 1 second
timer1.Enabled = true;
MessageBox.Show("End the game after 10s");
}
}
Test timer:
Hope it helps you.

You could try the following code.
<Grid>
<TextBlock Name="tbTime" />
</Grid>
Codebehind:
DispatcherTimer _timer;
TimeSpan _time;
public MainWindow()
{
InitializeComponent();
_time = TimeSpan.FromSeconds(10);
_timer = new DispatcherTimer(new TimeSpan(0, 0, 1), DispatcherPriority.Normal, delegate
{
tbTime.Text = _time.ToString("c");
if (_time == TimeSpan.Zero)
{
_timer.Stop();
MessageBox.Show("GameOver");
}
_time = _time.Add(TimeSpan.FromSeconds(-1));
}, Application.Current.Dispatcher);
_timer.Start();
}
The result:

Related

Timer firing every second and updating GUI (C# Windows Forms)

I have a Windows Forms application where I need to have a timer working for 90 seconds and every second should be shown after it elapses, kind of like a stopwatch 1..2..3 etc, after 90 seconds is up, it should throw an exception that something is wrong.
I have the following code, but the RunEvent never fires.
private void ScanpXRF()
{
bool demo = false;
System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
try
{
for (int timerCounter = 0; timerCounter < 90; timerCounter++)
{
timer.Interval = 1000;
timer.Tick += new EventHandler(RunEvent);
timer.Start();
if(timerCounter == 89) {
throw new Exception();
}
}
}
catch (Exception e)
{
timer.Dispose();
MessageBox.Show("There is a problem!");
}
}
private void RunEvent(object sender, System.EventArgs e)
{
//boxStatus.AppendText("RunEvent() called at " + DateTime.Now.ToLongTimeString() + "\n");
MessageBox.Show("timer fired!");
}
Is there anything I am doing wrong here or are there other suggestions for other ways to achieve the same result?
A timer needs to be declared at the form level, or else it may not be disposed of when the form closes:
System.Windows.Forms.Timer timer;
int counter = 0;
Your starting code should just start the timer:
private void ScanpXRF()
{
counter = 0;
timer = new System.Windows.Forms.Timer();
timer.Interval = 1000;
timer.Tick += RunEvent;
timer.Start();
}
The RunEvent is your Tick event being called every second, so your logic needs to go in there:
private void RunEvent(object sender, EventArgs e)
{
counter++;
if (counter >= 90) {
timer.Stop();
// do something...
}
}
made it work
private void ScanpXRF()
{
_pXRFTimerCounter = 0;
pXRFTimer.Enabled = true;
pXRFTimer.Interval = 1000;
pXRFTimer.Elapsed += new ElapsedEventHandler(pXRFTimer_Tick);
pXRFTimer.Start();
}
private static void pXRFTimer_Tick(Object sender, EventArgs e)
{
_pXRFTimerCounter++;
if (_pXRFTimerCounter >= 90)
{
pXRFTimer.Stop();
// do something...
}
else
{
MessageBox.Show(_pXRFTimerCounter.ToString() + " seconds passed");
}
}
I made the timer
System.Timers

How to Increment timer asynchronously ?

I am trying to Update a timer asynchronously On a Button Click .
say example i have set the time = 60 seconds
and when i run the program after few TIME the timer has reached to 45 seconds and when i click the Button ,then it should add j=15 seconds to the time and the timer should change to 60 seconds asynchronously. Please Help
private int time = 60;
DateTime dt = new DateTime();
private j = 15 ;
private DispatcherTimer timer;
public MainWindow()
{
InitializeComponent();
timer = new DispatcherTimer();
timer.Interval = new TimeSpan(0, 0, 1);
timer.Tick += timer_tick;
timer.Start();
}
void timer_tick(object sender, EventArgs e)
{
if (time >0)
{
time--;
text.Text = TimeSpan.FromSeconds(time).ToString();
}
else
{
timer.Stop();
}
}
private void Button_Click(object sender, RoutedEventArgs e)
{
text.Text = dt.AddSeconds(j).ToString("HH:mm:ss");
}
Here is my code you can try it it's working.
private int time = 60;
DateTime dt = new DateTime();
private int j = 15;
private Timer timer1 = new Timer();
void timer_tick(object sender, EventArgs e)
{
if (time > 0)
{
time--;
text.Text = TimeSpan.FromSeconds(time).ToString();
}
else
{
timer1.Stop();
}
}
public timer()
{
InitializeComponent();
timer1 = new Timer();
timer1.Interval = 1000;
timer1.Tick += timer_tick;
timer1.Start();
}
private void button1_Click(object sender, EventArgs e)
{
time += j;
}

How to set timer to execute at specific time in c#

I have a requirement where i need to execute timer at 00:01:00 A.M every day...But i am not getting how to achieve this ..If i am taking Systems time,it can be in different format..
Here is my timer code..
static System.Timers.Timer timer;
timer = new System.Timers.Timer();
timer.Interval = 1000 * 60 * 60 * 24;//set interval of one day
timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
start_timer();
static void timer_Elapsed(object sender, ElapsedEventArgs e)
{
// Add timer code here
}
private static void start_timer()
{
timer.Start();
}
If you want to start a timer at exactly 00:01:00am do some processing time and then restart the timer you just need to calculate the difference between Now and the next 00:01:00am time slot such as.
static Timer timer;
static void Main(string[] args)
{
setup_Timer();
}
static void setup_Timer()
{
DateTime nowTime = DateTime.Now;
DateTime oneAmTime = new DateTime(nowTime.Year, nowTime.Month, nowTime.Day, 0, 1, 0, 0);
if (nowTime > oneAmTime)
oneAmTime = oneAmTime.AddDays(1);
double tickTime = (oneAmTime - nowTime).TotalMilliseconds;
timer = new Timer(tickTime);
timer.Elapsed += timer_Elapsed;
timer.Start();
}
static void timer_Elapsed(object sender, ElapsedEventArgs e)
{
timer.Stop();
//process code..
setup_Timer();
}
What you should do is write your program that does whatever you need it to do, and then use your OS's built-in task scheduler to fire it off. That'd be the most reliable. Windows's Task Scheduler, for instance, can start your app before the user logs in, handle restarting the app if necessary, log errors and send notifications, etc.
Otherwise, you'll have to run your app 24/7, and have it poll for the time at regular intervals.
For instance, you could change the interval every minute:
timer.Interval = 1000 * 60;
And inside your Elapsed event, check the current time:
static void timer_Elapsed(object sender, ElapsedEventArgs e)
{
if (DateTime.Now.Hour == 1 && DateTime.Now.Minute == 0)
{
// do whatever
}
}
But this is really unreliable. Your app may crash. And dealing with DateTime's can be tricky.
You could always calculate it:
static void timer_Elapsed(object sender, ElapsedEventArgs e)
{
// Do stuff
start_timer();
}
private static void start_timer()
{
timer.Interval = CalculateInterval();
timer.Start();
}
private static double CalculateInterval()
{
// 1 AM the next day
return (DateTime.Now.AddDays(1).Date.AddHours(1) - DateTime.Now).TotalMilliseconds;
}
Here is a timer implementation which takes an Interval (just like any other timer) and fires exactly when that interval expires, even the machine goes to sleep mode in between.
public delegate void TimerCallbackDelegate(object sender, ElapsedEventArgs e);
public class TimerAbsolute : System.Timers.Timer
{
private DateTime m_dueTime;
private TimerCallbackDelegate callback;
public TimerAbsolute(TimerCallbackDelegate cb) : base()
{
if (cb == null)
{
throw new Exception("Call back is NULL");
}
callback = cb;
this.Elapsed += this.ElapsedAction;
this.AutoReset = true;
}
protected new void Dispose()
{
this.Elapsed -= this.ElapsedAction;
base.Dispose();
}
public double TimeLeft
{
get
{
return (this.m_dueTime - DateTime.Now).TotalMilliseconds;
}
}
public int TimeLeftSeconds
{
get
{
return (int)(this.m_dueTime - DateTime.Now).TotalSeconds;
}
}
public void Start(double interval)
{
if (interval < 10)
{
throw new Exception($"Interval ({interval}) is too small");
}
DateTime dueTime = DateTime.Now.AddMilliseconds(interval);
if (dueTime <= DateTime.Now)
{
throw new Exception($"Due time ({dueTime}) should be in future. Interval ({interval})");
}
this.m_dueTime = dueTime;
// Timer tick is 1 second
this.Interval = 1 * 1000;
base.Start();
}
private void ElapsedAction(object sender, System.Timers.ElapsedEventArgs e)
{
if (DateTime.Now >= m_dueTime)
{
// This means Timer expired
callback(sender, e);
base.Stop();
}
}
}

DispatcherTimer and Button c# conflict

I'm very new to WP8 dev and c#. I'm trying to make a loop that counts up by n on an interval. I want to press a button to increment n.
Here is my code right now:
namespace Petsounds {
public partial class MainPage : PhoneApplicationPage {
float clicks = 0;
float clickers = 0;
float clickerBuyers = 0;
float clickerCost = 5;
float clickerBuyerCost = 500;
long savedTime = DateTime.Now.Ticks / TimeSpan.TicksPerSecond;
bool buyClickerButtonFlag = false;
bool clickButtonFlag = false;
// Constructor
public MainPage() {
InitializeComponent();
//
DispatcherTimer t = new DispatcherTimer();
t.Interval = TimeSpan.FromMilliseconds(10);
t.Tick += (s, e) => startLoop();
t.Start();
}
private void clickButtonOnClick(object sender, RoutedEventArgs e) {
clickButtonFlag = true;
System.Diagnostics.Debug.WriteLine("clicked!" + clicks);
}
private void buyClickerButtonOnClick(object sender, RoutedEventArgs e) {
buyClickerButtonFlag = true;
}
private void startLoop() {
if (true) {
long nowTime = savedTime;
long timePassed = nowTime - savedTime;
//user input
if (clickButtonFlag) {
clickButtonFlag = false;
clicks++;
System.Diagnostics.Debug.WriteLine("clicked!" + clicks);
}
if (buyClickerButtonFlag) {
buyClickerButtonFlag = false;
if (clicks > clickerCost) {
clickers++;
clicks -= clickerCost;
clickerCost *= 1.6F;
}
System.Diagnostics.Debug.WriteLine("clicker bought!" + clickers);
}
//update vars
if (timePassed > TimeSpan.TicksPerSecond) {
savedTime = nowTime;
nowTime = DateTime.Now.Ticks / TimeSpan.TicksPerSecond;
clicks += clickers;
}
//update display
clickCount.Text = clicks.ToString();
buyClickerButtonCost.Text = "Cossst " + clickerCost.ToString();
}
}
}
}
My button's are inconsistent, and if I remove the thread, the buttons are responsive (but of course the counter doesn't work.)
EDIT:
I've changed
DispatcherTimer t = new DispatcherTimer();
t.Interval = TimeSpan.FromMilliseconds(10);
t.Tick += (s, e) => startLoop();
t.Start();
to
Timer myTimer = new Timer(startLoop);
myTimer.Change(1000, 10);
And now get an error:
A first chance exception of type 'System.UnauthorizedAccessException' occurred in System.Windows.ni.dll
on line
clickCount.Text = clicks.ToString();
First of all... you will quickly find that 10ms is not really 10ms... It might not even be that close... If you did 1000ms... that would be expected to be more accurate.
Also, a DispatcherTimer is going to queue up a function call to the GUI thread each interval... which means you are flooding the GUI thread with startLoop() calls. This doesn't give the thread much time to update anything else... like your buttons.
There is a different approach you might want to consider.
If your task is to increment a numeric value when a user touches a button (and have the numbers increase at a steady pace) consider using the RepeatButton.
RepeatButton: Represents a control that raises its Click event repeatedly from the time it is pressed until it is released.
XAML
<!--
Delay: The time, in milliseconds, the RepeatButton waits
when it is pressed before it starts repeating the click action.
Interval: The time, in milliseconds, between repetitions
of the click action, as soon as repeating starts.
-->
<RepeatButton Content='Buy'
Interval='50' Delay='100'
Click='RepeatButton_Click' />
Code
private float buyCounter = 0;
private void RepeatButton_Click(object sender, RoutedEventArgs e) {
buyCounter += 1;
buyClickerButtonCost.Text = buyCounter.ToString();
}
It's like #Andrew said - DispatcherTimer works on UI thread and with so small intervall you are blocking it.
If you want such a small interval you can use Timer on different Thread:
public MainPage()
{
InitializeComponent();
System.Threading.Timer myTimer = new Timer(MyTimerCallback);
myTimer.Change(1000, 10);
}
private static int value = 0;
private static void MyTimerCallback(object state)
{
value++;
}
But you must remember that you use it on different Thread - this Timer has no access to your UI elements (buttons and so on).
EDIT
You convinced me to check it:
static float clicks = 0;
static float clickers = 0;
static float clickerCost = 5;
static long savedTime = DateTime.Now.Ticks / TimeSpan.TicksPerSecond;
static bool buyClickerButtonFlag = false;
static bool clickButtonFlag = false;
public MainPage()
{
InitializeComponent();
first.Click += ShowCounter;
DispatcherTimer t = new DispatcherTimer();
t.Interval = TimeSpan.FromSeconds(5);
t.Tick += ShowCounter;
t.Start();
System.Threading.Timer myTimer = new Timer(MyTimerCallback);
myTimer.Change(10, 10);
}
private void ShowCounter(object sender, EventArgs e)
{
textBlck.Text = clicks.ToString();
}
private static void MyTimerCallback(object state)
{
clicks++; // added to check running
if (true)
{
long nowTime = savedTime;
long timePassed = nowTime - savedTime;
//user input
if (clickButtonFlag)
{
clickButtonFlag = false;
clicks++;
System.Diagnostics.Debug.WriteLine("clicked!" + clicks);
}
if (buyClickerButtonFlag)
{
buyClickerButtonFlag = false;
if (clicks > clickerCost)
{
clickers++;
clicks -= clickerCost;
clickerCost *= 1.6F;
}
System.Diagnostics.Debug.WriteLine("clicker bought!" + clickers);
}
//update vars
if (timePassed > TimeSpan.TicksPerSecond)
{
savedTime = nowTime;
nowTime = DateTime.Now.Ticks / TimeSpan.TicksPerSecond;
clicks += clickers;
}
}
}
I tested it on the device and buttons works.
On the other hand - what's the point of putting a method that waits for a flag buton click, when you can put the job easily to button click event. Let it happen when user clicked button - don't check buton state all the time.

Timer + display messages + Different time intervals

How to display some messages on a C# form application with different time intervals with buttons?
Something like:
private void button1_Click(object sender, EventArgs e)
{
label1.Text = "string1";
[wait 3 seconds]
label1.Text = "string2";
[wait 5 sec]
label1.text="string 3";
[end]
}
You can create a new thread, change the label text, sleep that thread and so on so forth:
using System.Threading;
// Somewhere in your Form, for example in Form_Load event:
new Thread(new ThreadStart(delegate {
var d = new setLabelTextDelegate(setLabelText);
label1.Invoke(d, new object[] { "string 1" });
Thread.Sleep(3000); // sleep 3 seconds
label1.Invoke(d, new object[] { "string 2" });
Thread.Sleep(5000); // sleep 5 seconds
label1.Invoke(d, new object[] { "string 3" });
})).Start();
private delegate void setLabelTextDelegate(string text);
private void setLabelText(string text)
{
this.label1.Text = text;
}
Use a Timer with an interval of X milliseconds and update the UI each Timer Tick. Keep track of the number of Timer Ticks received so you'll know which string to use. After each update has been processed stop the Timer.
Other solutions posted might be wiser, but this one is pretty simple.
Form1 contains a simple Label called Label1 and a button called Button1
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
t.Interval = 100;
t.Tick += new EventHandler(t_Tick);
t.Start();
}
Timer t = new Timer();
int counter = 0;
private void Button1_Click(object sender, EventArgs e)
{
t.Start();
}
void t_Tick(object sender, EventArgs e)
{
try
{
t.Enabled = false; //Disable timer so we don't start t_Tick when t_Tick is still runnnig
if (counter == 0)
{
label1.Text = "string1";
t.Interval = 3000;
}
if (counter == 1)
{
label1.Text = "string2";
t.Interval = 5000;
}
if (counter == 2)
{
label1.Text = "string3";
t.Stop(); //Stop timer
}
else
{
t.Enabled = true; //Resume timer
}
counter++;
}
catch (Exception ex)
{
MessageBox.Show("Never throw exception from timer..." + ex.Message);
}
}
To do exactly as your pseudo code suggest simply use Thread.Sleep() in place of your [wait x] lines. Note that it will likely make UI unresponsive for the duration of waiting.
Alternatively you can create a thread that does the same thing but doesn't block the UI thread. The only issue there is that you have to define delegate in UI thread otherwise it wont work.
private void button1_Click(object sender, EventArgs e)
{
ThreadPool.QueueUserWorkItem(delegate()
{
label1.Text = "string1";
Thread.Sleep(3000);
label1.Text = "string2";
Thread.Sleep(5000);
//etc...
});
}
private void button1_Click(object sender, EventArgs e)
{
label1.Text = "string1";
System.Threading.Thread.Sleep(3*1000);
label1.Text = "string2";
System.Threading.Thread.Sleep(5*1000);
label1.text="string 3";
}
Thank you sooo much.
Oh i love stakoverflow.com
I did something like this.:)
Thank you all gentle mens :)
Please comment how did i do? I actually wanted it all happen in click of button.
public partial class mainForm : Form {
public mainForm()
Timer myTimer = new Timer();
private void button1_Click(object sender, EventArgs e)
{
myTimer.Tick += new EventHandler(myTimer_Tick);
myTimer.Interval = 2000;
myTimer.Start();
}
int counter=0;
void myTimer_Tick(object sender, EventArgs e)
{
if (counter == 0)
{
label4.Text = "string1";
myTimer.Interval = 2000;
}
if (counter == 1)
{
label4.Text = "string2";
myTimer.Interval = 2000;
}
if (counter == 2)
{
label4.Text = "string3";
myTimer.Stop();
}
else
{
myTimer.Enabled = true;
}
counter++;
} }
I made it all work with valuable examples you all provided . i put it all together and got it working as i wanted.
Once again Thank you all :)

Categories

Resources