Timing actions in js (frame per second) - javascript

I'm doing a little mini-game and I need to do some animations (like frames per second), so far I manage to do this on my own:
var loadCount = 0;
var ticks = 15;
function loadingLoop() {
loadCount++;
}
switch (loadCount) {
case 1:
$("#img").attr("src", "src/images/cenario/img004.png");
break;
case 2:
$("#img").attr("src", "src/images/cenario/img005.png");
break;
case 3:
$("#img").attr("src", "src/images/cenario/img006.png");
break;
// etc.... //
}
setInterval(function(){
if (loadCount >= 6 && loadCount <= ticks){
loadingLoop();
if (loadCount === ticks) {
clearInterval();
}
console.log(loadCount);
}
}, 500);
So I would like to know if there is a better way to do this.

Because the numbering of your images is so clearly linked to the loadCount you could cut down the lines of code needed. Instead of having to spell out each instance in a switch you could simply have something like this:
$("#img").attr("src", "src/images/cenario/img" + (loadCount+3).toString().padStart(3, '0') + ".png");
padStart takes a string which represents a number and pads it at the start with a character, in this case we've asked for 0s to be put at the front. The 3 indicates that we want 3 digits.
The other thing I noticed in your timing function is that you do not save your setInterval, but you try to clear it. Depending on what you are trying to do you probably need something like:
let interval = setInterval(function(){
if (loadCount >= 6 && loadCount <= ticks){
loadingLoop();
if (loadCount === ticks) {
clearInterval(interval);
}
console.log(loadCount);
}
}, 500);

Related

Number is not incrementing by 1 in JavaScript

I have this code where if the opacity is less than or equal to 0, the message number is suppose to go up by 1, but when I run the code, the message number increases by 77 or 152 or 66, etc. Could you help me?
My code:
//variables
var x = 0;
var opacity = 0;
var messageNumber = 0;
var talk1 = ["hello", "welcome to idle ball", "potato"];
var lol = 1;
//set opacity to 1
function opacitySet1(speed) {
document.getElementById("talk").style.opacity = opacity;
opacity += speed;
}
//set opacity to 0
function opacitySet0(speed) {
document.getElementById("talk").style.opacity = opacity;
opacity -= speed;
}
function IntervalManager(flag, animate, time, para1) {
if (flag) {
var intervalSet = setTimeout(animate, time, para1)
}
}
function IntervalManagerII(flag, animate, time, para1) {
if (flag) {
var intervalSetII = setTimeout(animate, time, para1)
}
}
//to delay time
function nothing() {}
function message(startPart) {
document.getElementById("talk").innerHTML = messageNumber;
if (opacity >= 0 && lol == 0) {
setTimeout(nothing, 1);
IntervalManagerII(true, opacitySet0, 300, 0.005);
IntervalManager(false)
}
if (opacity <= 1 && lol == 1) {
IntervalManager(true, opacitySet1, 300, 0.005);
IntervalManagerII(false)
}
if (opacity <= 0) {
lol = 1;
IntervalManagerII(false);
messageNumber += 1;
} //this is the part that is not working
if (opacity >= 1) {
lol = 0;
IntervalManager(false);
}
};
setInterval(function() {
message(0)
});
New answer
After discussing in the comments, it turns out you think JavaScript timers are blocking the execution of the main thread. It does not work this way. Consider the following example (2 is printed almost instantly, and 1 is printed after one second).
> | setTimeout(function(){console.log(1)}, 1000);
| setTimeout(function(){console.log(2)}, 0);
< | ...
| 2
| 1
Also read this article from jQuery's creator.
Since your code is based on a wrong assumption, I think it makes no sense to work on your question any longer.
Old answer
Your setInterval timer is running a lot faster than your setTimeout timers, meaning that it queues a lot of setTimeout timers before starting to increment the opacity. During this time, the message is incremented and printed at interval max speed. After a couple of ms, all setTimeout timers start firing one after the other with almost no delay between them, and interleaving with setInterval timers, which leads to an (almost) unpredictable mess.

How to make a random number appear as many times as I want

So I want a random number (picture) from a code below to appear as much time as I want. In this case I am dealing with pictures. Let' say I want to make a picture named 1.png just to be printed on screen 4 times excatly and then let's say pictures 5.png and 6.png all together to be returned 10 times (it can be 3 times 5.png, 7 times 6.png and other ways we can get to 10) and so on for other examples. How can I do it, since I have no idea at all ?
I hope I explained the right way what I want, and I hope anyone can help, thank you for your help.
function RandomImage() {
return (Math.ceil(Math.random() * 10)).toString() + ".png";
}
If you want to duplicate a string you could use a function like this
function repeat(item, number=1) {
return Array.from({length: number}).fill(item)
}
You can then call it like:
repeat(RandomImage(), 3) // -> ["1.jpeg", "1.jpeg", "1.jpeg"]
You can do this by setting up a datastructure which keeps track of how many times a specific number has already been returned.
For this purpose we can utilize JavaScript's Map object.
So the basic idea is this:
Inside the random number function we generate a random number
Look into the map how many times we already returned that number
In case it matches e.g. 1==10 times we go back to step 1
If there's no match increment the map entry for the given number and ultimately return the number
Here's an example:
let randomNumbers = new Map();
let maxNumbers = 10;
for (let a = 0; a <= maxNumbers; a++) {
randomNumbers.set(a, 0);
}
function RandomImage() {
let failed = false;
let random;
do {
failed = false;
random = Math.ceil(Math.random() * maxNumbers);
switch (random) {
case 1:
if (randomNumbers.get(1) == 4) {
failed = true;
}
break;
case 5:
if (randomNumbers.get(5) + randomNumbers.get(6) == 10) {
failed = true;
}
break;
case 6:
if (randomNumbers.get(5) + randomNumbers.get(6) == 10) {
failed = true;
}
break;
}
}
while (failed);
randomNumbers.set(random, randomNumbers.get(random) + 1);
return random.toString() + ".png";
}
for (let a = 0; a < 50; a++) {
console.log(RandomImage());
}

JS Function Calls from HTML + Reactive display

The game is WAR, or Get Your Neighbour, a traditional game utilising a standard deck of 52 cards, no jokers. Currently the code recognises when a card is above 10 and so the rules of the game are being followed, all that is great, I've designed a timer that takes the value of the card 2-14, subtracts 10, then uses that number for the round of turns the other player has to draw above 10 before you win. Still building the cooperative/multiplayer element but for now, I'd just like to get this bloody button working!
When I click it, it does nothing. Before, it would tell me that "'timerf' is not a function". I'm probably doing something very obvious like problems with the order that things are loaded/data is parsed, but I'm still learning so I'd appreciate any help! Any questions, let me know.
var card = null; // setem 160517
var timer = null; //
window.onload = function() {
function draw(min, max) { // draw a card between 2-14
card = document.getElementById("draw").innerHTML = Math.floor(Math.random()*((max - min)+1) + min); // min 2, max 14
if (card > 10) {
timer = card - 10;
timerf(timer);
} else if (card < 11 && timer > 0) {
timer = timerf(timer-1);
}
} // draw
//draw(2,14);
document.getElementById("clickMe").onclick = draw(2,14);
} // window.onload
function timerf(timer) { // print turns to win
if (timer > 0 && timer < 5 && timer != 1) { // print turns to win
console.log("you have " + timer + " turns to win!");
} else if (timer == 1) {
console.log("you have " + timer + " turn to win!");
}
}
<div id="draw"></div>
<button id="clickMe">WAR!</button>
The return value of the draw function is undefined because it has no return statement.
document.getElementById("clickMe").onclick = draw(2,14);
… so you are assigning undefined to the onclick property.
You have to assign the function you want to call.

Javascript countdown then count-up from a prompted variable?

Please Help! I'm new to Javascript, so there's probably an easier solution to this. Basically, I need it to prompt for a number and then count down from that number to zero. Once it reaches zero, I need it to count-up and stop at the same prompted number.
I got it to count down at first, then I completely butchered it, I have no clue what to do.
<script type="text/javascript">
// get number from user
var startNum = parseInt(prompt("Input a number to start counting down from.",""));
var counter = setInterval(timer, 1000);
console.log(startNum);
function timer() {
startNum--; // reduce number by 1
console.log(startNum);
if (startNum <= 0) {
clearInterval(counter);
}
}
var counter = setInterval(timer2, 1000);
var endNum = 0
function timer2() {
console.log(endNum)
endNum++; // add number by 1
console.log(endNum);
if (endNum >= startNum) {
clearInterval(counter);
}
}
</script>
You've got a couple issues here. the first one was pointed out by Rob in the comments. You're running both functions at the same time.
The other issue you have is that you're never storing the number. You're just subtracting and adding to nothing essentially.
So -
<script type="text/javascript">
// get number from user
var startNum = parseInt(prompt("Input a number to start counting down from.",""));
var currentNum = startNum;
var counter = setInterval(timer, 1000);
function timer() {
console.log(currentNum);
currentNum -= 1; // reduce number by 1
console.log(currentNum);
if (currentNum == 0) {
clearInterval(counter);
counter = setInterval(timer2, 1000);
}
}
function timer2() {
console.log(currentNum)
currentNum += 1; // add number by 1
console.log(currentNum);
if (currentNum == startNum) {
clearInterval(counter);
}
}
</script>
Something like this should do the trick. Basically creating another variable to hold your start number and consider that the current number and the value that is going to change.
here's a fiddle - http://jsfiddle.net/w5FM6/
cheers

How to grow number smoothly from 0 to 5,000,000

This is probably basic math that I don't seem to remember.
I'm trying to get from 0 to 5,000,000 in 10 seconds while having all the numbers ticking. I don't have to have the number reach exactly 5,000,000 because I can just do a conditional for it to stop when it's over.
Right now I have this:
count+= 123456
if (count > 5000000) {
count = 5000000;
}
It gives the sense of number moving you know? But It really starts off too high. I wanted to gradually climb up.
You could do something like this:
function timedCounter(finalValue, seconds, callback){
var startTime = (new Date).getTime();
var milliseconds = seconds*1000;
(function update(){
var currentTime = (new Date).getTime();
var value = finalValue*(currentTime - startTime)/milliseconds;
if(value >= finalValue)
value = finalValue;
else
setTimeout(update, 0);
callback && callback(value);
})();
}
timedCounter(5000000, 10, function(value){
// Do something with value
});
Demo
Note that with a number as big as 5000000 you won't see the last couple digits change. You would only see that with a small number like 5000. You could fix that; perhaps by adding in some randomness:
value += Math.floor(Math.random()*(finalValue/10000 + 1));
Demo with randomness
You can tween:
import fl.transitions.Tween;
import fl.transitions.easing.Regular;
var count = 0;
var tween:Tween = new Tween(this, "count", Regular.easeInOut,0,5000000,10, true);
This will tween you variable count from 0 to 5000000 in 10 seconds. Read about these classes if you want to expand on this code.
Tween
TweenEvent
Good luck!

Categories