AS3 buttons changing text when pressed - actionscript-3

I need some help. In Flash, i have designed a sinmple button from the components panel. I have given it the instance name of btn_one. What i am attempting to do is everytime users click on the button i want the button to change text from send to next. But, how do you do this?
Unfortunately my knowledge of as3 is limited. They are many tutorials of as3 button but i have not found any in regards to this. I would really appreciate it if you guys could show me some examples of code or provide me some tutorials links.
Thanks

I've tried to do something about SimpleButtons' text fields, and came up with the following code. Hope it'll help.
public class GenericTextButton extends flash.display.SimpleButton {
public var buttonText:String;
private var tfs:Vector.<TextField>;
public function GenericTextButton():void
{
tfs=new Vector.<TextField>();
var tc:DisplayObjectContainer;
var i:int;
// now let's init embedded TFs
// trace((upState as DisplayObjectContainer).numChildren); // wow there's property available! YES
if (upState is DisplayObjectContainer) {
tc=(upState as DisplayObjectContainer);
for (i=0;i<tc.numChildren;i++)
if (tc.getChildAt(i) is TextField) tfs.push(tc.getChildAt(i) as TextField);
} // now same with overState and downState
if (overState is DisplayObjectContainer) {
tc=(overState as DisplayObjectContainer);
for (i=0;i<tc.numChildren;i++)
if (tc.getChildAt(i) is TextField) tfs.push(tc.getChildAt(i) as TextField);
}
if (downState is DisplayObjectContainer) {
tc=(downState as DisplayObjectContainer);
for (i=0;i<tc.numChildren;i++)
if (tc.getChildAt(i) is TextField) tfs.push(tc.getChildAt(i) as TextField);
}
// trace(name+' has '+tfs.length+' textfields'); // 3 !!!! Unbelieveable, but true
}
public function setText(the_text:String):void {
for (var i:int=0;i<tfs.length;i++) tfs[i].text=the_text; // and NOW we can do as simple as this
}
}
What does it do: You declare your button instance as GenericTextButton descendant, instead of SimpleButton, then you'll have setText() method available to instantly change all text in that button to whatever you supply. It enumerates internal structure of SimpleButton, grabs any TextFields there are, and stores it in a Vector for easy reference.

Related

Unable to reference MovieClip inside Button AS3

I have this annoying issue that I hope someone might be able to help me with.
I have a mute button that I created and I have another movieclip inside of that button. All I want it to do is when I toggle the mute the movieclip inside will go to the according frame.
However, every time I try to call the movieclip inside of the button, this error comes up:
Access of possibly undefined property mcMuteToggle through a reference with static type flash.display:SimpleButton.
The instance name for the movieclip within is "mcMuteToggle".
Why not make movieClips that act like buttons?? Since I dont think actual button (simpleButton) types can deal with sub-MovieClips (especially if they too have code). Even if possible don't do it, I can predict a mess whereby Button does things it shouldn't do depending on what code you have in those MClips.
Try an alternate button method, just for a test... You didnt show any test code to work with so I will make assumptions..
1) Make a shape (rectangle?) and convert to MovieClip (or if all coded, then addchild shape to new MovieClip). Let's assume you called it mc_testBtn.
2) Make that MC clickable by coding mc_testBtn.buttonMode = true;
3) Add your mcMuteToggle inside the mc_testBtn
(or by code: mc_testBtn.addChild(mcMuteToggle);
Now you can try something like..
mc_testBtn.addEventListener (MouseEvent.CLICK, toggle_Mute );
function toggle_Mute (evt:MouseEvent) : void
{
if ( whatever condition )
{
mc_testBtn.mcMuteToggle.gotoAndStop(2); //go frame 2
}
else
{
mc_testBtn.mcMuteToggle.gotoAndStop(1); //go frame 1
}
}
This is likely due to strict mode. You can either disable it in the ActionScript settings dialog, access it with a different syntax myButton['mcMuteToggle'], or make a class for the symbol that includes a property mcMuteToggle.
You can also check to make sure the symbol is actually on the stage and that clip is actually in the button:
if('myButton' in root) {
// ...
}
if('mcMuteToggle' in myButton) {
// ...
}
i think u just overwrite that codes. You u can use something like this:
var soundOpen:Boolean = true;
var mySound:Sound = new Sound(new URLRequest("Whatever your sound is"));
var mySc:SoundChannel = new SoundChannel();
var mySt:SoundTransform = new SoundTransform();
mySc = mySound.play();
mcMuteToggle.addEventListener(MouseEvent.CLICK, muteOpenSound);
function muteOpenSound(e:MouseEvent):void
{
if(soundOpen == true)
{
mcMuteToggle.gotoAndStop(2);
/*on frame 2 u need to hold ur soundClose buton so ppl can see :)*/
soundOpen = false;
mySt.volume = 0;
mySc.soundTransfrom = st;
}
else
{
mcMuteToggle.gotoAndStop(1);
soundOpen = true;
mySt.volume = 1;
mySc.soundTransfrom = st;
}
}
This is working for me everytime. Hope u can use it well ;)

Making multiple objects draggable

I have about 50 symbols that I want to make draggable. Nothing fancy, just the ability to click it and drag it to a different location.
I found as3 code for doing so but when I paste it into my file it gives me errors:
**Error** Scene=Scene 1, layer=Units, frame=1:Line 9: The class or interface 'MouseEvent' could not be loaded.
function mouseDownHandler(evt:MouseEvent):void {
That code is:
// Register mouse event functions
fighter_uk.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
fighter_uk.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
fighter_uk.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
fighter_uk.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
// Define a mouse down handler (user is dragging)
function mouseDownHandler(evt:MouseEvent):void {
var object = evt.target;
// we should limit dragging to the area inside the canvas
object.startDrag();
}
function mouseUpHandler(evt:MouseEvent):void {
var obj = evt.target;
obj.stopDrag();
}
I'm using flash pro 8, so I tried finding as2 code but couldn't find it.
Also, is there an 'easy' way to code all 50 objects?
I think you're trying to compile AS3 code with AS2 compiler. Try changing your compilation settings to target AS3.
Also you may need to include the class import at the top of your code:
import flash.events.MouseEvent;
To drag 50 objects, add them all on the same container sprite and add the listener to the container sprite only:
var holder:Sprite = new Sprite();
for ( var i:int = 0, l:int = 50; i < l; i++ ) {
var dragee:YOUR_CUSTOM_OBJECT = new YOUR_CUSTOM_OBJECT();
holder.addChild(dragee);
}
addChild(holder);
holder.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
holder.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
holder.addEventListener(Event.MOUSE_LEAVE, mouseUpHandler);
var currentDragee:YOUR_CUSTOM_OBJECT = null;
function mouseDownHandler(evt:MouseEvent):void {
currentDragee = evt.target as YOUR_CUSTOM_OBJECT;
if ( currentDragee !== null ) {
currentDragee.startDrag();
holder.addChild(currentDragee); // bring current to front position
}
}
function mouseUpHandler(evt:Event):void {
if ( currentDragee !== null ) currentDragee.stopDrag();
currentDragee = null;
}
YOUR_CUSTOM_OBJECT being the object class you need to drag. Hope it helps!
This page seems to have the answers you are looking for (AS2 drag and drop). If you've already seen it, you'll need to explain why it's not good enough for your needs.
If you want to drag/drop multiple instances in AS2, you can still add the code to the movieClip symbol, export it from the library and load the instances up using attachMovie (all 50 of them). If they are all different, then attach the code as necessary to the clips themselves, or to some function elsewhere that will capture all the clicks and decide what was clicked. This is all very doable in AS2.
Remember you can use your onClipEvent(load) function to set up a lot of the initial lifting.
Here's a sample I made in AS2 for making a node tree. It's all draggable (mouse drag) and zoomable (with mouse Wheel). You can add nodes by clicking on the little down arrow in the node box. Each node is listening for the mouse.
You'll want to look at this section for the most part:
// Enable drag on button press
on (press)
{
startDrag(this);
}
// Stop the drag on release of mouse button
on (release)
{
stopDrag();
}
Besides this, I'm not really sure how your setup looks, so I hope this helps get the ball rolling. (Check the link, there's lots of little gems in there).
Flash Professional 8 only supports ActionScript 2 & 1
You can follow this official URL and learn how to do that in ActionScript 2, but I extremely recommend you to work with ActionScript 3.

How can I detect StaticText in AS3?

I have StaticText fields in my flash project and I need to run some code when the mouse is hovering over them. So I tried this code
stage.addEventListener(MouseEvent.MOUSE_OVER, mouseRollOver);
function mouseRollOver(event:MouseEvent):void {
var tf:StaticText = event.target as StaticText;
if (tf){
//my code
}
}
but it doesn't work. When I use dynamic text fields and replace StaticText with TextField in the var tf, it works fine. I also thought that I could get this thing working with static text fields if I could make the mouse detect not StaticText as a target but some kind of object that has certain text properties (like "selectable" set to true), but I couldn't figure out how to do this. Anyway, I need to detect a static text field as a target somehow. Any help would be appreciated.
Thanks in advance
Your best option would be to put the static text box in a movieclip, and then assign your code based around that. Static text boxes don't have instance names, and can't be manipulated.
It is hard to do this. See this link enter link description here
As you can see you can check if the DisplayObject is StaticText and by checking the mousX and MouseY properties you can find if the rollover is related to this field. By if you use Dynamic text and uncheck selectable field you will get a textfield that acts as StaticField
EDIT
this is an explanation what I mean:
Let we have a StaticText field into stage in Black flash document.
var myFieldLabel:StaticText
var i:uint;
//This for check for all staticFields in state and trace its text. It is possible and it is working. I my case I have only one field and I get reference to it in myFieldLabel:StaticText var. Also I change it's alpha to 0.3.
for (i = 0; i < this.numChildren; i++)
{
var displayitem:DisplayObject = this.getChildAt(i);
if (displayitem instanceof StaticText) {
trace("a static text field is item " + i + " on the display list");
myFieldLabel = StaticText(displayitem);
trace("and contains the text: " + myFieldLabel.text);
trace( myFieldLabel.mouseX);
myFieldLabel.alpha = 0.3;
}
}
//Adds event listener to the stage for mouse move event
stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseRollOver);
//This is an event handler. I check if the mouse position is within the static field
function mouseRollOver(evnt:MouseEvent):void
{
if ( 0 <= myFieldLabel.mouseX && myFieldLabel.mouseX <= myFieldLabel.width && 0 <= myFieldLabel.mouseY && myFieldLabel.mouseY <= myFieldLabel.height )
{
mouseOverStaticText( evnt)
}
else
{
mouseNotOverStaticText( evnt)
}
}
// this two methods change the static field alpha. Thay are only to show that is posible to detect and manipulate some properties of the StaticField.
function mouseOverStaticText( evnt)
{
myFieldLabel.alpha = 1;
}
function mouseNotOverStaticText( evnt)
{
myFieldLabel.alpha = 0.3;
}
I'm not sure what is the purpose of the managing of the StaticText field. StaticText is not design to be managed if you have to do something this is almost sure that the field must not be a static - they can be dynamic ( without selectible property ) or can be capsulated with MovieClip or there can be a different solution in your case.

Why is my button instance forgetting its textfield text and event listener?

I'm working on an assignment due at midnight tomorrow and I'm about to rip my hair out. I am fairly new to ActionScript and Flash Builder so this might be an easy problem to solve. I think I know what it is but I do not know for sure...
I'm developing a weather application. I designed the GUI in Flash CS5. The interface has 2 frames. The first frame is the menu which has a zipcode input and a button instance called "submit". On the second frame, it has another button instance called "change" which takes you back to the first frame, menu.
In Flash Builder 4, I wrote a class to extend that GUI called Application. When Main.as instantiates it, the constructor function runs. However, this was my first problem.
public class Application extends InputBase {
public function Application() {
super();
// Y U NO WORK???
this.gotoAndStop(1);
this.change.tfLabel.text = "Change";
}
}
When I ran debug it tossed a #1009 error saying it could not access the property or method of undefined object. It is defined on frame 2 in Flash CS5. I think this is the problem... Isn't ActionScript a frame based programming language? Like, you cannot access code from frame 2 on frame 1? But, I'm confused by this because I'm not coding on the timeline?
Anyway, I thought of a solution. It kinda works but its ugly.
public class Application extends InputBase {
public function Application() {
super();
// Y U NO WORK???
this.gotoAndStop(1); // when app is first ran, it will stop on the first frame which is the menu frame
setButton(this.submit, "Submit", 1);
setInput(this.tfZipCode);
}
private function submitZip(e:MouseEvent):void {
this.nextFrame();
setButton(this.change, "Change", 2);
}
private function menu(e:MouseEvent):void {
this.prevFrame();
setButton(this.submit, "Submit", 1); // if I comment this out, the submit button will return to the default text label and it forgets it event.
}
private function setButton(button:ButtonBase, string:String="", action:uint=0):void {
button.buttonMode = true;
button.mouseChildren = false;
button.tfLabel.selectable = false;
button.tfLabel.text = string;
switch (action) {
case 1:
button.addEventListener(MouseEvent.CLICK, submitZip);
break;
case 2:
button.addEventListener(MouseEvent.CLICK, menu);
break;
default:
trace("Action code was invalid or not specified.");
}
}
}
Its not my cup of tea to run the set button function every time one of the button instances are clicked. Is this caused by frames or something else I maybe looking over?
I believe you have two keyframes & both have an instance of the button component called button.
If you are working on the timeline try putting the button in a separate layer, with only one key frame.
Something like the following:
Ensures that you are referencing the same button every time & not spawning new ones on each frame.

AS3 How to access a movieclip on the main timeline from within a movieclip?

Working on an RPG type flash, and I have to be able to control a text-box from quite a few locations. The one that is causing me trouble is the inventory. I need to be able to access the textbox with an instance of "statusWindow" from within the inventory clip (instance name "inventory"), so when I mouse over an item within the movieclip it will change the status window on the stage.
In this instance I want to mouse over inventory.invHealth from the main timeline to get the display.
itemName and itemProps are strings containing information about the item.
I tried the following but it gave me a "possibly undefined" error.
invHealth.addEventListener(MouseEvent.MOUSE_OVER, itemStats);
function itemStats(e:Event):void
{
root.statusWindow.text = itemName+"\n"+itemProps;
}
I'm not very adept in AS3 just yet, so if you could also explain your code when you post it -though most people usually do anyway- I would very much appreciate it. Thanks in advance!
I would advice you to store the information data in a class object; that object should be accessible by both the statusWindow and the inventory clip. This way there's no need to "read" a textbox, you will have different views on the same data. For example:
public class GlobalVars
{
public static var health:Number;
}
You could of course create a more structured information data, like:
public class Item
{
public function Item(setname:String)
{
name=setname;
health = 100;
quantity = 0;
}
private var name:String;
private var health:Number;
private var quantity:Number;
}
var inventory:Array = new Array();
inventory.push(new Item("hammer"));
inventory.push(new Item("gun"));
inventory.push(new Item("sponge"));