JSfiddle Lesson - Functions and Operators - javascript

below is a code from jsfiddles
http://jsfiddle.net/7n3rtpqo/3/
I am a little confused and do not fully understand the meaning of the operators '+=' and '-='. I would like to request the meaning in layman terms in the questions below.
Question 1 (refer to code //Question 1):
I do not understand this function to check if the train is going at top speed. Can this be explained? The explanation given is if it is greater than 10, then the train can go faster, so the next line subtracts 10 from the value of trainSpeed.
Why is the amount 10 and why subtract?
Question 2 (refer to code //Question 2):
Does this mean the train position is increased by 2px every time from its last updated position?
I am still fresh in learning JavaScript. Therefore, an explanation in layman terms wherever necessary would be nice as I am trying to make sense of it.
Thanks in advance!
var trainSpeed = 250;
var trainPosition = 0;
var animation;
var train = document.getElementById("train");
train.addEventListener("click", speedUp);
var stopButton = document.getElementById("stopButton");
stopButton.addEventListener("click", stopTrain);
//Question 1
function speedUp() {
if (trainSpeed > 10) {
trainSpeed -= 10;
}
console.log("train speed: " + trainSpeed);
clearInterval(animation);
animation = setInterval(frame, trainSpeed);
//Question 2
function frame() {
trainPosition += 2;
train.style.left = trainPosition + 'px';
console.log(trainPosition);
checkPosition(trainPosition);
}
}
function checkPosition(currentPosition) {
if (currentPosition === 260) {
alert("Crash!");
console.log("Crash!");
clearInterval(animation);
}
}
function stopTrain() {
if (trainPosition < 260) {
clearInterval(animation);
console.log("Whew! That was close!");
}
}

Hah. The code is deceptive. The train speed is not the train speed, it's the delay between each calculation of the train's position. This is evidenced in the line
animation = setInterval(frame, trainSpeed);
(The second parameter to setInterval determines how often the frame function is called, in milliseconds.)
If I was the author of the code, I'd rather rename the variable trainSpeed to trainDelay.

Related

How to make a counter that adds a specific number per second using javascript?

i have the following code, which should add 2.6 every second. But after the first add i get 8.
How can I fix this? On the tester here it works but on my page i get 8 https://260044-5.web1.fh-htwchur.ch/
Thanks in advance.
setTimeout(start, 0000);
var i = 2.6;
var num = document.getElementById('humans');
function start() {
setInterval(increase, 1000);
}
function increase() {
if (i < 100000000) {
i += 2.6;
num.innerText = Math.round(i);
}
}
<div id="humans">2.6</div>
<p>Menschen wurden geboren.</p>
You can try this. The main problem was your rounding off, you basically used Math.round() but yet you are dealing with a floating point data type. So just use YourNumber.toFixed(n) where n is the number of decimal points you want to show. You can check below. I just made your code shorter and brief but you can basically change the rounding off on your code and it should work..
setTimeout((function(){
var i = 2.6;
return function start() {
setInterval(()=> {
if (i < 100000000){
i += 2.6;
document.getElementById('humans').innerText = i.toFixed(1);
}
}, 1000);
};
})(), 0000);
<div id="humans">2.6</div>
<p>Menschen wurden geboren.</p>
You're rounding the value when setting the text:
num.innerText = Math.round(i);
If you want to show the value to the n'th decimal just use toFixed.
Example:
num.innerText = i.toFixed(1); /* will give you one number after the decimal point */
The code here it works, but in the link you posted, you have that in your script:
//funtion for humans born
setTimeout(start, 0000);
var i = 2.6;
var num = document.getElementById('humans');
function start() {
setInterval(increase, 1000);
}
function increase() {
if (i < 100000000) {
i += 2.6;
num.innerText = Math.round(i);
}
}
//funtion for trees cut
setTimeout(start, 0000);
var t = 475.646879756;
var t = document.getElementById('trees');
function startTwo() {
setInterval(increase, 1000);
}
You're executing start twice: one after "humans born" and the other after "trees cut".
Therefore you have two concurrent interval that execute increase twice every second, and each of the increase call is manipulating the same variables. That's why you got 8 immediately.
I'm not sure what's your goal here, but you either have different variables / function to increase every second for "humans born" and "trees cut", or you have one start call (and therefore one increase function called every second).
Anyhow, this is your mistake: if you want to clarify your logic; I / we can help further.

JavaScript How to make a count up timer with slowdown speed

I want to make a count up timer in my page.
It will set a target number and start from 0 to count up.
But I want to it with a slow down speed.
Start high speed, more and more slow to target number.
I can't find a good way or library to do this animate.
Can someone help me? Thanks.
You should use setInterval for this job, like below:
var counted = 0;
var target = 10; // 10 seconds
document.write("Counted : 0");
var i = setInterval(function () {
if (counted <= target) {
counted++;
document.write("Counted : " + counted);
} else {
clearInterval(i);
}
}, 1000);
Hope this works, I haven't tested it.

What is a better and more efficient way to do this blocking of a function?

var x = 2;
setInterval(function() {
while(z){}; //do nothing if z = 1, therefor stalling and blocking the next steps:
change(x++);
if (x > 39) x = 1;
}, 7000);
Somewhere else in program: A button is pause button pressed, toggling (xor-ing) z to either 1 or 0 to block the interval function. Otherwise if z == 0, skip this.
I am aware for a number of reasons this is inefficient and bad programming and can cause problems in JS but want to do something that accomplishes the same thing. I am a strong C programmer but javascript is brand new to me and none of my C approaches to this problem seem to be within my javascript abilities here. I basically am trying to pause the interval function when a pause button is pressed.
EDIT: The change() function is long and doesn't really matter, it could be an arbitrary set of instructions, thanks for the response
It would be better to store interval id
var x = 2;
var intervalID = setInterval(function() {
change(x++);
if (x > 39) x = 1;
}, 1000);
and when the pause button is pressed - use clearInterval to implement pause
clearInterval(intervalID);
https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/clearInterval

setInterval Speed Up | Javascript

I'm trying to gradually depreciate the interval in which the function inside a setinterval function is executed
Here's abstracted code for principle:
var speed = 100;
window.setInterval( speed-= 0.01 , speed);
Am I correct in believing the value for speed is taken once, on the first execution of setInterval and used, instead of being taken at every execution.
If so, how can I get around this? I verified this by setting the interval to 1000 and setting the "speed-=" to 999, and then printing the value for speed.
The value jumped from 1000 to 1 but then kept going down by 999, and even after the value became negative the functions inside setinterval were executed every 1 second.
An example of recursive call of setTimeout with changing interval.
function go() {
var node = document.createElement('div');
node.innerHTML = speed.toFixed(2);
document.body.appendChild(node);
if (speed > 1) {
setTimeout(go, speed);
}
speed *= 0.9;
}
var speed = 100;
go();

Run a function as far as a variable reaches specific values

I have a canvas game which calls a function incScore every time an action is performed in the game to increase the score.
Inside incScore I have a few if statements to draw a particular image to represent a level number on the canvas.
I also want to have a sound play once per level up. The way I've gone about things the lvlup sound will play every time the score matches the if statement.
Can anyone please help me get this so that the sound will only play once when the level changes and not again until the next level change? I'm also mention I'm using jQuery incase it has anything that could help me.
incScore(); //everytime an action in the game causes the score to increase
function incScore(){
if (scoreTotal < 500){
lvlimg = "L01";
drawLevel(lvlimg);
lvlupSound();
}
else if (scoreTotal > 500 && scoreTotal < 1000){
lvlimg = "L02";
drawLevel(lvlimg);
lvlupSound();
}
else{
lvlimg = "L03";
drawLevel(lvlimg);
lvlupSound();
}
}
You could shorten your function and use a semi static property to save the state. Using that, you can compare the current level to the previous and play a sound if they differ.
function incScore(){
incScore.level = incScore.level || 'L0'; //< initialize property
lvlimg = "L0" + scoreTotal < 500 ? 1 : scoreTotal < 1000 ? 2 : 3;
drawLevel(lvlimg);
if (incScore.level!=='L0' &&
incScore.level !== lvlimg) { lvlupSound(); };
// ^compare local level to current
incScore.level = lvlimg;
// ^ update local level
}
[edit, based on comment] The third line is a so called ternary, or conditional operator. See MDN. You can use more conditions.
To avoid playing a sound before the score has reached a first level, you could use
if (incScore.level!=='L0' && incScore.level !== lvlimg).
I've created a mockup jsFiddle
A simple solution could be comparing the current level to the old one, to detect when the level changed:
function scoreToLevel(score)
if(score < 500){
return 1
}else if (score < 1000){
return 2
}else{
return 3
}
}
function incScore()
var next_level = scoreToLevel(scoreTotal)
if(next_level !== current_level){
lvlimg = "L0" + next_level;
drawLevel(lvlimg)
lvlupSound()
}
}
The easiest solution is to factor the sound out of those if statements. If the levels are nice and regular like that(every 500 points) and the points always increase in a way that you will always land exactly on an even multiple of 500 when you level up, something like this should do:
if(scoreTotal % 500 === 0 && scoreTotal < 1001)
{
lvlupSound();
}
If you won't always land directly on the gate to the next level(maybe the player can earn anywhere between 1 and 15 points at a time) then you should be able to get by using something along the lines of this before you increment the player's score:
if( (scoreTotal % 500) > ((scoreTotal + increment) % 500)
{
lvlupSound();
}
if your level boundries are not regular like that obviously it gets a little bit more complex, but that should get you started.
That is because you have the in every statement for every score (which means from 0 to infinite).
You will need to write inner if statements such as;
if (scoreTotal < 500){
lvlimg = "L01";
drawLevel(lvlimg);
if(scoreTotal x times of each the level) // That means for each level completed
{
lvlupSound();
}
}
If your score increment is only 1, then only play the tone when the score equals the threshold for a new level.
If they can increase their score by more than 1, then you could pass the number of points in and check the score before and after to see if the numbers fall on each side of the threshold.
If that still doesn't work, some more info on the "level" and points would be appreciated.
Try something like this (demo):
var scoreTotal,
lastLevel = 0,
levels = [500, 1000, 2500, 5000, 10000, 25000, 50000, 75000],
currentLevel = 0,
lvlImg;
function incScore() {
while (scoreTotal > levels[currentLevel]) {
currentLevel++;
}
if (lastLevel !== currentLevel) {
lastLevel = currentLevel;
// gives a two digit number with a leading zero
lvlImg = ('0' + currentLevel).slice(-2);
drawLevel("L" + lvlimg);
lvlupSound();
}
}
Then you can easily add additional levels by adding the score cutoff to the levels variable.

Categories