Drawing images from an array - javascript

I'm currently working on drawing up a tilemap using a set of images loaded inn to an array.
I've defined a tile as an object like this:
function tile(gfx){
this.tile = gfx;
this.drawSelf = function(x,y)
this.tile.x = x;
this.tile.y = y;
}
Then I filled up an array with several tile objects which through the debugger displays correctly.
Now when I start drawing up the images using this code:
for (var x = 0; x < mapArray.length; x++){
xN = 183 + (50*x);
mapArray[x].drawSelf(xN, 134);
gameStage.addChild(mapArray[x].tile);
mapArray[x].tile.visible = true;
}
The problem is that all the "objects" in the array recive the same x and y coords. So what i suspect is that every single object in the array referes to each other.
What I'm trying to do is create a 20x10 map of tiles. And I need to be able to refer to each tile as a single object.
Shout out if I'm not making sense.

If you create all the tiles like this :
var gfx = new ...
for (...) {
mapArray[x].tile = new tile(gfx);
}
Then all of them share the same gfx object.
You should change your initialization like this :
for (...) {
var gfx = new ...
mapArray[x].tile = new tile(gfx);
}

Related

Three.js object returns wrong values for position/rotation/scale

I'm having a three.js object in my scene, which you can rotate/scale/move with the THREE.TransformControls. After positioning the object in the scene, the values of rotation/position/scale should be saved. I'm getting the values like this :
// Position
$scope.scene.updateMatrixWorld(true);
var position = new THREE.Vector3();
position.getPositionFromMatrix( $scope.object.matrixWorld );
// Rotation
var rotation = new THREE.Euler();
$scope.object.getWorldRotation(rotation);
// Size
var size = new THREE.Box3().setFromObject($scope.object);
var x = (size.max.x - size.min.x);
var y = (size.max.y - size.min.y);
var z = (size.max.z - size.min.z);
So, when I'm saving the values and reload the scene with the new values, the object looks really different than it should. So, I think, the functions deliver the wrong values for rotation/scale/position. For example, the size.z variable should always be 0, but when saving (and printing the value in the console) it gets an other value.
Does anyone have an idea why ?
Thanks for helping.
Three.js offers a matrix decomposition function: https://threejs.org/docs/#api/math/Matrix4.decompose
Here's an example of how to use it:
var translation = new THREE.Vector3();
var rotationQ = new THREE.Quaternion();
var scale = new THREE.Vector3();
myObject.matrixWorld.decompose(translation, rotationQ, scale);
Then if you want to save the rotation as an Euler:
var rotationE = new THREE.Euler().setFromQuaternion(rotationQ.normalize());
three.js r88

three.js remove specific object from scene

I have an array of Meshes, each Mesh has stored in a name property its ID. I would like to ask you, if it is possible to remove from scene an object with specific ID. Something like this.
var geo = some geometry;
var mat = some material;
for (var i = 0; i < 10; i++) {
var object = new THREE.Mesh(geo, mat);
object.name = i; // i would serve as ID in this case
}
After this, I would like to delete/remove some of these objects...
Maybe some function like
remove(id);
....
var remove = function (id) {
... some magic
scene.remove(...) // and this would remove that object, with id passed as parameter
}
Is such a thing possible?
Thanks!
yes it is:
function remove(id) {
scene.remove(scene.getObjectByName(id));
}
see: Object3D.remove() and Object3D.getObjectByName()

JavaScript fixed array or object length?

I need a way to store two values only within an array or object and limit its length to two values. The reason is that I am using a jQuery Vectormap to calculate the distance and a draw line between two coordinates x1/y1 & x2/y2.
Whenever a region/country is clicked, corresponding markers are loaded and added to the map
map.addMarker(id ,{latLng: [val.lat, val.long], name:val.name}) ; ect///
Now, whenever a marker is clicked I should be able to track count of two markers's selection and store their coordinates in an array then do the calculations..
onMarkerClick:function(e, code){
var coordinates = map.markers[code].config.latLng;
// latitude = coordinates[0]
// longitude = coordinates[1]
}
So if I were to use myArray.push([coordinates[0],coordinates[1]]) for each marker clicked then I end up with countless number of coordinates and thus making it impossible to draw my line.. Is there a way to set myArray length to 2 then when I push more values overwrite the existing one?
Thanks
If you want to be fancy about it, you can create your custom class that does this...
function CappedArray(Size)
{
this.push = function(Value) {
if(this.length==Size)
{
this.shift();
}
CappedArray.prototype.push.call(this, Value);
}
}
CappedArray.prototype = new Array();
//How you use it
var SomeArray = new CappedArray(2);
SomeArray.push([coordinates[0],coordinates[1]]);
...
Alternatively, if you want to force the fact that points should only be associated in successive pairs of insertions:
function PairArray()
{
this.push = function(Value) {
if(this.length==2)
{
this.splice(0, 2);
}
PairArray.prototype.push.call(this, Value);
}
}
PairArray.prototype = new Array();
//How you use it
var SomeArray = new PairArray();
SomeArray.push([coordinates[0],coordinates[1]]);
You could use an object like this:
var coords =
{
"c1": [x1,y1],
"c2": [x2,y2]
}
then when adding coordinates you could:
coords.c1 = coordinates[0];
coords.c2 = coordinates[1];

Dynamic add a multi-dimension array in javascript or jquery

The problem is I need to add a multi dimension array dynamically, please look at the following example:
var list = [];
var listname;
var height;
var width;
list.push(listname);
list[listname] = height;
list[listname] = width;
the code above is not what I expected , which should be [listname => [[0]=>height,[1]=>width]], what can I do if I do not want to create an array for listname, can I dynamic add a mulit dimension array ? thanks.
Don't confuse Arrays with Maps. They are different fundamental data-types1
var myLists = {}; // name => array
var listname = "stuff"; // why not?
var height = 1;
var width = 2;
// there is no Object.push, but we can assign a property by name
myLists[listName] = [height];
// then we can Array.push into the array we just assigned
myLists[listName].push(width);
Then, myLists:
{
stuff: [1, 2]
}
1JavaScript mostly maintains this distinction - if one doesn't add random properties to Arrays or otherwise fake an Object to behave like an array.

Mapping an external 2d array to another 2d array (javascript)

This was intended to create a 2d array of objects which would allow me to access any of the objects (the "clips") by banks[a][b], where [a] was a "bank" and [b] was a "clip". Works perfectly as - is, unfortunately this code is meant to look at some external files and see their properties. These files are already organized in an "array" based on some of their properties. Originally I was told this would be an 8x8 array, however now it turns out that this would be a 16x32 array and the requirements specify banks composed of 4x2 selections from the array.
In other words,
banks[0][0].track = 0
banks[0][0].slot = 0
banks[0][3].track = 3
banks[0][3].slot = 0
banks[0][4].track = 0
banks[0][4].slot = 1
banks[0][7].track = 3
banks[0][7].slot = 1
banks[15][0].track = 0
banks[15][0].slot = 31
banks[15][3].track = 3
banks[15][3].slot = 31
banks[16][0].track = 3
banks[16][0].slot = 0
banks[16][4].track = 3
banks[16][4].slot = 1
banks[63][0].track = 11
banks[63][0].slot = 30
banks[63][4].track = 11
banks[63][4].slot = 31
I need to iteratively create a 64x8 2d array of "clips", but at the same time set the above properties of those clips as shown. It seems clear that the relevant math belongs in the clip object. However, I can't see the math yet. Any suggestions would be greatly appreciated.
Sounds like you need this:
var theirBanks = [[...], [...], ...]; // 16*32 array of Clip objects
var x = 2; // reduce outer array to one of half length
var y = 4; // reduce inner arrays to one of fourth length
function reduce(sel) {
/* gets: a 2*4 selection of clips from theirBanks
returns: a new clip for banks */
... // not sure how you want this to be done
}
var banks = new Array(theirBanks.length / x);
for (var i=0; i<banks.length; i++) {
banks[i] = [];
for (var j=0; j<theirBanks.length/y; j++) {
var selection = [];
for (var k=i*x; k<(i+1)*x; k++)
selection.push(theirBanks[k].slice(j*y, (j+1)*y));
banks[i][j] = reduce(selection);
}
}
// banks is now a 8*8 array
The script builds 2*4 selections from the (two-dimensional) array, lets you reduce them to a new object and returns the new, smaller (two-dimensional) array.

Categories