-1

I'm trying to create a program. The first step is to have a "health" variable that decreases by random amounts at random intervals. So a player might experience something like.

5 seconds
Lose 20 health
3 more seconds
Lose 25 health
2 seconds
Lose 10 health
etc.

Let's call these occurences Injuries.

I don't want to use setInterval for these Injuries, because I want to health lost and time between Injuries to be always changing. So I tried to use timeOut like so:

var health = 100;
var possibleInjuries = [20, 10, 25];
var possibleIntervals = [5000, 2000, 3000];
let random = Math.floor(Math.random() * 3);

setTimeout(decreaseHealth, possibleIntervals[random])

function decreaseHealth() {
  random = Math.floor(Math.random() * 3);
  var hit = possibleInjuries[random];

  health = health - hit;

  $("#health").text(health);

  //its this line that makes it rapidly go down infinitey, and go from 100% to -11758 or something.  So it fires the first time fine, but then instantly fires infinitely more times...
  //OOH, what, I get it.  Because set timeout is not relative!
  //so I need to look for a RELATIVE version of settimeout
  setTimeout(decreaseHealth(), possibleIntervals[random]);

}
<html>

<head>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
  <title>Eat the lettuce</title>
</head>

<body>
  <span>Health:</span><span id="health">100</span>%
</body>

</html>

The best way to explain the problem, or what I think is the problem is that timeout is not relative. So if a timeout is set for 5000, that's 5000 after the page loads, not after the function fires. So how do I make a relative version of timeOut so there will be a randomized delay before the decreaseHealth function fires again?

Barmar
  • 741,623
  • 53
  • 500
  • 612
DennisM
  • 359
  • 1
  • 3
  • 13
  • 2
    `setTimeout(decreaseHealth(), possibleIntervals[random]);` should be `setTimeout(decreaseHealth, possibleIntervals[random]);` VERY common mistake, and nothing to do with `setTimeout` as such, just to do with how to pass a function to another function rather than calling it straight away. – Robin Zigmond Dec 16 '22 at 22:05
  • You didn't correctly in the first call to `setTimeout`, so you apparently know the correct way to do it. Then you did it wrong the second time, that's why it wasn't delayed an additional 5 seconds. – Barmar Dec 16 '22 at 22:16

1 Answers1

1

setTimeout is already relative to the time at which it is called.

The problem with your code is that you've written:

setTimeout(decreaseHealth(), possibleIntervals[random])

This calls the decreaseHealth function immediately, instead of when the setTimeout completes. You need to change it to:

setTimeout(decreaseHealth, possibleIntervals[random])
Andrew Parks
  • 6,358
  • 2
  • 12
  • 27