Why does the x & y values not increment? - javascript

I am building a virtual joystick and this is part of the code that I made so that when the joystick is in between a certain value the x and y value will keep on incrementing by a certain value for instance when the joystick is between 1 and 20 for deltaX it will keep incrementing every second once or if it is in between 21 and 40 it will increment twice every second and I want it to keep incrementing and not staying at the same value of two. When I try this code, the x & y values just stick to 1, 2 or 3 and doesn't increment, could anyone suggest why this happens?
edit:
The If statements need to be outside the function as the joystick breaks and doesn't run if its inside.
if (joystick.deltaX() >= 1 && joystick.deltaX() <= 20) {
(function movex1() {
x = x + 1;
setTimeout(movex1, 1000);
})();
}
if (joystick.deltaX() >= 21 && joystick.deltaX() <= 40) {
(function movex2() {
x = x + 2;
setTimeout(movex2, 1000);
})();
}
if (joystick.deltaX() >= 41 && joystick.deltaX() <= 60) {
(function movex3() {
x = x + 3;
setTimeout(movex3, 1000);
})();
}
if (joystick.deltaY() >= 1 && joystick.deltaY() <= 20) {
(function movey1() {
y = y + 1;
setTimeout(movey1, 1000);
})();
}
if (joystick.deltaY() >= 21 && joystick.deltaY() <= 40) {
(function movey2() {
y = y + 2;
setTimeout(movey2, 1000);
})();
}
if (joystick.deltaY() >= 41 && joystick.deltaY() <= 60) {
(function movey3() {
y = y + 3;
setTimeout(movey3, 1000);
})();
}

When your code executes, joystick.deltaX() and joystick.deltaY() more likely have a value of 0, so no timeout is ever set.
Also, avoid so many ifs when you can just replace them with a division.
Why not use an interval?
var x = 0, y = 0;
// Execute every second
var intervalId = setInterval(function() {
x += Math.ceil(joystick.deltaX() / 20);
y += Math.ceil(joystick.deltaY() / 20);
}, 1000);
// Stop after 20 seconds
setTimeout(function() {
clearInterval(intervalId);
}, 20000)

Related

How do I have multiple set timeouts running at once?

This is more of a question on how I should approach my problem, and not what code to use. this is the general framework/simplification of my code. I can provide the actual code if needed. question is below, it is similar to the last question I asked as it is part of the same system that isn't working:
for (i = 0; i < 10; i++) {
var amt = 0;
function checktime() {
console.log(amt + " / " + i);
amt++;
if (amt <= 5) {
setTimeout(checktime, 3000);
}
}
checktime();
}
I want it to have all the set timeouts running at once, for each i. the console results in
0 / 0
0 / 1
0 / 2
...
0 / 8
0 / 9
1 / 10
2 / 10
3 / 10
4 / 10
...
13 / 10
14 / 10
I'd like it to look like this:
0/0
0/1
0/2
0/3
...
0/9
1/0
1/1
...
5/9
5/10
sorry for the long question, but how would I go about doing this?
Have a function inside checktime that runs a loop. Set up your variables, and then pass the count variable into the inner function again with your setTimout.
function checktime() {
// Set the amt variable to zero
let amt = 0;
// Set count to zero if it doesn't exist
function loop(count = 0) {
// Log the new data
console.log(`${amt}/${count}`);
// Increase the count
++count;
// If count hits 10 reset the count
// and increase the amt variable
if (count === 10) {
count = 0;
++amt;
}
// Call the loop function again and pass in the new count
// as a parameter
setTimeout(loop, 1000, count);
}
loop();
}
checktime();
There are 2 ways you can do this.
Using nested loops like this
for(i = 0; i< 10; i++){
for(j = 0; j < 5; j++) {
console.log(i + " / " + j)
setTimeout(3000)
}
}
Using recursion like this:
function setTimeout_recurse(amt, i) {
if (amt < 5) {
console.log(i + " / " + amt)
amt ++;
setTimeout(3000)
setTimeout_recurse(amt, i)
}
}
for(i = 0; i< 10; i++){
var amt = 0;
setTimeout_recurse(amt, i);
}
You'll notice that the base is now i not amt which makes more sense to be the base.

How to load a site depending on hours and minutes

I have four screens that I want to display in the following order.
Screen1(2 seconds) -> Screen2 (2 seconds) -> Screen3 (2 Seconds)
I also have a fourth screen which should only show when the time is between 05:55-06:05 and 17:55-18:05
In order to accomplish this my code looks like this till now:
function timecondition() {
var hours = new Date();
var minutes = new Date();
var h = hours.getHours();
var m = minutes.getMinutes();
var timecondition;
if((h == 5 && m >= 55) || (h == 6 && m <= 5) || (h == 17 && m >= 55) || (h == 18 && m <= 5)) {
timecondition = true;
}
else {
timecondition = false;
}
return timecondition;
}
$(document).ready(
function() {
setInterval(function() {
setTimeout(function() {
if(timecondition()) {
$('#show').load("http://localhost:8084/test/screen4");
}
else {
$('#show').load("http://localhost:8084/test/screen1");
}
}, 2000);
setTimeout(function() {
if(timecondition()) {
$('#show').load("http://localhost:8084/test/screen4");
}
else {
$('#show').load("http://localhost:8084/test/screen2");
}
}, 4000);
setTimeout(function() {
if(timecondition()) {
$('#show').load("http://localhost:8084/test/screen4");
}
else {
$('#show').load("http://localhost:8084/test/screen3");
}
}, 6000);
}, 6000);
}
);
Unfortunately it doesnt work like I want it to be.
When I start the webapplication at 05:54 the sequence(screen1->screen2->screen3)
But once the clock hits 05:55 it won't display the fourth screen, like it was in my intention.
When I start the application within the timecondition eg. at 05:56 it shows the fourth screen, but won't leave screen4 when the timecondition is not true anymore a few minutes later.
Is it because I need dynamic functions?
Couple of potential bugs there.
1. You are taking the time twice
Every time you call new Date() you are taking a snapshot of an instant. In this case they are only milliseconds away from each other, but it's a bug nonetheless.
var hours = new Date();
var minutes = new Date();
One object should be enough:
var now = new Date();
var h = now.getHours();
var m = now.getMinutes()
2. Your time condition is wrong
var timecondition;
if((h == 5 || h == 6 || h == 17 || h == 18) && (m >= 55 || m <= 05)) {
timecondition = true;
}
else {
timecondition = false;
}
return timecondition;
There is two problems with this:
a) It is hiding the function name from within. This is just a minor bug and doesn't affect the functionality here yet.
b) You are checking for hours and minutes independently. This IS a serious bug because it doesn't comply with your business logic.
That whole code above can be smarter rewritten as:
h = h % 12
return (h == 5 && m >= 55) || (h == 6 && m <= 5)
3. You reload the page every few seconds
The second argument to setInterval and setTimeout respectively is in milliseconds. So you are issuing a load every 2 seconds.
4. You are nesting timeouts within intervals
This basically means that every six seconds you are setting a timer for the next 2, 4 and 6 seconds. This is not really a bug, but unnecessarily complex. Why not set one interval for running every two seconds?
Here's some refactored and hopefully fixed code. Didn't try it out yet, though.
function slideshow() {
var screens = [
"http://localhost:8084/test/screen1",
"http://localhost:8084/test/screen2",
"http://localhost:8084/test/screen3"
];
var specialScreen = "http://localhost:8084/test/screen4";
// Contains the index of currently shown screen or -1
// when the special screen is shown
var currentScreen = 0;
// Cache the element here so we don't need to search for it every two seconds
var show = $('#show');
function timecondition() {
var now = new Date();
var h = now.getHours();
var m = now.getMinutes();
h = h % 12;
return (h == 5 && m >= 55) || (h == 6 && m <= 5);
}
function update() {
if (timecondition()) {
if (currentScreen != -1) {
show.load(specialScreen);
currentScreen = -1;
}
return;
}
currentScreen = (currentScreen + 1) % screens.length;
show.load(screens[currentScreen]);
}
setInterval(update, 2000);
}
$(document).ready(slideshow);
If you wanted different durations for the screens, you could do it roughly like this:
function slideshow() {
var screens = [
{url: "http://localhost:8084/test/screen1", t: 2000},
{url: "http://localhost:8084/test/screen2", t: 3000},
{url: "http://localhost:8084/test/screen3", t: 10000}
];
var specialScreen = "http://localhost:8084/test/screen4";
// Contains the index of currently shown screen or -1
// when the special screen is shown
var currentScreen = 0;
// Cache the element here so we don't need to search for it every two seconds
var show = $('#show');
function timecondition() {
var now = new Date();
var h = now.getHours();
var m = now.getMinutes();
h = h % 12;
return (h == 5 && m >= 55) || (h == 6 && m <= 5);
}
var step = 1000;
var screenTimer = 0;
function update() {
if (timecondition()) {
if (currentScreen != -1) {
show.load(specialScreen);
currentScreen = -1;
}
return;
}
if ((screenTimer += step) >= screeens[currentScreen].t) {
currentScreen = (currentScreen + 1) % screens.length;
show.load(screens[currentScreen].url);
screenTimer = 0;
}
}
setInterval(update, step);
}
$(document).ready(slideshow);

How to make a JS Counter & Reset?

I am trying to make a JS counter to reach a random number and reset it self once it reaches the number and repeat again in 5 seconds.
For example: Random Number is 0.05.
0.00 > 0.01 > 0.02 > 0.03 > 0.04 > 0.05 > 0.00
<div id="current">0</div>
JS
var randomNum = Math.random();
if ( current <= randomNum ) {
for (current = 0; current < randomNum; current+=0.01) {
setInterval(function(){
current += .01;
},1000); } }
else {
current = 0;
}
You could use a closure over the variables and make a check inside of the callback, if greater then the wanted result.
This proposal uses setInterval for counting and setTimeout for the waiting time of 5 sec and the restarting with a new random value.
function startInterval() {
var randomNum = Math.floor(Math.random() * 8) + 2,
current = 0,
interval = setInterval(function() {
current += .01;
if (current > randomNum / 100) {
current = 0;
clearInterval(interval);
setTimeout(startInterval, 5000);
}
document.getElementById('current').innerHTML = current.toFixed(2);
}, 1000);
}
startInterval();
<div id="current">0</div>
Keep a counter variable outside of the loop and then simply clear it, when the desired value is reached.
var randomNum = Math.random() * 25;
var currentValue = 0;
var counter;
counter = setInterval(function() {
if (currentValue < randomNum) {
//Carefull with "0.1" as JavaScript doesn't like it!
currentValue = (currentValue * 10 + 1) / 10
}
if (currentValue > randomNum) {
currentValue = randomNum;
clearInterval(counter);
}
console.log(currentValue, '/', randomNum)
}, 1000 / 60)

Conway game of life in javascript( best sol [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
i am writing a code for conway game of life...... i am taking 2> arrays one fr old generation. and one for 2 nd genration.
**rules are : The universe of the Game of Life is an infinite two-dimensional orthogonal grid of square cells, each of which is in one of two possible states, alive or dead. Every cell interacts with its eight neighbours, which are the cells that are horizontally, vertically, or diagonally adjacent. At each step in time, the following transitions occur: **1.Any live cell with fewer than two live neighbours dies, as if caused by under-population.
2.Any live cell with two or three live neighbours lives on to the next generation.
3.Any live cell with more than three live neighbours dies, as if by overcrowding.
4.Any dead cell with exactly three live neighbours becomes a live cell, as if by reproduction.**
The initial pattern constitutes the seed of the system. The first generation is created by applying the above rules simultaneously to every cell in the seed—births and deaths occur simultaneously, and the discrete moment at which this happens is sometimes called a tick (in other words, each generation is a pure function of the preceding one). The rules continue to be applied repeatedly to create further generations.**
here is the code
I am getting a soln but i guess its not giving me the correct solution becuase its not checking the neighbors of the corners. i have marked that part
**
window.conway =
{
};
window.conway.maingame =
{
};
conway.maingame = function(width, height)
{
window.a = [];
this.width = width;
this.height = height;
this.map = new Array(width);
for( i = 0; i < this.width; i++)
{
this.map[i] = new Array(height);
}
console.log(this.map, "map")
}
conway.maingame.prototype.randomize = function()
{
for( y = 0; y < this.height; y++)
{
//console.log("enter for loop")
for( x = 0; x < this.width; x++)
{
if(Math.random() > .5)
{
i =true;
}
else
{
i = false;
}
//console.log("enter function")
this.set(x, y, i);
}
}
}
conway.maingame.prototype.set = function(x, y, val)
{
x = x % this.width;
y = y % this.height;
this.map[x][y] = val;
console.log(this.map, "map2");
}
conway.maingame.prototype.get = function(x, y)
{
x = x % this.width;
y = y % this.height;
return this.map[x][y];
}
*********************************************************************************
conway.maingame.prototype.neighbors = function(x, y)
{
count = 0;
if(x > 0 && y > 0 && this.get(x + 1, y + 1))
{
console.log(this.get(x + 1, y + 1), "value neighbor");
count++;
console.log(count);
}
if(x > 0 && y > 0 && this.get(x + 1, y))
{
console.log(this.get(x + 1, y), "vallue neighbor");
count++;
console.log(count);
}
if(x > 0 && y > 0 && this.get(x + 1, y - 1))
{
console.log(this.get(x + 1, y - 1), "vallue neighbor");
count++;
console.log(count);
}
if(x > 0 && y >=0 && this.get(x, y - 1))
{
console.log(this.get(x + 1, y - 1), "vallue neighbor");
count++;
console.log(count);
}
if(x > 0 && y > 0 && this.get(x - 1, y - 1))
{
console.log(this.get(x + 1, y - 1), "vallue neighbor");
count++;
console.log(count);
}
if(x > 0 && y > 0 && this.get(x - 1, y))
{
console.log(this.get(x + 1, y - 1), "vallue neighbor");
count++;
console.log(count);
}
if(x > 0 && y > 0 && this.get(x - 1, y + 1))
{
console.log(this.get(x + 1, y - 1), "vallue neighbor");
count++;
console.log(count);
}
if(x > 0 && y > 0 &&this.get(x, y + 1))
{
console.log(this.get(x + 1, y - 1), "vallue neighbor");
count++;
console.log(count);
}
return count;
}***
conway.maingame.prototype.newgeneration = function()
{
var newMap = new Array(this.width);
for( i = 0; i < this.width; i++)
{
newMap[i] = new Array(this.height);
}
for(var y = 0; y < this.height; y++)
{
for(var x = 0; x < this.width; x++)
{
console.log("enter all for");
newMap[x][y] = this.get(x, y);
console.log(newMap, "newarray");
//Rule 1: any live cell with fewer than two live neighbors dies
if(this.get(x, y) == true && this.neighbors(x, y) < 2)
{
newMap[x][y] = false;
console.log("rule1");
}
//Rule 2: Any live cell with two or three live neighbours lives on to the next generation
if(this.get(x, y) == true && this.neighbors(x, y) == 2 || this.neighbors(x, y) == 3)
{
newMap[x][y] = true
console.log("rule2");
}
//Rule 3: any live cell with more than three live neighbors dies
if(this.get(x, y) == true && this.neighbors(x, y) > 3)
{
newMap[x][y] = false;
console.log("rule3");
}
//Rule 4: any dead cell with exactly three live neighbors becomes a live cell
if(this.get(x, y) == false && this.neighbors(x, y) == 3)
{
newMap[x][y] = true;
console.log("rule4");
}
}
}
this.map = newMap;
console.log(this.map,"new generation")
}
**
I trawled through your code in JSHint and fixed all of the issues, wrote some glue to test it in the browser and here's the result: jsfiddle.
It looks like it's working to me, so I think the problem must have been due to one of the dozens of warnings that JSHint flagged up.
Re: your assertion that the issue was due to the corners, that's what these lines are for:
x = x % this.width;
y = y % this.height;
In my test case I'm using a 10 x 10, so when it comes to check the neighbours of (9,9) it looks at (10, 10) and (10 % 10, 10 % 10) is (0, 0), thus avoiding looking outside the array. I believe this is what's known as a toroidal array.
The lesson we learn from this? Keep on top of the small issues, and the big issues will take care of themselves.

Javascript Closure question

Why the following code prints "0 5 10 15 20 ... 100"?
(function () {
for ( var i = 100; i >= 0; i -= 5) {
(function() {
var pos = i;
setTimeout(function() {
console.log(" pos = " + pos);
}, (pos + 1)*10);
})();
}
})();
I declare pos = i , which should be in a descending order. This code originated from John Resig' fadeIn() function in his book Pro javascript techniques.
You're registering the timeouts in the correct order, the problem is they're timed in order of their value, so value 10 will be printed in 100ms, value 100 in 1000ms, etc.
So you need to change the timing calculation to subtract from the max value (in this case, 100)
(function () {
for ( var i = 100; i >= 0; i -= 5) {
(function() {
var pos = i;
setTimeout(function() {
console.log(" pos = " + pos);
}, (100 - pos + 1)*10); // note the subtraction here
})();
}
})();

Categories

Resources