i integer does not +1 the 1st time - actionscript-3

I have a gallery where it will load an image after a previous image is loaded, so every time 'i' will +1 so that it could move to the next image. This code works fine on my other files, but I dunno why it doesn't work for the current file.
Normally if I trace 'i' the correct will be
0,1,2,3,4,5,6... etc
adding on till the limit, but this files its 'i' repeat the 1st number twice, only it continues to add
0,0,1,2,3,4,5,6...etc
The code is completely the same with the other file I'm using, but I don't know why it just doesn't work here. The code does not seems to have any problem. Anyway i can work around this situation?
private var i:uint=0;
private function loadItem():void {
if (i<myXMLList.length()) {
loadedPic=myXMLList[i].thumbnails;
galleryLoader = new Loader();
galleryLoader.load(new URLRequest(loadedPic));
galleryLoader.contentLoaderInfo.addEventListener(Event.COMPLETE,picLoaded);
} else {
adjustImage();
}
}
private function picLoaded(event:Event):void {
var bmp=new Bitmap(event.target.content.bitmapData);
bmp.smoothing=true;
bmpArray.push(bmp);
imagesArray[i].addChild(bmp);
i++;
loadItem();
}

That code looks fine, it's really very difficult to tell what might be causing that. The best advice I can give you would be to set some break points; for example set one at the point where you add the event listener to the galleryLoader object, and then run Flash's debugger. You run it by going to Debug > Debug Movie.
The debugger will stop at that line, and you will be able to look in the Variables window to see your i variable as you step through the code line-by-line. You step through by pressing the step in button, inside the Debug Console window. I've put in an image below showing the debugger's specific windows (that you won't see at any other time in Flash):
I think that by doing that (if you haven't already tried, that is) you should pretty quickly see what's going wrong. Hope it helps anyway.
debu

I've finally found out whats the problem.
public function grid():void {
addEventListener(Event.ADDED_TO_STAGE, add2Stage);
}
private function add2Stage(event:Event):void {
myLoader=new URLLoader();
myLoader.load(new URLRequest(galleryXML));
myLoader.addEventListener(Event.COMPLETE,processXML);
}
Its because I'm using adding the functions to stage. After I remove the add2stage function then everything's fine. But why will it affect and run the function twice at 1st? I'm just adding it to the stage to get the stage width.

Related

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 =)

as3 Air - AddChild works but is slooooooooooow

I am creating an app where when a button is pressed a very large picture is added to the stage (it is larger than the screen but can be dragged around by the user)
When the button is pressed the picture (well, movieClip) does come up and it able to be dragged fine, buttons inside it work.
The problem though is that there is a pause of about 6 seconds between the button press and the image appearing. I am using one .fla file for publishing and compiling (let's just call it Main.fla for now), and another one to hold all the graphics. The graphics are then added with this embed command:
[Embed (source = "assets/graphic.swf", symbol = "Content")]
private var Content:Class;
private var _content:*;
I have these lines where all the variables are declared (in between the class definition and the constructor function) I was under the impression that embedding it like this was equivalent to loading it at compile time. Is this true? What could be causing this lag when the button is pressed?
If I can't cut out the lag, another idea I had was to make some spinning circle or something to tell the user, "hey, don't worry. It's loading!"
If the slowness is at addChild you can add the asset to the stage much earlier and set it's visiblility to false, then when the button is clicked set it back to true. Obviously this is a small hack but might be sufficient for what you are doing.
var asset:MovieClip;
private function init():void
{
asset = new Content();
assset.visible = false;
addChild(asset);
button.addEventListener(MouseEvent.CLICK, onMouseClick);
}
private function onMouseClick(e:MouseEvent):void
{
asset.visible = true;
}
Embedding your SWF is probably not what is causing the delay.. or rather it would not likely be better if you imported the SWF into your FLA. Is this on a device? Chances are you would either have to devise a different way of loading your asset, or be satisfied with a loading animation.
If the main K size is coming from a large image, you could consider loading it in segments, starting with the part that is initially visible.

AS3 Frame script executing immediately rather than when specified

I have the following code which should add a MovieClip and add a frame script to the MovieClip to be executed once the clip has finished playing. The code shown below however triggers the frame script as soon as the MovieClip is added and I can't figure out why.
function debugClick(e:MouseEvent) : void
{
nextLevAnim = new NextLevelAnim();
gfx.addChild(nextLevAnim);
nextLevAnim.addFrameScript(nextLevAnim.totalFrames, NextLevel);
}
function NextLevel() : void
{
nextLevAnim.addFrameScript(nextLevAnim.totalFrames, null);
// Actions....
}
I've tried with simpler examples and it works fine, the MovieClip is 21 frames long and I've tried triggering the frame script by totalFrames and totalFrames - 1, running out of ideas!
hmm, I haven't worked with addFrameScript much so I can't tell what is causing the problems, but you could try using a hack.
use an onEnterFrame listener and check if the current frame equals the number of frames (-1).
it's not ideal, but if you're stuck on this it might just do.
as far as addFrameScript goes, my guess is that it's not working because addMovieClip doesn't take effect until the render part of cycle, so the totalframes are still 0 for the child added. You can add a listener for onAddedToStage or onAdded and add the addFrameScript event handler after the MovieClip gets initialized
What is totalFrames variable in this case? Have you tried to trace() it? I'm pretty sure it does not contain the proper value of the total number of frames in nextLevAnim and you should probably use nextLevAnim.totalFrames instead.

hitTestObject, stopDrag stops drag on two movieclips even though function states one movieclip to stop drag

I have a function that states when movieclip1 is dragged and hits a line then it stops the drag, however it seems to stop the entire drag function in the swf on the other movieclips even though they arent called in the function. Can somebody please help me with this.
Regards
T
Here is the code:
function hitTest(event:Event):void
{
if (movieclip1.hitTestObject(line))
{
movieclip1.stopDrag();
}
else
{
}
}
Are you absolutely positive you only have one instance of movieclip1 on your stage? Definitely double check. Are you creating them dynamically, or are they preloaded when your SWF loads?
If they're preloaded:
Perhaps during testing you made some quick copies of it, and now those copies have the same name and they're all responding the same. That's my first guess.
If they're loaded dynamically:
Check the function where they're being created. If you're naming them in a loop (with a number on the end like the above), be sure that you're properly increasing the numeric value used on the end.

AS3 Event listeners when data is changed?

Hopefully you will excuse me if this is a simple/silly question. I started learning action script about 6 days ago and already working on a small project :D
Anyways, there is a property that changes occasionally to reflect the name of a level in a game (object._I._M.text). It could take a minute to change, or a max of two minutes, depending on how fast all players are able to finish the level.
I want to be able to listen for the change in this property to fire off another function. I have found very few answers to this online, and the examples I have found were very incomplete and poorly written. Does anyone know how I could do this?
I have tried ...
theobject._I._M.addEventListener(Event.CHANGE, myfunction);
To no success. Thanks for any help or advice, I am going to get back to learning while I await responses :D
I would probably use getters/setters, or just declare one method to change the text of that textfield so that you can dispatch an event every time.
function changeLevel(text:String):void {
levelTf.text=text;
dispatchEvent(new Event("levelChange"));
}
I'll agree the Adobe docs are a bit "heavy" to look through. A good resource is the kirupa forum.
As for the TextField change event listener, your original code is very close. Here is a good example of how to add an event listener. The basics are:
public class Main extends Sprite {
// Store a reference to the text field
// (you're already doing this somewhere, so adapt as you see fit)
private var inputfield:TextField = new TextField();
public function Main() {
// Make sure the field is added to an on-screen Sprite
addChild(inputfield);
// Add the event listener.
// I recommend adding the 'false, 0, true' params. There are lengthy
// discussions around about this.
inputfield.addEventListener(Event.CHANGE, changeListener, false, 0, true);
}
// This function gets called every time the event is fired.
private function changeListener (e:Event):void {
trace("event");
}
}
Hopefully that gets you started in the right direction.