How to reset image positions - javascript

I am making a game and I am trying to create a game end function. How would I go about resetting all images to their starting positions?

You can programaticly store all positions of a image class inside a Object inside a array.
And after you can loop the array restoring theirs positions back.
var positions = new Array(0); //positions array
function objPos(obj){
return({
'obj':obj,
'x':obj.style.left,
'y':obj.style.top
});
}
function savePositions(imgContainer){
var imgs = imgContainer.getElementsByTagName('IMG');
for(var i=0; i<imgs.length; i++){
positions[i]=objPos( imgs[i] );
}
}
function restoreStoredPositions(){
for(var i=0; i<positions.length; i++){
var img=positions[i];
img.style.top=positions[i].y;
img.style.left=positions[i].x;
}
}
Call the savePositions function on the initial state, and you can call restoreStoredPositions later. If you want persistent data, stringy the array to JSON and you can store it to a Cookie or HTML5 LocalStorage.
I know this is pure JS but this is just a concept that I wrote now.
You can adapt this to use the each() and the jquery selector on place of the getElementBy...
I used the style.top and left just for readability, computedStyles is the correct path.

Related

Why I cannot refer to the images array?

i try to swap the images continuously from the array, but the code does not get the image source, why this happened?
function nextPic(){
var picCollection =["pic_bulbon.gif","pic_bulboff.gif"];
for(i=0; i<picCollection.length; i++){
document.getElementById("myImage").src = picCollection[i].src;
}
}
function triggers(){
setInterval(nextPic,500);
}
Might be Your code should be
var picCollection =["pic_bulbon.gif","pic_bulboff.gif"];
var i=0;
var interval;
function nextPic(){
document.getElementById("myImage").src = picCollection[i];
// if you want to repeat for show image again and again tehn use below line
i= (i+1) % picCollection.length;
// if you want not to repeat again then use below line
// if(i+1>=picCollection.length) clearInterval(interval);
}
function triggers(){
interval=setInterval(nextPic,500);
}
Here you have to define the image name array in global which should be accessible in all desire functions. It is good if you store setInterval reference in variable and clear it by clearInterval.
You need create a global variable for picture number. Then use that inside callback passed to setInterval. The above code will only show the last image of array.
let pic = 0;
const picCollection =["pic_bulbon.gif","pic_bulboff.gif"];
function nextPic(){
document.getElementById("myImage").src = picCollection[pic];
console.log("The pic shown is ", picCollection[pic])
pic++;
if(pic === picCollection.length){
pic = 0;
}
}
function triggers(){
setInterval(nextPic,500);
}
triggers()
<img id="myImage"/>
There is no src key in your arrat. You can just use
document.getElementById("myImage").src = picCollection[i];
Your code should look something similar to below
function nextPic(){
var picCollection = ["./pic_bulbon.gif","./pic_bulboff.gif"];
for(i = 0; i < picCollection.length; i++){
document.getElementById("myImage").src = picCollection[i];
}
}
"./pic_bulbon.gif" may need to change based off of your file structure and where you are storing the gif you are trying to access.
If you could supply a screenshot of your file structure I could tell you exactly what you need
The other issue you are having is your trying to access picCollection[i].src
but picCollection[i] is only an array of string not objects.

Is it a good practice to create new objects outside of the main animation loop in HTML5?

In HTML5 we usually use requestAnimationFrame to animate the shapes or objects. But is it a good practice to create these shapes and objects outside of the animate function?
Say I have a function
function animate() {
renderA();
renderB();
requestAnimateionFrame(animate);
}
and I have a pre-allocated array outside of animate() defined as:
let arr = new Array(99999);
let currentIndex = 4999;
Say the actual length of arr is 5000, the rest of the array is undefined.
Now I want to insert some new objects into the array, can I change the animate function to this?
function animate() {
renderA();
let length = 100;
for (let i = 0; i < length; i++) {
arr[currentIndex + 1 + i] = new SomeObject({...});
}
currentIndex += length;
renderB();
requestAnimateionFrame(animate);
}
If I remember correctly in this example the animate function will be called multiple times during canvas animation. So if I create a new object inside this animate() function and then render it afterwards the resources will eventually drain up? Is it OK to create new object inside the animation loop?

Loop through parallel Layers

i have a problem with a recursive function. I´ll try to explain as good as possible:
I have a photoshop-document containing various smart-objects all named: Smart_Objectname.
The Smarts may also contain other Smarts.
I now try to write a function that runs trough the whole document and opens a smart(searches with regex for "Smart"), if it contains another it will open the next one and so on. If the last is reached it starts saving each layer inside the smart named with "Layername.png" as png and closes it again. Then it saves the layers of the Smart before until reaching the root document again.
The "going deeper into smarts part" is already working. But if i have two Smart-objects in the same hierarchy it won´t work and set the wrong Layer as active when going deeper into the first one. I simply can´t find the error, but something seems to be wrong with my code.
Any help or easier way to do this would be great :)
Here my code so far...maybe a bit complicated:
findSmart(app.activeDocument.layerSets); //call it
function findSmart(layerNode) {
for (var i=0; i<layerNode.length; i++) {
var res = /Smart/;// a reg exp
var mat = collectNamesAM(res);// get array of matching layer indexes
for( var y = 0; y < mat.length; y++ ){
makeActiveByIndex( mat[y], false );
// do something with layer
var activeLayer = app.activeDocument.activeLayer;
//Open smart
//=======================================================
var idplacedLayerEditContents = stringIDToTypeID( "placedLayerEditContents" );
var desc45 = new ActionDescriptor();
executeAction( idplacedLayerEditContents, desc45, DialogModes.NO );
}//next Smart match if any
//Go deeper
findSmart(layerNode[i].layerSets);
var len = app.activeDocument.layers.length;
for (var i = 0; i < len; i++) {
var layer = app.activeDocument.layers[i];
//search for all .png Layers to save
var id = ".png";
var exist = layer.name.slice(-id.length) == id; // true
app.activeDocument.activeLayer = layer;
var activeLayer = app.activeDocument.activeLayer;
//save pic if .png
if(exist){
saveAll(); //just opens each layer in another doc and saves it as png then closes the documents without saving
}//end if
}//end for
// Close the Smart Object and move to next one
activeDocument.close(SaveOptions.DONOTSAVECHANGES);
}//first smart
}//end function
I found the solution. it was just a little mistake with the call of the recursive part(i did it too early) and an if that checks for a smart inside a smart. so the last bit of the code right after the if(exist) thing should be:
if(y == 0){
findSmart(layerNode[y].layerSets);
}
//Close the Smart Object and move to next one
activeDocument.close(SaveOptions.DONOTSAVECHANGES);
}//next smart if any
}//end for
}//end function

Get array values and put them into different divs with a for loop?

I'm trying hard to learn javascrip+jquery on my own, and also trying to learn it right. Thus trying to enforce the DRY rule.
I find myself stuck with a problem where I have an array,
var animals = [4];
a function,
var legs = function(amount){
this.amount = amount;
this.body = Math.floor(Math.random()*amount)+1;
}
and an evil for loop. I also have 5 div's called printAnimal1, printAnimal2 and so on.. In which I wish to print out each value in the array into.
for(i = 0; i < animals.length; i++){
animals[i] = new legs(6);
$(".printAnimal"+i).append("animals[i]");
}
I feel as if I'm close to the right thing, but I cant seem to figure it out. I also tried something like this:
for(i = 0; i < animals.length; i++){
animals[i] = new legs(6);
$this = $(".printAnimal");
$(this+i).append("animals[i]");
}
But one of the problems seem to be the "+i" and I cant make heads or tails out of it.
I also know that I can simply do:
$(".printAnimal1").append("animals[i]");
$(".printAnimal2").append("animals[i]");
$(".printAnimal3").append("animals[i]");
...
But that would break the DRY rule. Is it all wrong trying to do this with a for loop, or can it be done? Or is there simply a better way to do it! Could anyone clarify?
Your first attempt should be fine, as long as you take "animals[i]" out of quotes in your append() call ($(".printAnimal"+i).append(animals[i]))
Also, I assume you declared var i; outside your for loop? If not, you'll want to declare it in your for loop (for(var i=0....)
EDIT: problems with your fiddle
you never call startGame()
you didn't include jQuery
you can't (as far as I know) append anything that isn't html-- in your case, you're trying to append a js object. What do you want the end result to look like?
http://jsfiddle.net/SjHgh/1/ is a working fiddle showing that append() works as you think it should.
edit: forgot to update the fiddle. Correct link now.
EDIT: reread your response to the other answer about what you want. http://jsfiddle.net/SjHgh/3/ is a working fiddle with what you want. More notes:
You didn't declare new when you called DICE
you have to reference the field you want, (hence dices[i].roll), not just the object
Just a few comments:
This is declaring an array with only one item and that item is the number 4
var animals = [4];
In case you still need that array, you should be doing something like:
var animals = []; // A shiny new and empty array
and then add items to it inside a for loop like this:
animals.push(new legs(6)); //This will add a new legs object to the end of the array
Also, what is the content that you are expecting to appear after adding it to the div?
If you want the number of legs, you should append that to the element (and not the legs object directly).
for(i = 0; i < animals.length; i++){
animals.push(new legs(6));
$(".printAnimal"+i).append(animals[i].body);
}
Adding another answer as per your comment
var i, dicesThrown = [];
function throwDice(){
return Math.ceil(Math.random() * 6);
}
//Throw 5 dices
for (i=0 ; i<5 ; i++){
dicesThrown.push( throwDice() );
}
//Show the results
for (i=0 ; i<5 ; i++){
$("body").append("<div>Dice " + (i+1) + ": " + dicesThrown[i] +"</div>");
}

Java Script fetches Document objects in infinite loop

I am writing a code to add a div depending on a set of 'object' found in document on click of button.
When Document.getElementsByTagName('object');
there is only one object, but it goes in to an infinite loop! giving me incremented value of swf.length incremented by one infinitely in an alert.
can you help whats wrong am i doing!
<script>
function get2(){
var swf = document.getElementsByTagName('object');
for (j=0;j<swf.length ;j++ )
{
alert(swf.length);
var objs = swf[j].getElementsByTagName('param');
for(i=0;i<objs.length;i++){
id = objs[i].getAttribute('name');
if (id == 'src'){
source = objs[i].getAttribute('value')
dv = document.createElement('div');
dv.setAttribute('id','myContent');
dv.setAttribute('border','2');
document.getElementsByTagName('body')[0].appendChild(dv);
/* code to embed a new swf object in new Div*/
}/*if*/
}/*for*/
}/*outer for*/
}/*function*/
here is the HTML part:
<body>
<div id="old">
</br><h1> Hello </h1>
<object id="myId1" width="250" height="250" name="movie1" classid="clsid:d27cdb6e-ae6d- 11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0"><param name="src" value="whitebird.swf">
</object>
<h1> welcome to flash</h1>
</div>
</br>
<input type="button" onclick="get2()" value="Insert"/>
</body>
Put a breakpoint in your inner for loop and inspect the values of j, i, and getElementsByTagName('object').length as well as swf[j].getElementsByTagName('param').length after the first iteration and post the results. Try getting your length outside the loop (which is good practice anyway). Also use the var keyword in your loops:
var objectLength = swf.length;
for (var j = 0; j < objectLength; j++)
{
...
}
You aren't adding more object tag in your div and just omitted that code are you?
I think the issue is that you're looping on the length of a dynamic array returned from getElementsByTagName('object') and then inside that loop you're adding a new object tag which will increase the array which will cause the loop to extend again which will add another object which will extend the loop again - forever. You can fix that by not looping on .length, but by getting the length of the initial array and only looping on that. Here are other things I suggest you fix too.
Use local variables, not global variables.
When you use getElementsByTagName, they return dynamic arrays that can change in length as you manipulate things. It's safer to loop on the initial length and thus never have infinite loop risk.
You can use document.body instead of document.getElementsByTagName('body')[0].
Some semi-colons missing.
Here's fixed up code that has these fixed/protections in it.
function get2(){
var swf = document.getElementsByTagName('object');
for (var j = 0, len = swf.length; j < len ; j++ )
{
var objs = swf[j].getElementsByTagName('param');
for(var i=0, oLen = objs.length; i < oLen; i++){
var id = objs[i].getAttribute('name');
if (id == 'src'){
var source = objs[i].getAttribute('value');
var dv = document.createElement('div');
dv.setAttribute('id','myContent');
dv.setAttribute('border','2');
document.body.appendChild(dv);
/* code to embed a new swf object in new Div*/
}/*if*/
}/*for*/
}/*outer for*/
}/*function*/
When using any of these dynamic arrays, I always prefetch the length of the array into a local variable and loop on that to avoid every having this situation.
There are two things here that make me suspicious.
The only thing that looks really suspicious to me is the following line:
document.getElementsByTagName('body')[0].appendChild(dv);
You're modifying the DOM here. What's this element that you're modifying here?
The structure of your outer loop:
for (j=0; j<swf.length; j++) { ... }
Its termination condition presumes that swf.length doesn't change.
There is a particular situation I can imagine where these two things can clash. What if you end up appending each new div right into the SWF element?

Categories