How to create a button that makes a new text field appear on screen? - actionscript-3

I've been having trouble getting this button to work. I want it so that whenever you click it, a new text field pops up that you can type stuff in. This is supposed to be for a trivia-like game, where the user inputs their own questions and answers. Here's the code so far...
This is the text field's properties -
QuestionTextField = new TextField();
QuestionTextField.defaultTextFormat = SmallTextFormat;
QuestionTextField.textColor = 0x660000;
QuestionTextField.x = stage.stageWidth * 0.1;
QuestionTextField.y = 200;
QuestionTextField.width = stage.stageWidth * 0.8;
QuestionTextField.height = 20;
QuestionTextField.selectable = false;
QuestionTextField.type = TextFieldType.INPUT;
QuestionTextField.border = true;
QuestionTextField.multiline = true;
QuestionTextField.wordWrap = true;
And this is the function that is supposed to create a new text field every time the button is clicked-
private function AddQuestionButtonClicked(m:MouseEvent){
for(var i = Questions.length; i>=1; i--){
container_buttonsMC.addChild(QuestionTextField);
Questions.push(QuestionTextField);
QuestionTextField.y += 20
}
}
Notes : "Questions" is an array that holds the number of text fields there are, container_buttonsMC holds all of the buttons on that are on the game's main menu.
The problem is that whenever I click it, it 1. Doesn't actually create a new text field, but instead moves it a certain amount of pixels down, and 2. It sort of duplicates the text field's position...if that makes ANY sense at all. If I click on the button once, it will move the text field down by 20 pixels. If I click on it again, it will move it down by 40 pixels, then by 80, and so on...
I also traced the length of the array, and surprisingly enough, the number that appeared would double every time I clicked it. However, only one text field is visible (apparently). It probably has something to do with the for loop's action, but I don't know for sure. Does anyone have an idea as to what the problem is? (Thanks in advance, I'm still new to AS3 and programming in general)

First, each need to create a new textfield every time you click the button, rather than adding it to the stage. With what you have at the moment, you only created one text field.
Secondly, you only want to do add one more text field, right? So instead of using a loop, which will create multiple new text fields, just create one extra text field and add it to the list.
The code will look something like
private function AddQuestionButtonClicked(m:MouseEvent){
var QuestionTextField:TextField = new TextField()
QuestionTextField.defaultTextFormat = SmallTextFormat;
QuestionTextField.textColor = 0x660000;
QuestionTextField.x = stage.stageWidth * 0.1;
QuestionTextField.y = 200;
QuestionTextField.width = stage.stageWidth * 0.8;
QuestionTextField.height = 20;
QuestionTextField.selectable = false;
QuestionTextField.type = TextFieldType.INPUT;
QuestionTextField.border = true;
QuestionTextField.multiline = true;
QuestionTextField.wordWrap = true;
// You can adjust the 50 here to control the spacing between text fields
QuestionTextField.y += 50 * Questions.length
container_buttonsMC.addChild(QuestionTextField);
Questions.push(QuestionTextField);
}

Related

ActionScript 3 Adding images; different positions

In short, I have clickable objects with varying colours. I want these colours upon being clicked to appear in my placeholders (there will be 6). I currently have managed to code so that upon clicking any colour it is placed in the first placeholder.
In what way am I able to code to recognise that the first placeholder has been filled and that once filled, the second placeholder should become the target?
Preferably until the 6th has been filled and then stopped, so that the user can see all 6.
I am thinking something like a for loop would be fitting, but I am not sure how to go about it.
So far it's looking something like this:
//Placeholder
var placeHolder1:MovieClip = new MovieClip();
placeHolder1.x = 20;
placeHolder1.y = 245;
stage.addChild(placeHolder1);
//Placeholder2 (UNUSED CURRENTLY)
var placeHolder2:MovieClip = new MovieClip();
placeHolder2.x = 60;
placeHolder2.y = 245;
stage.addChild(placeHolder2);
//Click and select colours
var newBlue:cBlue = new cBlue();
numBlue.addEventListener(MouseEvent.CLICK, fBlue)
function fBlue(e:MouseEvent){
placeHolder1.addChild(newBlue);
}
var newRed:cRed = new cRed();
numRed.addEventListener(MouseEvent.CLICK, fRed)
function fRed(e:MouseEvent){
placeHolder1.addChild(newRed);
}
First, you probably want to learn about Arrays (or Vectors). Arrays/Vectors are lists, so you would put all your placeholders into an array:
var placeHolders:Array = [placeHolder1, placeHolder2];
Though, since there is a formula to your place holder creation, you probably would want to do this in a loop to make it DRYer (Don't Repeat Yourself)
This loop would create 10 place holders and add them to the array:
var placeholders:Array = new Array();
for(var i:int=0; i < 10; i++){
var placeHolder = new Sprite(); //if your not using timelines, just use Sprite instead of MovieClip as it's less overhead
placeHolder.x = 20 * (i + 1); //i starts at 0, and goes to 9
placeHolder1.y = 245;
stage.addChild(placeHolder); //add it to the display list
placeholders.push(placeHolder); //add it to the array
}
Now (continuing to be DRY), attached the same event listener to all your color buttons:
numBlue.addEventListener(MouseEvent.CLICK, selectColor);
numRed.addEventListener(MouseEvent.CLICK, selectColor);
In that event handler I've called 'selectColor' (see code comments)
function selectColor(e:Event):void {
//get the first element in the array
var placeHolder:Sprite = placeholders.shift(); //shift removes the first item from the array, and returns it
placeHolder.addChild(e.currentTarget); //e.currentTarget refers to item that you attached the event listener to, in this case either numBlue or numRed
}
So to summarize, this gets the first placeholder in the array, remove that item from the array, then adds color button that was clicked as a child of that placeholder.

If two sprites are visible, do something (AS3)

I'm creating a memory like game. I built all the desktop, the cards generation. I now have two cards of each.
I'm trying to do the pairs delete system.
my function to show the color to find looks like this :
private function onClick(e:MouseEvent):void
{
if (vueDos)
{
vueDos = !vueDos;
faceCarte = new Sprite();
faceCarte.graphics.lineStyle(2,0x000000,.5);
faceCarte.graphics.beginFill(clr);
faceCarte.graphics.drawRoundRect(8,8,this.width - 16, this.height - 16, 10,10);
faceCarte.graphics.endFill();
var _t:TextField = new TextField();
_t.selectable = false;
_t.antiAliasType = "advanced";
_t.autoSize = "left";
_t.defaultTextFormat= new TextFormat(maFont.fontName,24,0x000000);
_t.text = couleur;
_t.x = (this.width - _t.width)/2
_t.y = (this.height - _t.height) >> 1;
faceCarte.addChild(_t);
faceCarte.cacheAsBitmap = true;
this.addChild(faceCarte);
}
if(!vueDos)
}
Does it exist a function wich see if the color of the card is visible (faceCarte), and limit the visibles carte to two then removeChild faceCart.
Thank you in advance
You have to make such a function yourself. It'll be better to assign a couleur property to the card itself, instead of putting it into the TextField and forgetting. This way you'll be able to open first card, get that property, then open second card and compare that one's property with what you received, if match, both cards will be removed.

Counter with "for" displaying on a dynamic textfield

im very new to as3 so i would appreciate any help.
Im trying to make a counter only using the command "for".
im counting on this from 1 to 1000 in steps of 20.
the next step i want to make is to display on the output tab
i already know i can make it with "trace();", but i also want this to be displayed on
the main .swf window, im trying using a dynamic text-field which i named "dyna"
The problem is that, it is only displaying the last number. "1000" or changing very fast that i barely notice, and the last one remains.
var i:int;
for (i = 1; i < 1001; i+=20)
{
trace(i);
//dyna is the name of my dynamic textfiled
dyna.text = i.toString();
//dinamico.text = String(i);
}
-Is there any way to record all the numbers on my dynamic textbox, something like [1,20,40,60,....] horizontally or vertically.
-Or maybe someway to run this from a button step by step.
like [click, 20; click, 40; click 60.....]
Thanks in advance
var i:int;
var str:String="1";
for (i = 20; i < 1001; i+=20)
{
str=str+","+i;
}
dyna.autoSize = TextFieldAutoSize.LEFT;
dyna.text=str;
Output
1,20,40,60,80,100,120,140,160...
Hope it helps
To run this from the button step by step you need a button, a listener attached to the button, a counter available to both button and text field, and a bit of code. The button has to be somewhere on the stage or in your asset, and named somehow, so you can address it by the name. Here it's named yourButton:
var counter:int=0;
yourButton.addEventListener(MouseEvent.CLICK,updateDyna);
function updateDyna(e:MouseEvent):void {
counter+=20;
if (counter>1000) counter=1000;
dyna.text=counter.toString();
}
Here you are, click - 20, click - 40, etc., up to 1000.

textbox autoresizing in actionscript3

I need to realize textbox autoresizing in actionscript3(IDE - adobe flash pro cs3). For example my textarea is in width 100 px, user has been wrote in it something, that is bigger than 100 px, then my textbox should become increasingly. any ideas?
Also I can't realize multiline option: when the text goes beyond the textbox, it starts to scroll. In line type I've chosen 'multiline'.
thanks
try this:
textfield.autoSize = "left";
textfield.multiline = true;
textfield.wordWrap = true;
Hope it helps,
Rob
If you want to resize textfield automaticaly you can use textfield.autoSize property.
Wnen you are using multiline textfield, then setting
textfield.autoSize = TextFieldAutoSize.LEFT;
will align text to left and resize field vertically. If you use single line text field, it will resize to the right.
The TextField's .autosize property is great for sizing dynamic text fields when you already know the text string (but mind the .multiline and .wordwrap properties), but won't be helpful for input text fields.
For input text, I'd suggest listening for the Event.CHANGE event, then updating the width/height based on the number of lines, the .textWidth, or TextLineMetrics info (e.g. myTextField.getLineMetrics).
Here's a quick example:
var myField:TextField = new TextField();
myField.x = 10;
myField.y = 10;
myField.width = 100;
myField.height = 20;
myField.border = true;
myField.type = TextFieldType.INPUT;
myField.addEventListener(Event.CHANGE, textChangeHandler);
addChild(myField);
function textChangeHandler(evt:Event) {
var buffer:Number = 10;
myField.width = Math.max(100, (myField.textWidth + buffer));
myField.scrollH = 0;
}
Edit: Oh, and if you want that to work with .multiline, then just add:
myField.multiline = true;
and in the textChangeHandler function add:
myField.height = myField.textHeight + buffer;

How to keep element grayed out unless a conditional is met?

I'm in the process of designing a Flash application, and it requires either two or three pieces of data from the user. The third data element is only relevant if one of the other elements has changed from the default value.
In order to prevent the user from inputting information that would skew the calculations based on the input, how can I gray out the text input box if the default conditional is unchanged? I could embed a conditional to ignore the input from that particular box, but I know that some users will fill in all data fields regardless of on-screen instructions.
Just use the Event.CHANGE listener + handler to check the condition/state of elements. This event is fired every single time the user alters a component. For example, heres a text input doing this:
var tf:TextInput = new TextInput();
var someOtherObject:Button = new Button();
tf.x = 100;
tf.y = 100;
tf.width = 150;
stage.addChild(tf);
stage.addChild(someOtherObject);
tf.addEventListener(Event.CHANGE, onFormChanged);
private function onFormChanged(e:Event):void
{
switch(e.currentTarget){
case tf:
//Do your conditional checks here.
if(tf.text.toString().length < 10){
someOtherObject.enabled = false;
someOtherObject.text = "";
someOtherObject.maxChars = 0;
}else{
someOtherObject.maxChars = 100;
}
break;
case someOtherObject:
break;
}
}
So basically, as the user types into tf, I'm making sure they have entered at least 10 characters. If they were to meet the condition, and then erase a character, the event would be fired again, and the condition would not be met, so someOtherObject is disabled.