If I have something like this:
var x = 1;
setInterval(function(){
if (x == "1") {x = "2"};
if (x == "2") {x = "3"};
if (x == "3") {x = "1"};
}, 250);
At the moment, the function runs the first if since it is inherintly true, then since the first if alters x to meet the conditions of the second if, it runs that as well, then does the same with the third and sets x all the way back to 1 How do I get each of the if functions to break out of the setInterval funtion so that after it has ran, the other ifs will not run? I've found how to do this with loops but not for functions. I understand that the above function would probably be better suited in a loop, but it's only an example for the sake of keeping the question short.
Use a ternary expression for this simple case:
var x = 1;
var interval = setInterval(function() {
x < 3 ? x++ : x=1
console.log(x)
}, 250);
// clears the interval after 5000 ms
setTimeout(function() {
clearInterval(interval)
}, 5000);
Related
I am currently studying if condition statement and it is one of my weakest topic ever. Here in this code below, there are two if conditions and I would like to know, how do we find the output of this? I know how to get the output when there is one if. But what about having two if?
function exercise3(){
var x, y, z;
x = 20;
y = 30;
z = 50;
if ((x - 10) < y) {
if (y - 5 > x) {
alert (z - x);
}
else {
alert (z - 5);
}
}
}
exercise3();
This is referred as Nested If statement. Basically you deal with the most outer block first before the going into the inner block. You would only go into the inner block if the condition in the statement is true.
Your statement condition is true
if ((x - 10) < y) {
...
}
Hence you would proceed to read through.
Take note generally to make it more readable better use If else statements rather than if alone as the execution will proceed to check the next if statement with is actually block one and block two (one by one) bringing about slow execution in long written statements.
Ref: https://www.w3schools.com/js/js_if_else.asp
Cheers, happy learning and happy coding.
That is the same as this, if it helps you understand better. The below snippet is just for example purpose, do not follow that. You need to use nested if conditionals.
function exercise3(){
var x, y, z;
x = 20;
y = 30;
z = 50;
// The first if and nested if from your snippet
if ((x - 10) < y) && (y - 5) > x) {
alert(z - x);
}
// The first if and nested else from your snippet
if ((x - 10) < y && (y - 5) <= x) {
alert (z - 5);
}
}
exercise3();
I am creating a game similar to Pacman. The game board is held in an array called "testLevel." Here, I am trying to code the ghosts and make them move one square per 5 second. What happens is that every 5 seconds the ghost function will be called, but the program runs so fast that the function gets called multiple times within that second when I only want it to run once then not run again until another 5 seconds. How can I fix this problem. Thanks!
var testLevel = [[0,0,0,0,0,0],[0,1,0,1,1,0],[0,0,1,0,1,0],[0,0,1,0,1,0],[0,1,4,1,1,0],[0,0,0,0,0,0]];
function draw() {
background(255);
var sec = second();
if (sec % 5 == 0) {
ghost();
}
}
function ghost(){
for(b=1; b <7 ;b++){// column
for (a=5; a>-1; a--){// row
if (testLevel[a][b] == 4 && testLevel [a-1][b] !== 0){
c = a;
d = b;
printBoard();
}
}
}
testLevel[c][d] =1;
testLevel[c-1][d] = 4;
}
It sounds to me like you want to use some sort of timing function, either
setTimeout(function, milliseconds)
---Executes a function, after waiting a specified number of milliseconds.
or
setInterval(function, milliseconds)
---Same as setTimeout(), but repeats the execution of the function continuously.
(From http://www.w3schools.com/js/js_timing.asp)
In this case, setInterval(ghost, 5000) in draw() should do the trick.
Instead of looping to determine 5 seconds, use setInterval:
var testLevel = [[0,0,0,0,0,0],[0,1,0,1,1,0],[0,0,1,0,1,0],[0,0,1,0,1,0],[0,1,4,1,1,0],[0,0,0,0,0,0]];
function draw() {
background(255);
var interval = setInterval(ghost, 5000)
function ghost(){
for(b=1; b <7 ;b++){// column
for (a=5; a>-1; a--){// row
if (testLevel[a][b] == 4 && testLevel [a-1][b] !== 0){
c = a;
d = b;
printBoard();
}
}
}
testLevel[c][d] =1;
testLevel[c-1][d] = 4;
}
Note: You can use clearInterval(interval) to stop the process.
My code below is supposed to draw a picture of a rock on the canvas at random times. But the code I currently have doesn't draw anything even after many refreshes. I also could do with loop round the mathRock function so that I get constant new random rocks without having to refresh the page, but I don't know which loop to use.
My code for the rock spawn is below:
var num;
var rock = new Image();
rock.src = "rock.png";
mathRock();
spawnRock();
function mathRock() {
var x = parseInt(Math.random()* 10);
document.getElementById("num");
}
function spawnRock() {
if (num == 2|| num == 4 || num == 6 || num == 8){
context.drawImage(rock, 500, 450);
} else {
}
}
Your mathRock function is a no-op: It assigns to a local variable and does a DOM query, but it doesn't do anything with that local variable or the result of the DOM query.
spawnRock will only ever see undefined for num, as you've declared it but never assigned a value to it.
It might be that mathRock was meant to assign to num rather than x, but it's unclear what (if anything) it was meant to do with the DOM query, or where context in spawnRock is meant to come from.
The document.getElementById("num") will look for an element with id="num", it doesn't do anything with the global variable num.
To make that work, you would assign the value to the variable. For calculating the random number, use the Math.floor method rather than parsing the number to a number:
function mathRock() {
var x = Math.floor(Math.random() * 10);
num = x;
}
However, you should rather return the value than using a global varible, and pass the value into the next function.
You can't use a regular loop to repeatedly change the image, you need a timer. Use the setInterval method for that.
var rock = new Image();
rock.src = "rock.png";
window.setInterval(function(){
var num = mathRock();
spawnRock(num);
}, 5000);
function mathRock() {
return Math.floor(Math.random() * 10);
}
function spawnRock(num) {
if (num == 2|| num == 4 || num == 6 || num == 8){
context.drawImage(rock, 500, 450);
} else {
}
}
I am trying to use Math.random to draw an image.
Though I know I haven't got it right.
I know I need a loop to go through the Math.random function, but don't know how to implement it. I also know I my spawnRock function isn't correct but do not know how to fix it. Any help?
This code also breaks my current drawImages.
var num;
function mathRock() {
var x = Math.floor((Math.random() * 10) + 1);
document.getElementById("num").innerHTML = x;
}
function spawnRock() {
if (num = 2, 4, 8){
context.drawImage(rock, 1500, 450);
} else {
}
var rock = new Image();
rock.src = "rock.png";
Here's a quick primer on Math.random
Math.random() * X will generate a random floating point number between zero up to (but not including) X. So Math.random*10 will generate, for example, 0.22, 1.56, 7.92 up to 9.9999999999.
If you need random integers, you can strip off the non-integer portion of the random number with parseInt( Math.random()*10 ) which will generate 0,1,2,3,4,5,6,7,8,9.
If you just want a random "coin-flip" (true or false) you can do that like this:
var randomTrueFalse=(Math.floor(Math.random()*2)==0);
If you need to do something randomly 3 out of 10 times then you can do that like this:
var thirtyPercentSuccess=( (Math.random()*10-7)>=0 );
Then use your desired version of the random number to choose whether to draw or do something else:
if (thirtyPercentSuccess){
context.drawImage(rock, 1500, 450);
}else{
// something else
}
mathRock is working fine, but I guess you should assing x to num variable: num = x then in spawnRock change the if condition to num == 2 || num == 4 || num==8 since == or === are used to compare and = to assign.
I don't know much about JavaScript, here is the code I have:
<script language="JavaScript">
var x = 10
function startClock() {
if (x !== ' ') {
x = x - 1
document.frm.clock.value = x
setTimeout("startClock()", 1000)
}
if (x == 0) {
x = ' ';
document.frm.clock.value = x;
success.location.href = "success.php";
}
}
</script>
<body onLoad(startClock);>
affected iframe:
<input name="clock" size="3" readonly="readonly"
<iframe name="success" src="blank.htm"></iframe>
when the timer counts down, success.php is loaded twice. I know thise because 1.)It inserts data into my DB twice, 2.)I can actually see the loading symbol in the tab reloading a second.
When I change the function to something like:
<script language="JavaScript">
var x = 10
var y = 1
function startClock() {
if (x !== 'Fin') {
x = x - y
document.frm.clock.value = x
setTimeout("startClock()", 1000)
}
if (x == 0) {
x = 'Fin';
document.frm.clock.value = x;
success.location.href = "success.php";
}
}
</script>
...the page is only loaded once.
Can anyone tell me what is happening here? I also tried using '0' in place of ' ' and got the same double execution...
In Javascript there are TWO comparison operators:
"==" -- means equal to
"===" means "exactly equal to" -- which means that the value and the TYPE must be the same
I suspect (although I dind't bother to test the theory) that if you use "===" rather than "==" in your original code you will find it works as you intended. However, there are a number of things that need fixing -- 1) you are inconsistent with using ";", 2) the code should be structured to ensure that on any given iteration it can only "restart" the timer OR fire the sucess and NEVER both. Here is a cleaner version:
<script language="JavaScript">
// 10 iterations at 1 second intervals
var x = 10;
function startClock() {
document.frm.clock.value = --x;
if (x <= 0) {
document.frm.clock.value = x;
success.location.href = "success.php";
} else {
setTimeout("startClock()", 1000);
}
} // startClock
</script>
<body onLoad(startClock);>
First a couple of things. There's a number of "sloppy" coding practices in your example (missing semicolons for instance). While the code may run, it could improve with some jslint help.
So look at the case when x = 1. You decrement x so now x = 0. You then call setTimeout which will wait 1 second and then call your method named startClock. However, setTimeout doesn't block your execution. So immediately after setTimeout is called with x = 0, the code below it is executed where you set x to ' ' (and load your page). Now one second after that code has run, your method is called again due to the timer firing. Since x is now ' ', the top block is skipped and you fall into x == 0 block a second time.
Change it to:
if (x == 0) { // note this is now first
x = ' ';
document.frm.clock.value = x;
success.location.href = "success.php";
} else if (x !== ' ') { // note the else/if
x = x - 1;
document.frm.clock.value = x;
setTimeout("startClock()", 1000)
}
Otherwise, when x is 1, a timeout for startClock() will be set, AND the location will be loaded. Then, the timeout will fire, loading the page again (since x = ' ' and ' ' == 0 returns true).
It is probably better practice to say:
if (x === 0) { // note the ===
x = ' ';
document.frm.clock.value = x;
success.location.href = "success.php";
} else if (x !== ' ') {
x = x - 1;
document.frm.clock.value = x;
setTimeout("startClock()", 1000)
}
Because you don't need the truth conversion that == does for you.
Your example with 'Fin' instead of ' ' worked, because on the startClock() call after the location had been loaded, x was 'Fin', and ('Fin' == 0) is false.