Defining for loop iterator before the for loop? - actionscript-3

Recently I'd been criticized for structuring my for loops like so:
var i:MovieClip;
for each(i in array)
{
// be awesome
}
Or,
var i:uint = 0;
for(i; i<10; i++)
{
// be more awesome
}
This reads better for me personally, yet I'm being attacked for it. Is there any difference?

Old Answer
Yes: The way you're doing it, the variable lives on after the loop ends. Making sure the variable doesn't exist outside of the scope of the loop ensures that you never accidentally refer to it outside the loop.
Update:
At least that's how most languages do it. However, in ActionScript the for loop variable is in the scope of the parent! So there really is no difference in ActionScript.

trutheality's answer is the best consideration in most languages, and a great response considering that this question wasn't tagged actionscript-3 until later.
However Actionscript uses variable hoisting where variables defined anywhere in the function are scoped to that function rather than its inner most block. This blog post describes it well, and it's mentioned in the docs on variable scope. Due to hoisting, there is no difference in Actionscript between defining the variables before or inside the loop.
To show how crazy this can get, you can even define the variable after the loop:
for (i = 0; i < 5; i++) {
trace(i);
}
var i:int;

Related

How do I execute functions in actionscript 3?

I'm completely new to actionscript (as3, not as2) and am having some problems with some simple functions and variables. Everything is in one .fla using the actions panel.
How do I get functions to execute? Nothing of my shape changes and there is no output.
*I am aware the first change won't be noticeable, I'll add a timer later on.
Here is the code*:
var starBlackWidth = 500;
var starBlackScaleX = 0.5;
function starStretch(){
starBlack.length = starBlackWidth;
trace("Stretched the star.");
}
function starReadjust() {
starBlack.scaleX = starBlackScaleX;
trace("Attempted at readjusting without using the width directly.");
}
As some of the commenters pointed out, yes you need to call the functions you created by adding these two lines of code.
starStretch();
starReadjust();
To expand upon what they said, yes these may be fundamental concepts of programming but if you're new to object oriented programming in as3 and even oop in general this link is extremely helpful at getting you going in as3, its 3 parts and it covers it pretty well!
http://www.untoldentertainment.com/blog/2009/08/25/tutorial-understanding-classes-in-as3-part-1/

using time intervals between sound failing flash as3

hi need to have a timer class that actually has very descent timming:
var playTimer:Timer = new Timer(1000);
playTimer.addEventListener(TimerEvent.TIMER,playhead);
playTimer.start();
function playhead(e:TimerEvent):void
{
for ( i = 0; i<myArray.length; i++)
{
soundArray[0].play();
break;
}
}
The above works but sadly the sound is not accurate, the sound playing is a clap like noise, theory i would presume it would clap on an even interval but it doesnt. any help would be apreciated
Not sure exactly what you are trying to do by playing a sound multiple times, based on the length of myArray, and then breaking.
But anyways, the the play() method of a Sound does accept parameters, and one of them is how many times you'd like to loop.
try this alone, without all that timer code etc :
sound.play(0,5);
The 0 cues it at the beginning of the sound, which is the default.
the 5 specifies to loop 5 times.

AS3 Global Variables

Ok so I have managed to do this once before but I simply cannot remember how or find the source I found back then. I am making a simple flash game. There are several characters moving. To make each level more difficult than the other I have decided to alter the movement speed of each character from level to level. If I declare and assign values to these variables on my main timeline in frame 1 it doesn't work the way I want it. When you go to level 2, which is in another frame, the speed goes up like it should. But when you go to the next level, which is level 1 with higher movement speed, the value assignment is processed again, which means the movement speed goes back to scratch.
//frame 1
var speed:int = 5;
//level accomplished, speed++, goto frame 2
//frame 2
//level accomplished, speed++, goto frame 1
And then all the code on frame 1 runs again, setting the value of "speed" back to 5.
I have tried putting the variable in a class, but the problem is still the same, everytime it goes back to frame 1 the code "var speed:Speed = new Speed();" runs again and the value of the variable goes back to whatever I assigned in the speed.as file.
I have tried so many different combinations to just make the global variables inside a package but outside any class so that it is always globally accessible without creating a new object.
Here is my current code:
//speed.as
package
{
public var speed:int = 5;
}
//game.fla
import speed;
trace(speed);
This throws the error "Access of possibly undefined property speed..."
As I said, I have tried many different combinations and got a lot of different errors, been googling and digging for 8-9 hours and it's driving me crazy. You guys are now my last hope, I would be very grateful for an answer easily telling me how to use my global variables (I know global variables are bad, seen a lot of people writing it even though I don't really know why), if there is another easy and better solution please do tell, but I don't want to rewrite the entire code or anything to make it compatible with some other solution. I know that global variables will solve this problem for me, I just don't know how to use them.
I will need instructions on what to do in both the .as file and the .fla file. Thanks in advance!
Does it cycle between frame 1 and 2? If it does, use functions to do it instead. You don't need the .fla.
//Declare variables
var speed:int = 5;
//In this case I use a button to transit into the frame. Edit the code as you wish.
btnLevel1.addEventListener(MouseEvent.CLICK, level1);
private function level1(e:MouseEvent):void
{
MovieClip(root).gotoAndStop(2);
speed++;
//Your other code for the level goes here
btnLevel2.addEventListener(MouseEvent.CLICK, level2);
}
private function level2(e:MouseEvent):void
{
MovieClip(root).gotoandStop(3);
speed++;
//Again, your other code goes here
btnLevel1.addEventListener(MouseEvent.CLICK, level1);
}
Should work, I think.
I think you should try changing it to
package{
public class Speed{
public static var SPEED:int = 5;
}
}
and then access it via
trace(Speed.SPEED)
But: this is very dirty :)
Ok so I found a little workaround, not global variables in a separate package, but variables that can be accessed by my entire timeline.
I simply made an extra frame with just code. In this frame I put my variables + a frameCounter variable. On my first frame I put this code:
if (frameCount == 0)
{
gotoAndStop(7);
}
So the code declaring the variables only runs once. Probably not the best solution but atleast it works as intended =)

Basic DOJO 1.8: How to get a reference to a method?

I'm am pretty new to DOJO 1.8 and would like to know how I can call a function from outside a require-method? I try to implement a message-box which fades in and out.
I created the method:
require(["dojo/dom", "dojo/on", "dojo/domReady!" ], function(dom, on, ready) {
/*function which shows a msg-box on top of the page */
var showMsg = function(text) {
dom.byId("msgbox").innerHTML = text;
}
});
OK! IT works....but I no I would like to call it from somewhere else in my application:
showMsg("Item saved");
But that doesn't work: Uncaught ReferenceError: showMsg is not defined
How do I get that reference?
Thank you for your help!
AFX
As things stand you're declaring a local variable and so it's not visible elsewhere in the program.
You could make the variable global, for example
window.showMsg = function(text) {
dom.byId("msgbox").innerHTML = text;
}
The downside of this approach is that as you application gets bigger you end up with more and more global variables and that makes maintenance harder.
So Dojo offers ways to package chunks of reusable code and refer to them. You are already exploiting some of those capabilities when you use "require" - you're getting access to chunks of dojo. You can make your own code visible as reusable chunks in the same way.
This is quite a big topic, but you could start by reading this
Another thing you can do is to move the require inside the function.
Even if you have many such functions, while it's annoying to repeat, there is essentially no runtime penalty for requiring over and over. The only thing to watch for is that code inside the function becomes asynchronous, so instead of returning a value you have to use a callback or promise.
Alternatively, if you're only using this function from within some event handlers (I see dojo/on), you can set them up within the scope of this same require block.

Conflict between Mootools and a pure JS script

I am stuck with a pure JS script that should be included in Joomla (1.7, Mootools 1.3.2)
and raises a conflict with this library while working perfectly outside it.
Examples :
no Mootools
http://jsfiddle.net/2W87v/
with Mootools
http://jsfiddle.net/2W87v/1/
Firebug error around line 133 :
document.getElementById("pu_" + champs[i]) is null
I tried all kinds of solutions, renaming certain variables, using $ instead of document.getElementById, wrapping each function around an anonymous function. To no avail.
If someone could point in the right direction, I'd be very grateful.
mootools is prototypical.
var champs = ['surfaceMaison','surfaceGarage','terrasseCouverte','terrasseNonCouverte','cloture'];
var prix = ['pack','valeur','valeur','valeur'];
var options = ['toitureMultipentes','doucheItalienne','wcSuspendu','enduitTaloche','voletsRoulants','climGainable'];
// and..
for (var i in champs)
for (var i in options)
is a no go as is, it will go up the prototype chain and get the stuff mootools adds to the Array prototype.
in general, for var in object as a construct has always been intended for OBJECTS and not arrays. it works anyway, because in javascript you don't have a proper Array type, it's just an Object type with Array-like properties (eg, length).
loop the arrays via options.each(function(el, i) {} or a normal for loop instead.
also, you can check for hasOwnProperty:
for (var i in champs)
if (champs.hasOwnProperty(i)) {
// do the stuff
}