Keep spawning object every second - javascript

I have a function which adds the RandomBlock object to the scene and moves it down the screen.
function enemyPaddleMovement()
{
scene.add(RandomBlock);
RandomBlock.translateX(-8);
}
RandomBlock is made by this code:
var shapes = [LeftBlock, RightBlock, middleRightBlock, middleLeftBlock, middleBlock];
var shape = shapes[Math.floor(Math.random()*shapes.length)];`
RandomBlock = new THREE.Object3D();
RandomBlock.add(shape);
What I want to do is to keep spawning a new RandomBlock object every second and move it down the screen. Ive tried using setInterval but it only replaces the same RandomBlock object rather than creating a new object everytime.
any Help?

This problem actually doesn't involve Three.js at all; it's just that you are not making any new objects, you are reusing the same one many times. Try something like this instead:
// this line stays outside the function
var shapes = [LeftBlock, RightBlock, middleRightBlock, middleLeftBlock, middleBlock];
function enemyPaddleMovement()
{
var shape = shapes[Math.floor(Math.random()*shapes.length)];
var randomBlock = new THREE.Object3D();
randomBlock.add(shape);
scene.add(randomBlock);
randomBlock.translateX(-8);
}
Note that there are no longer any mentions of randomBlock outside the function. This is because it is an object for that one call of the function and is unique to it.
I'm assuming you wanted to pick a different shape for each new object. If you don't, then just move var shape = ... back outside the function.

You need also to store this new Object. I think that you overwrite old object that is why is recreated.
Instead of RandomBlock you can have BlockContainer which will be a list.

Related

How to use a dynamic variable in JavaScript?

I need to create something like :
var term = new Terminal();
each time I click on a button. I have found that we can create dynamic variable like this in JavaScript:
window["term_" + _idContainer] = new Terminal({
cursorBlink: true,
});
But I'm not sure about this because I can only use the last one that I create.
So someone could tell me if it really create dynamic var and if they aren't overwritten each time we create one.
You could use an object, without polluting the global space, like
var collection = Object.create(null); // empty object without prototypes
// use
collection["term_" + _idContainer] = new Terminal({ cursorBlink: true });
JavaScript objects are effectively dictionary-style objects. Therefore, you can add a property to any object in these two ways:
myobj.newProp = 'I am new!';
myobj['newProp2'] = 'So am I';
And therefore, yes, what you are doing is creating a sequence of new properties on the window object. There is no reason the one would overwrite the other, unless you neglected to increment _idContainer.
I should add that adding variables to the window object is not a popular thing to do and you could be adding many with this mechanism. Perhaps better would be to just add one, and expand it as needed:
window.termList = {};
// Then, in a loop or whatever
window.termList[_idContainer] = new Terminal({cursorBlink: true});

Make a variable inherit the methods of an existing prototype?

So let's say i have a tile on a map.
function TileData (image, z) {
this.image = image;
this.z = z;
}
var tile = new TileData (tileimage, 0);
Now i can call tile.image and tile.z to reference the existing data.
I also have an array called map, which i can loop through to draw the map.
var map = [];
What i want to do is attach the methods of the existing tile to the 0th entry in the array so it will be drawn when the function is called.
So i tried doing something like this.
map[0] = tile;
So i can call map[0].image to get the image that represents that tile on the map.
Now i want to change the image of this tile, so i try doing this.
map[0].image = differentTileImage;
However what Javascript actually does is this:
tile.image = differentTileImage;
Which means any time i try to use that tile for another part of the map, it will have a different value.
map[1] = tile;
//map[1].image will return differentTileImage instead of tileimage.
Is there a way for a variable to inherit the properties and values of an existing prototype, rather than merely referencing it?
(Sorry if this is a dupe).
Yes, you can use Object.assign(), that function will create a copy of the Tile.
map[1] = Object.assign({}, tile);
You can find more useful information at: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
The problem is that objects in JavaScript are always passed by reference. When you change the original, changes all values in the chain, where you use this reference.
In your case tile and map[0] are the same think. If you change tile map[0] is changed because the reference in the memory is the same as tile.
Which means any time i try to use that tile for another part of the map, it will have a different value.
Well not exactly. It means that when you use a single tile for every part of the map, it will have the exactly same value everywhere. And if you change this single tile, the whole map will change.
What you want is to create multiple tile instances:
map[0] = new TileData (tileimage, 0);
map[1] = new TileData (tileimage, 0);
…
(you'd use a loop of course)
They still will all inherit from the same prototype object (TileData.prototype), but are distinct instances and every image can be changed separately.

Prototyping a sub-classes to already defined classes in Javascript

Sorry if it is trivial but I am a very beginner. In Javascript what is the best way to extend an already defined object class with propreties which are classes themselves?
For example suppose I have a class Sprite with some built in properties and methods. I want to have an extra property Sprite.position where the position part is a class with (say) two properties position.x and position.y. And I want it applied all the instances of the class Sprite (past and future), not to one single instance.
If position would be a simple input data (number or string) then I could just write Sprite.prototype.position='there'. Also if position was an array it would have been easy: just write Sprite.prototype.position="there", or even an array of array would work like this... But what if position is a class? Usually to build "classes" one would use the object constructor:
function position(x,y) {
this.x = x;
this.y = y;
}
but then I would need to instantiate the position objects with var myPosition = new position(0,0); but I want the position object to exist every time I instantiate a new Sprite object. If I write Sprite.prototype.position=new position(0,0);than there is a problem: if I define mySprite1.position.x=2 the value 2 is also given to the property position.x of every istance of the class Sprite. This doesn't happen with the command Sprite.prototype.position='there', in this case every istance will have and keep his own separate values. I want every istance with separate independent "position" objects.
Is it possible to do what I want in an easy linear way?
And I want it applied all the instances of the class Sprite (past and future), not to one single instance.
You're quite right that if you were dealing with a primitive (like your "testing" string), you could just add it to Sprite.prototype and it would appear on all Sprite objects without any crosstalk between them.
Also if position was an array it would have been easy: just write Sprite.prototype.position=[0,0]
While it's true that the array would show up on all Sprite objects, they would have the potential for cross-talk, because they'd all share the same array:
var sprite1 = new Sprite();
var sprite2 = new Sprite();
Sprite.prototype.position = [0,0];
sprite1.position[0] = 42;
console.log(sprite2.position[0]); // "42"
If you don't mind them all sharing the same array/object, you can do exactly the same thing with your class:
Sprite.prototype.position = new Position(/*...*/);
Again, they will all share one Position object.
If you want each sprite instance to have its own Position object (or array), independent of the one on other instances, you have only two choices:
Modify the Sprite constructor to assign the object/array to the instances as they're created.
Spin through all Sprite objects ever created and add the object/array.
Obviously you can't do #2 unless you have references to those objects.
It may well be that you don't have to do anything to Sprite.prototype at all, depending on how you want to handle a sprite not having a position. For example:
function doSomethingWithASprite(sprite) {
if (!sprite.position) {
// Doesn't have a position yet, give it one
sprite.position = new Position(/*...relevant args...*/);
}
}
Similarly, any time you want to get a sprite's position:
var x = sprite.position && sprite.position.x;
That will give you undefined if the sprite doesn't have a position yet.
A final option for you: Make position a function:
Sprite.prototype.position = function(x, y) {
// Make sure we have a position
if (!this.position) {
this.position = new Position(/*...relevant args...*/);
}
if (typeof x === "undefined") {
// Getter, return the current position
return this.position;
}
else {
// Setter, set the current position
this.position.x = x;
this.position.y = y;
}
};

What is the convention for dynamically creating an object instance?

I'm creating a page that will allow you to put multiple widgets on it, and some widgets can be duplicated on the page. So I need to understand the proper convention for creating an object instance on the fly.
// my bulb object
var bulb = {
state: 0
};
// programatically, hard-coded instance name of 'bulb1'
var bulb1 = new bulb();
$('button').click(function() {
// create another new bulb instance here with dynamic name
});
Or am I just going down the wrong path all together?
Thanks.
In JavaScript, we use functions (so called constructor functions) to instantiate object instances.
function Bulb() {
this.state = 0;
}
// one instance
var bulb1 = new Bulb();
// another instance
var bulb2 = new Bulb();
Your code doesn't work because your bulb is a regular object and not a function, so you cannot call it (which you are trying to do with bulb()).
Update: You could store your instances into an Array global variable:
var bulbs = [];
And then, whenever you create a new instance, just just make sure that you put it in the Array.
$('button').click(function() {
var bulb = new Bulb();
// do stuff with bulb
// make sure to store it into the Array
bulbs.push(bulb);
});
You can access the instances at any time like so:
bulbs[0] // the 1. instance
bulbs[1] // the 2. instance
// etc.

reinitializing javascript object's properties

In my Javascript drag and drop build app, a variety of buildings can be built. The specific characteristics of these are all saved in one object, like
var buildings = {
house: ['#07DA21',12,12,0,20],
bank: ['#E7DFF2',16,16,0,3],
stadium: ['#000000',12,12,0,1],
townhall: ['#2082A8',20,8,0,1],
etcetera
}
So every building has a number of characteristics, like color, size, look which can be called as buildings[townhall][0] (referring to the color). The object changes as the user changes things. When clicking 'reset' however, the whole object should be reset to its initial settings again to start over, but I have no idea how to do that. For normal objects it is something like.
function building() {}
var building = new building();
delete building;
var building2 = new building();
You can easily delete and remake it, so the properties are reset. But my object is automatically initialized. Is there a way to turn my object into something that can be deleted and newly created, without making it very complicating, or a better way to store this information?
You can keep initial state as a prototype on an object.
var Base = function(){};
Base.prototype={a:1,b:2};
var c = new Base();
Now, you can change value of a or b to whatever you want.
To restore, just use
delete c.a or delete c.b
You will get your initial value back.
Hope this help.
Just use a copy/clone method to restore the original state
var defaults = {
foo: "bar"
};
var building;
function reset(){
building = {};
for (var key in defaults) {
if (defaults.hasOwnProperty(key){
building[key] = defaults[key];
}
}
}
Now you can just call reset() whenever you need to have building reset.

Categories