AS3: Loading different, externa text values on MouseOver - actionscript-3

I'm stuck with this thing for a while now. I'm working on a map that displays popup with dynamically loaded text when you hover over specific objects (mc's). mc_box is my popup clip with text fields (aTxt, bTxt) and 1, 2 are objects I'm hovering over. This is part of the code I'm using, I figured I have to get the target name and data loaded from the text file, but I'm really not sure how can I go from here:
mc_box.visible=false;
var targetName:String;
this.addEventListener(MouseEvent.MOUSE_OVER, getName);
function getName(e:MouseEvent):void {
targetName = e.target.name;
}
var lv:URLLoader = new URLLoader();
lv.dataFormat=URLLoaderDataFormat.VARIABLES;
lv.addEventListener(Event.COMPLETE, onLoaded);
function onLoaded(e:Event):void {
txtData = e.target.data
}
lv.load(new URLRequest("text.txt"));
this.addEventListener(MouseEvent.MOUSE_OVER, mouseover, true);
function mouseover(e:MouseEvent) {
mc_box.visible=true;
mc_box.x=mouseX+5;
mc_box.y=mouseY+5;
mc_box.startDrag();
}
this.addEventListener(MouseEvent.MOUSE_OUT, mouseout, true);
function mouseout(e:MouseEvent) {
mc_box.visible=false;
}
The text file looks like this:
&a_1=some text 1
&b_1=some text 2
&a_2=some other text 1
&b_2=some other text 2
And my question is how the hell can I get it to display text fields according to the object name I mouseOver on? I've been trying to do something like this:
mc_box.aTxt.text=e.target.data.('a_'+targetName);
mc_box.bTxt.text=e.target.data.('b_'+targetName);
but obviously it won't work. Please help...

Related

How to load a swf and interact with it?

I have tried SWFLoader, but the problem is the loaded content is MovieClip and I don't know how to interact with it, and the MovieClip#numChildren is zero.
And by the way, I can't pass the flashvars to the swf.
Firstly, you should know that there is no exact answer to your question as it depends on your loaded SWF (you know it or not, its display list, ...) but I'll put a simple example to explain things and you have to adapt it to your case.
For this example, let's say that we have a very simple SWF (the loaded SWF) which contain a TextField (called txt_url) and a button (a MovieClip, called btn_go).
The btn_go button will open the URL entered in the txt_url TextField.
For our second SWF (the loader), we will use a Loader object to load our first one (which is in this case will be the Loader.content) and then we will set the URL (the txt_url text) and trigger the click event on the btn_go button.
So here is an example of the code of our loader.swf :
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, on_SWFLoad);
loader.load(new URLRequest('loaded.swf'));
addChild(loader);
function on_SWFLoad(e:Event): void
{
// get our loaded SWF
var loaded_swf:DisplayObjectContainer = DisplayObjectContainer(loader.content);
// because we know our target objects, we can use "getChildByName()"
// set the URL
TextField(loaded_swf.getChildByName('txt_url')).text = 'http://www.example.com';
// open the URL in the browser by triggering the click event on the "btn_go" button
MovieClip(loaded_swf.getChildByName('btn_go')).dispatchEvent(new MouseEvent(MouseEvent.CLICK));
}
This example will directly set and open the URL in the browser after loading the SWF, of course we can execute that action after clicking a button or something else but it's just a simple example to show you how you can do ...
Now, the problem is when we don't know anything about the loaded SWF and its children (names, depths, ...), in this case we should do more effort to do what we want : we should traverse the entire display list of the loaded SWF to identify the target objects.
Returning to our example and let's say that we only know that there are a TextField and a button in the stage, so our code can be like this for example :
function on_SWFLoad(e:Event): void
{
var loaded_swf:DisplayObjectContainer = DisplayObjectContainer(loader.content);
var num_children:int = loaded_swf.numChildren;
for(var i:int = 0; i < num_children; i++)
{
var child:DisplayObject = loaded_swf.getChildAt(i);
if(child is TextField)
{
trace(child.name); // gives : txt_url
TextField(child).text = 'http://www.example.com';
}
else
{
if(child.hasEventListener(MouseEvent.CLICK))
{
trace(child.name); // gives : btn_go
child.dispatchEvent(new MouseEvent(MouseEvent.CLICK));
}
}
}
}
Again, it's a very simple example just to show how we can proceed ...
...
Then about passing values (params) between SWFs, take a look on my answer of this question where you have a little example for that.
For more about Display programming (display list, display object, display object container, ...) take a look here.
Hope that can help.

The best method to create typewriter effect?

Hey everyone so I am creating a game that focuses on character to character interactivity. So when you interact with a character a chat box opens and the characters start talking to one another. I have the text setup like an old school typewriter effect one letter at a time. As of now I create it by typing each letter on separate frames and have them play through. When it gets to then end of the sentence in order for the user to go on to the next sentence I have a button that they tap Here is the code:
private function nextConvo(e:MouseEvent):void
{
nNext += 1;
trace(nNext);
if (nNext == 1)
{
conversation.gotoAndPlay(1);
}else
if (nNext == 2)
{
conversation.gotoAndPlay(117);
}
}
As you can see i set it up to play the next frame with the new conversation so on and so on. I have a lot more text to do I realized it will be really time consuming and wonder if there is a easier way.
A method to where it types the string in the text box and I can still use my button so when the user wants to see the next conversation they can press the next button.
I saw a video here of someone showing the code way of doing it but Not sure how I would implement the button without having to add a lot of new mouse listeners and timers. Code Method
Please any help would be appreciated.
Omg, yes, you will go nuts if you show one character per frame :)
The idea is to have a function to handle this for you that you have ONCE somewhere (for example, on your main timeline). Then you can call it from everywhere and just pass the text, textfield to type into and a button.
private var _myText:String;
private var _myTextField:TextField;
private var _myButton:Button;
private var _currentCharacterPosition:int;
public function typeText(text:String, myTextField:TextField myButton:Button):void
{
_myText = text;
_myTextField = myTextField;
_myButton = myButton;
_myButton.visible = false;
_currentCharacterPosition = 1;
typeNextCharacter();
}
private function typeNextCharacter():void
{
_myTextField.text = _myText.substr(0, _currentCharacterPosition);
if (_currentCharacterPosition == _myText.length)
{
// all text is typed out, show your button
myButton.visible = true;
}
else
{
// type next character. 0.2 is the delay between letters (200 ms)
_currentCharacterPosition++;
setTimeout(typeNextCharacter, 0.2);
}
}
Assuming you have the textfield and button in the same place (same frame), you could then do this in that frame:
_root.typeText("This is my text to type out", myTextField, myButton);

How to save dynamic text in a frame so that the text will appear when back to the frame?

I have a dynamic text in a frame 1. Let say the instance of the dynamic text is myText. The text in the dynamic text will be changed depends on the some events. I provide a button to go to the next frame and provide another button to back to frame 1 (using prevFrame() and nextFrame() )
what I want is when we back to the frame 1, the text in dynamic text before we leave frame 1 will still there.
I've tried to save the text in dynamic text in an array, but when I 'click' the button to go back to frame 1 [usinf prevFrame()], the content in the array is empty, but if I have a button in other frame and tried to trace the array, the text is in it..
am I doing this correctly? or any idea how to do this?
thank you..
Maybe you reinialize the array when enter into frame 1.
Make a global var and check for undefined when set it's value;
i.e.
var txt;
if ( undefined == txt )
{
txt = "Text";
}
On btn1.press do
foo=myText.text
nextFrame
On btn2.press do
prevFrame
if (foo!=undefined)
myText.text = foo
You are probably initializing the array in the frame 1. Check if the array is already initialized and don't initialize if it already is. I assume you have something like this in the first frame var arr = new Array();, so you need to add the check
if(arr == null)
arr = new Array();

How can I detect StaticText in AS3?

I have StaticText fields in my flash project and I need to run some code when the mouse is hovering over them. So I tried this code
stage.addEventListener(MouseEvent.MOUSE_OVER, mouseRollOver);
function mouseRollOver(event:MouseEvent):void {
var tf:StaticText = event.target as StaticText;
if (tf){
//my code
}
}
but it doesn't work. When I use dynamic text fields and replace StaticText with TextField in the var tf, it works fine. I also thought that I could get this thing working with static text fields if I could make the mouse detect not StaticText as a target but some kind of object that has certain text properties (like "selectable" set to true), but I couldn't figure out how to do this. Anyway, I need to detect a static text field as a target somehow. Any help would be appreciated.
Thanks in advance
Your best option would be to put the static text box in a movieclip, and then assign your code based around that. Static text boxes don't have instance names, and can't be manipulated.
It is hard to do this. See this link enter link description here
As you can see you can check if the DisplayObject is StaticText and by checking the mousX and MouseY properties you can find if the rollover is related to this field. By if you use Dynamic text and uncheck selectable field you will get a textfield that acts as StaticField
EDIT
this is an explanation what I mean:
Let we have a StaticText field into stage in Black flash document.
var myFieldLabel:StaticText
var i:uint;
//This for check for all staticFields in state and trace its text. It is possible and it is working. I my case I have only one field and I get reference to it in myFieldLabel:StaticText var. Also I change it's alpha to 0.3.
for (i = 0; i < this.numChildren; i++)
{
var displayitem:DisplayObject = this.getChildAt(i);
if (displayitem instanceof StaticText) {
trace("a static text field is item " + i + " on the display list");
myFieldLabel = StaticText(displayitem);
trace("and contains the text: " + myFieldLabel.text);
trace( myFieldLabel.mouseX);
myFieldLabel.alpha = 0.3;
}
}
//Adds event listener to the stage for mouse move event
stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseRollOver);
//This is an event handler. I check if the mouse position is within the static field
function mouseRollOver(evnt:MouseEvent):void
{
if ( 0 <= myFieldLabel.mouseX && myFieldLabel.mouseX <= myFieldLabel.width && 0 <= myFieldLabel.mouseY && myFieldLabel.mouseY <= myFieldLabel.height )
{
mouseOverStaticText( evnt)
}
else
{
mouseNotOverStaticText( evnt)
}
}
// this two methods change the static field alpha. Thay are only to show that is posible to detect and manipulate some properties of the StaticField.
function mouseOverStaticText( evnt)
{
myFieldLabel.alpha = 1;
}
function mouseNotOverStaticText( evnt)
{
myFieldLabel.alpha = 0.3;
}
I'm not sure what is the purpose of the managing of the StaticText field. StaticText is not design to be managed if you have to do something this is almost sure that the field must not be a static - they can be dynamic ( without selectible property ) or can be capsulated with MovieClip or there can be a different solution in your case.

How can I add an event listener to scrolling content?

I want to put some mouse event to scrolling text in dynamic text field.
For example: I type several sentences into one dynamic text field. For each sentence, I want to have a different mouse event. Like this:
sentenceA.addEventListener(MouseEvent.CLICK, functionA);
function functionA(evt:MouseEvent):void
{
trace("bla");
}
How can I add an eventlistener to each sentence in the scrolling text? Because the position of the mouse event should move when the relative text scrolling.
here you go...
_txt.htmlText = "<a href='event:sentence1'>This is one sentenc.</a> <a href='event:sentence2'>This is another sentence.</a>"
_txt.addEventListener(TextEvent.LINK, clickCopyHandler);
function clickCopyHandler(e:TextEvent):void {
trace(e.text);
}
var sentences:Array = [ sentenceA, sentenceB, ...... ];
function clickAllText(e:MouseEvent):void
{
var index:int;
for each(var s:String in sentences)
{
index = dynamicTextField.text.indexOf(s);
if(index >= 0 && index <= 3)
{
//if the sentence is in the front
this["sentence"+sentences.indexOf(s)]();
break;
}
}
}
function sentence0():void
{
}
function sentence1():void
{
}
If that is not the case, you would need to either use different text fields, or
get the proximity of the mouse point to the sentence x and y location on the
display.
Take a closer look at flash.event.TextEvent.LINK, it's thrown when you click on html text which has an attribute href='event:someText'. Consider the following example
var tf:TextField = new TextField();
tf.htmlText = "<a href='event:first'>sentence1.</a><a href='event:second'>sentence2.</a>";
tf.addEventListener("link", clickHandler); //link is value of flash.event.TextEvent.LINK
function clickHandler(e:TextEvent):void {
//here should be something like the following
if (e.text == "first") sentence1();
else if (e.text == "second") sentence2();
}
well, I guess you caught the idea! The problem is that sentences are to be put into tag, but you can make links look like ordinary text. If that variant does not fits your needs, you may try to compare selection boundaries(tf.selectionBeginIndex and tf.selectionEndIndex) with boundaries of sentences after click.