AS3 - Displaying points gained above the player - actionscript-3

So, I am adding this text field to my container MC whenever a certain condition is met.
In this case, I am trying to display the number of points gained above a playerMC whenever he grabs a coin. Kind of like the old Mario Games whenever you would step on a Goomba and points would appear above the dead Goomba.
I'd like to be able to assign the "points" text field to a "Text.as" file so I could just control the text field's behaviors from there instead of from within my Document Class.
I know how to create a text field from the document class, but I can't seem to create an empty text field on the stage and then convert it into a movie clip so that I can assign it a base class.
Anyone know of a good way to handle this situation? Any ideas you might have.

It's most efficient to just create the textField via code in the contstructor of your Text.as class. However, if you're set on doing it in the flash IDE... create your dynamic text field, give it an instance name, then convert it to a MovieClip with F8. Go to the library and enter you're new movieClip's properties, set the base class to your Text.as file.
Your class (which encapsulates the textField) should then start out looking something like this:
package {
public class Text extends Sprite {
public var myTextFieldInstanceName:TextField;
public function set text(val:String):void { myTextFieldInstanceName.text = val; }
public function get text():String { return myTextFIeldInstanceName.text;}
public function Text(defaultText:String){
text = defaultText;
}
}
}
In order to set the base class, you need to do the same thing that I recommended you do for your Bullet and Impact movieclips. You perform a linkage by selecting "Export to Actionscript". You can tell it what class to look at for its behavior. Then just addChild it to your playerMC (after adjusting x and y values of course).

Related

Square bracket notation to dynamically load library items?

So I've spent an embarrassing number of hours trying to save myself a few minutes and make my code a bit neater, and Google has produced nothing, so now I come crawling to stackoverflow. The problem is with square bracket notation + library items:
So let's say you have a MovieClip called "myMC_5", and you want to set its X position to 0..
myMC_5.x = 0;
..and if you don't want to hard-code the name of the MC but instead you want one line of code to move a specific MovieClip based on a variable, you could do something like this:
var selectMC = 5;
root["myMC_"+selectMC]x = 0;
..and this will have the exact same effect as myMC_5.x = 0, except that this time you must specify the location ("root" or "this" or something).
THE PROBLEM:
I'm working on a game in which the graphic for the background is loaded from the library, and it's different for each level. The initial loading of the vector from the library looks like this:
private var land:vector_land0 = new vector_land0();
..and this works fine, but it only loads that one specific vector. There should be about 30 or more. I'd like to just have 1 line of code in the constructor to load any of them, based on a variable which keeps track of the current level, like this:
private var land:["vector_land"+theLevel] = new ["vector_land"+theLevel]();
..but that doesn't work. I get syntax errors ("expecting identifier before leftbracket") because you need to specify the location of the object, like in the first example:
root["myMC_"+"whatever"].x = 0;
..but this library item has no "location". So, how the heck do I dynamically load a vector from the library? It's not "on the root", or anywhere else. It has no location. I refuse to believe that the standard method for accomplishing this is to create 30 different classes or write a giant block of code with 30 "if" statements, but searching Google has found nothing. :(
It sounds like you're looking for getDefinitionByName(), which you could use to do something like this:
import flash.utils.getDefinitionByName;
private var LevelVectorClass:Class = getDefinitionByName("vector_land" + theLevel) as Class;
private var land:Object = new LevelVectorClass();
This is a horrible way to solve the situation, I don't recommend using square brackets anywhere but arrays. I recommend you putting the "lands" into a LandContainer MovieClip, each frame of that MovieClip would container 1 graphic. It is much cleaner, and you could create constants to store the "identity" of the frames.Example:
var land:LandContainer = new LandContainer();
land.gotoAndStop(FIRST_LEVEL); //FIRST_LEVEL is a constant integer
You can even reuse this LandContainer instance because you can set it's visibility, remove from the display list, set it's frame to the next level without creating another instance. On second thought, I would write a wrapper for this class. Aka link it to your own class which extends the MovieClip class and create custom functions, fields... etc..
This dynamic thing is horrible, hard to maintain, and not efficient at all. Don't know why did not they delete it from AS3... they should have.

AS3 Databinding to Specific property at an index in ArrayCollection

I have a situation where I want to use databinding from an ArrayCollection to populate text fields in a Flex view.
The ArrayCollection is populated from an SQL Result object. I store the ArrayColelction in my model class using getters and setters like this:
private var _monthlyData:ArrayCollection;
public function set monthlyData(value:ArrayCollection):void{
_monthlyData = value;
}
[Bindable]
public function get monthlyData():ArrayCollection{
return _monthlyData;
}
I use the monthlyData as a dataprovider for a list etc which works fine. I also need to use properties at certain indexs in this collection as text field strings.
When the text field text properties are set I don’t neccesarily have the monthlyData arrayCollection populated yet.
The text fields are set in another outside class with has a singleton reference to this model so I set the fields like so at the moment:
textField.text = _model.monthlyData.getItemAt(3).Month;
I want to setup binding to the array collection instead of just using this assignment method so that when that item in the array is refreshed or the entire arrayCollection is populated or updated , it will update the textField text.
I’m having trouble getting the binding to work.
I’m using bindageTools at the moment but have been also using the built in as3 BindingUtils to little effect.
I can do the following which sets the initial text property correctly, but it wont update when the ArrayCollection changes:
Bind.fromProperty(_model.monthlyData.getItemAt(3),"Month").toProperty(textField, "text");
So if someone could please point me in the right direction as to which way is best to get the binding going in pure AS3 no MXML, I’d really appreciate it.
Cheers
Marco
From the code you provide, I can see that monthlyData is bindable, which is fine. I'll assume that _model is bindable too.
However the getItemAt() method is not bindable (it will not dispatch propertychange events when items change positions in the collection), hence the text property of the text field will not be updated.
What you can do is something like this:
[Bindable]
public var selectedDate3:MyDate;
<s:TextInput id="myTextInput" text="{selectedDate3.month}" />
or the AS equivalent (why you want to make things hard on yourself is beyond me though)
BindingUtils.bindProperty(myTextInput, "text", selectedDate3, "month");
and then programmatically update selectedDate3:
_model.monthlyData.addEventListener(CollectionEvent.COLLECTION_CHANGE, updateSelected);
private function updateSelected(event:CollectionEvent):void {
selectedDate3 = _model.monthlyData.getItemAt(3);
}
Note that the month property of MyDate must also be bindable.
You mention that these fields are in a VGroup. I'm guessing you want to display a top 3 or something. This is still a list. It would be much easier and cleaner to do this with a List or DataGroup and simply filter the ArrayCollection to only display the first 3 items (or whatever rule for the items to be displayed), or configure the DataGroup to display only three items (it has no scrollbar anyway).

AS3. How to change character's template in adobe flash cs5 using AS3?

I'm creating flash game. Here will be abillity to choose one of two (or more) character's. So I have in library created symbol hero. It have 7 animations on click (moving, jumping, attacking etc..)
So I want to create something like hero 2, that player could choose which one likes more. Just how to do that? Create new layer in hero and add animations or how?
I'm asking that because in Action Script 3 I'm adding hero in this case and It always will add the same:
private function create_hero()
{
addChild(Hero);
Hero.gotoAndStop("stay");
Hero.x = stage.stageWidth/2;;
Hero.y = ground.y - 60;
Hero.x_speed = 0;
Hero.y_speed = 0;
}
Maybe here is abillity to make something like that layer2.addChild(Hero);?
Or I need to create new symbol hero2? I don't like this idea, because I have long code to control hero, so for every character I'll need to dublicate code. Could you help me? Thank you.
The proper way is to dynamically create an instance Hero at game start based on the game player's selection. You indeed create two (or more) symbols in Flash CS, with common frame labeling (you can use different animation lengths for different heroes), then, once you've got your hero selection (hero1,hero2,hero3 etc, regardless of their amount) you get the class name from selection and get your Hero variable to be assigned an instance of the respective class. An example:
static var heroes:Array=[hero1,hero2,hero3]; // note: symbol names!
var Hero:MovieClip; // note, not "hero1" or anything, but general MovieClip type
public function selectHero(what:int):void {
// this is called with correct "what", design yourself. I use array index
var whatHero:Class = heroes[what]; // get selected hero symbol
if (Hero && Hero.parent) Hero.parent.removeChild(Hero);
// clean up previous hero. Drop listeners here, if any
Hero = new whatHero(); // get new hero
// process as usual, don't forget to "addChild(Hero)" somewhere
}
How this works: First, you give the player a hero selection dialogue, and call selectHero with proper value of what (0 for hero1, 1 for hero2, etc, as you make your heroes array). Then, the whatHero variable is assigned the corresponding class (yes, one can assign classes to variables in AS3!) And then the class gets instantiated via new construction, and the resultant movie clip is then assigned to Hero variable. After this is done, you can use your hero as before.

How to copy Input Text Value into Dynamic Text that is in a MovieClip1 Inside a MovieClip2

Current my code is as such
setcustomlocation.addEventListener(MouseEvent.CLICK,customlocation2);
function customlocation2(e:MouseEvent):void
{
locationinput.text = FlashingWon.Won1.name.text;
}
I'm trying to make it such that it would copy the input text field values into a dynamic text. However, it throws up the error that
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at main/customlocation2()[main::frame1:9]
Which can I only assume that it is not able to communicate with the dynamic text field in the movieclip within another movieclip.
First, you can be 100% sure that it CAN communicate with the dynamic TextField in the MovieClip.
From you description I understand that you wish to copy from input into dynamic. But from your code I see that you take from the dynamic into the input, please check that out:
// This will copy in such a way: input <= wonText
locationinput.text = FlashingWon.Won1.name.text;
// This will copy from input
FlashingWon.Won1.name.text = locationinput.text;
Anyhow, the error that you get has nothing to do with this, it's rather like you already noticed, that one of your TextField is not 'found'. For this I recommend you a best practice: To create instances of the objects you want to use and populate them from the stage through the getChildByName method. This way you will promptly now (specially if you do this on construction or init) if you had any misspelling or miss structure on the childs you want to get.
like so:
var inputText: TextField;
var dynoText: TextField;
In your Constructor or else where at a soon level, give to your vars the proper value:
inputText = getChildByName('locationinput') as TextField;
dynoText = FlashingWon.Won1.getChildByName('name') as TextField;
This way you will soon enough know if one of this 2 textFields were not found under the object you give, and you have only one place to miss spell it. Also you will get code completion on your TextFields.
Finally the copy text part:
dynoText.text = inputText.text;
Hope it helps.
Alright, sorry for the delay, I was out on holidays.
I have opened your example and can see where the problems are:
1) You are trying to reach the FlashingWon when initiating the dynoText on the FIRST frame like so var dynoText = FlashingWon.Won1.getChildByName('name_txt'); BUT the FlashingWon element is ONLY available on the FIFTH frame. Meaning that you cannot refer to it quite yet, unless you add it on the first frame and make in invisible till the fifth frame. (You can make it visible in the goto1 function if you wish after the goToAndStop(5) line)
2) You called the TextField on the Won1 element 'name' which is a restricted sting in AS3, so change it to name_txt or label if you wish and it will work.
Let me know how it worked.

textfield.text not showing every characters

I have a setup a PageHolder class (based on MovieCLip) that displays a doted area with a (page) number in the middle.
Now attempting to populate my LayoutPane, I create new instances of of PageHolder whose constructor is tasked to set the text value of its only Texfield to the value specified in the new PageHolder parameter.
The problem here is that only the character present in the Library Object will display at run time.
For example, I have setup my PageHolder object with a text field containing the number "0". Now at run time, every instance of PageHolder is blank except fro the one that I passed a "0" as part of the init parameter (10,20,30,...) and on those pages, only the "0" is showing. If I change the original object to display a "1" instead, then every "1" of the page number that contains a "1" show ups.
Can somebody shed some light on this?
package
{
import flash.display.MovieClip;
public class LayoutPage extends MovieClip
{
public function LayoutPage(page:uint)
{
pageNumber_txt.defaultTextFormat = pageNumber_txt.getTextFormat();
pageNumber_txt.text = String(page);
}
}
}
You may need to embed the font you are using for the text field.
Select the text field you have put in your PageHolder class and click the Embed button underneath the font family drop-down box, then check the item labeled 'Numerals[0..9]' and click OK.