Actionscript 3 Dynamically created buttons not showing - actionscript-3

I am new to Flash and Actionscript. I have a movie that is initiated from a C# program. In the movie I am creating different textfields and passing the data back to the C# program. I also have a hotspot that when it is clicked I want to create a small menu that pops up. I've looked at a number of ways to do this and I decided that the easiest way to do this (or so I thought) would be to create a couple of buttons right under the hotspot. For some reason the buttons do not show up on the stage when I click on the hot spot. I know it is going through the routine that creates the buttons because I display a message. I have posted my code. Thanks for the help!!
import flash.text.TextField;
import fl.controls.Button;
import flash.events.Event;
hotSpot.addEventListener(MouseEvent.CLICK, showMenu);
var continueBtn:Button;
var exitBtn:Button;
function showMenu(evt: Event):void
{
continueBtn = new Button();
continueBtn.x = 20;
continueBtn.y = 100;
continueBtn.width = 30;
continueBtn.height = 20;
continueBtn.border = true;
continueBtn.visible = true;
continueBtn.label = "Continue";
addChild(continueBtn);
exitBtn = new Button();
exitBtn.x = continueBtn.x;
exitBtn.y = continueBtn.y + continueBtn.height;
exitBtn.width = 30;
exitBtn.height = 20;
exitBtn.border = true;
exitBtn.visible = true;
exitBtn.label = "Exit";
addChild(exitBtn);
continueBtn.addEventListener(MouseEvent.CLICK, sendMsg);
exitBtn.addEventListener(MouseEvent.CLICK, endFlash);
inTxt.text = "showMenu";
}
The message "showMenu" is displayed but neither one of the buttons show.
Gary

function showMenu(evt: Event):void
The evt must be a "MouseEvent" instead of "Event" because the listener you added to the "hotSpot" sprite (probably, or other display object) is a MouseEvent not an Event.
hotSpot.addEventListener(MouseEvent.CLICK, showMenu);
This calls the showMenu function which listens and catch the MouseEvent and not the Event event.
You also imported only the Event, import the MouseEvent instead!
New Code:
import flash.text.TextField;
import fl.controls.Button;
import flash.events.MouseEvent; //This line changed!
hotSpot.addEventListener(MouseEvent.CLICK, showMenu);
var continueBtn:Button;
var exitBtn:Button;
//This line changed!
function showMenu(evt:MouseEvent):void{
continueBtn = new Button();
continueBtn.x = 20;
continueBtn.y = 100;
continueBtn.width = 30;
continueBtn.height = 20;
continueBtn.border = true;
continueBtn.visible = true;
continueBtn.label = "Continue";
addChild(continueBtn);
exitBtn = new Button();
exitBtn.x = continueBtn.x;
exitBtn.y = continueBtn.y + continueBtn.height;
exitBtn.width = 30;
exitBtn.height = 20;
exitBtn.border = true;
exitBtn.visible = true;
exitBtn.label = "Exit";
addChild(exitBtn);
continueBtn.addEventListener(MouseEvent.CLICK, sendMsg);
exitBtn.addEventListener(MouseEvent.CLICK, endFlash);
inTxt.text = "showMenu";
}

Related

Add movieclips within another movieclip

I am having trouble embedding a child object to a movieClip with code using AS3 and I am not sure what I am doing wrong.
I am trying to create a new movieclip with code and add it to the stage. I am then trying to embed dynamically created objects inside that movieclip. When I trace the objects it shows that they are on the stage and not embedded into the movieclip. I looked through the forums but I didn't find an answer. Below is a watered down version of the code I have. Any help is appreciated.
import flash.display.MovieClip;
import flash.events.Event;
import flash.display.Sprite;
import flash.text.*;
import flash.net.URLRequest;
import flash.display.Loader;
var btnAImage:Loader = new Loader();
var image:URLRequest = new URLRequest("btn_A.png");
public function TextWithImage()
{
var TextField1:TextField = new TextField;
var myText1:String = "TEXT FIELD 1";
var BtnMovieClip:MovieClip = new MovieClip();
var btnPadding = 5;
addChild(BtnMovieClip); //add new MC to stage
btnAImage.load(image);
BtnMovieClip.addChild(btnAImage); // no error gets thrown. I am trying to add the btnAImage inside of my BtnMovieClip.
btnAImage.x = btnPadding; //I am able to reference the btnAImage without referencing the BtnMovieClip object.
btnAImage.y = btnPadding;
var screenW = stage.stageWidth;
TextField1.height = 40;
TextField1.width = 250;
var textPadding = 5;
var TextField1_fontFormat:TextFormat = new TextFormat ;
TextField1_fontFormat.size = 40;
TextField1_fontFormat.font = "TestFont";
TextField1.defaultTextFormat = TextField1_fontFormat;
BtnMovieClip.addChild(TextField1); // no error gets thrown. I am trying to add the text field inside of my BtnMovieClip.
TextField1.text = myText1;
TextField1.x = (btnAImage.width + textPadding);
TextField1.y = textPadding;
}
I wasn't preloading my image so here's how I fixed it. Thank you to Organis for the help!!!
public var btnAImage:Loader;
private function Question8_Answer()
{
trace("Question8_Answer() was called");
btnAImage = new Loader();
btnAImage.load(new URLRequest("btn_A.png"));
btnAImage.contentLoaderInfo.addEventListener(Event.COMPLETE, TextWithImage);
}
public function TextWithImage()
{
var TextField1:TextField = new TextField;
var myText1:String = "TEXT FIELD 1";
var BtnContainer:Sprite = new Sprite();
var btnPadding = 5;
addChild(BtnMovieClip);
BtnMovieClip.addChild(btnAImage);
btnAImage.x = btnPadding;
btnAImage.y = btnPadding;
var screenW = stage.stageWidth;
TextField1.height = 40;
TextField1.width = 250;
var textPadding = 5;
var TextField1_fontFormat:TextFormat = new TextFormat ;
TextField1_fontFormat.size = 40;
TextField1_fontFormat.font = "TestFont";
TextField1.defaultTextFormat = TextField1_fontFormat;
BtnMovieClip.addChild(TextField1); // no error gets thrown. I am trying to add the text field inside of my BtnMovieClip.
TextField1.text = myText1;
TextField1.x = (btnAImage.width + textPadding);
TextField1.y = textPadding;
BtnContainer.width = 300;
}

AS3 - Cannot tab through textfields nested in Movieclips

I"m having an issue at the moment trying to tab through textfields within movieclips (called through a for loop). It no matter which one is selected, hitting tab will always select the first textfield created and won't move from there. Not even using tabbing index works
Here's the code within the movieclip (the textfields are physical objects)
import flash.text.TextField;
import flash.events.FocusEvent;
import fl.managers.FocusManager;
import flash.events.Event;
var str:String = "Default";
textf.text = str;
textf.textColor = 0x848484;
hlborder.visible = false;
var focusManager:FocusManager = new FocusManager(this);
textf.addEventListener(FocusEvent.FOCUS_IN, tffin);
textf.addEventListener(FocusEvent.FOCUS_OUT, tffout);
function tffin(e:Event):void{
textf.borderColor = 0x0066FF;
hlborder.visible = true;
if(textf.text == str){
textf.text = "";
}
}
function tffout(e:Event):void{
textf.borderColor = 0x000000;
hlborder.visible = false;
if(textf.text == ""){
textf.text = str;
}
}
Here's where they are added to the main timeline
var carr:Array = new Array();
for(var i = 0; i<10; i++){
carr.push(new custField());
carr[i].y = i*30;
carr[i].x = 30;
addChild(carr[i]);
carr[i].textf.tabIndex = i;
}
Have you tried putting each TextField in a seperate movieclip? I think that should most likely fix the problem.
Same issue. I have MovieClips with 3 TextFields and single TextFields. Helped this:
Remove all tabIndex
Set on MovieClips tabChildren = true
Now tab goes from left to right and from top to bottom even throw child TextFields.

Changing the UrlLoader.load

package {
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.TimerEvent;
import flash.utils.Timer;
import flash.text.StyleSheet;
import flash.text.TextField;
import flash.text.TextFieldType;
import flash.text.TextFormat;
import flash.text.*
import flash.net.*
public class SpeechBox extends MovieClip{
public var textLoader:URLLoader = new URLLoader();
public var box:Sprite = new Sprite();
public var nextBox:Sprite = new Sprite();
private var nextText:TextField = new TextField();
private var textBox:TextField = new TextField();
private var speechText:String;
public var _speechBoxCheck:Timer = new Timer(1000);
public var clickedNext:Boolean = false;
public function SpeechBox()
{
textLoader.addEventListener(Event.COMPLETE, onLoaded);
textBox.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownScroll);
_speechBoxCheck.addEventListener(TimerEvent.TIMER, speechBoxCheck);
_speechBoxCheck.start();
//////////////////SPEECH BOX///////////////////
box.graphics.lineStyle(3.5,0xffffff);
box.graphics.beginFill(0x003366, .35);
box.graphics.drawRoundRect(0,0,650,145,20);
box.graphics.endFill();
box.x = 100;
box.y = 450;
addChild(box);
//////////////////SPEECH TEXT///////////////////
var speechFont = new DataText();
var textFormat:TextFormat = new TextFormat();
textFormat.font = speechFont.fontName;
textFormat.align = TextFormatAlign.LEFT;
textFormat.leading = 3;
textFormat.color = 0xFFFFFF;
textFormat.size = 16;
textBox.defaultTextFormat = textFormat;
textBox.width = 620;
textBox.height = 115;
textBox.x = box.x + 14;
textBox.y = box.y + 14;
textBox.multiline = true;
textBox.wordWrap = true;
textBox.selectable = false;
addChild(textBox);
//////////////////NEXT BUTTON///////////////////
nextBox.graphics.beginFill(0x000000, 0);
nextBox.graphics.drawRect(0,0,50,30);
nextBox.graphics.endFill();
nextBox.x = box.x + 600;
nextBox.y = box.y + 115;
nextText.defaultTextFormat = textFormat;
nextText.text = "Next";
nextText.textColor = 0xffffff;
nextText.autoSize = "left";
nextText.selectable = false;
nextText.mouseEnabled = false;
nextText.x = nextBox.x + 2
nextText.y = nextBox.y + 5
nextBox.buttonMode = true;
//nextBox.mouseEnabled = true;
nextBox.addEventListener(MouseEvent.MOUSE_DOWN, clickNext);
nextBox.addEventListener(MouseEvent.MOUSE_OVER, moveOver);
nextBox.addEventListener(MouseEvent.MOUSE_OUT, moveOut);
}
function onLoaded(e:Event):void {
trace(e.target.data);
textBox.text = e.target.data;
}
function mouseDownScroll(event:MouseEvent):void
{
textBox.scrollV+=4;
textBox.addEventListener(MouseEvent.MOUSE_UP,mouseup);
}
function mouseup(event:MouseEvent):void
{
if(textBox.scrollV == textBox.maxScrollV)
{
addChild(nextBox);
addChild(nextText);
}
}
function clickNext(event:MouseEvent):void
{
trace("click");
clickedNext = true;
_speechBoxCheck.stop();
(parent as Main).onTransition.start();
textBox.scrollV = 0;
textLoader.removeEventListener(Event.COMPLETE, onLoaded);
this.parent.removeChild(this);
}
function moveOver(event:MouseEvent):void
{
nextText.textColor = 0xffcc00;
}
function moveOut(event:MouseEvent):void
{
nextText.textColor = 0xffffff;
}
///////////////////////////////////////////////////////////////
function speechBoxCheck(event:TimerEvent)
{
if ((parent as Main).introduction == true)
{
textLoader.load(new URLRequest("Texts/LV1introduction.txt"));
trace("beginning");
(parent as Main).onTransition.stop();
}
if ((parent as Main).levelNum == 1)
{
textLoader.load(new URLRequest("Texts/LV1complete.txt"));
trace("go to lv 2")
(parent as Main).onTransition.stop();
}
if ((parent as Main).levelNum == 2)
{
textLoader.load(new URLRequest("Texts/LV2complete.txt"));
trace("go to lv 3")
(parent as Main).onTransition.stop();
}
}
}
}
EDIT: When the game starts, the LV1 introduction text starts. Once the scrollV equals maxScrollV, a next buttons appears. Click that, it will delete itself and the game starts. Once you beat stage one, levelNum automatically equals 2 and I add this class again from my main document class. However, it will show the same text over and over, regardless of what level.
So does the urlLoader always stay the same? If so, how can I change it?
URLLoader can be reused to load another data with new URLRequest instance. It is completely OK to reuse same URLLoader instance to load another file. Your problem is not in URLLoader, but in logics or somewhere else. You'd better try debuggers to make sure variable level has correct value of 2.
Why are you loading text file EVERY second? It would be ok to load them only level is changed.
does this textLoader instance have event listeners attached?
:::::::::EDITED:::::::::
You are removing event Listeners from textLoader in clickNext() call. textLoader will load file, but will not run onLoaded() to update textBox.text
Your speechBoxCheck() method is doing it wrong. 1. You must make only 1 load() call in speechBox() method. Your conditionals in the method are not exclusive, and it may cause trouble when multiple load() calls are made (previous loading operation will be canceled). consider "else if" chain.
it is not recommended to do something like loading files in this fashion. Unnecessary I/O operations, especially in runtime, should be avoided. Only load files when it is needed; In this case, it is when level changes.

Is it possible to make looped Movieclip clickable and Session data at the same time?

I am new to AS3, and i am trying to achieve the following situation.
First i receive the JSON data,sort them and put them into boxes . Each box has its set of data, e.g.Box1 (Name1,Location1,Zip1), Box2(Name2,Location2,Zip2) so on.
Boxes are put into another AS file for display, and will be put into a viewport slider.
Trying to make the boxes clickable, and when a box is clicked, it will go to next page and display the details of that specific "Listing".
1st thing is, how to make the movieclip box clickable when it is sitting inside another as file.
2nd thing is, how to pull the data from that box when it is clicked, as it is generated by the looped JSON data. (As i need to use the ID from the listing to parse it to the php to pull the details and display the full detail in the next as file.
Thanks for your time!
AS file where the boxes are generated.
package com.clark
{
import flash.display.MovieClip;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
import flash.text.TextFormatAlign;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
public class SearchVectorTest extends MovieClip
{
public function SearchVectorTest(test:Vector.<searchVO1>)
{
super();
for (var j:int = 0; j < test.length; j++)
{
trace(test[j].nobed);
trace(test[j].zip);
trace(test[j].Location);
trace(test[j].price);
}
var len:int = test ? test.length : 0;
listings = new Vector.<Listing8>(len, true);
var currentY:int = 100;
for (var k:int = 0; k < test.length; k++)
{
var Bolder:Listing2 = new Listing2();
Bolder.x=20;
var bf:TextField = new TextField();
var bf1:TextField = new TextField();
var bf2:TextField = new TextField();
var bf3:TextField = new TextField();
bf3.width = 100;
bf.defaultTextFormat = new TextFormat("Arial", 12, 0, null, null, null, null, null, TextFormatAlign.CENTER);
bf.width = 100;
bf.autoSize = TextFieldAutoSize.CENTER;
bf1.width = 100;
bf1.autoSize = TextFieldAutoSize.CENTER;
bf2.autoSize = TextFieldAutoSize.CENTER;
bf3.autoSize = TextFieldAutoSize.CENTER;
bf3.width = 100;
bf1.y= bf.height+5;
bf.text = test[k].nobed;
bf1.text = test[k].zip;
bf2.text = test[k].Location;
bf3.text = test[k].price;
bf.x = (Bolder.height-bf.height)*.2
Bolder.addChild(bf);
Bolder.addChild(bf1);
Bolder.addChild(bf2);
Bolder.addChild(bf3);
Bolder.properties = test[k].nobed;
Bolder.properties = test[k].zip;
// position the object based on the accumulating variable.
Bolder.y = currentY;
addChild(Bolder);
Bolder.mouseChildren = false; // ignore children mouseEvents
Bolder.mouseEnabled = true; // enable mouse on the object - normally set to true by default
Bolder.useHandCursor = true; // add hand cursor on mouse over
Bolder.buttonMode = true;
listings[k] = Bolder;
currentY += Bolder.height + 10;
}
}
}
}
AS file where the VectTest file sits
package com.clark
{
import flash.display.*;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.display.Stage;
import fl.controls.Button;
public class sresultnologin extends MovieClip {
public var s1:Searchreult = new Searchreult ();
public function sresultnologin(){
addEventListener(Event.ADDED_TO_STAGE, onadded);
function onadded (event:Event):void{
s1.x=-10;
s1.y=10;
addChild(s1);
}
var s3:SearchVectorTest= new SearchVectorTest(new Vector.<searchVO1>);
addChild (s3);
s1.SRhome.addEventListener(MouseEvent.CLICK, fl_ClickToGoTol);
s1.ARsearch.addEventListener(MouseEvent.CLICK, fl_ClickToGosearch);
if( s3.listings.length > 0 )
{
// get the first listing in the listing array
var newListing:Listing8 = s3.listings[0];
newListing.addEventListener(MouseEvent.CLICK, gotoscener);
}
else
{
//
}
}
// private methods
private function fl_ClickToGoTol(event:MouseEvent):void
{
var s9:Account = new Account ();
removeChild(s1);
addChild(s9);
}
private function fl_ClickToGosearch(event:MouseEvent):void
{
var s9:searchVO1 = new searchVO1 ();
removeChild(s1);
addChild(s9);
}
}
}
Edit(Added in SearchVectorTest)
var len:int = test ? test.length : 0;
listings = new Vector.<Listing8>(len, true);
Edit(Added in sresultnologin)
if( s3.listings.length > 0 )
{
// get the first listing in the listing array
var newListing:Listing8 = s3.listings[0];
newListing.addEventListener(MouseEvent.CLICK, gotoscener);
}
else
{
//
}
One
The "other as file" (a class) must be instantiated, and (as a DisplayObject) must be added to the stage for it to become visible.
Consider the following stage layout:
root:MainTimeline ¬
0: background:Shape
1: listingWindow:Slider
And the sresultnologin (when instantiated) looks like this:
this:sresultnologin ¬
0: s3:SearchVectorTest ¬
0: Bolder:Listing2 ¬
0: bf:TextField
1: bf1:TextField
2: bf2:TextField
3: bf3:TextField
1: s1:Searchreult
All you need to do is addChild(sresultnologin) to the stage (or your Slider), and those child elements will appear.
To make it clickable, simply attach the listener to your object via object.addEventListener("mouseUp", listener). This can be done at any point: in the constructor of SearchVectorTest, or sresultnologin, or after it's been added to the stage when your "box is clicked" and the new listing appears. If you wanted to do that from the document code, it might look like this:
var newListing:Listing2 = listingWindow.getChildAt(0).getChildAt(0).getChildAt(0);
newListing.addEventListener("mouseUp", doStuff);
However, that's wholly dependent on DisplayList indexes (which could change wildly). A better solution may be to name these items and use getChildByName("string") instead. That too, however, could be perilous if you have non-unique names for each object. Consequently, if you're adding these new listings from inside one of your classes (such as sresultnologin), you could simply provide a property on the class which points to the current listing, and reference that from document code.
Two
JSON data is no different from any other object structure in AS3. If you want, you could store it as a property of the class, and reference the variable at the appointed time. If you want to store data specific to a particular listing on the particular object which represents it, try adding to Bolder in SearchVectorTest the following:
Bolder.properties = test[k];
Edit:
Remember that the variable name is not the same as the name property on an object. In other words...
var Bolder:Listing2 = new Listing2(); // variable is Bolder, of type Listing2
Bolder.name = "foo" // the name property on Bolder is now "foo"
getChildByName("Bolder") // this should fail since there is no object with that name
getChildByName("foo") // works.
This really isn't complicated as long as you're aware of the differences. Please run the script I gave you (under "Pathing to Objects") which shows you the hierarchy of your stage. After you have the output, it should be self-explanatory what pathing you need to use to reference your variables.

AS3 / Displaying textField on movieClip with a Vector

I wanted to place a textField on a movieClip so i used:
vec[0].addChild(text1);
If I use that there comes an error. Or should i make a new Vector?
TypeError: Error #2007: Parameter child must be non-null.
at flash.display::DisplayObjectContainer/addChild()
at FQuiz_fla::MainTimeline/frame1()
>
Move your text field declaration portion to top, that is before your add child method.
import flash.display.MovieClip; import flash.events.Event; import flash.display.SimpleButton; import flash.text.TextField; import flash.events.MouseEvent;
var volgende:Volgende = new Volgende(); volgende.x = 663; volgende.y = 546; volgende.visible = true; volgende.useHandCursor = true; addChild(volgende);
var vec:Vector. = new Vector.
vec[0] = new Vraag1(); vec[1] = new Vraag2();
var tekstveld1:TextField = new TextField();
tekstveld1.antiAliasType = AntiAliasType.ADVANCED; tekstveld1.text = "" tekstveld1.type = TextFieldType.INPUT; tekstveld1.textColor = 0xEC8DAD; tekstveld1.width = 390; tekstveld1.height = 248; tekstveld1.x = 165; tekstveld1.y = 312; tekstveld1.border = false; tekstveld1.borderColor = 0xDA1C5C; tekstveld1.wordWrap = true; tekstveld1.restrict = "A-Za-z0-9";
vec[1].addChild(tekstveld1);
addChild(vec[0]); //add one of the MovieClips to stage
volgende.addEventListener(MouseEvent.CLICK, onClick);
function onClick(e:MouseEvent):void { for(var i:int = 0; i < vec.length; i++) //go through the Vector one by one { if(contains(vec[i])) //if the Object at position i in the Vector is on stage { removeChild(vec[i]); //remove the Object var next:int = i; //create a temporary holder if(next == vec.length) //check if the displayed Object was the last in the list { next = 1; //if so, set to 0 }else{ next++; //otherwise, only add 1 } addChild(vec[next]); //add the next Object to the stage. If the removed Object was the last in the Vector, it'll add the first Object in the Vector to the list break; //escape the for loop, otherwise it'll always only show the last Object }
} }
Hope it helps. Me too on mobile ;)
import flash.text.TextField;
var vec:Vector.<MovieClip> = new Vector.<MovieClip>
vec[0] = new Start();
var text1:TextField = new TextField();
text1.text = "ramesh";
vec[0].addChild(text1);
addChild(vec[0]); //add one of the MovieClips to stage
This should work.