I'm an experienced programmer but just starting out with Flash/Actionscript. I'm working on a project that for certain reasons requires me to use Actionscript 2 rather than 3.
When I run the following (I just put it in frame one of a new flash project), the output is a 3 rather than a 1 ? I need it to be a 1.
Why does the scope of the 'ii' variable continue between loops?
var fs:Array = new Array();
for (var i = 0; i < 3; i++){
var ii = i + 1;
fs[i] = function(){
trace(ii);
}
}
fs[0]();
Unfortunately, AS2 is not that kind of language; it doesn't have that kind of closure. Functions aren't exactly first-class citizens in AS2, and one of the results of that is that a function doesn't retain its own scope, it has to be associated with some scope when it's called (usually the same scope where the function itself is defined, unless you use a function's call or apply methods).
Then when the function is executed, the scope of variables inside it is just the scope of wherever it happened to be called - in your case, the scope outside your loop. This is also why you can do things like this:
function foo() {
trace( this.value );
}
objA = { value:"A" };
objB = { value:"B" };
foo.apply( objA ); // A
foo.apply( objB ); // B
objA.foo = foo;
objB.foo = foo;
objA.foo(); // A
objB.foo(); // B
If you're used to true OO languages that looks very strange, and the reason is that AS2 is ultimately a prototyped language. Everything that looks object-oriented is just a coincidence. ;D
Unfortunately Actionscript 2.0 does not have a strong scope... especially on the time line.
var fs:Array = new Array();
for (var i = 0; i < 3; i++){
var ii = i + 1;
fs[i] = function(){
trace(ii);
}
}
fs[0]();
trace("out of scope: " + ii + "... but still works");
I came up with a kind of strage solution to my own problem:
var fs:Array = new Array();
for (var i = 0; i < 3; i++){
var ii = i + 1;
f = function(j){
return function(){
trace(j);
};
};
fs[i] = f(ii);
}
fs[0](); //1
fs[1](); //2
fs[2](); //3
Related
I have a List of the type Model. when I loop all its elements and loop the next one except for the last one, then change the last one manually, the one before changes.
here is a little code to reproduce the problem (also you can run it directly in dartpad from here)
void main() {
List<Model> s = [];
for (int i = 0; i < 5; i++) {
s.add(Model(i));
}
for (int i = 0; i < s.length - 1; i++) {
s[i] = s[i + 1];
}
print(s);
s[s.length-1].x = 100;
print(s);
}
class Model {
int x;
Model(this.x);
#override
String toString() => 'x: ' + this.x.toString();
}
notice that this problem does not happen when you comment out the for loop or the manual change, or instead of changing the last one's property, you reassign a new value to it, like s[s.length - 1] = Model(100);. seems like dart for some reason is re-running the loop.
When you run the second for loop, you assign the i + 1th Model to the ith position in the list:
// initialise list
for (int i = 0; i < s.length; i++) {
s[i] = s[i + 1]
}
If you unwrap the loop, it looks roughly like this:
s[0] = s[1];
s[1] = s[2];
s[2] = s[3];
s[3] = s[4];
Notice that this leaves s[4] unchanged, but also assigns it to s[3].
In Dart, variables contain references to objects. This means that when your list runs s[3] = s[4];, both s[3] and s[4] point to the same object.
Now, if you modify s[4] you, are actually modifying the objects that s[4] refers to, which happens to also be the object that s[3] refers to, so they both appear to change in your list.
He,everyone. I'm new in ActionScript 3 and I don't understand where is my mistake.
for (var i:int = 0; i < 26; i++) {
button = new Sprite();
button.name = String.fromCharCode(65 + i);
button.graphics.lineStyle(2, 0x000000);
button.graphics.beginFill(0x00FF00);
button.graphics.drawRect( Keyboard_Container.x + i * ButtonSize,Keyboard_Container.y,ButtonSize,ButtonSize );
button.graphics.endFill();
button.addEventListener(MouseEvent.CLICK,InitLetter);
Keyboard_Container.addChild(button);
}
And the InitLetter function from event listener is
private function InitLetter(event:MouseEvent):void {
this.letter = event.target.name;
}
The error that I received is "ReferenceError: Error #1069: Property 0 not found on String and there is no default value."
Why I cannot gain access name of button trough event.target. Why? Thank you very much.
Your problem is in your main Hangman class, in the CheckLetter() function :
for (var i:int = 0; i < word.length; i++)
{
if (word[i] == currentLetter) // word is a String and not an Array
{
// ...
}
}
Here you should know that to get a char from a String, we use string.charAt(i), if you want to use an Array object, you can do :
word:Array = "word".split(""); // gives : ["w", "o", "r", "d"]
Also, I don't know why you are using this : setInterval(PlayGame,100);, normally you can check the word just when the user put a new letter and not every 100 ms ! and even you have to use it ( in another case ), it's better to use a Timer or just Event.ENTER_FRAME ...
Hope that can help.
Getting error on this:
for (i = 1; i <= 18; i++) {
oAllKits = myNode.getElementById('node' + i).getElementsByTagName('a');
}
I have a series of IDs on the html document called: node1, node2,... node18. I am trying to target the A tags on these IDs since these A tags are the only elements inside these ids. The console is giving me this message: # has no method 'getElementById'.
I am doing a for loop because I want the variable oAllKits to hold an all those A tags inside the Ids. Thank you advance for your help.
That can be done easily. Find it here
or you can see the code
var avar = document.getElementById('div');
var bvar = div.getElementsByTagName('a');
var cvar = children.length;
for (var i=0;i < len;i++) {
document.getElementById('aclass').innerHTML +='<br> ' + children[i].href;
}
getElementById exists on the document. There should be only 1 of any particular ID so the selector is fast.
var div = document.getElementById('id1');
var children = div.getElementsByTagName('a');
var len = children.length;
for (var i=0;i < len;i++) {
document.getElementById('found').innerHTML += '<br> ' + children[i].href;
}
http://jsfiddle.net/UhT2W/1/
I'm trying to distribute 3 objects randomly on my stage but it's not working. My movie is 800x800.
function makeRock():void{
var tempRock:MovieClip;
for(var i:Number = 1; i < 3; i++){
tempRock = new Rock();
tempRock.x = Math.round(800);
tempRock.y = Math.round(-800);
addChild(tempRock);
}
}
What am I doing wrong?
Replace Math.round(800); with Math.random()*800;
function makeRock():void
{
var tempRock:MovieClip;
var i:uint = 0;
for(i; i < 3; i++)
{
tempRock = new Rock();
tempRock.x = Math.random()*800;
tempRock.y = Math.random()*800;
addChild(tempRock);
}
}
Math.round(800) is just returning 800.
Math.random() returns a random number between 0 and 1, which you can multiply by 800 to get a random result of 0-800. A good note to make is that Math.random() never actually returns 1.0. Just everything from 0 up to 1.
Further reading:
As a side note: this makes it simple to return a random element from an array; because you're never getting 1 you can cast the result of Math.random()*array.length to uint() and always be within the boundaries of the array length.
eg.
var ar:Array = [1,2,"hello",4,5,6,7,8,9,0];
var randomElement:Object = ar[uint(Math.random()*ar.length)];
trace(randomElement);
Is it possible to execute a "foreach" through each of my SharedObjects?
Something like this . . .
_so = SharedObject.getLocal("test","/");
foreach (var item:Object in _so)
{
// print key name and value
}
I'm not sure I understand.
1.Do you want to loop through all your Shared Objects ?
2.Do you want to loop through all your objects inside the data property of a SharedObject ?
1.Assuming sharedObjects is an array containing SharedObject instances
var sharedObjects:Array = ['test','fred','louie'];
var sharedObjectsData:Array = [];
for(var i:int = 0 ; i < sharedObjects.length ; i++){
sharedObjectsData.push(SharedObject.getLocal(sharedObjects[i],"/").data);
}
//or something like that
2.Try using an old school for in loop.
for(var i in _so.data){
trace('property: ' + i + ' value: ' + _so.data[i]);
}
Hope it helps!