Display of current and past actions threw text - actionscript-3

So iv set up a set of text to display the last actions you'v done within my game. Iv managed to get it to add the text below the current text, but how would i move all of the previous text upwards so each time it adds a new text it will place it in the same spot and only move the previous text, then delete the oldest text after a certain amount has been displayed
This is the game
http://www.fastswf.com/F7ei81E
this is the code im currently using
protected function createEventText()
{
chatScreen = new Sprite();
chatScreen.x = 280;
chatScreen.y = 520;
addChild(chatScreen);
addText("The world has spawned!");
}
public function addText(t:String)
{
eventArray.push(t);
for (var i:int = eventArray.length - 1; i < eventArray.length; i++)
{
et = new EventTextMC();
et.txt.text = String(eventArray[i]);
et.y = i * 20;
chatScreen.addChild(et);
}
}

What I suggest is that you keep a finite number of EventTextMC instances on your chatScreen. Then, when you add the text, you can "push" the text from the top field to the bottom field.
private var _historyLength:int = 5; // number of text fields to generate
private var _textFields:Array = []; // array to keep track of textfields
// create the finite number of fields (based on historyLength)
private function initLog():void
{
// adding 5 (historyLength) text fields to the chatScreen
for(var i:int = 0; i < historyLength;i++)
{
var et:EventTextMC = new EventTextMC();
et.y = i * 20;
textFields.push(et);
chatScreen.addChild(et);
}
}
public function addText(t:String)
{
eventArray.push(t); // this array isn't actually being used in this example
// starting with the last text field, copy the previous field's text
// this will create a "pushing down" effect
// CLARIFICATION:
// The text from the second to last field will be placed into the last field.
// The text from the third to last field will be placed into
// the second to last field.
// This will continue until the text from the first field will be placed
// in the second field, freeing up the first field for the new text.
for(var i:int = historyLength-1; i > 0; i--)
{
textFields[i].txt.text = textFields[i-1].txt.text;
}
// add the new text to the first (top-most) textfield
textFields[0].txt.text = t;
}
While I'm not actually using the eventArray in this example, you could easily use it later on to "scroll" through the logs.

Related

How to convert different line of a dynamic text box to Movie clip in AS3

I have a question regarding to my project which is How to convert different line of a dynamic text box to Movie clip in AS3?
Actually, I have an text file named test.txt. For instance:
It consists of:
today is Sun;
today is Mon;
today is Tue;
today is Wed;
today is Thu;
today is Fri;
today is Sat;
and then I want to put all of them into an array and then a string to show them in the dynamic text Box called text_txt.
I have different objects in my library. If we see "sun" in the first line, the first object (obj01) will be shown in a specific area which is inside a movie clip called mc.
The question is here:
Fist: if I have different texts in my first line. for instance "today is sun;". how to find that the "sun" is in this line???
Second: How to convert different line of a dynamic text box to Movie clip. So, if user click on the "obj01", the first line in the dynamic textbox will become bigger???
Thanks for your time and help in advance.
import flash.events.MouseEvent;
var flag:int = 0;
//load the txt file
var myTextLoader:URLLoader = new URLLoader();
myTextLoader.addEventListener(Event.COMPLETE, onLoaded);
myTextLoader.load(new URLRequest("test.txt"));
//when the scene loads, all the info from txt file shown into the dynamic text;
function onLoaded(e:Event):void
{
//put all the info into array
var days:Array = e.target.data.split(/\n/);
var str:String;
//show them in the dynamic text
for (var i=0; i<days.length; i++)
{
str = days[i];
text_txt.appendText(str + "\n");
//if one text founded, do somethind and shoe an objectinthe output;
switch (str)
{
case "sun;\r" :
var obj01:Show = new Show();
mc.addChild(obj01);
obj01.x = -200;
obj01.y = -15;
break;
default :
trace("None of the above were met");
}
}
obj01.buttonMode = true;
//if the object clicked then something must be happend to the first line in the dynamic text box
obj01.addEventListener(MouseEvent.CLICK, firstLine);
function firstLine(e:MouseEvent):void
{
flag = 1;
switch (flag)
{
case 1 :
trace("Clicked!");
//the first line in the text box should get a different background and become more bigger
//Do I need to convert the first line to a movieclip? OR I need to do in another way?!
break;
default :
trace("None");
}
}
}
First: if I have different texts in my first line. for instance "today
is sun;". how to find that the "sun" is in this line???
split whole of the dynamic-text value with its lines to an Array
then check each array item if contains that key ("sun").
you have to use some thing like it Array[x].indexOf(key) >= 0
Second: How to convert different line of a dynamic text box to Movie
clip. So, is user click on the "mc.obj01", the first line in the
dynamic textbox will become bigger???
i just give you an example to find the reason of difference in size of movieclip and text-display. this image comes from adobe-flash. a text field with its value "brown fox jumps" has the same size as the green rectangle. but the text-size shown by the red rectangle.
Green is textfield size, same as textField.width & textField.height
Red is text size, same as textField.textWidth & textField.textHeight
so you must resize your movieclip/textfield to second Values(Red);
my answer is not walkthrough but a guidance.
After too much research and try a lot of functions, I have find the answer for Second part of this question.
I was sure that there must be a way to do it and that's why I made it as my Favorite question.
//
var newMcTitle:Array = [];
//put all the info into array
var days:Array = e.target.data.split(/\n/);
for (var i=0; i<days.length; i++)
{
str = days[i];
//put the texts line by line into a textfield and put the textfield into a movie clip
var newMc:MovieClip = new MovieClip();
var newText:TextField = new TextField();
newText.text = days[i];
newMc.addChild(newText);
newMc.x = 30;
newMc.y = positionY;
newMc.scaleX = 2;
newMc.scaleY = 2;
addChild(newMc);
positionY += 30;
//unique instance names:
newMc.name = days[i];// or more generally when no arrays used
newMc.name = 'mc_' + i;
//trace(newMc.name);
//asssign unique property to be used to identify newMc
newMc.ivar = i;
//populate an array instantiated outside for-loop (eg, var newMcA:Array=[];)
newMcTitle.push(newMc);
}
And now you can use:
//if the object clicked then something must be happend to the first line in the dynamic text box
obj01.addEventListener(MouseEvent.CLICK, firstLine);
function firstLine(e:MouseEvent):void
{
flag01 += 1;
switch (flag01)
{
case 1 :
//the first line in the text box should get a different background and become more bigger
newMcTitle[0].scaleX *= 1.2;
newMcTitle[0].scaleY *= 1.2;
break;
default :
trace("None");
}
}

using Action Script 3 remove an object that appeared in the run time

I use this code to create list of words from an array and make them act like buttons
in the main page i have 2 buttons that activate the for loop to create the list of words
the problem is when i hit the second button in the main the list of words of the first button still shown on the screen, i need to remove the list first then activate the second loop
i used the removeChildAt() function but it didn't worked
what should i do ?
var words:Array = [];
var word:MovieClip=new MovieClip();
if(e.target.name=="glossumbolA"){
words=['School1','School2','School3','School4','School5','School6']
for (var j:int = 0; j < words.length; j++)
{
word = createTextButton(words[j]);
addChild(word);
word.addEventListener(MouseEvent.CLICK, wordButtonClick);
}
}
else if(e.target.name=="glossumbolB"){
words=['Class1','Class2']
for (var i:int = 0; i < words.length; i++)
{
word = createTextButton(words[i]);
addChild(word);
word.addEventListener(MouseEvent.CLICK, wordButtonClick);
}
}
function createTextButton(){
//code to make the word in the array a button
}
function wordButtonClick(){
//code to make an action when the word in the array clicked
}
you have multiple ways to do that:
1. create one new MovieClip inside 'word' (with name A), for glossumbolA and one new for glossumbolB (with name B), create buttons inside MCs. You can set 'visible' true || false for A and B. If glossumbolA button is clicked - check if B is visible, set visible to 0.
or
while (word.numChildren > 0) {
word.removeChildAt(0);
} then create new buttons

How would i make the buttons pressed in my calculator show up in my dynamic text box

I am making a calculator with a dynamic text box, buttons from 0-9, and +,-,/,*,=, and clear button. but for some reason everytime I press the buttons on my calculator, they don't show up in my dynamic text box like I need them to. My problem specifically is how do I make it that when the number buttons on my calculator are pressed, the numbers show up in my dynamic text box, like a proper calculator. I would really appreciate your help.
Here is my code:
import flash.events.MouseEvent;
var numbers:Array= [btnNum0,btnNum1,btnNum2,btnNum3,btnNum4,btnNum5,btnNum6,btnNum7,btnNum8,btnNum9];
var operations:Array = [btnAdd_,btnSubtract_,btnMultiply_,btnDivide_,btnEqual_,btnClear_];
var o:String;
var number1:Number;
var number2:Number;
function addListeners():void
{
for(var i:uint = 0; i < numbers.length; i++){
numbers[i].addEventListener(MouseEvent.CLICK, pressNumber);
}
for(i = 0; i < operations.length; i++){
operations[i].addEventListener(MouseEvent.CLICK, pressOperations);
}
btnClear.addEventListener(MouseEvent.CLICK, clearAll);
btnDot..addEventListener(MouseEvent.CLICK, addDot);
}
function pressNumber(event:MouseEvent): void
{
// find name of button pressed
var instanceName:String = event.target.name;
// get the number pressed fom the instanceName
var getNum = instanceName.charAt(6)
if(output.text == "0"){
output.text = "";
}
output.appendText(getNum);
}
function pressOperations(event:MouseEvent): void
{
var instanceName:String = event.target.name;
var currentOperator:String;
currentOperator = instanceName.slice(3,instanceName.indexOf("_"));
trace(currentOperator)
}
function clearAll(event:MouseEvent): void
{
output.text = "";
number1 = NaN;
number2 = NaN;
}
function addDot(event:MouseEvent): void
{
if(output.text.indexof(".") == -1){
output.appendText(".");
}
output.text = "0";
addListeners();
}
You shouldn't try to store information in the instance name. Use objects stored in arrays for the buttons. This is how you can handle everything like this.
Using objects stored in arrays to handle your buttons, the basic code to make a new button and set its properties (store information about the button in the instance):
var aButtons:Array = new Array();var i: int = 0;
for (i = 0; i < 10; i++) {
var mcButton: McButton = new McButton();
mcButton.iButtonValue = i;
mcButton.sButtonName = "Button Number " + i;
aButtons.push(mcButton);
}
Then you can reference the buttons by
aButtons[i]
aButtons[i].iButtonValue
You have first to set a value to your text field, because appendText() method can't append text to an empty text field (nothing will appear).
At the begining of your code:
output.text = '0';
To use property "name" you must set this property after creating instance. Like this:
var btnNum0:Button = new Button();
butNum0.name = "btnNum0";
If you don't do this "name" property will be empty that looks like your case.
UPDATE:
Helloflash is right in his comment to question. At first time I did not see that but in code more mistakes than I thought.
First of all you need to put off your init code from function addDot() to the begining of the code. At now this code will be never called because you try to add listeners into listener addDot().
output.text = "0";
addListeners();
Also change indexof to indexOf and remove extra dot from statement btnDot..addEventListener(MouseEvent.CLICK, addDot);. And big advice/request: use some formatting rules when you write a code (specially about brackets). Your code will be more clean and readable.

Flex: Change text value with loop and make image from every changed value?

I want to change taxt value from loop and every time I have changed it I take image from that.
I have two numeric steppers where other is start number and other is end number. I have also button that starts function.
So after pressed it starts:
private function makeFrames():void
{
for (var i:int = 0; i < endFrameNumber.value; i++)
{
currentFrameNumber++;
frameText.text = currentFrameNumber.toString();
makeImage(currentFrameNumber);
}
}
Then I make image from text:
private function makeImage(value:int):void
{
var projectFolderName:String = createFolder();
bitmapData = new BitmapData(frameText.width,frameText.height, true, 0x00ffffff);
bitmapData.draw(frameText,new Matrix());
var bitmap : Bitmap = new Bitmap(bitmapData);
var png:PNGEncoder = new PNGEncoder();
var ba:ByteArray = png.encode(bitmapData);
newImage = File.desktopDirectory.resolvePath(projectFolderName + "/" + "frame-number_" + value + ".png");
fileStream = new FileStream();
fileStream.open(newImage, FileMode.APPEND);
fileStream.writeBytes(ba);
fileStream.close();
}
So first I change text value and then I try to capture it. It make images yes, but all numbers is same. So how I can make it to change text value every time when I run "makeImage" in loop and it captures all images between start and end numbers??
Using Flash Builder 4.6 and AIR.
You should read about Flex Components Lifecycle.
So, there are two way to solve your problem:
Using invalidateProperties -> commitProperties.
addEventListener on Event.ENTER_FRAME
Sure you can't use foreach. In each enter frame you should:
Set new text
Invalidate text display
Make and save image

Dynamic text within one UILoader in ActionScript-3

I want to show some dynamic text and that is read from a php file within xml. Here in swf player i just set three button. Two button for text and one button for images. This all are working fine but the swf background covered by the white background. Here is the normal view and some of this code snippet
normal view image http://outshinebd.com/sm/Flash/normal_view.png http://outshinebd.com/sm/Flash/normal_view.png
Code :
btnItem.addEventListener(MouseEvent.CLICK, showItem);
//btnItem.addEventListener(Event:event, showItem);
function showItem(event:Event):void
{
imgLoader.alpha =0;
textLoader.alpha=0;
imgLoader3.alpha=0;
imgLoader4.alpha=0;
imgLoader5.alpha=0;
imgLoader2.alpha=0;
var itemLoader:URLLoader = new URLLoader();
itemLoader.load(new URLRequest("http://localhost/sm/flash/productdata"));
itemLoader.addEventListener(Event.COMPLETE , onItemLoad);
function onItemLoad(e:Event):void
{
var myLoader:XML = new XML(e.target.data);
xmlList = myLoader.children();
//this values array will hold all of the values we need to paginate
var values:Array = new Array();
//defining the 'i' variable so we can use it multiple times in for loops
var i:int;
for(i = 0; i < xmlList.length(); i++){
//textLoader.text = xmlList[i].elements("productname");
values[i] = xmlList[i].elements("productname");
}
//the current page we're on
var page:int = 1;
//the limit of values we need per page
var limit:int = 1;
//the current row that we're working on
var row:int = 0;
//The total pages that we have
var totalPages:int = Math.ceil(values.length/limit);
function createValues():void{
//this will always limit the amount to the limit variable
//but, "i" will act as a marker for which part of the values
//array that we're going to use
for(i=(page-1)*limit;i<page*limit;i++){
//checks if there actually is a value where "i" is
//otherwise we'll get some undefined movieclips
if(i < values.length){
var newValue:UILoader = new UILoader();
//sets the coordinates based on the row
newValue.x = 5;
newValue.y = 5+newValue.height*row;
//sets this guys value to the correct part of the array
textLoader.text = values[i];
//changing this guys name so we can reference it later
newValue.name = 'value'+row;
//adds the mc to stage
addChild(newValue);
//move onto the next row
row ++;
}
}
//then we reset the rows so we can use the variable again
row=0;
}
//function to remove the mc's
function removeValues():void{
//this loop will run once for each mc on stage
for(i=0;i<limit;i++){
//get the object in the current row and kill it!
removeChild(getChildByName('value'+i));
}
}
//next page and previous page functions
function prevPage(event:MouseEvent):void{
//checking if the current page isn't too low
if(page > 1){
//take away all of the objects so we can make new ones
removeValues();
page --;
createValues();
//then update the page text
//updateString();
}
}
function nextPage(event:MouseEvent):void{
//checking if the current page isn't too high
if(page < totalPages){
removeValues();
page ++;
createValues();
//updateString();
}
}
//then we place the movieclips onto the stage
createValues();
//adding listeners to the buttons
btnPrev.addEventListener(MouseEvent.CLICK, prevPage);
btnNext.addEventListener(MouseEvent.CLICK, nextPage);
}
}
And the view after clicking the button
after clicking image http://outshinebd.com/sm/Flash/after_click.png http://outshinebd.com/sm/Flash/after_click.png
I'm stacked with in the last two days. Please give me a solution.
It seems that you are using an input TextField or a TextTield with a border and a background, just turn them off:
textLoader.border=textLoader.background=false;