Flash AS3 class - actionscript-3

So I'm new to Flash and I'm currently following a tutorial about login and registration.
The tutorial that I followed has an external AS file just like this :
where I type the name of the class in the space given. So far, when I run the program, it gives me the correct output.
Now here comes my problem. I've made some modifications to the way it references(?) the class, which in this case, I export the class just like this in the symbols properties. And now, the code won't work and I've been trying to figure this out for about 5 hours already and I can't seem to get it done.
Here's the image of me adding the class in the symbols properties :
And here is my login class :
package {
/*
always extend a class using movieclip instead of sprite when using flash.
*/
import flash.display.MovieClip;
import flash.events.*;
import flash.net.*;
import flash.text.*;
/*
create our class
*/
public class login extends MovieClip {
public function login(): void {
/*
buttonMode gives the submit button a rollover
*/
login_button.buttonMode = true;
/*
what this says is that when our button is pressed, the checkLogin function will run
*/
login_button.addEventListener(MouseEvent.MOUSE_DOWN, checkLogin);
/*
set the initial textfield values
*/
username.text = "";
password.text = "";
}
public function checkLogin(e: MouseEvent): void {
/*
check fields before sending request to php
*/
if (username.text == "" || password.text == "") {
/*
if username or password fields are empty set error messages
*/
if (username.text == "") {
username.text = "Enter your username";
trace(success);
}
if (password.text == "") {
password.text = "Enter your password";
}
} else {
/*
init function to process login
*/
processLogin();
}
}
public function processLogin(): void {
/*
variables that we send to the php file
*/
var phpVars: URLVariables = new URLVariables();
/*
we create a URLRequest variable. This gets the php file path.
*/
var phpFileRequest: URLRequest = new URLRequest("php/controlpanel.php");
/*
this allows us to use the post function in php
*/
phpFileRequest.method = URLRequestMethod.POST;
/*
attach the php variables to the URLRequest
*/
phpFileRequest.data = phpVars;
/*
create a new loader to load and send our urlrequest
*/
var phpLoader: URLLoader = new URLLoader();
phpLoader.dataFormat = URLLoaderDataFormat.VARIABLES;
phpLoader.addEventListener(Event.COMPLETE, showResult);
/*
now lets create the variables to send to the php file
*/
phpVars.systemCall = "checkLogin";
phpVars.username = username.text;
phpVars.password = password.text;
/*
this will start the communication between flash and php
*/
phpLoader.load(phpFileRequest);
}
public function showResult(event: Event): void {
/*
this autosizes the text field
***** You will need to import flash's text classes. You can do this by adding:
import flash.text.*;
...to your list of import statements
*/
result_text.autoSize = TextFieldAutoSize.LEFT;
/*
this gets the output and displays it in the result text field
*/
result_text.text = "" + event.target.data.systemResult;
trace(success);
}
}
}
Edit :
Here is the picture where the base class just disappears :
Thanks for the help.

Related

AS3 Dynamically change image of object

How does one change image of already created object
Let's say I have an empty class named Icon and on runtime I want to change its image to something and add it on stage. The image can be from the library as another object or just a bitmap.
var icon1 = new Icon(myIcon);
...
public class Icon extends MovieClip {
public function Icon(icon:Class) {
//change image
addChild(this);
}
EDIT: in java I used to do it like this:
new Icon(myIcon);
...
public class Icon {
public Image image;
public String icon;
public Icon(String icon) {
ImageIcon ii = new ImageIcon(this.getClass().getResource(icon + ".png"));
image = ii.getImage();
this.icon = icon;
}
and on paint method I just type icon1.image to show on screen and also can change image if needed by accessing this variable.
Is this possible to do it something like this on as3?
Let's say I have an empty class named Icon and on runtime I want to
change its image to something
Before code make sure you prepared by following these example steps...
1) Open the Library (ctrl+L) and right click to choose "create new symbol" of MovieClip type and give it the name Icon then look at the Advanced tab further below...
2) Tick the box called "Export For ActionScript" and that should auto-fill a box called Class with text saying Icon. Click OK and you are ready.
3) Add one or two images to Library and right-click to choose "properties" and again like step (2) in the linkage section you tick the "Export for AS" option and give a name you prefer to type later via code. We'll assume you chose names like Pic1 and Pic2. Notice as well that the "base Class" for these bitmaps is bitmapData? That's the data you change to update your image by code.
So to update dynamically by code... Create a bitmap and update its pixel data with any bitmapData from Library. Something like:
//# in your imports...
import flash.display.MovieClip;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.utils.getQualifiedClassName;
import flash.utils.*;
....
//# in vars declarations...
public var my_icon : Icon = new Icon ();
public var my_BMP : Bitmap;
public var str_Type : String = ""; //later holds library object type for checks
....
//# later in your code
stage.addChild(my_icon); //looks invisible since empty
my_BMP = new Bitmap; //create new instance
my_icon.addChild ( my_BMP ); //add the empty bitmap into Icon
change_Icon ( Pic1 ); //parameter can be Library's Bitmap or Movieclip
Making the change_Icon function...
If you just kept it bitmaps (PNG files?) you could use a simple function like this...
public function change_Icon ( in_Param : Class ) : void
{
my_BMP.bitmapData = new in_Param as BitmapData; //replace pixels of existing bitmap container
}
But since you say it could be anything, sometimes a Bitmap or sometimes a MovieClip, well in that case you have to check the input and handle accordingly.
public function change_Icon ( in_Param : * ) : void
{
//# Check the input type and handle it
str_Type = String ( getDefinitionByName( String( getQualifiedSuperclassName(in_Param) ) ) );
if ( str_Type == "[class BitmapData]" )
{
trace ( "this object is a Bitmap..." );
my_BMP.bitmapData = new in_Param as BitmapData; //replace pixels of existing bitmap container
}
if ( str_Type == "[class MovieClip]" )
{
trace ( "this object is a Movieclip..." );
var temp_MC = new in_Param();
var temp_BMD : BitmapData = new BitmapData( temp_MC.width, temp_MC.height );
my_BMP.bitmapData = temp_BMD; //assign data to this bitmap
temp_BMD.draw (temp_MC); //update by drawing
}
}
After adding your icons (image files) to your library, converting them to MovieClips and setting their AS linkage like this, for example :
You can use, for example, a Sprite object to load your icon inside your Icon class instance where your Icon class can be like this, for example :
package {
import flash.display.Sprite;
public class Icon extends Sprite
{
private var _icon:Sprite;
public function Icon(IconClass:Class): void
{
_icon = new IconClass();
addChild(_icon);
}
public function changeIcon(IconClass:Class): void
{
removeChild(_icon);
_icon = new IconClass();
addChild(_icon);
}
}
}
Then in your main code, you can use that class :
import Icon;
var icon:Icon = new Icon(PHPIcon);
addChild(icon);
then to change the icon, you've just to call the changeIcon() function :
icon.changeIcon(JSIcon).
Edit :
If you don't want to call addChild() to add your Icon class's instance to it's parent container, the constructor of your Icon class can be like this for example :
public function Icon(container:DisplayObjectContainer, IconClass:Class): void
{
container.addChild(this);
_icon = new IconClass();
addChild(_icon);
}
then for its instance
var icon:Icon = new Icon(this, PHPIcon);
Hope that can help.
Thanks finally now I have a base class to work with on future projects, I also use list so all I have to do is call new Icon(myIcon, x, y, this);
package {
import flash.display.Sprite;
import flash.display.DisplayObjectContainer;
public class Icon extends Sprite {
public static var list:Array = new Array();
private var icon:Sprite;
private var n:int;
public function Icon(IconClass:Class, x:int, y:int, container:DisplayObjectContainer):void {
container.addChild(this);
icon = new IconClass();
n = list.push(this);
addChild(icon);
this.x = x; this.y = y;
}
public function changeIcon(IconClass:Class):void {
removeChild(icon);
icon = new IconClass();
addChild(icon);
}
public function removeIcon():void {
this.parent.removeChild(this);
list.splice(n-1,1);
}
}
}

AS3 UrlLoader does not fire Event.COMPLETE

Everything work, except the Event.Complete... (that means that I retrieve the good content at the server side, and the progress event work as expected)
I have a simple code that process an upload. I use this class : https://github.com/Nek-/Multipart.as/blob/master/src/com/jonas/net/Multipart.as
And my code:
package com.foo.http
{
import com.jonas.net.Multipart;
import flash.net.*;
import flash.events.*;
import flash.utils.ByteArray;
import flash.external.ExternalInterface;
public class RequestManager
{
private var request:Multipart;
private var loader:URLLoader;
/**
* The url can be http://foobar:952/helloworld
* #param url
*/
public function RequestManager(url:String)
{
this.loader = new URLLoader();
this.request = new Multipart(url);
// This is needed, if we don't set it, the complete event will never be trigger
// We retrieve some text
this.loader.dataFormat = URLLoaderDataFormat.TEXT;
// Events
this.attachEvents();
}
public function getRequest():Multipart
{
return this.request;
}
public function send():void
{
this.loader.load(this.request.request);
}
private function attachEvents():void
{
this.loader.addEventListener(Event.COMPLETE, this.requestCompleted);
this.loader.addEventListener(ProgressEvent.PROGRESS, this.requestProgress);
this.loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, this.securityError);
this.loader.addEventListener(IOErrorEvent.IO_ERROR, this.networkError);
}
// Of course there is also listener methods (with a trace inside and call to JS, nothing more)
}
}
Any idea what it comes from ?
It looks like my problem was not from actionscript or flash itself but from my javascript and the flash debugger on firefox.

Unable to have Flash Component (SWC) access the library in live preview

I am building a set of Flash components with the ability to replace the skin of the component with another one in the library.
Currently, I am able to access the library after running the application, but not during live preview and I'd like to know if it is possible for the component to access the library while running in live preview mode (the mode where you can drag the component around the stage and change its properties in the Component Parameters window)
Here is a simplified code that just looks to see if there is a symbol of the name specified and than instantiates it and adds it as a child.
package
{
import fl.core.UIComponent;
import flash.display.MovieClip;
import flash.system.ApplicationDomain;
/**
* ...
* #author Roy Lazarovich
*/
public class CompTest extends UIComponent
{
private var customfile :String;
public function CompTest()
{
}
override protected function configUI():void
{
}
override protected function draw():void
{
super.draw();
}
private function setCustomFile():void
{
if (ApplicationDomain.currentDomain.hasDefinition(customfile))
{
var c:Class = Class(ApplicationDomain.currentDomain.getDefinition(customfile));
var mc:MovieClip = new c();
addChild(mc);
}
}
[Inspectable(name = "_Custom File", defaultValue = "")]
public function set _customfile(value:String):void
{
customfile = value;
setCustomFile();
drawNow();
}
}
}
Thanks!
I'm not entirely sure what you have already tried to fix this situation. But hopefully this might help.
Right click on the MovieClip in your library, select Linkage and give it a class name, ie. MyThing.
In your code,
newMyThing = new MyThing();
this.addChild(newMyThing);
trace("tada!");
Hope that helps or gets you closer to a solution.
This works for me in LivePreview, as long as I apply it in configUI, and not draw:
public class EditableBitmap extends UIComponent
{
protected var placeholder:String = "None";
protected var bitmap:Bitmap;
protected var scale:Number = 1;
[Inspectable(name = "Placeholder", type = String, defaultValue="None")]
public function set Placeholder($value:String):void
{
placeholder = $value;
configUI();
}
public function get Placeholder():String { return placeholder; }
public function EditableBitmap()
{
//Console.Debug("NEW EditableBitmap");
super();
}
override protected function configUI():void
{
//Console.Debug("EditableBitmap configUI: " + width);
if (!isNaN(width))
{
wDim = width;
hDim = height;
graphics.clear();
graphics.beginFill(0x000000, 0.1);
graphics.drawRect(0, 0, wDim, hDim);
}
if (placeholder != "None" && placeholder != "")
{
var asset:Class = getDefinitionByName(placeholder) as Class;
var data:BitmapData = new asset() as BitmapData;
bitmap = new Bitmap(data);
}
super.configUI();
}
override protected function draw():void
{
if (bitmap)
{
addChild(bitmap);
bitmap.x = off_x * scale;
bitmap.y = off_y * scale;
bitmap.scaleX = bitmap.scaleY = scale;
}
}
}
NOTE: When I'm working on the FLA where I am editing the component, the bitmap is only displayed from the library inconsistenty. Sometimes it works, sometimes it doesn't. But when I export the SWC and then import the component to another movie, it works every time, in LivePreview as well as at runtime.
UPDATE
It seems this doesn't work in CS6 unless the symbol is already embedded in the component .SWC I wanted to see if I could trick it, by embedding one image in the SWC and then replacing it with another of the same name in the destination file. This didn't work, but it did point me to how you can do this:
So, it's a bit laborious, but you could work around this by:
1) Creating a dummy asset for each property in the component SWC.
2) Overriding this using a custom class in the file where you deploy the component
... all of which may be more trouble than it's worth, but which should provide a solution to the problem.

How to keep the ColorPicker swatch open all the time with Flash AS3?

I want the ColorPicker popup swatch to always stay open.
var cp:ColorPicker = new ColorPicker();
cp.open();
works fine but when focus is lost the window closes.
Any suggestions?
Thanks
The flash default color picker
Depends on which ColorPicker you are using. ( i mean who wrote it ).
But this one works as you need: http://www.bit-101.com/blog/?p=2347
Update
Then you need to create you own ColorPicker class which will extend the original ColorPicker:
package
{
import fl.controls.ColorPicker;
import flash.events.MouseEvent;
/**
* ...
* #author Jevgenij Dmitrijev ( http://www.ifmi.lt )
*
* #created {2012.05.10 16:08}
*
*/
public class CustomColorPicker extends ColorPicker
{
var _allowHide:Boolean = false;
public function CustomColorPicker()
{
}
override protected function onStageClick(event:MouseEvent):void
{
//Simple example .
if(_allowHide)
super.onStageClick(event);
}
override protected function onSwatchClick(event:MouseEvent):void
{
// since on click it is closing, ovveride the function
// and super the over function, since it is the one
// which changes the color.
super.onSwatchOver(event)
}
override protected function onSwatchOver(event:MouseEvent):void
{
// just ovveride it, so it would do nothing.
}
}
}
And then in you project use:
var colorPickerMC:CustomColorPicker = new CustomColorPicker ();
addChild(colorPickerMC);

How do I make my public static logging method write to an inputfield?

I figured out how to create a static method that is available everywhere, for example:
UtilLib.as:
package
{
public final class UtilLib
{
public static function getTimeStamp():uint
{
var now:Date = new Date();
return now.getTime();
}
}
}
I can access this everywhere by doing UtilLib.getTimeStamp() - Now, I want to create a new staic method called log(msg:String). This should log a message to a multi-line inputfield.
The problem however is that this inputfield must be created somewhere and must be accessible and visible all the time, and I don't want to pass it through the function parameters all the time as this would cause a lot of trouble (I'd have to pass it through objects aswell..).
So, how do I make a "public textfield" so my static log method can write to it?
UPDATE:
I now tried the following class, with a static constructor (I think). However, the textfield object is not showing. When I do an addChild(debugField) after creating it, it gives me error 1180.
Logger.as
package
{
import flash.display.Sprite;
import flash.text.TextField;
import flash.text.TextFieldType;
public class Logger extends Sprite
{
public static var debugField:TextField;
/* static block */
{
trace("Logger initializing.");
debugField = new TextField();
debugField.width = 500;
debugField.height = 100;
debugField.x = 100;
debugField.y = 400;
debugField.background = true;
debugField.backgroundColor = 0xFFFFFF;
debugField.defaultTextFormat = new CustomTextFormat();
debugField.mouseWheelEnabled = true;
debugField.multiline = true;
debugField.type = TextFieldType.DYNAMIC;
}
public static function log(msg:String):void
{
if (debugField) debugField.appendText(msg);
}
}
}
I initialize it like this:
var test:Logger = new Logger();
addChild(test);
And I log a new message like this:
Logger.log("test");
Unfortunately, the textField is not showing.
Essentially you need:
somewhere to log a message which is globally accessible
the ability to update a text field whenever the log message changes
A simple solution using objects could look like this:
Example
package {
import flash.display.Sprite;
import flash.text.TextField;
import flash.events.Event;
public class Example extends Sprite {
private var messageLog:TextField;
public function Example() {
createTextField();
MessageLogger.getInstance().addEventListener( MessageLogger.LOG, handleMessageLoggerUpdate );
MessageLogger.getInstance().log( "Message!" );
}
private function handleMessageLoggerUpdate( event:Event ):void {
messageLog.text = MessageLogger.getInstance().getLog();
}
private function createTextField():void {
messageLog = new TextField();
addChild( messageLog );
}
}
}
MessageLogger
package {
import flash.events.EventDispatcher;
import flash.events.Event;
public class MessageLogger extends EventDispatcher {
private static var instance:MessageLogger;
public static function getInstance():MessageLogger {
if ( !instance ) {
instance = new MessageLogger( new InstanceKey() );
}
return instance;
}
public static var LOG:String = "MessageLoader#log";
private var messageLog:String;
public function MessageLogger(key:InstanceKey) {
messageLog = "";
}
public function log( message:String ):void {
messageLog += message;
notify();
}
public function getLog():String {
return messageLog;
}
private function notify():void {
dispatchEvent( new Event( LOG ) );
}
}
}
class InstanceKey {}
The important thing here is that a message can be logged from anywhere using
MessageLogger.getInstance().log( "Your Message Here" );
and anything can be notified of when a message has been logged using
MessageLogger.getInstance().addEventListener( MessageLogger.LOG, listenerFunction );
at any point the current message log can be obtained using
MessageLogger.getInstance().getLog();
Create a new Logging class and have that class have a static constructor. Add your logging method to this class. Make the static constructor save the logging field to a private variable. Now before you call the logging method just call your static constructor with the input field you'd like to use. This will create the class, set up the input field as the destination, and now you can simply just call the log function from anywhere.
Traditionally, the way you let static methods interact with private variables is to pass them in. Pass in a pointer to your textbox.
so instead of
public static function getTimeStamp():uint { ... }
you have
public static function writeTimeStamp(messageBox):uint { ... }
The syntax might be incorrect as I'm not an AS dev but, do you see what I mean? From there, that block of code can access messageBox as if it were a local variable. Well it is.
(I renamed the method name for clarity. You could even stop it returning a variable if it doesn't need to but you'll need to change the declaration further.)
In your updated post the debug text field needs to be added to the display list somewhere. Right now it looks like it is just created and used during that log method. You add display objects to the display list by calling addChild( displayObject:DisplayObject ):Boolean; on a DisplayObjectContainer that is already a child of stage.