I am writing a simple game where animations are done using a timer. Timer rate is initially set to 200, but for every 1000 points player gets I want timer to get faster, so I thought I could just decrease the interval
if (score > 0 && score % 1000 == 0)
{
GameTimer.Interval -= 20;
}
But when I reach score of 1000, winform crashes with following error on the line given above:
System.ArgumentOutOfRangeException: 'Value '0' is not a valid value for Interval. Interval must be greater than 0.
Parameter name: Interval
How can I correctly reduce the interval rate? (or make my program tick faster by any other means)
Edit: The code piece given above was placed inside the tick event, which caused if statement to execute several times
The error indicates that the Interval value has reached zero.
So these lines are executed several times until it crashes:
if (score > 0 && score % 1000 == 0)
{
GameTimer.Interval -= 20;
}
And that is because the condition is met in every interval after the timer passes the condition once.
Define your logic outside the timer code and you'll be fine:
void Score(int value){
score += value;
if (score <= 0) return;
if(score % 1000 == 0)
{
GameTimer.Interval -= 20;
//if(GameTimer.Interval <= 0) I suppose level is already finished...
}
}
edited
mjwills pointed out this issue that the interval still may hit zero. So you must write your code in a manner that eliminates this risk.
a non-linear reduction makes more sense in this case:
void Score(int value){
score += value;
if (score <= 0) return;
if(score % 1000 == 0)
{
GameTimer.Interval *= .9f;
if(GameTimer.Interval <= 0) GameTimer.Interval = 1;
}
}
The tick rate cannot be less than or equal to 0.
You could simply add an if statement to check that:
if (GameTimer.Interval <= 20) {
GameTimer.Interval = 1;
} else {
GameTimer.Interval -= 20;
}
However, this means that the timer interval will reach a limit after a certain score is reached. Also, the screen can't update that fast (1000 times a second). You should probably keep the frame rate at 30fps.
Therefore, to make the animation appear faster, do a larger proportion of the animation in each second. For example, to move something 1000 pixels to the right, don't move it 1 pixel every 1/1000 of a second. Instead, move it 50 pixels every 1/20 of a second.
From your comment:
The issue is that I do not understand why interval is going below zero, the if statement is executed only once, and it immediately gives me that error.
Then you are executing the if statement more than once. My guess is that you are running it in the timer tick event handler. Once your score reaches a multiple of 1000, that if statement will be run every time the timer ticks, until your score changes.
To fix this, you can put the code in the setter of the score.
the timer interval keep decrease until it reach to zero "0" that is your error
you can use
int x = (score/1000)*20
if (x < 200)
GameTimer.Interval = (200 - x);
Related
I have a car game when the car runs out the road, its healthbar will be decreased. But i want to slow down the decrease. How can I do it?
This is the current code.
for (int i = 20; i >= 0; i--)
{
if (car.getPosY() < 450 || car.getPosY() > 500)
{
car.hitPoints = car.hitPoints - 1;
// if (car.hitPoints <= 0) car.active = false;
}
}
But i want to slow down the decrease.
You will need to implement a timer for your car as follows: Whenever the car gets damaged, it has its health reduced and for a small time (say 1 second or 1000 ms) the car ignores all damage.
I have already questioned the use of the outer loop in the comments, so I won't dwell on that here. I am not using the loop as you have in your code.
Your car class needs to have a int variable for storing the time (in milliseconds) as shown
class Car
{
int Timer=0;
...//Other stuff you have already
}
Next change your logic as shown:
if (car.getPosY() < 450 || car.getPosY() > 500)
{
if(car.Timer==0) //This code happens once per second (according to the Timer value below)
{
car.hitPoints = car.hitPoints - 1;
// if (car.hitPoints <= 0) car.active = false;
}
car.Timer += gameTime.ElaspedGameTime.Milliseconds;//Value of time (in milliseconds) elasped from the previous frame
if(car.Timer >= 1000) //max value of time when damage is ignored. You can change this value as per your liking.
car.Timer = 0; //Reset the timer
}
else car.Timer = 0; //Reset the timer
I typed this code without testing. Let me know if there are any issues.
I'm trying to build a heart rate monitor, which I intend to code a mobile application around. Currently, I'm receiving the data in my application. Heres an example of the data:
However, I really would like to be able to remove the static element below the pulsating curve through some sort of high pass filter. Currently, I have the following code:
//HIGH PASS
//Fetch the next measurement item
j = float.Parse(Encoding.Default.GetString(e.Characteristic.Value));
counter++;
total += j;
if (counter % 5 == 0)
{
avg = total / counter;
total = 0;
counter = 0;
}
if (j < h || h > avg && h >= 0)
{
h = j;
}
else if (h <= 0) //Initially h is 0
{
h = j;
}
float g = j-(h-5); //This is the output
The code does to some degree work. What it does, is that it monitors the data and sets h=j if a lower value is present (by doing so, I constantly have the lowest point on the curve, which I can then remove).
Furthermore, for every 5 data points, a new average is put. Primarily to constantly check whether the filter is set too high. (i have roughly 6 data points every second)
The code is not really optimal. One of the major flaws is, if I remove my finger from the Heart rate sensor (j is being significantly lower), meaning that the curve will have almost no HR sine curve.
I could potentially add h=avg; to the counter if-statement. But that would cause the curve to constantly flicker up and down.
What are your suggestion guys? how can I tweak this?
i want to make a function.
every timer ticks it will flash green color
and every second timer ticks it will close green color.
i have a timer in my win forms which is 100 ms interval.
so
every 200 ms my color will flash as green..
can you help me about it
this doesnt work
var green = (((float)System.Environment.TickCount / 100) % 2) != 0;
if (green==true)
{
greenColor);
if (green==false)
{
noColor);
}
Because you have 2 states (color or no color) that swap each time I recommend to use a bool and just invert its value at the end of the timer-tick like so:
bool tick;
private void theTimer_Tick( object sender, EventArgs e )
{
if(tick)
{
colorLabel.BackColor = Color.Red;//Using label as example
}
else
{
colorLabel.BackColor = Color.Green;
}
tick = !tick;//Invert tick bool
}
This way you don't need the time of the counter and don't have to calculate all sorts of things.
You were almost there. Just don't use (float). Use integer arithmetic.
bool green = (System.Environment.TickCount / 100) % 2 == 0;
If you use floating point remainder (which I don't recommend), then your test should not be == 0 it should be < 1. Otherwise it'll only be green for 1 ms when the division remainder is precisely zero.
bool green = (((float)System.Environment.TickCount / 100) % 2) < 1;
I'm making a game with a score text and was wondering how I would write a script that doubles the points added to the score if some condition happens twice in a row? So far, I have a block that adds 2 points instead of 1 if the player gets the bullet in a certain region. The code is as follows:
if (-0.02f < transform.forward.x && transform.forward.x < 0.03f) {
perfectScoreText.GetComponent<Animator> ().Play ("PerfectHit");
currentScore += 2;
scoreText.text = "" + currentScore;
}
I was wondering how I'd make that code add two times as much as the user completes the condition twice/thrice/etc in a row.
Thanks.
Add a counter for perfect hit. Lets say perfectHitCounter. When perfect hit occurs increase this counter by one, if perfect hit fails make this counter zero. And when it reaches 2, add double score and reset the counter or if your game has the combo system you can increase the counter till you miss the perfect shot.
PSEUDO
I assume the code you provide is where the perfect hit happens.
if (-0.02f < transform.forward.x && transform.forward.x < 0.03f) //Perfect Hit
{
//Perfect hit
perfectHitCounter += 1;
//Add normal score if you wish
}
if('not perfect score condition')
{
perfectHitCounter = 0;
}
if(perfectHitCounter >= 2)
{
currentScore += 2;
//perfectHitCounter = 0; //If there is no combo system.
}
Hope this helps. Cheers!
I am programming a video game, and in it, I would like to call a method that adds a player bonus life for every 2,000 points scored. I have no idea what operator(s) to use for such a thing.
If (score is divisible by 2000, each increment){
DoSomething();
}
I'm not even sure if I'm asking this question correctly. Basically when the player scores 2,000pts, 4,000pts, 6,000pts, etc, I want to give him/her a bonus life by calling a method. I already have the method created; I was just wondering how I can apply the conditions that call it.
I tried using this:
public int bonusTarget = 2000;
paddle = GameObject.Find("Paddle").GetComponent<Paddle>();
if(score >= bonusTarget){
paddle.Bonus();
bonusTarget += 2000;
}
but, it awarded more than one bonus life each increment. I need to award the bonus life only one time for each 2,000pts
"score is divisible by 2000"
if (score % 2000 == 0) DoSomething()
If You need to track score use property instead of varilable eg.:
private int _score;
public int Score
{
get
{
return _score;
}
set
{
var a = Math.Floor(_score / 2000)
var b = Math.Floor(value / 2000)
if (a < b) DoSomething();
_score = value;
}
}
Put the if(score is divisible by 2000) check inside the DoSomething() method.
There's no reason to keep this outside the method that increases the bonus lives, in the dozens of possible code paths that increase the score. You need ONE CENTRAL location that the score increases, and checks various conditions.
You need a centralized location to add to the score, like this:
public void AddToScore(int points)
{
score += points;
if (score >= bonusTarget)
{
bonusTarget += 2000;
paddle.Bonus();
}
}
I switched the two lines inside the conditional block in case paddle.Bonus() tries adding points itself, which could cause issues, possibly even infinite recursion.
If you make it so you always add to the score using this method, you can add any special handling you want. You might also want to write a ResetScore() and a GetScore() so you never access score directly elsewhere in your code.