Why Does Flash Builder Make Every Instance Var a String? - actionscript-3

Suppose you are using flash builder(4.7) with flash professional (or bringing in flash professional assets in a swc or swf) and you have the whole screen in one symbol. So then you want to pull everything out into a variable. Something like this:
_pictureThing = _startScreen["pictureThing"] as Sprite.
It will give you the red under bar because you haven't mentioned _pictureThing yet. So you hit ctrl+1, choose make an instance variable. Sure. But now when you go up to the top of the class, it is a String! WHAT? I said as Sprite. The only thing I would expect this to be is a Sprite. How could this possibly not be a feature of Flash Builder? It's as if they went to almost the perfect editor and then said, "Nah. Let's just not finish it. Let's just make it do this crazy camera jumping instead". Making every variable type String may seem like not a big deal, but when you have a lot of variables the time really adds up. Maybe my way just works, but isn't actually the syntax that Flash Builder wants me to write it?

Since every object has a toString() implementation, if the Flash Builder editor cannot detect the supposed type of a variable, it assumes a String as default failsafe value for its type. The question of why did FB's devs not made it parse as statement as a supposed var type setter is open, my weird suggestion will be inheritance, as Sprite is a descendant of say DisplayObjectContainer type, so maybe that var should be of that type, or maybe one level less (EventDispatcher), or maybe Object right away. Probably the fix Fygo posted in comments can make it for you:
_pictureThing = Sprite(_startScreen["pictureThing"]); – Fygo 22 mins ago
but the inheritance ambiguity still remains. I say just let it be.

Related

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.

Flash CS3 (AS3) is giving my graphics (buttons and movieclips) outlines

So, I'm pretty much a beginner in Flash and Actionscript (using AS3, as I said in the title), and I'm trying to make a basic escape the room game. I haven't gotten far, and right now that's because every time I test my game (or publish preview it) the graphics get this annoying outline. Here it is when tested: http://i305.photobucket.com/albums/nn228/chokingondrama/flash.png
Every outline corresponds to some object present in the game, most of which have an alpha component of 0 since they're on different sides of the room. This didn't happen before, but once I added the code that allowed the player to change their view with the arrow (each viewpoint/wall is a different frame) these appeared.
It's a little different when published to HTML, basically it just gives each image a white background: http://i305.photobucket.com/albums/nn228/chokingondrama/html.png
Also, it would be nice if somebody could give me advice on how to make sure importing to flash won't result in lower quality.
Thanks in advance. If needed, I'll post any part of the code.
Some tips:
Don't set alpha to 0, instead use the visible property, setting movieclip.visible = false will make it a lot more efficient.
As for the importing and quality, after you import to stage or library, bring up the library (ctrl + l), and right click on the file you imported, go to properties. If it's an image, set compression to lossless, and allow smoothing.
For audio, go to file-> publish settings, and change audio stream and audio event (whichever you might use) to 128kbps.
As for your main question, I need more info, if you want you can post your source. It might be because of how you are placing your graphics on the stage.
For each of your MovieClips in question:
Try disabling button mode and see if the rectangles go away.
movieClipName.buttonMode = false;
If that doesn't help, or you really want button mode, try setting
movieClipName.tabEnabled = false;
There's a chance that since you added keyboard interaction each of your MovieClips are now expecting to be selected by the user when they press the tab key, much like any normal web form.
tabEnabled in the docs
You could also try
movieClipName.focusRect = false;
focusRect in the docs

AS3 How to communicate between frames

I have been writing a game in timeline code. I want the different frames (rooms) in the game to be able to share information between each other. Of course, timeline code is limited to the frame it is written in.
After doing quite a bit of reading ("Foundation Game Design with Flash" and a number of articles, tutorials, forums etc) I decided to employ a document class. This did not work either. It seems it only works for frame one but not the rest of the frames (I have four).
How can I have frame four respond to something that happpened in frame one? For example, if the player achieves something in frame one, I want a movie clip in frame four to be visible.
If You are writing your code on the timeline, My suggestion would be to create two layers in the timeline, one for 'frame-actions' - in this layer you insert the code specific to a single frame (will work when the movieclip is stopped on that particular frame).. And also create one more layer called global-actions (for the entire timeline). Only the first frame will be a key frame and there should be empty frames till the end of the timeline.
In this layer actions write the code that you want to access from any keyframe in the same timeline.
If you define a variable in the actions which are written for the whole timeline (global-actions) then that will be available on all the frames.
Now if you want to go to a different frame based on some action, just write some functions in the layer which contains global actions and call that particular function through the frame actions. To go to a different frame use the 'gotoAndStop(frameNumber)' function of flash.
I want to tell you that while it will work, I would not recommend using it in this way.
HTH.
You can use static variables - these are variables which are linked to a class, rather than an instance of it.
Suppose your document class was called Document.as, and you wanted a variable, playerLives, to be visible from any part of the program.
Declare it inside Document.as:
public static var playerLives:int = 3;
You can then reference this directly from anywhere else in your code with:
Document.playerLives
(note that the variable is a member of the class itself, not an instance of it).
You could use a dedicated Statics class to hold these variables if you want to keep your document neat, or attach them to the relevant classes (eg Player.lives)
I've not used timeline/frames for some years but I believe this is how I used to do it!
NB Statics will be fine for your purposes but they are, in some ways, an equivalent to the _global variable in AS2 (at least, they can be used in the same manner) - many would not approve of their use, or over-use, as they are freely accessible from anywhere in your program (thus anathema to the OO concept of encapsulation), but personally I try not to worry about it in small cases - the most important thing to know about the rules of any design pattern is when they can be broken!
They are also slightly slower to access than instance members, but you won't notice this unless you are constantly accessing/changing them (making things like player velocity, which will need to be referenced/changed every frame, static, is not a good idea).
Hope this helps.
You may find the simplest way to link everything with the document class is to move your four frames into a movieclip together and have that on the first frame, then interact with that movieclip.
E.g. in the document class, where the movieclip instance on the timeline is called 'game'.
game.gotoAndStop(4);
game.objectToDisplay.visible = true;
If you encounter reference errors in the IDE then you can avoid these by using [] notation to refer to the properties of game, e.g. game["objectToDisplay"].visible = true;
Note that it's not really best practice to do this, but it will at least help you to finish that first game which is really more important at this stage in your learning. Afterwards, if you want to learn more then I'd recommend "The Essential Guide to Flash Games" by Jeff Fulton from 8bitrocket.com - it will teach you how to use the document class effectively.

Code for A Graphical User Interface window

How would someone go about coding a 'window'? I'm starting to make a GUI, and I want to learn how to code one. One that can be skinnable, and one that actually loops and creates itself at runtime. I understand that this might be a bit vague, so I'll add details.
One that actually 'creates' itself. Most GUI tutorials I've looked on depends on an 'image' that just gets added on the screen. I want to be able to use skins in my windows. One where my 'skin' is just a collection of 'borders'. Then when I insert window.create(50,50) where 50,50 is my height, width, It would just create that window, following the skin.
I understand that it probably follows just like when a language draws a rectangle, it just follows a different set of rules (maybe?). However, for all my Google-fu skills I cannot find a tutorial that teaches me this.
Please Help. I didn't include the language I used as you can see, because I believe I just need to know how to create one. Anyway though, I am using Actionscript 3. A tutorial would be just fine, or even A SINGLE CLASS THAT HAS THIS FUNCTIONALITY, I'll just study the code. Or if you know one, maybe a whole book about GUI and programming it :D
Pure As3.0 GUI coding is quite troublesome. I try to Googling, but not come out well. anyway for my case, i generate using a SWC, and Class Mapping and Customizing. but i'm not sure best way. in other way i use a bit101 library. this is gives me want Window, Charts, Componets easily of high abstraction. see the below image.
It can be pretty hard and complicated to do, or very easy, it just depends on how flexible your solution should be. You need firstly to design a structure of your program and approach to the problem.
I like to go from the image of how it should look like from API point of view. I think I would create a GUI element like this:
var wholeGui:MyGUI = new MyGUI();
var window:IGuiElement = new GuiWindow(dataObject, skinObject);
wholeGui.addElement(window);
So what would you need?
1) Object that would manage all GUI elements. Why? Simply because your GUI elements shouldn't be destroyed by themselves if user will click "X" on your little window. The wholeGui object would manage them and listen for any events including those that would destroy them. You may consider creating custom events for interaction between the wholeGui object and your window object if this interaction is going to be complicated.
2) Interface for your GUI objects. Some problem here is that AS3 actually doesn't have interface for Sprite, and you would like to interact with it like with extended Sprite. The workaround here is to have in this interface a declaration like this:
function asSprite():Sprite;
And your implementation in GuiWindow would look like this:
public function asSprite():Sprite {
return this;
}
And your GuiWindow class should extend Sprite of course. Then you would have access to it's Sprite properties and methods by writing for example: window.asSprite.startDrag();
This interface should give you abilities that you need to operate on your GUI element.
3) Class for your GUI element, in this example GuiWindow.
4) Class for your data that would be injected into your element. If you would load data dynamically, and from some location, you would need to deal with the situation when no data can be provided - but that logic would be inside your window.
5) Class for your skin - so you would be able to dynamically create a skin object and use it to create your window in a way you want.
That's just few thoughts to consider.
PS. It may be good idea to fill GuiWindow object with data AFTER creating it, and not in constructor, as you would be able to visualize loading process then.

What is the data type from the source of an image

another flashbuilder brainbreaker for me...
I have a class with a contstructor that should only change the source of an image.
[Bindable]
[Embed(source='../pictures/test.jpg')]
private var _picture:Class;
public function Test(newSource:*****)
{
_picture.source = newSource;
}
(the image is not an image, but a class, I am aware of this, it is meant to be so :-) )
The problem is that when I call the constructor, let's say:
var test:Test = new Test(pictureAtStage.source);
Flashbuilder will give an error, becouse I can't tell the compiler what data type "newSource" at the constructor will have...
*edit:
When i use _picture.source, the embedded source does not seem to be changed...?
Anyone knows an answer?
Are we talking about mx.controls.Image? if so, then the source of an image can be: a Class, a Bitmap (not a BitmapData), a String (in which case it is assumed that you wanted to load it instead of using an embedded one). If you want to find a common denominator for all these, then Object is that class, however, I would rather limit it to something particular to your use case.
However, if I may advise anything... don't use mx.controls.Image, it's too bloated, even for Flex framework. If it must be a UIComponent - extend UIComponent and let the source be of type BitmapData - this way you will be able to manage resources better - you could reuse the same actual image for example. You could then use graphics property of the control to display the image.
Another advise, if you are still here :) Don't use [Bindable], especially the short version of it, especially not on a private variable - you will save yourself the frustration of countless hours of debugging it... Besides, in your case you aren't going to change the value of that variable anyway...
Are you still here? Well, don't use [Embed] on variables, use it on class definition - slightly more work for you, but this will, potentially, make your code more portable. If you embed on class the compiler will not generate a silly "something-something-Asset" class, it will use Bitmap or BitmapData - whichever your class extends. Thus, you will not introduce a dependency on Flex framework, and, in general, you will have more control over your code.
EDIT: the above was written assuming that _picture (class) variable and _picture (some variable used in a function) are not the same thing. But if they are the same thing, then Class class is dynamic, which means that you can add to it properties at runtime (don't know why, it's a design decision by Adobe...), however, the compiler will act as if it's not possible, so you would work around that by adding the property through reflection:
var _picture:Class = Sprite;
_picture["source"] = whatever;
trace(Sprite["source"]);
This is indeed slightly confusing, It will be of the type BitmapAsset which extends Bitmap. So any of those will work.
Since I'm very new to flashbuilder I didn't see the obvious solutions...
The solution for the first part of my question (before the edit):
Setting the data type to Object did the trick:
[Bindable]
[Embed(source='../pictures/test.jpg')]
private var _picture:Class;
public function Test(newSource:Object)
{
_pucture.source = newSource;
}