Update text field into movie clip from main timeline code - actionscript-3

I'm working in a project for basketball. I have an issue, all my code works great if all my components are in the main timeline.
But as soon as I convert the text fields into a movie clip so I can animate and apply alpha value, all stops working.
what am I doing wrong ? The only solution that I could think of is writing the result of my countdown into the text field in the movie clip, but it didn't work as well.
this is my code.
function onTimer ( ev:TimerEvent ) : void {
timeRemaining--;
if (timeRemaining < 0) {
timeRemaining = 0;
loseGame();
}
else
showTime.text = formatTimeRemaining ();
var miReloj:MovieClip;
var titulo_txt:TextField = new TextField();
titulo_txt.text = formatTimeRemaining ();
addChild(miReloj);
miReloj.addChild(titulo_txt);
// miReloj.addChild(showTime1.text);
//miReloj.showTime1.text = formatTimeRemaining ();
}

There's never a value being assigned to miReloj, that's why it's null
var miReloj:MovieClip; // no assignment here
var titulo_txt:TextField = new TextField();
titulo_txt.text = formatTimeRemaining ();
addChild(miReloj); // miReloj is still null here
miReloj.addChild(titulo_txt); // cannot call method on null
But as soon as I convert the text fields into a movie clip
That's impossible. From your code it looks like what you actually want to do is to add the TextField object to a container. There's no need to use a MovieClip for that, simply create a Sprite object:
var container:Sprite = new Sprite(); // create container
var title:TextField = new TextField();
title.text = formatTimeRemaining();
addChild(container); // add container
container.addChild(title); // add title to container
Always use English for all your programming. Don't mix other languages into it. It becomes a pain to read your code and decreases the number of people that can help you if you have problems with your code.

Related

Loading images using the URLRequest

recently started to learn ActionScript 3 and already have questions.
question remains the same: I'm uploading a picture using the object Loader.load (URLRequest). Loaded and displayed a picture normally. But it is impossible to read the values of attributes of the image height and width, instead issued zero. That is, do this:
var loader:Loader=new Loader();
var urlR:URLRequest=new URLRequest("Image.jpg");
public function main()
{
loader.load(urlR);
var h:Number = loader.height;// here instead of the width of the image of h is set to 0
// And if you do like this:
DrawText(loader.height.toString(10), 50, 50); // Function which draws the text as defined below
// 256 is displayed, as necessary
}
private function DrawText(text:String, x:int, y:int):void
{
var txt:TextField = new TextField();
txt.autoSize = TextFieldAutoSize.LEFT;
txt.background = true;
txt.border = true;
txt.backgroundColor = 0xff000000;
var tFor:TextFormat = new TextFormat();
tFor.font = "Charlemagne Std";
tFor.color = 0xff00ff00;
tFor.size = 20;
txt.x = x;
txt.y = y;
txt.text = text;
txt.setTextFormat(tFor);
addChild(txt);
}
Maybe attribute values must be obtained through the special features, but in the book K.Muka "ActionScript 3 for fash" says that it is necessary to do so. Please help me to solve this. Thanks in advance.
Well it's simple.
Flash is focused on the Internet, hence such problems.
If you wrote loader.load (urlR); it does not mean loaded. Accordingly, prior to the event confirming the end of loading, in loadare Null
if, instead of certain functions would be more code that would perhaps tripped your approach.
Yeah plus still highly dependent on the size of the file that you read.
Well, in general it all lyrics. Listen event on loader.contentLoaderInfo.addEventListener (Event.INIT, _onEvent), onEvent and read properties.
You need to wait for your image to load to be able to get values out of it.
Attach an eventListener to your URLLoader.
var urlR:URLRequest = new URLRequest("Image.jpg");
loader.load(urlR);
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loader_complete);
function loader_complete(e:Event): void {
// Here you can get the height and width values etc.
var target_mc:Loader = evt.currentTarget.loader as Loader;
// target_mc.height , target_mc.width
}
Loader

Remove randomly generated sprites with Mouse.Event

I am making a game for my class where different chemical elements are generated as sprites at the top of the screen and then fall down. Different types are made and I want students to mouse over specific types depending on where they are in the game.
My question is how to write the function to remove them when they are correctly selected? I've tried a lot of different ways but am having a lot of trouble. An example of the code that I wrote to make each element is below and then I have a separate function to move down all of the sprites created.
var spriteArray:Array = new Array();
var halogenArray:Array = new Array("F", "Cl", "Br", "I");
var rndnum:Number = Math.random();
//Halogens
if (rndnum < 0.05)
{
var halo:Sprite = new Sprite();
halo.graphics.beginFill(0x00FF00, 1);
halo.graphics.drawCircle(7.5, 7.5, 15);
halo.graphics.endFill();
halo.addEventListener(MouseEvent.MOUSE_OVER, removeElement);
halo.x = Math.random()*500 + 50;
halo.y = -18;
var textField = new TextField();
textField.text = halogenArray[int(Math.random()*4)];
textField.width = 30;
textField.height = 30;
textField.x = (15 - textField.textWidth)/2; // center it horizontally
textField.y = (15 - textField.textHeight)/2; // center it vertically
halo.addChild(textField);
spriteArray.push(halo);
addChild(halo);
}
At what point are you struggling?
I am assuming it is in determining the types of the halogens.
In your remove function I assume you have the desired type already figured out, you would then compare it to
element.getChildAt(0).text
and you would get the element by either looping across every element in the spriteArray, or using the mouseEvent's target
My suggestion is to use a halogen Class to contain the grapics & textfield, and a vector to hold the objects. It would then be easier to get the type rather than searching the anonymous children of the sprite.
I believe you are looking for something like this:
//give your textfields a name, it isn't totally necessary as we can do getChildAt(0)
//but it's more readable, and if you decide to add more children before you
//add the text field, then this will still work
var textField = new TextField();
textField.text = halogenArray[int(Math.random()*4)];
textField.width = 30;
...
textField.name = "haloTx"; //for tracking later
//assuming you have some variable set to the correct answer
var correctAnswer:String = "F";
function removeElement( e:MouseEvent ):void {
var element:TextField = ( e.target as Sprite ).getChildByName( "haloTx" );
//if we have the correct element, remove from parent and list
if ( element && element.text == correctAnswer ) {
var index:int = spriteArray.indexOf( e.target as Sprite );
removeChild( spriteArray.splice( index, 1 )[0] );
}
}
Although #VBCPP is right, doing that in a separate class is definitely the best way organizationally. Which might look something like:
class ElementSprite extends Sprite {
public var textField:TextField;
//pass shapeArgs as string, so say a circle at x=7.5, y=7.5, and radius=15 -- shapeArgs = "7.5, 7.5, 15"
public function ElementSprite( element:String, drawShape:String="Circle", shapeArgs:String="7.5, 7.5, 15", fillColor:uint=0x00FF00 ) {
//set textfield properties etc. or textFormat
textField = new TextField();
textField.text = element;
addChild( textField );
//if you passed some arguments to draw our shape
if ( shapeArgs != "" ) {
graphics.beginFill( fillColor );
graphics[ "draw" + drawShape ].apply( this, shapeArgs.split( "," ) );
}
}
public function get currentElement():String { return textField.text }
}
Then you would use it like so in your if statement if (rndnum < 0.05):
var elementSprite:ElementSprite = new ElementSprite( "A" );
//elementSprite.x = set your x;
//elementSprite.y = set your y;
addChild(elementSprite);
That would be replacing all your current code in that if statement. This is all a working example, if you have an questions feel free to comment.

use 1 object multiple times in as3?

I'm trying to make something like bookmarks, I have 1 note on the stage and when the user clicks it, it starts to drag and the users drops it where they want. the problem is I want these notes to be dragged multiple times.. here is my code:
import flash.events.MouseEvent;
//notess is the instance name of the movie clip on the stage
notess.inputText.visible = false;
//delet is a delete button inside the movie clip,
notess.delet.visible = false;
//the class of the object i want to drag
var note:notes = new notes ;
notess.addEventListener(MouseEvent.CLICK , newNote);
function newNote(e:MouseEvent):void
{
for (var i:Number = 1; i<10; i++)
{
addChild(note);
//inpuText is a text field in notess movie clip
note.inputText.visible = false;
note.x = mouseX;
note.y = mouseY;
note.addEventListener( MouseEvent.MOUSE_DOWN , drag);
note.addEventListener( MouseEvent.MOUSE_UP , drop);
note.delet.addEventListener( MouseEvent.CLICK , delet);
}
}
function drag(e:MouseEvent):void
{
note.startDrag();
}
function drop(e:MouseEvent):void
{
e.currentTarget.stopDrag();
note.inputText.visible = true;
note.delet.visible = true;
}
function delet(e:MouseEvent):void
{
removeChild(note);
}
any help will be appreciated.
You need to create a new instance of your note class when you drop, copy the location and other variables from the note you were dragging, add your new note to the stage, and return the dragging note to its original position.
Something like:
function drop($e:MouseEvent):void
{
$e.currentTarget.stopDrag();
dropNote($e.currentTarget as Note);
}
var newNote:Note;
function dropNote($note:Note):void
{
newNote = new Note();
// Copy vars:
newNote.x = $note.x;
newNote.y = $note.y;
// etc.
// restore original note.
// You will need to store its original position before you begin dragging:
$note.x = $note.originalX;
$note.y = $note.orgiinalY;
// etc.
// Finally, add your new note to the stage:
addChild(newNote);
}
... this is pseudo-code really, since I don't know if you need to add the new note to a list, or link it to its original note. If you Google ActionScript Drag Drop Duplicate, you will find quite a few more examples.
I think you are not target the drag object in drag function and problem in object instantiation
for (var i:Number = 1; i<numberOfNodes; i++) {
note = new note();
addChild(note);
...
....
}
function drag(e:MouseEvent):void{
(e.target).startDrag();
}
If you are dragging around multiple types of objects (eg. Notes and Images), you could do something like this, rather than hard coding the type of object to be instantiated.
function drop(e:MouseEvent):void{
// Get a reference to the class of the dragged object
var className:String = flash.utils.getQualifiedClassName(e.currentTarget);
var TheClass:Class = flash.utils.getDefinitionByName(className) as Class;
var scope:DisplayObjectContainer = this; // The Drop Target
// Convert the position of the dragged clip to local coordinates
var position:Point = scope.globalToLocal( DisplayObject(e.currentTarget).localToGlobal() );
// Create a new instance of the dragged object
var instance:DisplayObject = new TheClass();
instance.x = position.x;
instance.y = position.y;
scope.addChild(instance);
}

AS3 multiple textfields made easy

I am working on a Results page for my game as well as upgrade page and looking for an easy way to do many textfields. I have a format for my text that takes care of font, colour, and size, but looking for an easy way to do the width and height of textfields to increase all at the same time.
I have been informed about a "with" keyword that may work but do not understand how to implement this within my program and essentially want to shorten my results class if possible.
Thank you,
The best way would be to create a custom function for generating textfield.
The example can be found in the livedocs itself.
So something like the following should suffice :
private function createCustomTextField(x:Number, y:Number, width:Number, height:Number):TextField {
var result:TextField = new TextField();
result.x = x;
result.y = y;
result.width = width;
result.height = height;
return result;
}
You may also set a default value to each attribute in the function.
private function createCustomTextField ( x:Number= <Default Value>, ...
Use it to add a textfield inside the container form.
var container:Sprite = new Sprite(); // New form container
container.addChild(createCustomTextField (20,20,50,50)); // Text Filed 1
container.addChild(createCustomTextField (20,50,50,50)); // Text Filed 2
addChild(container); // Add to current class
You may want to modify the function to accept a name so that each variable can be accessed later.
As far as I am aware, you can't use a "with" keyword to target multiple objects. Here's the documentation for it: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/statements.html#with
What I've done in the past is just make an array of all the targets, and then write a loop to apply properties to each:
var textFormat:TextFormat = generateMyCustomTextFormat();
var textField1:TextField = new TextField();
var textField2:TextField = new TextField();
//...
var textField3:TextField = new TextField();
var targets:Array = [textField1, textField2, textField3];
for(var i:int=0; i<targets.length; i++)
{
targets[i].defaultTextFormat = textFormat;
targets[i].width = 250;
//...
}

AS3 Can't access MC on Stage

I have 54 MC's on stage, generated dynamically. Now I want to get their x and y positions when rolling over but I am having problems getting the path correct e.g.
function copyFlightCellData():void {
var r; var s;
var cellData:Array = new Array ();
for (r = 0; r < 54; r++){
//var copyCellData = new MovieClip();
cellData[r] = Object(root).mc85.name; //["mc"+r+r];
trace("$$$$$$$$$$$$$$$$$$$$$" + cellData[r]);
}
}
I used the list objects in debug and they are listed in _level0 e.g.
Movie Clip: Frame=1 Target="_level0.mc85"
Not sure why I can't access their properties.
This is the code that created the MC's
// Create copies of flightCell for board grid
var my_mc = new flightCell();
my_mc.name = "mc" + i + j;
trace("^^^^^^^^^^^^^^****************" + my_mc.name);
addChild(my_mc);
Answer is pretty simple, use the DisplayObjectContainer object's, in this case root, getChildByName() method, for example:
var sprite1:Sprite = new Sprite();
sprite1.name = "sprite1";
addChild(sprite1);
trace((root as DisplayObjectContainer).getChildByName("sprite1").name); // output : sprite1
It's probably a better idea to store the movieclips you have on your stage in an array to begin with.
To access it by name you have to assign a name to them when you create them.
mc85.name = "mc85";
As an alternative that I recommend, you can use getChildAt(index) : http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/DisplayObjectContainer.html?filter_flash=cs5&filter_flashplayer=10.2&filter_air=2.6#getChildAt()
Also, I highly recomend you to create an empty movieclip or sprite and add all of this mcs to them instead of the root.