Decreasing Counter - c#

I am wondering how I can make a decreasing counter to replace a timer, as in the timer would start at 3, and decrease every second, until reaching zero, where it would preform an action. Any Help?
// Change Image from "Hut" to Mole \\
private void ChangeImage()
{
Image newImage = HoleImage();
molePopup = MoleImage();
int numCol = Convert.ToInt32(NumberOfColumns);
//Random Number - Col
Random randomColumns = new Random();
int ranCol = randomColumns.Next(1, numCol);
//Random Number - Row
Random randomRow = new Random();
int ranRow = randomRow.Next(1, NumberofRows);
string Moleimage = TUtils.GetIniFileString(Moleini, "ImagePath", "PictureFile", Root + "mole2.png");
//Populate Grid with Mole at Random Times \\
Grid.SetRow(molePopup, ranRow);
Grid.SetColumn(molePopup, ranCol);
grid_Main.Children.Add(molePopup);
molePopup.MouseUp += new MouseButtonEventHandler((o, e) =>
{
MolePoints++;
grid_Main.Children.Remove(molePopup);
});
}

I may be unclear, but as long as you only have the one thread in the program (and nothing going on otherwise), you'd use something like this:
for(int i = 3; i > 0; i--)
{
Thread.Sleep(1000);
}
doWhatever();
For each iteration of the loop, you "sleep" the thread 1000 milliseconds, or 1 second. To do this, you will need to include System.Threading with using System.Threading. If you're doing something in the background, use alternate methods instead of Sleep, since it locks the thread execution for the duration specified.
EDIT:
This is the MSDN documentation for Thread.Sleep() method. Seems to be very similar to what you want to do, if I take your meaning correctly.

Use DispatcherTimer
Set the interval property to 1000 (= 1 second)
Create a variable that represents your countdown timer
Create a tick event in which you check if your countdown variable is zero. If it is zero => stop timer and perform action. If not => decrease variable
Start the timer

Related

beginner trying to implement a timer in a for loop c#

I'm very new to c# and coding in general and am having some problems implementing a timer in a for loop. Basically, the bit of code below is trying to create a number representative of trash output by an island at set intervals, with each output weighted based on island population to be a bit less predictable. it then adds the generated trash figure to a total. The problem I'm having is that the way tutorials use the Timer class means creating an 'Intervaltimer_Elapsed(object sender, ElapsedEventArgs e)' function outside of Main() and I can't work out how to then add whatever is generated by this back to the weights[] array in the Main(). All I really want to do is as soon as the compiler goes into the for loop, tell it to wait 'x' ticks, then continue. Thread.Sleep isn't an option because this is to go in unity, so would interrupt other things. apologies if the code below is a bit gory!
{
class Program
{
public static double trashperstan8 = 600 * 3.21;
public static int population = 1000;
public static double trashperpersperday = 1;
public static double interval = 60;
public static double intperday = 1440 / interval;
public static double trashperint = population * trashperpersperday * (interval / 1440);
public static int weightnum = population / 200;
static void Main(string[] args)
{
double Trashlevel = new double();
double stand8sfilled = new double();
Timer intervaltimer = new Timer((interval / 30) * 1000);
Console.WriteLine(weightnum);
for (int inti = 0; inti < intperday; inti++)
{
/* at this point, I want to basically tell the code: each time you go
through the for loop, wait for x number of ticks then do the method */
Console.WriteLine(inti);
double[] weights = new double[weightnum];
Random rand = new Random();
for (int i = 0; i < weightnum; i++)
{
double weightcontrib = rand.NextDouble();
weights[i] = weightcontrib;
Console.WriteLine("{0}: {1}", Array.IndexOf(weights, weightcontrib), weightcontrib);
}
double finalweight = 2 * (weights.Sum() / weightnum);
Console.WriteLine("final weight " + finalweight);
double weightedtpi = trashperint * finalweight;
Trashlevel = Trashlevel + weightedtpi;
stand8sfilled = stand8sfilled + (weightedtpi / trashperstan8);
}
Console.WriteLine("trash level " + Trashlevel);
Console.WriteLine("stand8s filled " + stand8sfilled);
}
private static void Intervaltimer_Elapsed(object sender, ElapsedEventArgs e)
{
}
}
}
All I really want to do is as soon as the compiler goes into the for loop, tell it to wait 'x' ticks, then continue. Thread.Sleep isn't an option because this is to go in unity, so would interrupt other things.
Solution 1: Don't write a loop at all. The timer already is logically a loop.
Write a method that is the "body" of the "loop".
"Starting the loop" is activating a timer where the body method is the event handler and the timer fires every n milliseconds
"Terminating the loop" is deactivating the timer.
Solution 2: Write a loop, don't use a timer.
Make the method async and then await Task.Delay(whatever); to asynchronously wait for your delay. Your method will suspend when it hits the await, and resume at some point after the delay task is complete.
The latter is probably the better solution in that the code more closely resembles your description of it.
I don't know enough about Unity to say which is the better solution in their framework.

thread.sleep is messing with stopwatch

I'm using a stopwatch to know how long some operations run for points (game) system.
I'm defining it like this:
Stopwatch sekunde = new Stopwatch();
long tocke;
long glavnetocke;
long cas;
tocke and glavnetocke are points.
Then in "construct" I need to do this:
sekunde.Start();
Thread.Sleep(10000);
sekunde.Stop();
If I don't do Thread sleep for 10000 it won't work.
Later in event handlers I use it like this:
sekunde.Start();
viewer.Clear();
viewer.DrawBody(body, 10.0, Brushes.Green, 10.0, Brushes.Green);
sekunde.Stop();
cas = (long)sekunde.Elapsed.TotalSeconds;
tocke = tocke + ((cas / 10));
if (tocke > 200)
{
glavnetocke = glavnetocke + 1;
tocke = 0;
}
viewer is to draw body of the person standing in front of a camera.
If I leave thread.sleep to 10000 it will work, otherwise it will not. But I need this to go away, because it stops the whole program. Even thou it happens only after I press a button in my form, I need to wait 10sec, before starting. Was thinking of just adding loading screen, but it doesn't work, as it freezes the whole program, so it doesn't show the loading gif.
EDIT:
well, as you can see that "tocke = tocke +((cas / 10));
tocke is always 0 if I remove thread.sleep or even lower the sleep number. Does stopwatch need time to initialize or something?
I want to get time of how long the operation runs to a long type variable so I can then use it for ingame points calculating. (cas = (long)sekunde.Elapsed.TotalSeconds;)
By casting TotalSeconds as a long you are chopping off the fraction part. I've redone your example using doubles and it seems to work for me:
Stopwatch sekunde = new Stopwatch();
long glavnetocke = 0;
double cas;
double tocke = 0;
sekunde.Start();
sekunde.Stop();
cas = sekunde.Elapsed.TotalSeconds;
tocke = tocke + ((cas / 10));
if (tocke > 200)
{
glavnetocke = glavnetocke + 1;
tocke = 0;
}
Result
cas = 0.0000015 (on my setup)

Stop a looped thread method after x seconds

I'm creating a console game as simple as "I generate a random number, find it", but with many options.
My current code (without what I want here) is availlable on GitHub: https://github.com/crakmaniaque/trouvezmoi
What I want is to create a version of my game which will be timed, so the computer generates numbers, the user finds it, it generates a new one and the player have 90 seconds to find a max lot of random numbers. I can code this easily.
What I will need help is to stop the game (a thread) after 90 seconds and retrieve the number of answers founded from the thread. The Console.Title should also show time remaining. The attempt I've tried works, but the thread is not interrupted if console is asking for number input (Console.ReadLine()). But the timer is for the entire process, not only user input.
private static void timerb()
{
int t = 90;
for (int i = 0; i < 90; i++)
{
Console.Title = t + " seconds remaining";
Thread.Sleep(1000);
t--;
}
}
private static void cGame()
{
Thread t = new Thread(timerb);
t.Start();
while (t.IsAlive)
{
bool good = false;
int rnd = new Random().Next(0,10); // 0 and 10 are sample
while (!good)
{
try
{
Console.Write("Enter a number between x and y >");
int i = int.Parse(Console.ReadLine());
if (i == rnd)
{
good = true;
}
}
catch (FormatException)
{
Console.WriteLine("Invalid answer.");
}
}
}
}
I don't know much about threading and at that point I'm stuck.
Can someone help me with my problem? I'm using .NET 2.0.
Perhaps you are looking for a timer? You could register an event, that would fire after 90 seconds, that would run while the loop is happening. The documentation can be found here: Timer class MSDN documentation.
I believe the usage would be:
Timer timer = new Timer { Interval = new Timespan (0,1,30);
timer.elapsed += //function to fire to kill the app or the game
You'd need to make each console read with a timeout equal to the amount of time left in the game. That solves that issue.
Then, you need a way to signal the timerb thread to shut down when the main game loop has ended. I think the simplest way would be to end the game loop when the remaining time is <= zero. Alternatively, you could make timerb singnal the main thread to shut down when t == 0. Inter-thread communication is always complicated and error-prone, though.
You can signal the timerb thread to shut down by setting a volatile bool shutdown to true and by making timerb poll that variable and shut itself down.

Chow to count of 1/10 of a second

I am trying to figure out how to count 10 times each second and display it.
I have an int called countpoints which is what the user starts with points. Lets say 800.
I would like to drop 10 points each second but showing each point falling instead of every 10 points like my script below does.
here is how I have done so far:
if(miliseconds <= 0){
if(seconds <= 0){
minutes--;
seconds = 59;
}
else if(seconds >= 0){
seconds--;
countpoints = countpoints-10;
}
miliseconds = 100;
}
miliseconds -= Time.deltaTime * 100;
This runs in void update and here countpoints falls by 10 each second. but i would like to be able to show the numbers drop down like a stopwatch each second. How do i do that?
Any help is appreciated and thanks in advance :-)
You should use coroutine for that calculation instead of in Update(). It can be very easy with the coroutine. You just need to start croutine and then wait for 0.1 seconds and decrease counterpoints by 1. Again call that coroutine inside that to keep it running. Just add condition whenever you want to keep on calling it.
private int countpoints=800;
private float t=0.1f;
private int noOfSeconds=90;
private int min;
private int sec;
private int temp=0;
void Start ()
{
StartCoroutine(StartTimer());
}
IEnumerator StartTimer ()
{
yield return new WaitForSeconds(t);
countpoints--;
temp++;
if(temp==10)
{
temp=0;
noOfSeconds--;
}
min = noOfSeconds/60;
sec = noOfSeconds%60;
if(noOfSeconds>0)
{
StartCoroutine(StartTimer());
}
}
void OnGUI ()
{
GUI.Label(new Rect(100f,100f,100f,50f),countpoints.ToString());
GUI.Label(new Rect(100f,160f,100f,50f),"Time : "+min.ToString("00")+":"+sec.ToString("00"));
}
You could just do it in the Update method and decrement the points once every 100ms, you need to take care of not rounding things up or down as the error would be systematic and you'll get choppy results.
Using coroutines won't work as expected as the interval is not guaranteed.
private float _milliseconds = 0;
private int points = 800;
void Update()
{
_milliseconds += Time.delta * 1000;
if( _milliseconds > 100 )
{
points--;
//add updating GUI code here for points
_milliseconds -= 100;
}
}
You won't get choppy decrements as the _milliseconds are decremented by 100, so even if there are differences in the duration of the frames in the long run you'll get a proper handling.
One problem with the script is if frames take a lot more than 100ms consistenly , but if it takes that long you probably have bigger problems:D

What are my options for timing?

I'm making a TextBox control in XNA and do not have access to the GameTime class. Currently I am trying to simulate the blinking text cursor caret and have successfully done so using this code:
int deltaTickCount = Environment.TickCount - previousTickCount;
if (deltaTickCount < CursorBlinkRate && Selected)
{
spriteBatch.Draw(emptyPixel, new Rectangle(caretLocation, Rectangle.Y + 1, caretWidth, caretHeight), Color.Black);
}
else if (deltaTickCount > CursorBlinkRate * 2)
{
previousTickCount = Environment.TickCount;
}
However, I'm a bit wary of using Environment.TickCount. If the computer was running long enough, wouldn't the program eventually crash or produce unpredictable behavior when the tick count exceeded its integral size?
Does anyone know what Windows does? I imagine it would use the system clock. Would that be a more suitable solution? I imagine they used something like total milliseconds in to the second instead of the tick count, but I'm not sure.
Thanks for reading.
I generally use the system diagnostics timer in a lot of situations.
It's a pretty powerful tool which creates a timer for you with a lot of good controls.
using System.Diagnostics;
Stopwatch timer = new Stopwatch();
Then use inbuilt controls:
timer.Start();
if(timer.elapsedMilliseconds() > ...)
{ }
timer.Reset();
etc...
This would allow you to reset the timer?
When Evnironment.TickCount rolls over, deltaTickCount will end up being negative, so you know it has happened. The calculation then becomes:
if (deltaTickCount < 0)
deltaTickCount = int.MaxValue - previousTickCount + Environment.TickCount;
Without bothering with what would happen in the case of an integer overflow, simply change to:
int deltaTickCount =
Environment.TickCount > previousTickCount
? Environment.TickCount - previousTickCount
: CursorBlinkRate * 3;

Categories

Resources