Switching id names in javascript - javascript

Working on chess board using html and javascript. I am trying to add a function so that the user can flip the perspective of the board and running into a glitch that I understand, but can't figure out how to solve. Code as below....
function flipBoard(){
document.getElementById("a8").id = "h1";
document.getElementById("a7").id = "h2";
document.getElementById("a6").id = "h3";
document.getElementById("a5").id = "h4";
document.getElementById("a4").id = "h5";
document.getElementById("a3").id = "h6";
document.getElementById("a2").id = "h7";
document.getElementById("a1").id = "h8";
document.getElementById("h8").id = "a1";
document.getElementById("h7").id = "a2";
document.getElementById("h6").id = "a3";
document.getElementById("h5").id = "a4";
document.getElementById("h4").id = "a5";
document.getElementById("h3").id = "a6";
document.getElementById("h2").id = "a7";
document.getElementById("h1").id = "a8";
}
So.... I thought this would work just fine, but discovered that this wreaks havoc on my board by position half white, half black pieces on both sides of the board. The problem of course is that after the original "a1" square is renamed to "h8", there are now TWO "h8" squares, and at the end of the code it switches both back to "a1".
I have no idea how to get the id names to switch at the same time, otherwise I'd have to add a whole lot of code switching the id names to some third name as a place holder before switching them over to the desired name. Possible, but tedious and I feel there has to be a simpler way to do this.
Any ideas?

You can reduce the repetition of your current code by generating the id values programmatically in a loop:
function flipBoard(){
var a, h, aVal, hVal, aEl, hEl;
for(a = 8, h = 1; a > 0; --a, ++h) {
aVal = 'a' + a;
hVal = 'h' + h;
// Store off the current values
aEl = document.getElementById(aVal);
hEl = document.getElementById(hVal);
// swap them
aEl.id = hVal;
hEl.id = aVal;
}
}
demo fiddle

Save the reference to the element in variable. For example:
function flip(){
var aEight = document.getElementById("a8"),
hOne = document.getElementById("h1");
aEight.id = "h1";
hOne.id = "a8";
}
By separating out the steps of finding your elements and changing their ids, you'll easily be able to keep track of the flipped elements.

Related

THREE JS applying Gradient to imported Models

The difference between the following two spheres - in terms of how their gradient colors were applied, comes down to one statement:
sphereGeometry = sphereGeometry.toNonIndexed();
Being that I really like the smoother look that .toNonIndexed() gives us, I tried applying it to some of the imported “.glb” models available on the THREE.js GIT - but it’s not working.
For example, here’s what happens when I use the horse model available here: https://github.com/mrdoob/three.js/blob/master/examples/models/gltf/Horse.glb
It basically completely ignore my colors and defaults to red and black for some reason.
But when I comment out the .toNonIndexed() line, it gives me the colors I asked for - except you definitely see the triangles, which is the look I'm trying to avoid:
Here's my code for loading the object:
function loadAny3DModel() {
loader.load("./Horse.glb", function(theHorse) {
console.log("===>'theHorse' has arrived!!!\n");
var horseScene = theHorse.scene;
horseMesh = horseScene.children[0];
var horseGeometry = horseMesh.geometry;
let horseMat = horseMesh.material;
var horseVertexPositionsArray = horseGeometry.attributes.position;
// Here's the command that isn't working:
// horseGeometry = horseGeometry.toNonIndexed();
// horseVertexPositionsArray = horseGeometry.attributes.position;
let theColor = new THREE.Color();
let colorsArray = [];
for(let i = 0; i < horseVertexPositionsArray.count; i++) {
let randC1 = "purple";
let randC2 = "white";
let chosenColor = i % 2 == 0 ? randC1 : randC2;
theColor.set(chosenColor);
colorsArray.push(theColor.r, theColor.g, theColor.b);
}
horseGeometry.setAttribute("color", new THREE.Float32BufferAttribute(colorsArray, 3));
horseMat.vertexColors = true;
render();
scene.add(horseScene);
}
}
What should I be doing to get the smoother gradients going?
=====================================================================
UPDATE:
Here is a very rough idea of what I'm trying to do: extend a gradient over an entire model, as opposed to every single triangle that is forming the model. (Compare this image to the one above.)
If you comment in the following line...
horseGeometry = horseGeometry.toNonIndexed();
...it means you create a new (!) geometry. As long as you don't assign the geometry back to Mesh.geometry, this code won't have any effect. So the fix is to add the following line after using toNonIndexed():
horseMesh.geometry = horseGeometry;

Attempt to filter array items that were recently used

Array.prototype.spil = function (x,max) {
if (this.length===max) {
this.shift();
this.push(x);
} else {
this.push(x);
}
return this;
}
var heard = [0],
freash = [];
$('#speak').bind('touchstart', function() {
var sounds = [
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,
21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40
];
var temp = sounds;
for (var i=0; i<heard.length; i++) {
temp.splice(temp.indexOf(heard[i]), 1);
}
freash = temp;
var say = Math.floor(Math.random() * freash.length+1) + 1;
heard.spil(say,10);
say = document.getElementById('c'+say); // audio element
// use the sound...
});
My attempt to make the sound that plays 'an un-recent one' is not working! I want to make the last sound that played not play again for 10 button clicks.
heard is the array of sounds that you have already heard, this has a Array.spil function which will fill the array via push until it reaches its max length of ten when it will shift then push instead.
freash is the array of sounds with no members of the heard array present.
You can see that heard and freash are declared outside of the click (touchstart) scope.
If I click/tap over-and-over sometimes I am hearing sounds that have been played already much sooner than I am suppose to, often following each other.
This has been bothering me for days but, I can't see the problem in my logic. Can you?
I think this line
var say = Math.floor(Math.random() * freash.length+1) + 1;
should be
var say = freash[Math.floor(Math.random() * freash.length)];
Also consider the shortcut
var say = freash[Math.random() * freash.length | 0];

Javascript choose biggest more often than smaller

I'm busy with nodejs a bit for modding a game, but I'd like to know how to do something like this:
var zombieDirector =
{
zombieBison = 1
zombieChicken = 2
zombie = 3
skeleton = 3
}
and those names have another var like
var zombieBison = 'Entities/Zombies/zombieBison.cfg'
and now make the Bison spawned rare and skeleton and zombie more often.
you get this, where randomZombie equals to 'Entities/Zombies/aZombie.cfg'
ks.map.spawnEntity('zombie', randomZombie, 0, 0, 3);
I can't get any further than
var randomZombie = zombieDirector[Math.floor(Math.random() * zombieDirector.length)];
On another note: No JQuery please
Thanks in advance
In essence, you're talking about weighted random number generation. A little tricky, if you want to use math, but you can do it with an array, like this:
var choices = [];
for(prop in zombieDirector) {
for(var i = 0; i<zombieDirector[prop]; i++) {
choices.push(prop);
}
}
var choice = choices[Math.floor(Math.random() * choices.length + .5)];
The variable choice will now have a random monster name, weighted based on the number you provide in zombieDirector.

Simple javascript game, hide / show random square

I'm working on a simple game and I need some help to improve my code
So here's the game:
Some square show and hide randomely for a few seconds and you have to clic on them.
I use RaphaelJS to draw the square and a few of JQuery ($.each() function)
I work in a div, that's how I draw my squares (6 squares), x y are random numbers.
var rec1 = paper.rect(x, y, 50, 50).attr({
fill: "blue",});
Can I use for() to build my squares with a different var name for each one ?
I try with var = varName+i but it didn't work.
To hide and show the square I use two functions call with two setTimeout:
function box1() {rec1.show();}
function hidebox1() {rec1.hide();}
var time1 = setTimeout(box1, 1000);
var time1 = setTimeout(hidebox1, 2000);
I know it looks crappy...
I'm sure there is a way to use a toggle, or something more fancy to do that if you could help me finding it :) Because right now I have to do that for every square...
Thanks a lot for your help.
Your instinct to try to use varName plus some i to identify which varName you want is spot on, and JavaScript (like most languages) has that idea built in through what's called an array.
A simple one looks something like this:
var foo = [1, 5, 198, 309];
With that array, you can access foo[0] which is 1, or foo[3] which is 309.
Note two things: First, we identify which element of the array we want using square brackets. Second, we start counting at 0, not 1.
You can create an empty array like var varName = []; and then add new elements to it using varName.push( newValueToPutIn );
With those tools, you can now get at what you wanted. Now you can do something like:
var recs = [];
for(var i = 0; i < 100; i++) {
var rec = paper.rect(x, y, 50, 50).attr({fill: 'blue'});
recs.push(rec);
}
And recs[0] and recs[1] and so forth will refer to your various boxes.
For the first question, an array is the way to go.
For the second part, you could encapsulate the square and its show/hide stuff into a new anonymous object, like this:
var recs = [];
var numberOfRecs = 6;
for (var i = 0; i < numberOfRecs; i++) {
//determine x and y?
recs.push({
box: paper.rect(x, y, 50, 50).attr({ fill: "blue" }),
showBriefly: function(timeFromNow, duration) {
window.setTimeout(this.box.show, timeFromNow);
window.setTimeout(this.box.hide, timeFromNow + duration);
}
});
}
//show the 3rd box 1000 ms from now, for a duration of 1000 ms
recs[2].showBriefly(1000, 1000);

JavaScript: cycle through an array (rather than pop)?

I'm creating map markers, and I want to assign a different colour to each county on the map.
I don't know in advance how many counties there will be showing on the map, so I need to figure out a way to assign an unlimited number of colours.
At the moment, I'm assigning a colour to each county using the following code, but I run into a problem when I pop() the list too many times:
var colours = ['6183A6', '3A66A7', '3B4990', '5B59BA'];
var h_colours = []; // associative array
function addMarker(county, colour) {
if (colour==undefined) {
if (h_colours[hundred]==undefined) {
h_colours[hundred] = colours.pop();
} } }
Is there a way I could cycle through the list without actually deleting items, and continuing from the start of the list when I reach the end?
thanks!
Yes.
var getNextColour = (function() {
var colours = ['6183A6', '3A66A7', '3B4990', '5B59BA'];
var cc = 0;
return function() {
var rv = colours[cc];
cc = (cc + 1) % colours.length;
return rv;
};
})();
Now you can just say:
if (colour == undefined) colour = getNextColour();
or simply
colour = colour || getNextColour();
Of course, applying the colors to the elements of the map such that you don't color adjacent areas with the same color is a considerably more interesting problem.
You can use a counter for the index in the array.
Increment whenever you fetch a color, reset it to 0 when it is the size of the array -1.

Categories

Resources