Archive for March, 2009

Common Flash Compiler Errors: #1046

Wednesday, March 25th, 2009

This error shows the following in the Compiler Errors window:


1046: Type was not found or was not a compile-time constant: [Class name].

Quick Answer and Solution

Where I have “[Class name]” above you will have any number of names listed, for example it may say Event, Sprite, TextField, etc. What this means is you are using a piece of code that utilizes a class (typically seen as files with a “.as” extension) that you have not “imported” so that your code knows where to find it. To fix this problem perform the following:

  1. Open a web browser and navigate to Google.
  2. Enter the search “[class name] actionscript 3 site:livedocs.adobe.com” (replacing [class name] with whatever the class name is in the error message, such as TextField, MouseEvent, URLLoader, etc.). For example, “Event actionscript 3 site:livedocs.adobe.com”
  3. Look for a search result that lists the class in a format of a series of words with dots between them, probably will be the top result. Examples include:
    • flash.events.Event
    • flash.display.Sprite
    • fl.transitions.Tween
    • flash.geom.Rectangle

    This is the path to the class, which you can use to import the class into your code.

  4. Without clicking on the search result, copy the class name as it appears in the previous step.
  5. Return to Flash and double-click the error message.
  6. Scroll to the top of the code area. Type “import” and paste the path to the class. For example,
    import flash.events.Event;

If you are using code on the Timeline, this can be placed at the top of the Actions panel. If you have written a class file that is referencing another class, this code appears between the package { curly brace, and class declaration, public class MyClass.

For example,

package
{
	// class import statements appear here
	import flash.display.MovieClip;
 
	public class Main extends MovieClip
	{
		public function Main()
		{
		}
	}
}

Technical Overview

A class file is an external text file that contains variables and functions (known as properties and methods in the object-oriented programming context), essentially this means class files are self-contained blocks of code that contain code related to a particular task. To access these variables and functions within your own block of code the class file needs to be imported. If your code contains any references to a class file that has either: (a) not been imported, or (b) is not within the same folder as your .fla or .as files, then a #1046 error will be thrown. For example, suppose you have the following class file declared for a button:

package
{
	import flash.display.MovieClip;
 
	public class MyButton extends MovieClip
	{
		public function MyButton()
		{
			this.addEventListener( MouseEvent.CLICK , _clicked );
		}
 
		private function _clicked( evt:MouseEvent ) : void
		{
			// button was clicked!
		}
	}
}

Testing this code would produce the following error:

1046: Type was not found or was not a compile-time constant: MouseEvent.

With the source listed as…

private function _clicked( evt:MouseEvent ) : void

This is because the class MouseEvent is referenced in the code, but is not imported at the top of the class file. The fix is simple and looks like this:

package
{
	import flash.display.MovieClip;
	// import the MouseEvent class
	import flash.events.MouseEvent;
 
	public class MyButton extends MovieClip
	{
		public function MyButton()
		{
			this.addEventListener( MouseEvent.CLICK , _clicked );
		}
 
		private function _clicked( evt:MouseEvent ) : void
		{
			// button was clicked!
		}
	}
}

Typically if you are a beginning ActionScripter, you will run into this error when referencing classes created by Adobe. However, as you become more advanced in your scripting abilities you may place your own custom class files in “packages” that would then need to be imported using the same above process. In case you are wondering what the stuff is before the actual class name, such as “flash.display” and “flash.events,” this is the “package” that class resides in, which is essentially the folders the class file resides in on disk. For example, suppose I created a class called “MyButton” and placed it in the package “com.anselmbradford.” This class would appear in a text file called “MyButton.as” that would be in a folder called “anselmbradford” that would itself be in a folder called “com.” The class file would look like:

package com.anselmbradford
{
	import flash.display.MovieClip;
 
	public class MyButton extends MovieClip
	{
		public function MyButton()
		{
		}
	}
}

To import this class file into another class file I would place the “com” folder (containing the class file two levels in) in the same directory as my .fla or .as file that I wanted to import this class into. I would then import it using the syntax shown previously. For example:

package
{
	import flash.display.MovieClip;
	// class is imported
	import com.anselmbradford.MyButton;
 
	public class Main extends MovieClip
	{
		public function Main()
		{
			// class is referenced in code, so must be imported
			var button:MyButton = new MyButton();
		}
	}
}

Note: Whole sets of class files that are within the same package can be imported using the “*” wildcard operator. For example, flash.events.Event, and flash.events.MouseEvent, both reside in the flash.events package. Instead of having two lines to import both of these classes, you can have import flash.events.*;, which will import all the necessary classes from the flash.events package.

UPDATE October 4, 2009:This error will also occur if you have a symbol on your stage that has an instance name that is the same as a class name associated with the symbol. Check the Library panel, under the Linkages column, does any of your symbols have a name next to “Export:” that is the same as the instance name in the Properties panel of one of those symbols on the stage?

type_error

The ever-evolving interactive web space: Microsoft’s Silverlight initiative, Google’s love of JavaScript, Adobe’s comfortably massive Flash Platform

Thursday, March 19th, 2009

Microsoft’s Web design and development conference, MIX09, is currently happening in Las Vegas, Nevada. As is tradition with major corporate-backed events such as this one, a slew of new products were released. Of note is the Silverlight 3 beta (available here, but it sounds like it is very much a preview). The new features are extensive and—for many of them—sound very Flash-esque (Ryan Christensen’s site provides a nice write up of the new features). Along with Silverlight, Internet Explorer 8 was released out of beta, and thankfully sounds to be the most standards-compliant Internet Explorer version to date. It is foreseeable that if Microsoft were able to bundle the Silverlight plugin with a standard’s compliant browser that gained broad support from developers—without raising the eyebrows of antitrust regulators—that Flash would be presented with its greatest obstacle in maintaining its present dominance in the interactive website space.

In the mean time, while Adobe and Microsoft develop increasingly similar looking products, Google and open source initiatives such as JQuery UI are moving JavaScript beyond a mere scripting language. Google has launched a site called Chrome Experiments, which showcases contemporary interactive pieces built entirely in JavaScript. Many are quite impressive, for example, this piece could easily be a Flash piece (turn your speakers on). I noticed Flash master Mr. Doob has a piece up there too. The about page begins “We think JavaScript is awesome.” I’ve been playing with JQuery UI recently and I do have to admit it has come a long way from what JavaScript was capable of when I really seriously last played with it in the late 90’s.

At any rate it’s exciting to see the explosion of possibilities all these projects will bring. More than ever the Web feels like the digital frontier.

Common Flash Compiler Errors: #1042

Thursday, March 19th, 2009

This error shows the following in the Compiler Errors window:


1042: The this keyword can not be used in static methods. It can only be used in instance methods, function closures, and global code.

Quick Answer and Solution

Most likely you are you using the keyword “this” inside a class file, but it is not inside the curly braces of a function. By double-clicking on the error it will take you to the offending line of code. Check carefully to make sure where you have placed the keyword “this” is actually between the opening “{” and closing “}” braces of a function declaration. If it looks correct, but is accompanied by error #1126 (described here), then fix that error first. Also, if the “this” keyword appears in a function that has the “static” keyword in its declaration, error #1042 will also be thrown.

The following are three scenarios where a class file will throw this error:

package
{
	import flash.display.MovieClip;
 
	public class Main extends MovieClip
	{
		public function Main()
		{
		}
		// "this" keyword used outside a function
		this.visible = false;
	}
}
package
{
	import flash.display.MovieClip;
 
	public class Main extends MovieClip
	{
		public function Main()
		{
		}
 
		// function does not have a body because of misplaced semicolon,
		// so error #1126 is thrown
		public function hide():void;
		{
			// the "this" keyword is actually not in the body of a function
			// because of the above #1126 error
			this.visible = false;
		}
	}
}
package
{
	import flash.display.MovieClip;
 
	public class Main extends MovieClip
	{
		public function Main()
		{
		}
 
		// function is a "static method," meaning it runs inside the class,
		// not the object created from the class
		static public function hide():void
		{
			// the "this" keyword is inside a static method
			this.visible = false;
		}
	}
}

The corrected form of the above examples would be:

package
{
	import flash.display.MovieClip;
 
	public class Main extends MovieClip
	{
		public function Main()
		{
		}
 
		public function hide():void
		{
			// the reference to "this" is inside a non-static function
			// (called an instance method)
			this.visible = false;
		}
	}
}

Technical Overview

There are two types of methods (functions) that can appear in a class file, static methods and instance methods. Static methods refer to methods that are run via the class itself, while instance methods refer to methods run via an instance of the class. Consider the following class file:

package
{
	import flash.display.MovieClip;
 
	public class Main extends MovieClip
	{
		public function Main()
		{
		}
 
		static public function staticMethod():void
		{
			trace( "static method called!" );
		}
 
		public function instanceMethod():void
		{
			trace( "instance method called!" );
		}
	}
}

To call the first method, a new “Main” object does not need to be created, as the static method can be called on the class itself, like so:

Main.staticMethod();

Conversely, to access the other method, an (object) instance of the Main class needs to be created and then the method can be called through that object, like so:

var main:Main = new Main();
main.instanceMethod();

Use of the “this” keyword refers to the object instance of the class that the code is currently dealing with (in the above case if this appeared in the body of the instanceMethod() method it would be referring to the object placed in the main variable). Since no object instance has to be created to use static methods, the “this” keyword can not be used within those methods because there is no object in existence to refer to. Additionally, all code outside of a function declaration runs before an object instance is created (before the constructor function runs), so any references to “this” do not have an object to refer to in that context either.

2 invaluable Drupal development tips: list all available variables and backtrace a page

Saturday, March 14th, 2009

The Drupal Devel module includes some invaluable functions that make working with Drupal much much easier. A short list of these functions can be found at this post. One of these is the dpm() command (which I would guess stands for “Drupal Print Message,” or at least that’s how I remember it). Given an array or object, this function will output a div structure at the top of your page that you can use to visually walk through the contents of either of these sets of data. Combine this with existing PHP debugging and instrospection commands and you have a very useful and powerful development tool at your disposal. For example, place this at the top of your Drupal theme’s page.tpl.php template:

<?php
	 dpm( get_defined_vars() );
?>

Now when you navigate to your page you will have a clickable bar at the top that will list all variables available to the page when it loads, which you can access via the code in your theme page template if you want.

dpm_get_defined_vars

Or maybe you would like to know what path your page took through Drupal’s architecture to its final incarnation, use dpm() with PHP’s debug_backtrace() function. This will output an array of each function your page contents went through before they were output to the browser, plus it shows the location of these functions. Try this in place of the code snippet above:

<?php
	 dpm( debug_backtrace() );
?>

dpm_debug_backtrace

Common Flash Compiler Errors: #1126

Friday, March 13th, 2009

This error shows the following in the Compiler Errors window:


1126: Function does not have a body.

Quick Answer and Solution

By double-clicking on the error it will take you to the offending line of code. This error commonly happens when the end of line designator “;” is placed at the end of a function name declaration, as in:

1
2
3
4
function init() : void;
{
	/*function body*/
}

Notice the presence of the semicolon at the end of line 1. To fix the error the semicolon is removed:

1
2
3
4
function init() : void
{
	/*function body*/
}

Technical Overview

A function is a block of code that will only run when it is “called,” meaning the above example would be run by writing the function name elsewhere, like so: init();. When a particular function is called, the code that appears between the curly braces (“{}”) is run. This is referred to as the function “body.” When you test a movie in Flash the code is read line by line by the compiler and eventually turned into a SWF. However, what you see as a single line of code and what the compiler sees as a single line of code are two different things. The compiler ignores extra white space and carriage returns. For example, to the compiler the following function declaration:

function init() : void
{
	/*function body*/
}

…is the same as:

function init():void{/*function body*/}

Because of this, it depends on the semicolon and closing curly brace (“}”) to denote that a line of code has ended. The closing curly brace is used for every piece of code that creates a block of code (functions, for example), while the semicolon is used for everything else. If a semicolon were to appear before the opening curly brace (“{“) in the above line of code, the compiler would hit the semicolon and throw an error that the function did not have a “body” because it had reached the end of the line of code without encountering an opening and closing curly brace.

Note: The one exception to this rule is the constructor function found in class files, which can oddly enough contain a semicolon after the function name declaration and the compiler will not complain, for example the following will not throw an error:

package
{
	import flash.display.MovieClip;
 
	public class Main extends MovieClip
	{
		public function Main();
		{
			/*constructor function body*/
		}
	}
}

However, while the compiler will not complain, the constructor function actually ends at the semicolon, so what’s written between the curly braces (the “constructor function body”) will not be run when a new object of this class is instantiated (well, actually it will run, but it will be in the scope of the class, not the object, so it will run prior to the creation of the object). Constructor functions are different in one other aspect as well, they do not specify a return type (no “:void” after the parentheses, for example).