tivaelydoc
147 posts
|
The easiest way to show you is with this fla:
http://tivaelydoc.110mb.com/soundbut.fla
Or swf (hold space and click on button to notice error):
http://tivaelydoc.110mb.com/soundbut.swf
Pretty much, as you can see from the swf, I have an array of words stored on buttons. What I want to do is when you hold space and click on the button, it loads the link with whatever word is in the array. This is the AS:
var wordlist:Array = Array(“dog”, “bowl”, “fighting”, “chair”, “venezuela”, “dog”, “bowl”, “fighting”, “chair”, “venezuela”, “bowl”, “fighting”, “chair”, “venezuela”);
for (i=0; i<5; i++) {
//button shit
words.onPress = function() {
if (Key.isDown(Key.SPACE)) {
getURL(“http://www.urbandictionary.com/”+wordlist[i],“_blank”)
} else {
//play sound
}
}
}
How come it’s not loading the right word? It’s only opening chair.
|
|
|
Phantasmagoria
728 posts
|
Ah, this error again. A common misunderstanding of how closures work.
As you run through the loop, assigning that function to several buttons, what you’re really doing is creating something called a closure and assigning that to the buttons. A closure is a function, plus the environment that the function exists in – in other words, since this function refers to something outside the function (your i variable), it has to keep track of this in order to be able to find i later on when a button is pressed.
(This is a bit of a complicated subject and you may not understand all the ramifications of it unless you play around with closures for a while)
Now, in your code, you create only one i variable. All of your closures, on all of the different buttons, refer to this same variable. Because of this, they naturally all do the same thing.
To make them do different things, you have to create different variables for them to refer to. In Actionscript, the easiest way to do this is to embed the creation of the closure within a separate function, like this:
function makeButtonFunction(i) {
return function() {
if (Key.isDown(Key.SPACE)) {
getURL(“http: //www.urbandictionary.com/"+wordlist[i],"_blank")
} else {
//play sound
}
}
}
for (i=0; i<5; i++) {
words.onPress = makeButtonFunction(i);
}
When this code is run, a new i variable will be created every time makeButtonFunction is called, so each of your closures will refer to a different i, and the values of these variables won’t change.
|
|
|
tivaelydoc
147 posts
|
That makes sense, but where do I put the attached buttons?
If I do this:
function makeButtonFunction(i) {
return function() {
words = attachMovie(“wordbut”, "wordbut"+(i+1), getNextHighestDepth());
words.x = (words.width/2)10;
words.y = mcStarty;
mcStart_y += (words._height10);// gives the next button a new location on screen
words.butt_text.text = wordlist[i];// prints the text to a dynamic text field in each instance of the movieclip
words.onPress = function() {// makes each instance clickable
if (Key.isDown(Key.SPACE)) {
getURL(“http://www.urbandictionary.com/”wordlist[i],“_blank”)
} else {
root.ss = new Sound(this);
_root.ss.setVolume(vol);
_root.ss.attachSound(this.butttext.text);
_root.ss.start(0,1);
}
};
words.onRollOver = function() {
this.gotoAndPlay(2);
};
words.onRollOut = function() {
this.gotoAndPlay(1);
};
}
}
for (i=0; i<5; i+) {//the array’s first value has its 0’ path
words.onPress = makeButtonFunction(i);
}
It’s doesn’t attach them. I tried moving them around and whatnot, but I can’t seem to get it to work.
|
|
|
Phantasmagoria
728 posts
|
Woah, woah, woah, why are you putting all that junk into makeButtonFunction? makeButtonFunction should return the function that you want to assign to the button’s onPress, and nothing else. (Perhaps I should’ve called it makeClosureToBeAssignedToWordButtonDotOnPress?) All it does is to create a closure and return it, it doesn’t assign anything to anything, it doesn’t even know about the buttons.
The way that code is written, you have the code that actually creates the button inside a function that won’t be executed until the button is clicked on. That’s silly.
|
|
|
tivaelydoc
147 posts
|
Alright. So where do I put what code?
I guess I don’t understand your syntax. If I put the script for the link and for the sound button to play in the makeButtonFunction, and the rest in the words.onPress = function() { it doesn’t work. I tried this before and it don’t load the buttons.
|
|
|
Phantasmagoria
728 posts
|
You don’t seem to understand what the problem in the original code was, or how my code works…
Everything except the creation of the closure which is assigned to onPress should be exactly the same as you originally had it.
This:
words.onPress = function() {
if (Key.isDown(Key.SPACE)) {
getURL(“http: //www.urbandictionary.com/”+wordlist[i],"_blank")
} else {
//play sound
}
}
should be replaced with this:
words.onPress = makeButtonFunction(i);
and this should be added somewhere in your code, doesn’t matter where so long as it can be called when needed:
function makeButtonFunction(i) {
return function() {
if (Key.isDown(Key.SPACE)) {
getURL(“http: //www.urbandictionary.com/"+wordlist[i],"_blank")
} else {
//play sound
}
}
}
Change nothing else from the way you originally had it, and it should work.
(oh, and make sure to remove the space from the url string… I have to write it with a space here or Kongregate’s broken formatting will mess up the code.)
|
|
|
tivaelydoc
147 posts
|
where do i put the for loop?
|
|
|
Phantasmagoria
728 posts
|
The for loop should be exactly where you had it before. I didn’t tell you to change it, so don’t change it.
|
|
|
tivaelydoc
147 posts
|
thats what i thought, but i tried that earlier when i was moving things around and I still can’t get it to work:
words.onPress = makeButtonFunction(i);
function makeButtonFunction(i) {
return function() {
words.onPress = function() {// makes each instance clickable
if (Key.isDown(Key.SPACE)) {
getURL(“http://www.urbandictionary.com/”+wordlist[i],“_blank”)
} else {
root.ss = new Sound(this);
_root.ss.setVolume(vol);
_root.ss.attachSound(this.butttext.text);
_root.ss.start(0,1);
}
};
}
}
for (i=0; i<5; i++) {//the array’s first value has its 0’ path
words = attachMovie(“wordbut”, "wordbut"+(i+1), getNextHighestDepth());
words.x = (words.width/2)10;
words.y = mcStarty;
mcStart_y += (words._height10);// gives the next button a new location on screen
words.butt_text.text = wordlist[i];// prints the text to a dynamic text field in each instance of the movieclip
words.onRollOver = function() {
this.gotoAndPlay(2);
};
words.onRollOut = function() {
this.gotoAndPlay(1);
};
}
|
|
|
Phantasmagoria
728 posts
|
_
Your code is horribly wrong, not at all like what I told you to do, and it’s obvious that you don’t understand what’s going on.
Seriously, if you’re writing stuff like this:
function makeButtonFunction(i) {
return function() {
words.onPress = function() {// makes each instance clickable
you clearly don’t understand the flow of execution within that code.
Since you can’t even copy the code I gave you without breaking it, I see no reason to bother with this any further. Go study Actionscript’s syntax, closures, and higher order functions, and then maybe you’ll be able to understand it.
|
|
|
tivaelydoc
147 posts
|
Yea I know it’s horribly wrong :p
I was that as an example cuz I don’t understand closures at all.
Ohh, I see. So like this without the onPress cuz it calls it from the makeButtonFunction:
words.onPress = makeButtonFunction(i);
function makeButtonFunction(i) {
return function() {
if (Key.isDown(Key.SPACE)) {
getURL(“http://www.urbandictionary.com/”+wordlist[i],“_blank”)
} else {
//sound shit
}
}
Then I just leave all the shit in my for loop?
|
|
|
Phantasmagoria
728 posts
|
Yes. That’s why I pointed you in the direction of the things you need to study, closures among them.
Go study them.
There’s nothing stopping you from understanding them if you bother to learn.
|
|
|
tivaelydoc
147 posts
|
Like, I just changed everything to exactly what you said. I took out the words.onPress inside the makeButtonFunction and left everything alone.
|
|
|
Phantasmagoria
728 posts
|
The makeButtonFunction should work now, but you still have the words.onPress line in the wrong place. It should be where the code it replaced was, since that’s what it means to replace something.
|
|
|
tivaelydoc
147 posts
|
Oh yea, in the for loop. That makes sense.
So, why does it still load the wrong ones?
Here is my FLA:
http://tivaelydoc.110mb.com/soundbut.fla
|
|
|
tivaelydoc
147 posts
|
Ya know, I’ve been staring at this for awhile and trying various shit, and I still can’t figure it out.
|
|
|
ruudiluca
3366 posts
|
|