How do I fix my timer so it counts in seconds? - c#

I want my game's screen to have a timer on screen that shows how many seconds have passed (representing the player's point score). I am able to get the timer on screen, however, the counter freaks out and my console doesn't print the result correctly either. Any ideas?
I've tried to use timer.Elapsed however SplashKit (what i must use) does not seem to recognise that.
Sorry if this is a repeated question, I am new to programming and have searched around but couldn't find anything I could comprehend/assist.
public void Timer()
{
//begin timer and print results
timer.Start();
//write to console how many milliseconds have passed, and divide by 1000 for seconds.
Console.WriteLine($":{timer.Ticks} milliseconds have passed");
Console.WriteLine($"which is {timer.Ticks /1000} seconds");
//covert timer.Ticks to string and store into string 'score
score = Convert.ToString(timer.Ticks);
//assign font
Font Quicksand = SplashKit.LoadFont("Quicksand", "Resources\\fonts\\Quicksand-Regular.otf");
//use SplashKit to print to screen..
SplashKit.DrawText(score, Color.Black, Quicksand, 70, 700, 900);
}

+1 to Eric j's comment- all the Timer types the framework that I know of are not for providing stopwatch style "the game has been running 5 minutes" type functions directly themselves. They're classes that raise an event at some predefined interval. The actual timing of the game, if using a Timer, would be done by you by recording the start time and differencing the time now to it upon the timer elapsing it's interval:
public class Whatever{
private Timer _t = new Timer();
private DateTime _start;
public Whatever(){ //constructor
_t.Elapsed += TimerElapsed; //elapsed event handled by TimerElapsed method
_t.Interval = 1000; //fire every second
}
public void StartGame(){
_start = DateTime.UtcNow;
_t.Start();
}
private void TimerElapsed(){
Console.WriteLine("Game has been running for " + (DateTime.UtcNow - _start));
}
The timer interval merely controls how often the clock will update on screen. If you're offering game times of 10.1,10.2 seconds etc then make the timer interval less than 100 (updates more than once every 0.1 seconds) for example

It's not clear what type timer is, but the property Elapsed is probably a TimeSpan.
The total seconds including decimal amount is present in the double value:
timer.Elapsed.TotalSeconds
You can truncate that to an integer by casting it
var seconds = (int)timer.Elapsed.TotalSeconds;

Related

How to make powerup timer?

I want to make countdown timer that will return value of bool when he is active , so I can check on other script if is active give double points if is not then you need to give normal points..
I want to make it more complicated and I want to add time on timer if the timer is active, if is not then we use default time on countdown...
I don't know how to use courutine specially when I need to add time if the timer is not over..
Lets say like a example:
I pick up power up and timer starts for 5 seconds counting to 0.
If i pick up again powerup and timer is on lets say 3 , Power up need to have now 8 seconds. When powerup is over he must go from 5 seconds when player pick up new one..
Here is my code that doesn't work how I want also my code doesn't have a function to add time to power up when power up is active.. In other words I don't know how i can check if powerup is active and if yes just to add to counter 5 more seconds..
Here is code that doesn't contain adding time it only contains working counter..
void startDoublePoints()
{
StartCoroutine("doublePoints");
Time.timeScale = 1;
}
//Simple courutine
IEnumerator doublePoints()
{
while (true)
{
yield return new WaitForSeconds(1);
timeLeft--;
}
}
I hope someone will explain me more about how I can achieve my goal.. I hope I explained what I need to achieve.. If you do not understand something please ask on comment and I will try to explain it again..
Thank you so much community I don't know how would I learn anything without this great place :)
float powerUpTimer;
bool isDoublePoints = false;
void Update()
{
// Check timer only when Power up time
if(isDoublePoints)
{
// Countdown the timer with update time
powerUpTimer -= Time.deltaTime;
if(powerUpTimer <= 0)
{
// End of power up time
isDoublePoints = false;
powerUpTimer = 0;
}
}
}
// Add any time player picks to timer
public void OnPickPowerUp(float buffTime)
{
isDoublePoints = true;
powerUpTimer += buffTime;
}

How can I get better timed events for my games?

I have written an ordinary dispatcher timer method for creating a gameloop in WPF. I notice though that if it is set to a shorter interval than say 200 ms, it doesn't catch up correctly.
I printed the seconds to screen (see code below) and compared it to my wrist watch. With a setting of 500 ms, it's okay, but if I set it much lower there is a huge discrepancy. I tried a setting of 10 ms, and that meant that the time onscreen passed only 38 seconds in a (real) minute! (Note that all my game engine code was removed during testing, so it's just the timer loop that is called. Also, it doesn't matter if I run the code from VS or the exe file in the Debug folder.)
Note that the games I create run smoothly, it's just that my (standard) Each_Tick method doesn't get called at the correct times. This in turn means that my games will run faster on a faster computer.
So how do I keep correct track of time and make sure that the Each_Tick method fires at the same time, independently of the computer (or cellphone) used? That is, I would rather have a limit on the number of game objects, collision detection precision etc, but on time, rather than just going as fast as possible. Put differently, if I set the timer increment value to 50ms (which I think is reasonable as that would mean 20 times per second), I really want the game to be updated 20 times per second.
I really don't want to get into threading etc if it's possible to avoid it, as the games themselves run fine now. I just want them to play back at the same speed.
I looked up some great replies at How to control frame rate in WPF by using dispatcher timer accurately? but this still doesn't answer my question: how do I get my games to run at the same speed, regardless of (modern) computer/cell phone and whether it's WPF/UWP or perhaps something else?
Or is this impossible to do in a rather easy manner, and I should just accept that game speed depends on the computer used?
Thanks!
Code:
public void StartTimer()
{
//This variable is used to get to the controls (labels etc) of the MainWindow (WPF)
MainWindow mainWin = System.Windows.Application.Current.Windows.Cast<System.Windows.Window>().FirstOrDefault(window => window is MainWindow) as MainWindow;
time = TimeSpan.FromSeconds(0);
//What the code below does is this:
//For each 10 ms, call the different methods. Then add 10 ms to the current time.
timer = new DispatcherTimer(new TimeSpan(0, 0, 0, 0, 10), DispatcherPriority.Normal, delegate
{
if (runGame == false) return; //only go on if not in pause mode
mainWin.txtInfo.Text = time.ToString("mm\\:ss");//Shows the timer in a textbox, only showing minutes and seconds.
//Collision code etc removed during the test
time = time.Add(TimeSpan.FromMilliseconds(10)); //adds a specified time to the current time
}, System.Windows.Application.Current.Dispatcher);
}
Note that the code above was added for testing purposes. The original code (facing the same problems) looks like this:
public void StartTimer()
{
//A note on the dispatcherTimer http://www.wpf-tutorial.com/misc/dispatchertimer/
var timer = new DispatcherTimer();
timer.Interval = new TimeSpan(0, 0, 0, 0, 10); // Each every n milliseconds (set low to avoid flicker)
timer.Tick += EachTick;
timer.Start();
}
// A testing counter
int counter = 0;
// Raised every tick while the DispatcherTimer is active.
private void EachTick(object sender, object e)
{ etc
Build in timers are not very accurate. Use this code snippet. Ive used this timer many times. This timer is really accurate. Kudos to John
public class AccurateTimer
{
private delegate void TimerEventDel(int id, int msg, IntPtr user, int dw1, int dw2);
private const int TIME_PERIODIC = 1;
private const int EVENT_TYPE = TIME_PERIODIC;
[DllImport("winmm.dll")]
private static extern int timeBeginPeriod(int msec);
[DllImport("winmm.dll")]
private static extern int timeEndPeriod(int msec);
[DllImport("winmm.dll")]
private static extern int timeSetEvent(int delay, int resolution, TimerEventDel handler, IntPtr user, int eventType);
private readonly int _mTimerId;
public AccurateTimer(int delay)
{
timeBeginPeriod(1);
_mTimerId = timeSetEvent(delay, 0, TimerTick, IntPtr.Zero, EVENT_TYPE);
}
public void Stop()
{
timeEndPeriod(1);
System.Threading.Thread.Sleep(100);// Ensure callbacks are drained
}
private void TimerTick(int id, int msg, IntPtr user, int dw1, int dw2)
{
Console.WriteLine("Tick " + DateTime.Now.TimeOfDay.TotalMilliseconds);
}
}

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.

More Precise timer than Stopwatch?

I'm trying to have a stopwatch start and stop when recording positions for the Kinect:
//process x and y coordinates
public void calculateJoints(Skeleton skeleton)
{
Joint rightHand = skeleton.Joints[JointType.HandRight];
Joint leftHand = skeleton.Joints[JointType.HandRight];
rightX = rightHand.Position.X;
rightY = rightHand.Position.Y;
}
//start the stopwatch (tried to use a greater time between positions 1 and 5 vs 1 and 2
public void processJointsAndRepeat(Skeleton skeleton)
{
startTime();
while (numPositions < 5)
{
calculateJoints(skeleton);
numPositions++;
}
stopTime();
double tempTime = calculateTimeElapsed();
}
//calculate time in milliseconds
private double calculateTimeElapsed()
{
long milliseconds = stopWatch.ElapsedMilliseconds;
return (double)milliseconds;
}
But whenever I try to put in the x, y, and time values with time as the key, it throws an error for duplicate keys. When I retrieved the value of tempTime, it only showed 0.
Is this a problem with my code, or do I need a more precise stopwatch?
I realize that getting a time for something that is 30 fps is difficult, so if you have any other suggestions, that'd be great! I'm basically just trying to calculate the average velocities between points to adjust the playback speed of an audio file. Thanks!
Stopwatch is wrapper around timer with higerst resolution on regular Windows box. You can use less fancy functions to get higer than MS resolution by using Stopwatch.ElapsedTicks and Stopwatch.Frequency.
Note that your problem is probably not related to timers but rather some other code you did not show...

Adding delay in program C#

In my WP7 app, player draws a line and then CPU draws a line. I want CPU to wait for 5 sec before processing and drawing the line. I use this System.Threading.Thread.Sleep(5000);just after player is done drawing. But the player's line is not drawn completely and system goes to sleep and after 5 sec both lines are drawn. How to complete the player's line and then to start the delay ?
System.Threading.Thread.Sleep(5000) will freeze your app and your UI. Your app will surely not pass certification because of this.
Use DispatcherTimer.
Follow this link for more info.
You can use DispatcherTimer to add some delay immediately after the player's turn.
This is typically what you could do:
Class Variables:
DispatcherTimer delayTimer = new DispatcherTimer();
int timesTicked = 0;
In your Constructor:
delayTimer.Interval = new TimeSpan(0, 0, 0, 0, 5000);
delayTimer.Tick += new EventHandler(timer_Tick);
Handler:
void delayTimer_Tick(object sender, EventArgs e)
{
timesTicked++;
if(timesTicked == 2)
{
timesTicked = 0;
delayTimer.Stop();
RunCPU();
}
}
The above tracks the amount of times the Timer has ticked and after two ticks, it calls the RunCPU method. Note that the above will 10 seconds. You can play around with the numbers to find a niche for the delay.
Try with Application.DoEvents(); before sleep.

Categories

Resources