In my project, I want my array to increase in size every 5 seconds. I tried to use setInterval to call a function to do this, but it resets my array every 5 seconds with an increased amount rather than naturally growing. Is there a way to increase the amount without having to reset the array each time?
These are the functions I am using to call my "plants":
var myPlants = new Array();
var plantSpawn = 0;
function createPlants() {
reproducePlants();
setInterval(reproducePlants, 5000);
}
function reproducePlants() {
plantSpawn += 5;
for(var i=0; i<plantSpawn; i++){
var rr = Math.round(Math.random() * 150);
var gg = Math.round(Math.random() * 255);
var bb = Math.round(Math.random() * 150);
var plant = new Object();
plant.x = Math.random() * canvas.width;
plant.y = Math.random() * canvas.height;
plant.rad = 2;
plant.skin = 'rgba('+rr+','+gg+','+bb+', 1)';
myPlants[i] = plant;
}
}
You are explicitly reseting all the values of the array when you do this:
for(var i=0; i < plantSpawn; i++){... myPlants[i] = plant; ...}
Note that plantSpawn will hold the new array size, so you are looping over all the old indexes plus the new ones and re-assigning the values on they.
So, instead you can add 5 new elements to the array with Array.push() this way:
var myPlants = new Array();
var plantsInc = 5;
function createPlants()
{
reproducePlants();
setInterval(reproducePlants, 5000);
}
function reproducePlants()
{
// Push N new plants on the array.
for (var i = 0; i < plantsInc; i++)
{
var rr = Math.round(Math.random() * 150);
var gg = Math.round(Math.random() * 255);
var bb = Math.round(Math.random() * 150);
var plant = new Object();
plant.x = Math.random() * canvas.width;
plant.y = Math.random() * canvas.height;
plant.rad = 2;
plant.skin = 'rgba('+rr+','+gg+','+bb+', 1)';
// Push a new plant on the array.
myPlants.push(plant);
}
}
And as a suggestion, you can even wrap the logic to create a new plant inside a method, like this:
var myPlants = new Array();
var plantsInc = 5;
function createPlants()
{
reproducePlants();
setInterval(reproducePlants, 5000);
}
function createPlant()
{
var rr = Math.round(Math.random() * 150);
var gg = Math.round(Math.random() * 255);
var bb = Math.round(Math.random() * 150);
var plant = new Object();
plant.x = Math.random() * canvas.width;
plant.y = Math.random() * canvas.height;
plant.rad = 2;
plant.skin = 'rgba('+rr+','+gg+','+bb+', 1)';
return plant;
}
function reproducePlants()
{
// Push N new plants on the array.
for (var i = 0; i < plantsInc; i++)
{
myPlants.push(createPlant());
}
}
You are overriding all the existing values so instead of using myPlants[i] = plant; use myPlants.push(plant)
You'll want to modify your function to add a plant onto an existing array, rather than looping over your array and assigning it new values.
if you want to add a new value to your array every 5 seconds, something like this should work:
var myPlants = new Array();
var plantSpawn = 0;
function createPlants() {
reproducePlants();
setInterval(reproducePlants, 5000);
}
function reproducePlants() {
var rr = Math.round(Math.random() * 150);
var gg = Math.round(Math.random() * 255);
var bb = Math.round(Math.random() * 150);
var plant = new Object();
plant.x = Math.random() * canvas.width;
plant.y = Math.random() * canvas.height;
plant.rad = 2;
plant.skin = 'rgba('+rr+','+gg+','+bb+', 1)';
myPlants.push(plant);
}
This just adds a new plant to the end of your array rather than assigning new values to your current array each time you call your function. From here you should be able to put that into a for loop if you wanted to add more plants than 1 at a time. each iteration of the loop will only add a single plan to your array.
Related
I am trying to make a function that randomizes the placement of some clouds I imported, but the problem is, it generates the amount of clouds, but in the same position! I randomized the position, but when the code runs I have like 10 clouds in the same position. What can I do? this is the code:
loader.load('/clouds/clouds1/scene.gltf', function (clouds1) {
var clouds1array = []
function addClouds1(){
for (var i = 1; i < 10; i++) {
const clouds1Mesh = clouds1.scene
const clouds1Position = clouds1Mesh.position
clouds1Position.x = Math.random() * 10
clouds1Position.y = Math.random() * 10
clouds1Position.z = (Math.random() - 0.5 ) * 300
clouds1Mesh.scale.setX(0.05)
clouds1Mesh.scale.setY(0.05)
clouds1Mesh.scale.setZ(0.05)
scene.add(clouds1Mesh)
clouds1array.push(clouds1Mesh)
}
}
addClouds1()
})
edit: clouds1.scene structure is this:
I don't know why it has this amount of children, I tried to solve with the answer, but it still does not work. The 3rd child in the end contains the mesh, and I tried using that for it to work, but it says that I cannot use it in the scene.add() function
edit: I solved the problem! I just had to put the for loop outside the load function
for(let i = 0; i < 30; i+= 3)
loader.load('/clouds/clouds1/scene.gltf', function (clouds1) {
const cloud = clouds1.scene
const child1 = clouds1.scene.children[0].children[0].children[0].children[2].children[0]
child1.material = new THREE.MeshStandardMaterial({ emissive: 'white', emissiveIntensity: 0.5})
cloud.scale.set(0.05, 0.05, 0.05)
cloud.position.x = (Math.random() - 0.5) * 500
cloud.position.y = (Math.random() + ((Math.random() + 20 ) + 70))
cloud.position.z = (Math.random() - 1) * 500
cloud.rotation.x = Math.random()
cloud.rotation.y = Math.random()
cloud.rotation.z = Math.random()
scene.add(cloud)
})
The GLTFLoader results, which you have as clouds1 is a generic object, from which you properly extract clouds1.scene. However, clouds1.scene is also a single Scene object. If you have 10 clouds in the GLTF model you loaded, then clouds1.scene will have 10 children, and you will need to loop through them like this:
loader.load('/clouds/clouds1/scene.gltf', function (clouds1) {
var clouds1array = []
const clouds1Children = clouds1.scene.children
for (var i = 1; i < 10; i++) {
const clouds1Mesh = clouds1Children[i]
const clouds1Position = clouds1Mesh.position
clouds1Position.x = Math.random() * 10
clouds1Position.y = Math.random() * 10
clouds1Position.z = (Math.random() - 0.5 ) * 300
clouds1Mesh.scale.setX(0.05)
clouds1Mesh.scale.setY(0.05)
clouds1Mesh.scale.setZ(0.05)
scene.add(clouds1Mesh)
clouds1array.push(clouds1Mesh)
}
})
I create demo game Tic Tac Toe with OOP javascript. But I have problem with get value at table which have attached value then display the table in console.log();
This is my code:
/**
* #constructor
* #param {Number} width - dimension width for table
* #param {Number} height - dimension height for table
*/
function Table(width, height) {
this.table = new Array(height * width);
this.width = width;
this.height = height;
}
Table.prototype = {
/**
* Representation for get width of table
*/
getWidth: function () {
return this.width;
},
/**
* Representation for get height of table
*/
getHeight: function () {
return this.height;
},
/**
* Representation for get table array 2d
*/
getTable: function () {
var x = new Array(this.getHeight());
for (var i = 0; i < this.getHeight(); i++) {
x[i] = new Array(this.getWidth());
};
},
/**
* Representation for set position of table
*/
setPosition: function (x, y, ch) {
return this.table[x][y] = ch;
},
I have problem it here. I can't get value at table and check isEmpty.
/**
* Representation for get value detail at cell of table
*/
getValueAt: function (x, y) {
return this.table[x][y];
},
/**
* Representation for check empty conditional
*/
isEmptyAt: function (x, y) {
if (!this.table[x][y])
return true;
},
};
/**
* #constructor
* #param {String} character - X or O
*/
function Player(name, ch) {
this.name = name;
this.ch = ch;
}
var Printer = function () {
};
This is function print display in console.log().
Printer.prototype = {
/**
* Representation print table
*/
printTable: function (table) {
var str = '';
for (var i = 0; i < table.width; i++) {
var x = i;
for (var j = 0; j < table.height; j++) {
var y = j;
str += '' + table.getValueAt(x, y) + '|';
}
str += '\n------------\n';
}
console.log(str);
},
/**
* Representation check winner conditional
*/
printWinner: function (player) {
},
};
Math.floor(Math.random() * 2);
/**
* #param newTable [array] : The array two-direction table
* #param player [object] : the object contain player X and O
*/
var GamePlay = function (table, playerOne, playerTwo) {
this.table = table;
this.playerOne = playerOne;
this.playerTwo = playerTwo;
this.printer = new Printer();
};
GamePlay.prototype = {
run: function (x, y) {
console.log('Game start ...!');
x = Math.floor(Math.random() * 2);
y = Math.floor(Math.random() * 2);
this.putChessman(x, y, this.playerOne.ch);
console.log('put', this.putChessman());
this.printer.printTable(this.table);
},
/**
* #param player [keywork] : the keywork X and O
*/
checkWin: function (player) {
},
putChessman: function (x, y, ch) {
console.log('isEmptyAt', table.isEmptyAt(x, y));
if (this.table.isEmptyAt(x, y) === true) {
console.log('# player ' + ch + ' put');
this.table.setPosition(x, y, ch);
} else {
console.log('# Other player already put on it');
}
},
};
var table = new Table(3, 3);
var playerOne = new Player('playerOne', 'O');
var playerTwo = new Player('playerTwo', 'X');
var game = new GamePlay(table, playerOne, playerTwo);
game.run();
Please help me resolve problem -.-
You're not initializing table correctly. You're doing this:
this.table = new Array(height * width);
...but later trying to use it like this:
this.table[x][y];
To use it like that, you need not just an array, but an array of arrays (JavaScript's equivalent of a two-dimensional array). To initialize an array of arrays, you do this:
this.table = [];
for (var x = 0; x < width; ++x) {
this.table[x] = new Array(y);
}
Note that the entries in the sub-arrays (e.g., this.table[0][0]) will be undefined*. If that's what you want (it would work with isEmptyAt), that's fine. If you want them to have a different value, you need to fill that in:
this.table = [];
for (var x = 0; x < width; ++x) {
this.table[x] = [];
for (var y = 0; y < height; ++y) {
this.table[x][y] = theValueGoesHere;
}
}
Separately: Calling isEmptyAt will result in either true or undefined, because isEmptyAt only returns a value when it returns true; in the other case, it doesn't return anything, and the result of calling it is the value undefined. Instead, I would have it explicitly return something in both cases:
isEmptyAt: function(x, y) {
return !this.table[x][y];
}
* Technically, with new Array(height), the entries won't be there at all; despite the array having a length of height, it has no entries at all until you add them. But when you try to retrieve an entry, you'll get the value undefined, so I fudged the explanation a bit for simplicity.
I really try to find out why the for loop is looping again and again. My question is why is the first for looping again and again thought x is 1?
The result shows random counts of progressbars with a random progresses (img element is the progress). But it should only show 1 because x is 1. Can somebody tell me whats the answer?
function progress(){
var min = 0;
var max = 10;
/*var x = Math.floor(Math.random() * (max - min)) + min;*/
var x = 1;
var main_div = document.createElement('div');
main_div.className = "main_div";
document.body.appendChild(main_div);
for(var i = 0; i < x; i++){
var einfuegen = document.createElement('div');
einfuegen.className = 'statusbar';
main_div.appendChild(einfuegen);
var einfuegen2 = document.createElement('img');
einfuegen2.id = 'bild';
einfuegen2.name = 'bild';
einfuegen2.src = 'project_status.gif';
var zielort = document.getElementsByClassName('statusbar')[i];
zielort.appendChild(einfuegen2);
var min = 0;
var max = 100;
var x = Math.floor(Math.random() * (max - min)) + min;
document.getElementsByTagName('img')[i].style.width = x+"%";
}
}
You need to use some different names for variable in loop
var min = 0;
var max = 100;
var x = Math.floor(Math.random() * (max - min)) + min;
it should be
var min1 = 0;
var max1 = 100;
var x1 = Math.floor(Math.random() * (max1 - min1)) + min1;
As you are using x in loop condition and modifying it inside loop, causing malfunction of loop.
You're changing x here:
var x = Math.floor(Math.random() * (max - min)) + min;
So the loop will loop a random number of times between 0 and 100.
Use a different variable name for the value of your progress bar, and for that matter, the max and min values of the progress bar:
var value = Math.floor(Math.random() * (maxValue - minValue)) + minValue;
document.getElementsByTagName('img')[i].style.width = value+"%";
This confusion is the very reason why JSLint recommends declaring all of your variables at the top of your function:
function progress(){
var min = 0,
max = 10,
x = 1,
i,
main_div = document.createElement('div'),
einfuegen,
einfuegen2,
zielort,
minValue = 0,
maxValue = 100,
value;
// rest of function...
}
The variable list above is very long because it has the values for both the outside of the loop and the inside of the loop. The solution to this is to factor your code out into separate functions:
function progress(){
var min = 0,
max = 10;
x = 1,
main_div = document.createElement('div'),
i;
main_div.className = "main_div";
document.body.appendChild(main_div);
for(i = 0; i < x; i += 1){
mainDiv.appendChild(makeProgressBar());
}
}
function makeProgressBar() {
var einfuegen = document.createElement('div'),
einfuegen2 = document.createElement('img'),
min = 0,
max = 100,
x = Math.floor(Math.random() * (max - min)) + min;
einfuegen.className = 'statusbar';
einfuegen2.id = 'bild';
einfuegen2.name = 'bild';
einfuegen2.src = 'project_status.gif';
einfuegen.appendChild(einfuegen2);
einfuegen2.style.width = x+"%";
return einfuegen;
}
This will also help to prevent variable name collisions.
x starts as 1 but you change it in the loop like this:
var x = Math.floor(Math.random() * (max - min)) + min;
which returns a number between 0-100 and the loop continues until it reaches above the random number.
I have the following code, which attempts to generate a 2 dimensional array of random numbers:
var block_size = 32;
var can_width = can.width;
var color_depth = 12;
var passes = can_width / block_size;
var map_store = new Array(passes);
for(i=0;i<passes;i++) {
for(j=0;j<passes;j++) {
map_store[i] = new Array(passes);
color = Math.random() * color_depth;
map_store[i][j] = Math.round(color);
}
}
which seems to work fine if i put console.log statements within the loop, however if I try to access the map_store array outside of the loops. all of it's elements are undefined. why is this?
map_store[i] = new Array(passes); should be above the 2nd for loop. You're clearing your previous j values.
for(i=0;i<passes;i++) {
map_store[i] = new Array(passes); // <--
for(j=0;j<passes;j++) {
color = Math.random() * color_depth;
map_store[i][j] = Math.round(color);
}
}
I have an error and i cannot get this out of my script. I think it's because of some double entries.. but i expect that it ignores the long and lat then:
// creeert een geordende database van de gebruikte woorden
var wordConnection = new Array();
var wordCoords = new Array();
var index = 0;
var indexY = 0;
var brightRed;
var randomnumber = Math.floor(Math.random() * 256);
var randomnumber2 = Math.floor(Math.random() * 256);
var randomnumber3 = Math.floor(Math.random() * 256);
var colourRandom = colorToHex('rgb('+randomnumber+', '+randomnumber+', '+randomnumber+')');
// document.writeln(randomnumber)
for (var x = 0; x < wordSort.length - 1; x++)
{
var wordSort1 = wordSort[x];
var wordSort2 = wordSort[x + 1];
// if ((latSort[x] != latSort[x+1])&& (longSort[x] != longSort[x+1]) ){
if (latSort[x] != undefined){
document.writeln(latSort[x]);
document.writeln("----");
document.writeln(longSort[x]);
wordCoords[indexY] = new google.maps.LatLng(latSort[x], longSort[x]);
indexY++;
}
// }
if (wordSort1 != wordSort2)
{
colourRandom = colorToHex('rgb('+randomnumber+', '+randomnumber2+', '+randomnumber3+')');
wordConnection[index] = new google.maps.Polygon(
{
paths: wordCoords,
strokeColor: colourRandom,
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: "#FF0000",
fillOpacity: 0.35
});
wordConnection[index].setMap(map);
wordCoords.length = 0;
indexY = 0;
randomnumber = Math.floor(Math.random() * 256);
randomnumber2 = Math.floor(Math.random() * 256);
randomnumber3 = Math.floor(Math.random() * 256);
index++;
}
}
It doesn't give any faults :(
i get a list of words combined with a list of geo locations. It inserts them into an array. The words are sorted alphabetically. If the next word doesn't resemble, then it shows the array of geo locations and makes a new one. I've discovered that it works, when i insert an alert to count the 'index' var :S Maybe i put it in the wrong place in the whole script? (Don't think so)