change dynamic text value in different frame Action Script 3 - actionscript-3

I have problem with dynamic text update value.
When I set the value in frame 1, it works fine, but problem came when I go to frame 2, the value didnt change.
here's the code
package {
import flash.display.MovieClip;
public class test extends MovieClip {
public function test() {
// constructor code
if (this.currentFrame == 1){
changeTitle("frame 1");
}
else if (this.currentFrame == 2){
changeTitle("frame 2");
}
}
public function changeTitle(newTitle:String){
label_title.text = newTitle;
}
}
}

Inside the constructor code the currentFrame for that DisplayObject will always be the first.
Maybe what you want to check is the currentFrame of the container of the object but you can't know that from the constructor as well, you need to wait until it's been added to a display list.

Related

AS3: class not functioning properly

Sorry for a blurry title, but this is probably the best way I can describe the issue that seems absurd to me by now.
I need a simple action done by an MC: going to a certain frame. I couldn't get it to work, although I had an exact same type of action done by another Movie Clip in the same class code. Here's how I did it:
if (currentItem.type == "blue") {
guy.gotoAndPlay("blue")
}
Yes, the class I'm referring to ('guy') is extended as a Movie Clip. Again, exact same code works fine with other Clips. I tried another method: switching the frame from the Clip's class, the frame it switches to is defined by a variable which is changed by main class. But somehow, this doesn't work either. It gives me the 1069 error. Here's the code of the 'guy' class:
package
{
import flash.display.MovieClip;
import flash.events.Event;
public class guy extends MovieClip
{
public static var gotoer:String = "fffuuu"
public function shaman_armsUp()
{
super();
addEventListener(Event.ADDED_TO_STAGE, init)
}
public function init(e:Event):void {
removeEventListener(Event.ADDED_TO_STAGE, init)
armLoop()
}
public function armLoop():void {
if (gotoer == "brown") {
this.gotoAndPlay("brown")
}
if (gotoer == "red") {
trace(gotoer)
this.gotoAndPlay("red")
}
}
}
}
Is there anyone who has a logical explanation for this? Can this be caused by a bug?
maybe the code you are writing in the method shaman_armsUp() should be moved to the constructor?
Follow my edited version of your class guy (also, renamed to Guy, follow the class name convention)
package
{
import flash.display.FrameLabel;
import flash.display.MovieClip;
import flash.events.Event;
// renaming the class name (guy to Guy)
public class Guy extends MovieClip
{
// not sure if using an static variable for this case is the best idea, but I decided to keep because I don't know your initial idea
public static var gotoer:String = "fffuuu";
public function Guy()
{
// move the addedToStage event to the constructor
super();
addEventListener(Event.ADDED_TO_STAGE, init, false, 0, true);
}
public function shaman_armsUp()
{
}
public function init(e:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
armLoop();
}
public function armLoop():void
{
// Note: the value of gotoer is "fffuuu" and there is no conditional for it.
// are you chaging this value before calling armLoop? because when the init method is called it has the same value
// why not try something like:
// checking if the frame exist and if so, calling the gotoAndPlay method (try to imagine if you have 100 frame names? the old approach will be very hard to maintain
if (hasFrameLabel(gotoer))
{
this.gotoAndPlay(gotoer);
}
else
{
trace('frame: ', gotoer, ' not found');
}
/*
if (gotoer == "brown")
{
this.gotoAndPlay("brown");
}
if (gotoer == "red")
{
trace(gotoer);
this.gotoAndPlay("red");
}
*/
}
// helper function to avoid calling a frame that doesn't exist
private function hasFrameLabel(frameLabel:String):Boolean
{
var returnValue:Boolean;
const obj:Object = this.currentLabels;
for each (var i:FrameLabel in obj)
{
if (i.name == frameLabel)
{
returnValue = true;
break;
}
}
return returnValue;
}
}
}

Actionscript 3.0...Preloader not working....Stuck in frame 0?

I'm trying to make my first preloader come to fruition on my game. I've done quite a bit of experimenting and here's what I've found.
First off, when I simulate my file, I am simply getting a blank white screen until the file...or actually just a large image I'm using att the moment...is fully loaded. I used the Bandwidth Profiler to check what was going on. It is loading at a proper rate and I can see the loading percentage increasing. Unfortunately my loader just doesn't appear, and the weird thing is it says it's in frame 0. I have no idea why it is telling me this.
What I've done to try and fix it. I've made sure that EVERY movieclip in my game has the box for exporting on first frame is unchecked, EXCEPT my preloader, so that shouldn't be the problem. I also created a blank .fla file and simply imported my preloader into it and ran it. Surprisingly, it worked! (once again, just loaded a large image). I didn't change anything....all the same names and stuff. I have no idea why that one would work and this one wouldn't.
My timeline basically is the following: Two layers: First layer first frame actions says stop();. I would assume my preloader should load on the first frame like I've told it too. Once finished loading, it runs through the timeline to frame 3, where my main game should start running since I also put in the actions of frame 3. Second layer second frame I have a MovieClip that contains the image that I want it to load.
Here is my document class
package com.classes
{
import flash.display.MovieClip;
import flash.display.Stage;
import flash.display.Sprite;
import flash.events.Event;
public class DocumentClass extends MovieClip
{
private var preloader:ThePreloader;
public static var enemyList1:Array = new Array();
// moved stickobject1 to a class variable.
private var stickobject1:Stickman2;
private var scoreHud:ScoreHud;
public function DocumentClass() : void
{
preloader = new ThePreloader(390, this.loaderInfo);
stage.addChild(preloader);
preloader.addEventListener("loadComplete", loadAssets);
preloader.addEventListener("preloaderFinished", showSponsors);
var bg1:background1 = new background1();
stage.addChild(bg1);
stickobject1 = new Stickman2(stage);
stage.addChild(stickobject1);
stickobject1.x=50;
stickobject1.y=300;
//running a loop now.... so we can keep creating enemies randomly.
addEventListener(Event.ENTER_FRAME, loop, false, 0, true);
stickobject1.addEventListener("hit", stickobject1Hit, false, 0, true);
scoreHud = new ScoreHud(stage); //create our HUD
stage.addChild(scoreHud); //and display it.
}
private function loadAssets(e:Event) : void
{
this.play();
}
private function showSponsors(e:Event) : void
{
stage.removeChild(preloader);
trace("show sponsors");
}
//our loop function
private function loop(e:Event) : void
{
//run if condition is met.
if (Math.floor(Math.random() * 40) == 5)
{
//create our enemyObj1
var enemyObj1:Enemy1 = new Enemy1(stage, stickobject1);
//listen for enemyObj1 being removed from stage
enemyObj1.addEventListener(Event.REMOVED_FROM_STAGE, removeEnemyObj1, false, 0, true);
enemyObj1.addEventListener("killed", enemy1Killed, false, 0, true);
enemyList1.push(enemyObj1);
stage.addChild(enemyObj1);
}
}
private function enemy1Killed(e:Event) : void
{
scoreHud.updateKills(1); //add 1 to enemy kills
scoreHud.updateScore(e.currentTarget.points); //add that points variable we created earlier
}
private function stickobject1Hit(e:Event) : void
{
scoreHud.updateHits(1); //add 1 to number of hits
}
private function removeEnemyObj1(e:Event)
{
enemyList1.splice(enemyList1.indexOf(e.currentTarget), 1);
}
}
}
and here is my "ThePreloader" class
package com.classes
{
import flash.display.LoaderInfo;
import flash.display.MovieClip;
import flash.events.*;
public class ThePreloader extends MovieClip
{
private var fullWidth:Number; //the width of our mcPreloaderBar at 100%
public var ldrInfo:LoaderInfo;
public function ThePreloader(fullWidth:Number = 0, ldrInfo:LoaderInfo = null)
{
this.fullWidth = fullWidth;
this.ldrInfo = ldrInfo;
addEventListener(Event.ENTER_FRAME, checkLoad);
}
private function checkLoad (e:Event) : void
{
if (ldrInfo.bytesLoaded == ldrInfo.bytesTotal && ldrInfo.bytesTotal != 0)
{
//loading complete
dispatchEvent(new Event("loadComplete"));
phaseOut();
}
updateLoader(ldrInfo.bytesLoaded / ldrInfo.bytesTotal);
}
private function updateLoader(num:Number) : void
{
//num is a number between 0 and 1
mcPreloaderBar.width = num * fullWidth;
}
private function phaseOut() : void
{
removeEventListener(Event.ENTER_FRAME, checkLoad);
phaseComplete();
}
private function phaseComplete() : void
{
//go on to the next phase
dispatchEvent(new Event("preloaderFinished"));
}
}
}
My main confusion is why the Bandwidth Profiler is telling me I'm stuck in frame 0 and until it's pretty much 100% loaded. Thus, not ever displaying the preloader....thank you!
I think your preloader should be listening to LoaderInfo's progress event. Since, you have stopped execution, I don't think ENTER_FRAME would get called for you.
Also, AFAIR, single frame movie are treated specially by the player and player sends ENTER_FRAME periodically for them. Probably, that is the reason you test application worked out.

Writing an 'if' statement in ActionScript

Is there a way of writing an if statement that involves the following?
if (MovieClip1 reaches last frame)
{
addChild(MovieClip2)
removeChild(MovieClip1)
}
Basically, all I want to happen is when my MovieClip finishes, it will change to another MovieClip or image. I know it is probably very simple, but how can I do it?
All code runs on command. So your conditional will run immediately and never run again.
Instead, you use events. You attach a listener to an event and when that event fires (is "dispatched" to use correct vocabulary), your code is called again.
var movieClip:MovieClip = new MovieClip();
movieClip.addEventLister( Event.ENTER_FRAME, this.enterFrameHandler ); //will be called on every frame enter
function enterFrameHandler( e:Event ):void {
if ( movieClip.currentFrame == movieClip.totalFrames ) {
// do something
}
}
So you listen for each new frame and in that handler, you check if it is the last frame or not.
As an extra tidbit, the standard naming convention for AS3 is to use lowercase, camelcase (thisIsAnExampleOfthat) for all objects. Package names should be in all lowercase and only Class names should be capitalized.
package
{
import flash.display.MovieClip;
import flash.events.KeyboardEvent;
import flash.events.Event;
public class Main extends MovieClip
{
var firstScene:FirstScene = new FirstScene;
var movement:Movement = new Movement;
var green:Green = new Green;
public function Main()
{
addChild(firstScene);
firstScene.addEventListener(KeyboardEvent.KEY_DOWN, mClick);
movement.addEventListener(Event.ENTER_FRAME, endChange);
}
function mClick(event:KeyboardEvent):void
{
if (event.keyCode == 77);
{
addChild(movement);
removeChild(firstScene);
}
}
function endChange(event:Event):void
{
if (movement.currentFrame == movement.totalFrames)
{
addChild(green);
removeChild(movement);
}
}
}
}

how to detect children size change actionscript?

if i got a container,there were children display object in it.
the container's size was decided by the children's size.when the size change i need to do something to fit the new size.
since i didn't find the kind of event to detect it,i use ENTER_FRAME event,that's quite silly.
keep every last frame's size,and compare to current frame.maybe the size changed after you deal with the enter frame event,so in some cases,you might see the correct result in the next frame.
i don't think it's a good solution for a component.give me you ideas,thanks.
Well there is no standard solution for this. You could create a custom class which overrides the setters of width/height/x/y/scaleX/scaleY/scrollRect .. and maybe some other properties. The children should extend such a class.
I used a boolean to prevent its dispatched multiple times, after a frame the flag will be resetted.
override public function set width(value:Number):void
{
if (value !== super.width && !isNaN(Number(value)) this.dispatchResize();
super.width = value;
}
override public function set height(value:Number):void
{
if (value !== super.height && !isNaN(Number(value)) this.dispatchResize();
super.height = value;
}
override public function set scaleX(value:Number):void
{
if (value !== super.scaleX && !isNaN(Number(value)) this.dispatchResize();
super.scaleX = value;
}
override public function set scaleY(value:Number):void
{
if (value !== super.scaleY && !isNaN(Number(value)) this.dispatchResize();
super.scaleY = value;
}
private var _hasDispatchedResize:Boolean;
protected function dispatchResize():void
{
// do something
if (!this._hasDispatchedResize)
{
this.dispatchEvent(new Event(Event.RESIZE));
this._hasDispatchedResize = true;
this.addEventListener(Event.ENTER_FRAME, handleEnterFrameOnce);
}
}
private function handleEnterFrameOnce(event:Event):void
{
this.removeEventListener(Event.ENTER_FRAME, handleEnterFrameOnce);
this._hasDispatchedResize = false;
}
Now, in the container class you can listen to a Event.RESIZE of the children. Your not really sure if the value actually changed (in case of a frame change on a MovieClip), but in most cases this will work. I've added an extra check inside this setters before dispatching the resize. It depends on the case if this will suit your case.
What I would do is whatever function resizes the children, add your own dispatch event to it that would broadcast that a size change occurred.
//Never forget to import your classes.
import flash.events.EventDispatcher;
import flash.events.Event;
//Our custom listener listens for our custom event, then calls the function we
//want called when children are resized.
addEventListener("childResized", honeyIResizedTheChildren);
function resizingLikeFun(){
datClip.width++;//they be resizin, yo.
dispatchEvent(new Event("childResized"));//Our custom event
}
function honeyIResizedTheChildren(e:Event){
trace("Giant Cheerios");
//Whatever you want to do when the children are resized goes here.
}
I assume some things with that code, so let me know if this doesn't fully apply to you.

Accessing Function on MovieClip from Document Class

[NOTE: Right off the bat, I already know the popular theory about "no code on MovieClips," so please don't reply with that (or
downvote because of it). Every project is different. I just need the answer.]
I have a project in Adobe Flash CS5.5, Adobe AIR 3, and ActionScript 3.
I need to call a function on the main timeline of the project that the document class is linked to from inside the document class. For the sake of example, let's call this function "Ring()".
How do I call this function, "Ring()" from inside my document class?
Put the function you want to call in your document class, and dispatch a custom event (or any event, if the code is readable) from the timeline of the object and listen for that event on your document class.
So the code breakdown would look like this:
On some frame of the timeline in your document (should work on any object):
var customEvent:Event = new Event(Event.COMPLETE);
this.dispatchEvent(customEvent);
In your document class:
public function DocumentClass()
{
// get the reference to the object
lolcats.objectThatDispatchesEvent.addEventListener(Event.COMPLETE, _customHandler);
}
protected function _customHandler(event:Event):void
{
// FUNCTION NAMES SHOULD START WITH LOWERCASE! ^_^
Ring();
}
http://www.adobe.com/devnet/actionscript/articles/event_handling_as3.html
Basically you register any string that defines your event, Event.COMPLETE evaluates to "complete", you can just register whatever you want, like:
var custEvent = new Event("anyCustomString");
this.dispatchEvent(custEvent);
// catch it with
addEventListener("anyCustomString", _handler);
Well, since you seem to be using some oldskool ninja techniques, I would suggest that you should keep it simple and straightforward.
Say you have some functions on the main timeline:
function Ring1():String
{
return "Ring1() called!";
}
var Ring2:Function = function () : String
{
return "Ring2() called!";
};
The scenario for a document class of the said timeline would be like this:
package {
import flash.display.MovieClip;
import flash.events.MouseEvent;
import flash.utils.getQualifiedClassName;
import flash.utils.describeType;
public class Test extends MovieClip
{
public function Test()
{
stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
}
private function onMouseDown(event:MouseEvent):void
{
trace(getQualifiedClassName(this)+".onMouseDown()");
try {
var ring1:Function = this["Ring1"] as Function;
var ring2:Function = this["Ring2"] as Function;
} catch (error:Error) {
// ignore
}
if (ring1 != null) {
trace("\t", "Ring1", "=", ring1);
trace("\t", ring1());
} else {
trace("\t", "Ring1() function not found in "+this+"!");
}
if (ring2 != null) {
trace("\t", "Ring2", "=", ring2);
trace("\t", ring2());
} else {
trace("\t", "Ring2() function not found in "+this+"!");
}
// for your interest:
var doc:XML = describeType(this);
var ring1Node:XML = doc.descendants("method").(#name == "Ring1")[0];
var ring2Node:XML = doc.descendants("variable").(#name == "Ring2")[0];
trace("declaration of Ring1:", ring1Node.toXMLString());
trace("declaration of Ring2:", ring2Node.toXMLString());
// so, you may probably make use of reflection
// unless you need to reference dynamic members on the main timeline
}
}
}
See comments in the code above.