Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
70 views
in Technique[技术] by (71.8m points)

javascript - Smoothly increase a variable

I'm making a game where you can earn money at a steady rate (ex. 50 dollars a second). However, when increasing "money", I want it to smoothly increase, not jump 50 dollars every second.

setInterval(increasemoney,1000);
function increasemoney() {
  money = money + moneypersecond;
}

My current strategy is to divide it into two categories; one where you earn 1 dollar per 1/moneypersecond seconds (where moneypersecond < 1000), and one where you earn y dollars per 0.001 seconds.

However, there are two issues; because I want to avoid floats, y has to be rounded, but that will lose precision. Edit: Floats are FINE! I can also increase precision by increasing the time between "updates" (which also makes it look less smooth, and only increases precision instead of removing the imprecision).

My questions:

  • Is this the right track?
  • How should I implement the solution? (Preferably in a way that removes imprecision)

Requirements: I want to avoid floats Edit: Floats are okay, and the more accurate the better.

question from:https://stackoverflow.com/questions/65942476/smoothly-increase-a-variable

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

1. common game loop

Here we build an example with a common start function that initializes your game, and an update function which is called every frame. Go ahead and change target in realtime to watch the output lerp to its destination -

let money;
let target;

// initialize
function start ()
{ money = document.forms.example.money
  target = document.forms.example.target
}

// each frame
function update (delta)
{ const next = lerp(Number(money.value), Number(target.value), delta/1e2)
  money.value = next.toFixed(2)
}

// helpers
function lerp (v0, v1, t, p = 1e-3)
{ const next = (1 - t) * v0 + t * v1
  if (Math.abs(v1 - next) < p)
    return v1
  else
    return next
}

function sleep (ms)
{ return new Promise(r => setTimeout(r, ms)) }

function time ()
{ let now = Date.now()
  let last
  return _ =>
  { last = now
    now = Date.now()
    return now - last
  }
}

async function loop ()
{ const deltaTime = time()
  await start()               // call `start` to initialize
  while (true)
  { await update(deltaTime()) // call `update` each frame
    await sleep(50)
  }
}

// run the game
loop()
<form id="example">
  target: <input type="number" name="target" value="3000">
  &larr; try a big value like <b>99999999</b><br>
  money: <output name="money">0.00</output><br>
</form>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...