AS3 Global Variables - actionscript-3

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

Related

How can I transfer code inside of a symbol in Flash to my document class?

I am pretty new to coding in general so I'll admit my understanding of inheritance is poor. I have this code that works when it's embedded in a symbol in my Fla doc, but I can't figure out how to transfer it to the Main document.
stop();
stage.focus = input_txt;
var outputText:String;
input_txt.visible = true;
input_txt.addEventListener(KeyboardEvent.KEY_DOWN, pressEnter);
function pressEnter(e:KeyboardEvent):void {
if(e.charCode == 13) {
captureText();
this.nextFrame();
}
}
function captureText():void {
outputText=input_txt.text;
}
All that code occurred on frame2 of the office_mc symbol, and then frame 3 has this:
output_txt.text = outputText;
I'm aware that I needed to reference the txt objects as office_mc.input_txt inside the main document since they are embedded. I'm also aware that outputText would need to be a global variable. But no matter how I tried to move things around I kept having an error due to something being null. For a little background information, I'm just trying to have user input displayed in a different area within this symbol.
Could someone explain or give an example of how to execute this code in a document class? Also I'm just totally confused about how to communicate between classes in general so if anyone could point me towards tutorials or example code that could help with that understanding, it'd be greatly appreciated. :)
Don't code in timeline at all (this is a good practice).
You should use only classes which eventually points to objects from the timeline.
Here you have some good tutorials:
How to Use a Document Class
AS3 OOP (good tutorial)

Flash Escape Game Item

I'm making a flash game that requires picking up items. The item disappears when you click on it, but it reappears when you leave the room and come back. I tried setting a variable in the function and then using an if statement in the main code but that didn't work because the variable is local. And if I declare the variable outside the function, it reinitializes when you enter the frame(return to the room). A global variable should solve this problem. I know everyone says they're bad to use but I'm just looking for a solution.
//Pick up key
key_btn.addEventListener(MouseEvent.MOUSE_UP, getKey);
function getKey(Event: MouseEvent):void{
var gotKey:Boolean = true;
}
if(gotKey == true){
key_btn.visible = false;
}
First of all: I suggest you to keep all codes in one frame and use movieclips to represent different rooms.
You can add a layer for the global vars and expand it, such as this:

Actionscript 3 problems with "Call to a possibly undefined method"

Thanks partly to info from people here, I'm getting more comfortable with Actionscript 3, but I've got a problem that is very puzzling.
The program (done entirely in AS3, no Flash) has several different screens. One does music and it's working very well. Another does video. Obviously when somebody goes from music to video we need to make sure the music is turned off. There is a Main screen that handles going from one to the other.
I started out doing it this way, and the reason I got "Call to a possibly undefined method" is obvious. The following is in the Main class, with the "private var" part inside the class but external to the functions and the "music = new MusicPanel" part in one of the functions:
private var music:MusicPanel;
music = new MusicPanel(trackNames.songNames, trackNames.numSongs);
When switching to the video panel, I added a public function in MusicPanel called StopMusic and called it when the user went to the video panel:
if(music != null)
music.StopMusic();
That got the error:
Call to a possibly undefined method StopMusic
I was checking to make sure music was not null, but that error didn't seem like a bad thing. So I changed the code to:
private var music:MusicPanel = new MusicPanel();
and added a function that would get the song names and number of songs to the music class. That did not help- I got the same error, and in fact the function that tried to put the song names and number of songs got the error also.
At the same time, the Video panel does not give me that error, even though I have laid it out in exactly the same way.
private var video:VideoPanel = new VideoPanel;
video.PlayVideo();
I do a fair amount of setup on the music screen when it gets called as a new class, I do less setup for the video screen. I'm not sure if that makes a difference.
Clearly there is something I don't understand here. Anybody got any idea what's going on? I've looked at a number of questions about this, but have not found an answer. I think I'm doing this right, but the compiler thinks I'm doing it wrong, so I must be doing it wrong.
Later Note: One answer mentioned the difference between Sprite and MovieClip. I gave that a try, changing to MovieClip does not help, and the VideoPanel, which works, extends Sprite.
What is the base class of MusicPanel, Sprite or MovieClip? If Sprite, change to MovieClip and see what that does. In AS3 Sprites are not dynamic, so can't take properties that are not inherent in the class.
It appears that the problem is coming either from Actionscript 3 or from FlashDevelop. I built a new module (SongsPanel) which is very close to the same as the original MusicPanel. It works. If I add a public function in MusicPanel the compiler comes back with the same error. If I add a public function in SongsPanel everything works.
Does FlashDevelop keep track of errors in some hidden file? I'm guessing that's what's going on, and that there is a bug in the way that is done.
PITA!- but at least it now works.

as3 Variables changing impossibly

I'm having an issue with a "Point" type variable velocity changing without any calls to change it.
private function framecode(e:Event) {
trace(getVelocity().y);
tracks.gotoAndStop(2);
trace(getVelocity().y);
}
This code is part of a class called "tank" which extends the one that velocity is used in (my moving object class). velocity is a private point type variable and getVelocity() is a public access method. tracks is a named movieClip contained inside the one linked with tank. The event listener is ENTER_FRAME. There is no coding on the frames of tracks.
Somehow these two traces give different values (the first one being correct) and I can't figure out how the gotoAndStop() can possibly effect it (and hence how to fix it).
I've found that play() does not reproduce the bug but prevFrame() and nextFrame() do. As the variable is private this class should not even have access to it to change it.
Another strangeness is that if the event listener is changed to FRAME_CONSTRUCTED or EXIT_FRAME, there is massive lag and my movieClip randomly disappears after a few seconds.
Thank you for reading, any help would be appreciated.
Your velocity variable is private, so one one can access that outside of the class.
However, getVelocity() is returning a reference to your velocity variable. Once someone has that reference, they can change the values of it's properties: getVelocity().y = 3. So it's not impossible for this to happen.
One way to trouble shoot this is to add a trace() statement to/set a breakpoint in getVelocity() so you can see where it's being used.
You could do something similar w/the Point class, but you'll have to extend it, add getter/setter methods for y (that traces out when they are called), and modify your code to use the getter/setter. This might be worthwhile (its simple enough), and the act of modifying your code to use the getter might help you discover where the problem is.

i integer does not +1 the 1st time

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.