I have a simple little javascript count up timer on my page that I want to tweak, but really don't know where to begin.
The goal is that instead of it counting straight up in timed intervals is to have it jump randomly upward.
for example, if my timer is showing 100 and is set to increase again in 1 second, instead of it showing 101, I want it to show some random number between 101 & 106.
Any nods in the right direction would be greatly appreciated.
I appreciate the help you guys gave me (posts 1&2) ... but i'm still missing it somehow.
Here is the link to what i currently have... http://jsfiddle.net/FQSAH/19/
As you see it run, it's moving up by 1, but i'm wanting it to move up by a random number between 1&5 each time.
var x = 0;
setTimeout(function() {
// random interval between 1 and 10
var interval = Math.floor((Math.random() * 10) + 1);
x += interval;
}, 1000);
Tweak 10 as large as you want for a higher variability in intervals.
With a setInterval() you could schedule a function to run every second.
To get the random effect working, you could create a function to update a variable using Math.random().
For example:
var value = 0;
function randomize() {
value += (1 + (Math.random() * 5)); //random value between 1 and 5
}
setInterval(randomize, 1000);
Related
I am building a incremental game. I have a progress bar that fills up 1 point every second.. And when that bar reaches 10 points it resets back to 0..
The problem I am having is checking if the variable is 10 at all times. I am currently using setInterval to run the function every 10 milliseconds but I feel like this is not good for the website.
I have been trying to find a solution for this for months, can someone please help me out here..
In short: How do I check a variables value at all times without causing lag/inefficiency
So, to recap, you're running a setInterval at 10ms which task is just to check if the value of some variable equals 10. There's so many solutions, but hard to answer specifically without seeing any code.
Solution 1: Call a desired function immediately after where you increment your variable
const doTheMagic = (points) => {
console.log(`You reached score: ${points}`)
};
let points = 0; // Start at 0
const incrementPoint = () => {
points += 1;
if (points === 10) doTheMagic(points);
points %= 10; // Loop-back points to 0 when reaches 10
};
// You say you increment `points` at intervals of ~1000ms:
setInterval(incrementPoint, 1000);
Wait 10s... Then again 10s... etc...
Solution 2: Use setter
Solution 3: Use Proxy
I have been trying to create a function that generates a random number but I want this number to change every 5 minutes. Below is the code that I have tried:
function randNum(){
let randomNumber = Math.floor(Math.random() * 10);
const paragraphNew = document.createElement("p");
const watchNow = document.createTextNode(randomNumber + " are viewing this product now.");
paragraphNew.appendChild(watchNow);
const element1 = document.getElementById("cart-container");
element1.appendChild(paragraphNew);
}
When I try using the setInterval function like this:
let randomNumber = setInterval(Math.floor(Math.random() * 10), 5000);
I always get 1 as a result. I have also tried calling the function like this:
setInterval(randNum, 5000);
The problem is that a new paragraph is getting added everytime, without deleting the last one.
How can I make it work so I can generate the same number that lasts 5 minutes even after I refresh the page?
Ok) so basically when you refresh your page, all the variables and timeouts are reset. What comes to mind - you can store the variable in some sort of storage (ex. - localeStorage) along with creation date, then run your func with timeout like you did, but if you reload the page - look at storage first, and compare datestamp with current date)
Also keep in mind the things #Josh mintioned in his answer
You're returning the interval instead of the value it generates. Try something like this:
let randomNumber = 0;
setInterval(() => {
randomNumber = Math.floor(Math.random() * 10)
}, 5000);
alert(randomNumber)
Now you're updating the random number every 5 minutes. If you want to display the number every 5 minutes, add your log inside the arrow function. Let me know if you have anymore questions!
I missed the refresh the page part of your question. As #Nikita Mazur mentioned, local storage is the best way!
I have this problem that came up and I realized that I don't understand callbacks nearly as good as I should.
The way it's worded makes me think that I need to make it a set interval, but then you see that there is the syntax of "function randomExecution(callback) {}" and that really trips me up.
On top of all of this, this problem really makes me realize how inefficient I am at breaking down a problem into smaller parts. I see the "make sure it's on average about 1~2 times per minute" and I just get lost.
(I get that i can be less than 10 seconds that I have the min set to, but I'm pretty lost here and that was my only solution to make it so it doesn't get called within ten seconds)
What am I doing wrong here?
Also, any advice on how to approach questions like this would be greatly appreciated.
Cheers!
The Problem:
function randomExecution(callback) {
// start an interval that executes `callback()` at random intervals
// make sure it's on average about 1~2 times per minute
// make sure it doesn't execute twice within 10 seconds
}
My attempt:
function randomExecution(callback) {
const min = 10
const max = 120
const random = Math.floor(Math.random() * (max - min + 1) + min)
// callback = console.log('Wait for ' + random + ' seconds')
return random
}
setInterval(console.log(`hi, after ${randomExecution()} seconds`) , randomExecution)
The problem lies in the fact that you use the function SetInterval, which, as the name suggests, is used to call a specified function repeatedly after a fixed interval. A better approach would be to create a recursive loop with SetTimeout, where your code would look like this:
function example() {
console.log('See you soon!')
}
function randomExecution(callback) {
// start an interval that executes `callback()` at random intervals
// make sure it's on average about 1~2 times per minute
// make sure it doesn't execute twice within 10 seconds
const min = 30
const max = 60
var random = Math.floor(Math.random() * (max - min + 1) + min)
setTimeout(function() {
callback();
randomExecution(callback);
}, random * 1000);
}
randomExecution(example)
I'm trying to make a simple javascript game. Basically, you get pancakes at a certain amount per second. In the code, I call this value (the rate at which you get pancakes) pps. I want to make it so that as the HTML span tag that shows the total amount of pancakes gets more pancakes, (at the rate of pps), it ascends so it looks nicer.
For example, if I get pancakes at 5 pps, right now it just goes 0, 5, 10, etc... every second. I want it to go 0,1,2,3,4,5(1 second), next second 6,7,8,9,10, etc...
Here is the code that I have so far, for the pancake counter:
pps = 100;
tp = 0;
window.setInterval(function(){
tp += parseInt(pps);
document.getElementById("test").innerHTML = tp;
}, 1000);
Anyone know how to do this?
This is a problem common to all games, and one that you need to solve correctly for your game to work outside of your own computer.
The correct solution is that you need to measure the elasped time between each iteration of your game loop, or between each frame render. This is, in practice, going to be a very small number; you can think of this number as a "scaling factor".
If your game was about moving a space ship, and you wanted it to move 5 screen units per second, your game loop would:
Find the time elapsed since the last interval, in seconds. In a game rate-limited to 60 frames-per-second, this would be around 1/60th of a second
Multiply the ship's speed (5 units per second) by 1/60; the ship would move 0.8333... units this tick
move the ship by that amount.
By the time 1 full second has passed, the ship will have moved 5 units.
The exact same principal applies to your PPS.
The important part is that, in the real world, it will not be exactly 1/60th of a second between frames. If you're not computing the "scaling factor" each iteration of your loop, your game will slowly accrue error. setInterval is particularly bad for this, and not at all suitable as a source for time in a game.
The implementation in JavaScript is simple: Each game loop, record the current time from whatever source of time is available to you; in your case, you can use get Date().getTime(), which returns the time since the UNIX epoch in milliseconds. Record this value.
In the subsequent redraw, you will again call get Date().getTime(), and then subtract the previous value to the the elapsed time. That is your scaling factor, in milliseconds. You can multiply pps by that value to determine how many pancakes to add.
It's important that you still follow this approach, even if you're using setInterval. You might think you can simply setInterval(..., 1000 / 60) to invoke your callback 60 times per second, but setInterval (and setTimeout) are not accurate - they invoke your callback at least that far in the future, but potentially much further. You still need to scale pps by the elapsed times since the last redraw.
Here's a simple implementation:
var PPS = 5;
var lastTime = new Date().getTime();
var cakes = 0;
setInterval(function () {
var currentTime = new Date().getTime()
var elapsedTime = currentTime - lastTime;
lastTime = currentTime;
cakes += (PPS * (elapsedTime / 1000)) // elapsedTime is in milliseconds, divide by 1000 to get fractional seconds
document.getElementById('pps').innerText = cakes;
}, 10);
<div id="pps"></div>
As an aside, the incorrect solution is one you find in a lot of old games: Increment things as fast as you can. On old computers this was a viable solution; the game redrew slowly enough that the game would advance smoothly. As computers got faster, the game would run faster, until it became unplayable.
A simple interval timer would do the trick. Something like this:
function incrementToNumber(tag, currentNumber, targetNumber) {
var numTicks = targetNumber - currentNumber;
var interval = setInterval(function() {
currentNumber++;
tag.innerText = currentNumber;
if(currentNumber == targetNumber) {
clearInterval(interval);
}
}, 1000 / numTicks);
}
That particular function increments over the course of one second. To change the time it takes to increment, swap out the 1000 with whatever milliseconds you want it to take.
For a version that increases forever:
function inrementForever(tag, currentPancakes, pancakesPerSecond) {
setInterval(function() {
currentPancakes++;
tag.innerText = currentPancakes;
}, 1000 / pancakesPerSecond);
}
Let me explain what I'm trying to do.
I want to make a simple box which counts down numbers at intervals I specify.
For example, I'd like to set it to start at 150, and then I want to set it to drop by 15 every 30 seconds.
Is this possible with AJAX/Javascript? If so, could someone point me in the right direction?
Would really appreciate any help on this script, been Googling for hours now! :(
Cheers
Kieran
Have a look at the setTimeout or setInterval methods, they allow you to execute a function after a specified number of milliseconds (1000ms = 1second). Use that, to call a function that keeps dropping the number and writes it to a HTML element to the user can see it.
this isn't tested, but i hope it shows you the way to go.
var start = 150;
var drop = 15;
var interval = 30;
function countdown(){
document.getElementById('mybox').innerHTML = start;
start-=drop;
window.setTimeout("countdown",interval*1000);
}
countdown();
You may use jQuery to do that, see http://keith-wood.name/countdown.html -> tab Callbacks
Keep in mind that 30 seconds in my browser are not necessarily equal to 30 seconds in your browser. It depends on the workload of the browser.
The time difference is minor for a short time but can increase over a long time. The times will drift apart. If the times must not be equal (or nearly equal) between two visitors than such simple solution should be fine.
We had once a problem to introduce a live clock / countdown in one of our projects. We build a script with javascript, ajax and PHP for clock synchronisation (server time was timeserver).
You should use setInterval / clearInterval which is made for this kind of tasks:
function cooldown(element, start, stop, step, delay) {
var current = start;
element.innerHTML = current;
var timer = setInterval(function () {
current -= step;
if(current < stop) current=stop;
element.innerHTML = current;
if(current == stop) clearInterval(timer);
}, delay*1000);
}
Demonstrated here : http://jsfiddle.net/PCMHn/