GameTime and real time - c#

I am trying to fill a rectangle in 3 seconds of real time
I want the increment to be a constant value to look nice and not have acceleration
and I am having trouble understanding what to do
this is my code
// constant
// 1.0f = 100% of rectangle, 3 sec = 3000.0 miliseconds
float addValue = 1.0f/3000.0f;
public override void Update(GameTime gameTime)
{
newGameTime += gameTime.ElapsedGameTime.Milliseconds;
// once the percentage is set to 0 this starts
if ((percentage < 1))
{
// calculate value here in order to time
percentage += addValue;
}
}
I've been trying all kind of crazy math to get it right but i completely lost it. :(
I know I should be using gameTime or newGameTime but I'm lost

I assume thats your update / rendering function.
Let's say, for example, that since the last rendering, 300ms elapsed. That means you'd have to add 100%/3000ms * 300ms = 10% to your rectangle.
-> You're missing the elapsed time in the calculation:
percentage += addValue * gameTime.ElapsedGameTime.Milliseconds;

I may be completely wrong with this answer according to what ccKep just mentioned in his comment.
But just in case it's what you're looking for, I put this together.
The main idea is having a timer event controling the increment. Even if the code I'm submitting isn't appropriate, maybe the idea will apply.
public int percentage;
public int Percentage
{
get { return percentage; }
set
{
percentage = value;
if (Percentage >= 0 && Percentage < 100)
{
progressBar1.Value = value;
}
else
{
Percentage = 0;
timer1.Stop();
}
}
}
private void button1_Click(object sender, EventArgs e)
{
Percentage = 0;
timer1.Interval = 1000;
timer1.Start();
}
private void timer1_Tick(object sender, EventArgs e)
{
double addValue = 100 / 3;
Percentage += (int)addValue;
}

Related

Dynamic real-time graph calculation

I have a dynamic graph that plots every second with a timer on the X-axis ticking up and a calculation called battery discharge on the Y-axis. The battery discharge is a formula that uses the timer to calculate it so that over time the battery will eventually discharge to 0. The problem is that on the graph, it only shows and calculates the initial charge of the battery. How do I make it so that it dynamically calculates the charge every second.
Below is the code for the calculation of the battery discharge using the getter and setter.
public double dTime { get { return time; } set { time = value; batteryDischargeCalc(); } }
private double time;
private void batteryDischargeCalc()
{
bEnergy = (nVoltage * capacity * 3600)/1000000; //battery energy in megajoules
energyDischarge = bEnergy - ((motorPower/1000) * time ); //discharge after certain amount of time in megajoules
}
Below is the code that initiates the graph drawing.
private void button5_Click(object sender, EventArgs e)
{
graphStart = true;
globalTimer.timer.Start();
graphForm.Show();
battery.Capacity = Convert.ToDouble(textBox3.Text);
battery.Nvoltage = Convert.ToDouble(textBox4.Text);
battery.MotorPower = Convert.ToDouble(textBox5.Text);
battery.dTime = Convert.ToDouble(tCount);
Below is the code for the graph plotting. In the ticker.
private void Timer_Tick(object sender, EventArgs e)
{
if (graphStart == true)
{
graphForm.TimeGraph(tCount);
graphForm.chartGraph["Energy Discharge"].Points.AddXY(tCount, battery.energyDischarge);
}
else
{
tCount++;
resform.GiveTime(tCount);
}
}

fade window on close

How can I set time to run a for loop?
I'm going on fade a form on close and this is my code:
Time ftmr=new Timer();
//set time interval 5 sec
ftmr.Interval = 5000;
//starts the timer
ftmr.Start();
ftmr.Tick += Ftmr_Tick;
private void Ftmr_Tick(object sender, EventArgs e)
{
for (int i = 0; i <= 100; i++)
{
this.Opacity = 100 - i;
this.Refresh();
}
Dispose();
}
There are several things wrong in your code. First, you shouldn't use a loop to set the Opacity since it will only really do something after the event is handled entirely. Let the timer do the looping. Second, don't Dispose your form in the timer. It will get rid of all UI elements, so you can throw your form away...
Try this:
Time ftmr=new Timer();
//set time interval 5 sec
ftmr.Interval = 5000 / 100; // 100 attempts
//starts the timer
ftmr.Start();
ftmr.Tick += Ftmr_Tick;
double opacity = 1;
private void Ftmr_Tick(object sender, EventArgs e)
{
this.Opacity = opacity;
opacity -= .01;
this.Refresh();
if (this.Opacity <= 0)
{
ftmr.Stop();
}
}
Note that this code will take longer than 5 seconds to run due to the way the timer works. You might need to tweak the numbers a little bit.
This is one of the few cases where it is acceptable to hang the UI thread and use Thread.Sleep() instead. The Opacity property is immediately effective and doesn't require a repaint. Do so in the FormClosing event.
Be sure to start with the Opacity set to 0.99 so you don't get flicker from the native window getting re-created. Five seconds is too long, both to the user and the operating system, about a second is reasonable. For example:
public Form1() {
InitializeComponent();
this.Opacity = 0.99;
}
protected override void OnFormClosing(FormClosingEventArgs e) {
base.OnFormClosing(e);
if (!e.Cancel) {
for (int op = 99; op >= 0; op -= 3) {
this.Opacity = op / 100f;
System.Threading.Thread.Sleep(15);
}
}
}
}

Why when changing the comboBox item it's not changing the time counting in the correct way?

comboBox selectedindexchanged event:
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
updateTime = Convert.ToInt32(comboBox1.SelectedItem);
xpProgressBar1.Position = 0;
counter = 0;
panel1.Select();
}
Update method:
public void Update()
{
counter += 1;
int position = (int)Math.Round((counter / updateTime) * 100);
xpProgressBar1.Text = counter.ToString() + " %";
xpProgressBar1.Position = position;
if (counter == 10)
{
if (!backgroundWorker1.IsBusy)
{
timer1.Stop();
backgroundWorker1.RunWorkerAsync();
}
counter = 0;
}
}
Timer tick event:
private void timer1_Tick(object sender, EventArgs e)
{
Update();
}
In the combBox by default it's on the first item the number 10 then i can change and select the item with the number 30,50,60,120,300 and all this values are in seconds.
The timer1 interval is set to 1000
The problem is when it's on 10 by default when running the program or if i change it back to 10 in the comboBox it's working good. What it does it's counting 10 seconds and updating the progressBar(xpProgressBar1) by 10's i mean each second the progressBar move by 10 percentages. So after 10 seconds it's getting to 100 percentages.
But when i change the comboBox to the second item to 30 it should count now 30 seconds untill 100%
So i'm not sure in what steps it should move and how to do it. Same if i change it to 120 then it should move progress 120 seconds and again i'm not sure what steps and how to do it so it will get to 100%
What it does now for example if i change it to 120 i see it start counting to 120 by steps of 1 but then when it's getting to 10% it's jumping back to the start and not continue.
It should keep counting the whole 120 seconds untill 100%
If i change it to 30 i see it also counting by steps of 1 each time but again in 10% it's jumping to the start and not continue.
When it's on 10 it's counting by steps of 10 untill 100% so i wonder what should i do and how in the others if it's on 120 to step by 120 ? not logic. So tmake them all to step by 1 also the when it's on 10 ? And again how to do it so it will not stop a 10% and start over again.
Now i changed in the Update method the line if (counter == 10) to:
if (counter == updateTime)
So now if i change in the comboBox select 120 it will count in steps of 1 untill 120 but now when it will get the progressBar to 100% it will keep counting untill 120.
There is no sync between the 120 seconds and the 100% of the progressBar.
EDIT
The Update method:
private int _updateCounter;
public void Update()
{
counter += 1;
xpProgressBar1.Text = counter.ToString() + " %";
xpProgressBar1.Position = _updateCounter++ * 10;
if (counter == 10)
{
if (!backgroundWorker1.IsBusy)
{
timer1.Stop();
backgroundWorker1.RunWorkerAsync();
}
counter = 0;
}
}
This is called prescaler (frequency divider). You have single clock source (Timer) with fastest frequency using which you can achieve needed frequencies by skipping certain calls (events).
All you miss is that skipping:
private int _timer1Ticks;
private void timer1_Tick(object sender, EventArgs e)
{
if(_timer1Ticks++ >= int.Parse(comboBox1.Text) / 10)
{
_timer1Ticks = 0;
Update();
}
}
This way Update will be called exactly 10 times, disregard of combobox selection.
And to calculate progress:
private int _updateCounter;
public void Update()
{
xpProgressBar1.Position = _updateCounter++ * 10;
...
// do not forget to stop timer
if(_updateCounter == 10)
{
timer1.Stop();
_updateCounter = 0; // add some cleanup if using timer more than once
_timer1Ticks = 0;
...
}
}

Progressbar stops at +-90%

I am making a Q&A program where you have 15 sec to answer a question. The problem is that the progress bar is only filling like 90% and moves to the next question. I can put the code here but I have worked in Dutch so maybe it's difficult to understand.
private void volgendeVraagFormButton_Click(object sender, EventArgs e)
{
//button for going to next question
vraagFormulierProgressBar.Value = 0;
vraagFormulierTimer.Start();
}
private void vraagFormulierTimer_Tick(object sender, EventArgs e)
{
if (vraagFormulierProgressBar.Value < vraagFormulierProgressBar.Maximum)
vraagFormulierProgressBar.PerformStep();
//checks if the value is lower than 15 sec(max)
else
{ //stops the progress if the 15 secs are over and moves to next question
vraagFormulierTimer.Stop();
vraagFormulierProgressBar.Value = 0;
vraagFormulierTimer.Start();
}
}
Here's the same code with variable names in English:
private void nextQuestionFormButton_Click(object sender, EventArgs e)
{
//button for going to next question
questionFormProgressBar.Value = 0;
questionFormTimer.Start();
}
private void questionFormTimer_Tick(object sender, EventArgs e)
{
if (questionFormProgressBar.Value <questionFormProgressBar.Maximum)
questionFormProgressBar.PerformStep();
//checks if the value is lower than 15 sec(max)
else
{ //stops the progress if the 15 secs are over and moves to next question
questionFormTimer.Stop();
questionFormProgressBar.Value = 0;
questionFormTimer.Start();
}
}
Take a look at this: Disabling .NET progressbar animation when changing value?
So try to increment your progress bar by 2, then decrement by 1. That should fix the animation problem
Edit
Also, change this line
if (vraagFormulierProgressBar.Value < vraagFormulierProgressBar.Maximum)
to this
if (vraagFormulierProgressBar.Value + 1 < vraagFormulierProgressBar.Maximum)
Edit 2
OK, I've got it this time. First, set the maximum of your progress bar to 300 and the interval to 1 (You can fix the timing later). Next, replace the timer tick function with this:
if (progressBar1.Value < progressBar1.Maximum - 1)
{
progressBar1.Increment(2);
progressBar1.Increment(-1);
}
else
{
timer1.Stop();
progressBar1.Maximum = 10000;
progressBar1.Value = 10000;
progressBar1.Value = 9999;
progressBar1.Value = 10000;
System.Threading.Thread.Sleep(150);
progressBar1.Value = 0;
progressBar1.Maximum = 300;
timer1.Start();
}
Sorry about using the English names, I copied this out of my test form. Anyway, hope this helps!

How to count down time until timer's next tick?

I have 2 timers. One of them is counting each time it ticks; while using steady interval, or one randomly generated. Second timer counts down to next tick in first timer.
As of right now I am doing as such:
private void btnStart_Click(object sender, EventArgs e)
{
nextClick = int.Parse(nudClickInterval.Value.ToString());
if (nudPlusMinus.Value != 0) tmrClickInterval.Interval = random.Next( int.Parse(nudClickInterval.Value.ToString()) - int.Parse(nudPlusMinus.Value.ToString()), int.Parse(nudClickInterval.Value.ToString()) + int.Parse(nudPlusMinus.Value.ToString()));
else tmrClickInterval.Interval = int.Parse(nudClickInterval.Value.ToString());
tmrClickInterval.Start();
}
private void tmrClickInterval_Tick(object sender, EventArgs e)
{
if (nudPlusMinus.Value == 0) tmrClickInterval.Interval = int.Parse(nudClickInterval.Value.ToString());
else tmrClickInterval.Interval = random.Next(int.Parse(nudClickInterval.Value.ToString()) - int.Parse(nudPlusMinus.Value.ToString()), int.Parse(nudClickInterval.Value.ToString()) + int.Parse(nudPlusMinus.Value.ToString()));
tmrNextClick.Interval = tmrClickInterval.Interval / 10;
tmrNextClick.Start();
content++;
nextClick = tmrClickInterval.Interval;
label1.Text = content.ToString();
}
private void tmrNextClick_Tick(object sender, EventArgs e)
{
if (nextClick <= 0) tmrNextClick.Stop();
else
{
nextClick = nextClick - (tmrClickInterval.Interval / 10);
lblNextClickCount.Text = (nextClick / 100).ToString();
}
}
I am setting up an interval of my count down timer by using first timer's interval dividing by 10. The problem is that I keep getting some errors such as: Value '0' is not a valid value for Interval. Interval must be greater than 0. at line: tmrNextClick.Interval = tmrClickInterval.Interval / 10;.
I'm not sure how to avoid my errors so I figure there might be a better way of counting down time until next timer tick. Plus, I'd want a count down in nice steady interval instead but I am getting quite confused and not sure how to manage this problem.
Hope for some help.
System.Windows.Forms.Timer has an int intervall. Dividing a number which is samller than 10 by 10 results in 0 (integer division!).
Try to use System.Timers.Timer, it has an interval of type double, or check for 0 and assign 1 in that case.

Categories