I am trying to put a vertical scrollbar onto a dynamic TextField in Flash CS4. When I do this in Scene 1, everything works just fine. However, if I move the TextField+Scrollbar to Scene 2, it breaks. The errors I get when I run the code indicate that Flash is loading the scrollbar right away and then trying to find the associated TextField. The problem is that, since the TextField doesn't load until you get to Scene 2, Flash throws an error.
I tried a lot of things to solve this issue. What it mostly came down to was that I needed to create the TextField and Scrollbar in actionscript (instead of from the component library) so that I could control when each was created. To create the TextField, I typed:
//create a textfield for the story
import flash.text.TextField;
var story_txt:TextField = new TextField();
//story_txt.multiline = true;
story_txt.x = 154;
story_txt.y = 233.5;
story_txt.width = 348;
story_txt.height = 104.5;
story_txt.border = true;
story_txt.type = "dynamic";
story_txt.backgroundColor = 0xffffff;
story_txt.background = true;
story_txt.wordWrap = true;
story_txt.multiline = true;
and to create the scrollbar, I then typed:
import fl.controls.UIScrollBar;
//add the story_txt to the stage
addChild(story_txt);
var mySb:UIScrollBar = new UIScrollBar();
mySb.direction = "vertical";
// Size it to match the text field.
mySb.setSize(story_txt.width, story_txt.height);
// Move it immediately to the right of the text field.
mySb.move(story_txt.x, story_txt.height + story_txt.y);
// put them on the Stage
mySb.scrollTarget = story_txt;
//mySb.scrollTargetName = "story_txt";
stage.addChild(mySb);
The only problem is that this code only works if I make the ScrollBar horizontal and turn off wordwrap. For some reason, the vertical scrollbar will not work with wordrap on (and w/o wordwrap, Flash thinks that there's no need for a vertical scrollbar, as it sees only a single line of text.
Getting a textfield w/a scrollbar should be a simple process, but this is really out of hand. Any ideas on how to get the ScrollBar to work when wordWrap is turned on?
Basically you should never use Scenes in Flash. There are a lot of known issues with them.
This thread might help.
Scene usage is generally bad practice. They are a legacy feature left in to keep current versions of flash compatible with earlier versions. If you must use the IDE to place things on stage you should use distinct frames on the main timeline in place of scenes, and place things that need the timeline to animate inside their own movieclips. The flash IDE actually reduces all the scenes down to one timeline at compile time any way but with many anomalies that wouldn't be present in manual timeline manipulation.
disadvantages of scenes from adobe: http://help.adobe.com/en_US/Flash/10.0_UsingFlash/WSd60f23110762d6b883b18f10cb1fe1af6-7eb3a.html
Related
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.
I have 3 layers in the timeline, and I want to make a new layer, and then use the new layer to be my first frame (like a startpage).
How do I do that?
Flash does not support show/hide of layers. Learn about working with Movieclips. You should find a lot by just searching for it.
myStartClip.visible = true;
A "shaking screen" means you probably have compile errors.
Don't use layers or frames (aside from the first frame where you put all your code as usual of course).
It's an AS3 exercise, which means you should be working mainly in AS3 code, and not in frames and layers.
You put the "start page" in a container, which can be a Sprite or a MovieClip.
The "start page" can contain for instance a background, a textfield with some instructions and a start button.
This means that you have to create a new container for instance
var startContainer:Sprite = new Sprite();
addChild(startContainer); // and maybe position it with x and y
Then you create the things you need on your start page
var infoTf:TextField = new TextField();
infoTf.text = "some game description and how to play";
var bg:SomeBackground = new SomeBackground();
var startBtn:SomeBtn = new SomeBtn();
startBtn.addEventListener(MouseClick.CLICK, handleMClick_startGame);
And then you add these things to the container.
startContainer.addChild(bg); // add the other things too of course
Then when you press the startBtn, you use removeChild on the entire container and don't forget to remove the eventListener for the startBtn
After that you add the content for the game either directly on the stage, or to another mainContainer if you so prefer.
And in the end you use the same technique for the game over page.
My head is spinning from two days of trying to find an answer to this seemingly simple question.
I'm developing a Flex/AIR application built entirely in ActionScript -- there's no MXML beyond what was originally auto-created.
I need to dynamically generate some kind of editable text-field with high control over formatting. The TLF text fields all seem great, except that I can't get any of them to render on the screen. Due to the nature of the application, they have to be inside a MovieClip, but since I've read that everything must be a descendant of UIComponent, I use UIMovieClip, which is AddChild'ed to the stage.
I'm about to go crazy here, the whole application is in jeopardy over this. I CAN NOT use MXML, and all the 10,000 examples on the internet are MXML. I need to generate these dynamically. I need to generate upwards of 50 fields under one movieclip based on database data. There's no way to hardcode that with MXML. Please don't suggest to change this. The GUI is very specific about this, and it's the right GUI.
In two days of searching, I can't find a single example in ActionScript, only MXML. I've tried everything that smelled like an example.
Is there some obvious general pointer I'm missing? I'll be happy to post code, but it doesn't make sense because I've been through so many examples.
Does anyone have the simplest possible code for creating any kind of TLF text editing field in ActionScript only (zero MXML), which is then added to a MovieClip or UIMovieClip, which is added to the stage of a desktop AIR application?
I will greatly cherish any help here.
Best,
Per
This should get you started:
//create your TextFlow component
var textFlow:TextFlow = new TextFlow();
var p:ParagraphElement = new ParagraphElement();
var span:SpanElement = new SpanElement();
span.text = "hello world";
p.addChild(span);
textFlow.addChild(p);
//create a Sprite that will contain the text
var textBlock:Sprite = new Sprite();
//create a controller for compositing
var controller:ContainerController = new ContainerController(textBlock);
//set the size of the composition
controller.setCompositionSize(100, 200);
//make the controller control the TextFlow object
textFlow.flowComposer.addController(controller);
//update the composition
textFlow.flowComposer.updateAllControllers();
//add to the stage
addChild(textBlock);
About the size: it is important you use setCompositionSize() instead of the Sprite's width and height properties.
Using addController() you could spread the text over several Sprites. Each Sprite would have its own ContainerController, but all would share the same FlowComposer which would calculate the composition.
warning : using TLF like this can be pretty complicated. Above code is the bare minimum to get things running. I do not know your requirements, but you'll probably hit a few other roadblocks along the way. You have to ask yourself this question: are you really willing to drop all the built-in features of TextArea? It might cost you months of development to get things right, depending on the requirements. You still may want to reconsider your architecture...
I have an FLA file with two frames. On the first frame I have nothing but a textfield and some code to do the preloading. After it is done preloading it does gotoAndStop(2)
On frame 1 I have:
stop();
stage.scaleMode = StageScaleMode.SHOW_ALL;
//Import the required assets
import flash.display.*;
//Stop the playhead while loading occurs
this.stop();
//Create a listener to call the loading function as the movie loads;
this.loaderInfo.addEventListener(ProgressEvent.PROGRESS, PL_LOADING);
this.loaderInfo.addEventListener(Event.COMPLETE, PL_FINISH);
function PL_LOADING(event:ProgressEvent):void
{
var pcent:Number = event.bytesLoaded / event.bytesTotal * 100;
//Display the % loaded in textfield
txt.text = int(pcent) + "%";
//If the movie is fully loaded, kick to the next frame on the main timeline
}
function PL_FINISH(event:Event):void
{
removeChild(txt);
gotoAndStop(2);
}
On frame 2 I have nothing except:
var game:Game = new Game();
addChild(game);
In my publisher settings I have export to frame 2.
My problem is that the preloader won't display until 100%. Does anyone know why?
P.S. For testing I put a large image file on the stage in frame 2 and the result is the same.
This normally happens if you haven't deselected "Export in frame 1" in each of the library symbols that you are exporting for ActionScript.
You'll need to make sure that you create reference to these objects (so that ActionScript can access them) by placing them onto the stage in frame 2 (out of sight).
What's happening is that all of the symbols are being loaded before the preloader itself has loaded.
If this isn't the issue, then please provide some code so I can better assess your issue.
Have you tried putting something static on frame one? Just because there is a preloader, that doesn't mean that your swf will be displaying at all...
I know that I had one swf once which simply took a minute to actually get the Flex preloader to even show up because of network latency. It could be that your swf isn't displaying until 90% of it has already loaded.
I´m dealing with similar problems, and there is something i found out: my antivirus contains a kind of "browser protection" feature, which sort of checks all files in advance before it allows the browser to actually display them. If this antivirus feature has not been installed on the system, the preloader works beautifully. I´ve checked some other web-sites with flash content, and they also behave "wrong" under these circumstances. Now, some people seem to have found a way to stop the antivirus from messing around, but i don´t know how they do it... not yet...
I usually, use SWF Protection, to protect my swf's from decompiling.
It also adds a load bar to the swf.
The problem is that I have codes like this:
logo= new marca();
parent.addChild(logo);
logo.mouseEnabled=false;
I use parent, because I need to put the movie clip above everything, because my application allows the user to add a lot of things to the stage, so a don't want anything covering the logo.
The application works well while unprotected, but If I protect it using SWF Protection, then, I get just white screen. Nothing appears after loading.
Is there another way, to put a movieclip above everything, without being necessery to add a ON ENTER FRAME LISTENER, to update the movieclip deph, to keep it above everything?
You can use addChildAt instead of addChild to add your other clips to the stage under the logo's level.
var levelUnderLogo:uint = numChildren == 1 ? 0 : numChildren-2;
clipYouWantUnderTheLogo = new MovieClip();
addChildAt(clipYouWantUnderTheLogo, levelUnderLogo);
edit: You can also put every other clip inside another clip that is always under the logo.
var base = new MovieClip();
addChild(base);
var logo = new Logo();
addChild(logo);
// Add all your other objects into the "base" clip.
var someClipUnderTheLogo = new MovieClip();
base.addChild(someClipUnderTheLogo);
You are getting the white screen because the swf embed method is breaking in the javascript. Basically you have a javascript error.
Because you did not post code I can't help you much more. All I can say is put alerts in the javascript and see how far you get.