MovieClip vs Sprite in Actionscript 3.0 - actionscript-3

What more can be done if I extend MainClass with MovieClip rather than Sprite. I know that MovieClip extends Sprite and it has Timeline defined under it. but still how it will be usable to me by MovieClip ?
package {
import flash.display.Sprite;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.display.MovieClip;
import flash.text.TextFieldType;
public class MainClass extends Sprite{
public function MainClass() {
var m:Module=new Module("Admin","John");
var tf:TextField=new TextField();
tf.text=m.info;
tf.border=true;
tf.type=TextFieldType.INPUT;
var myFormat:TextFormat = new TextFormat();
myFormat.size = 3;
tf.defaultTextFormat=myFormat;
addChild(tf);
this.width=500;
this.height=300;
this.x=0;
this.y=10;
}
}
}
class Module{
private var m_mName:String;
private var m_owner:String;
public function Module(mName:String,owner:String):void{
m_mName=mName;
m_owner=owner;
}
public function get info():String{
return owner+' is owner of '+mName;
}
public function get mName():String{
return m_mName;
}
public function get owner():String{
return m_owner;
}
}
Another little question, How to use Timeline if I replace Sprite by MovieClip ?

Quoting from an AS3 book:
Prior to ActionScript 3.0, the MovieClip class was used as an all-purpose graphics container (much like ActionScript 3.0s Sprite class is used). As of ActionScript 3.0, MovieClip is used only to control instances of movieclip symbols created in the Flash authoring tool. Because ActionScript 3.0 does not provide a way to create timeline elements such as frames and tweens, there is no need to create new empty movieclips at runtime in ActionScript 3.0. Instead, all programmatically created graphics should be instances of the appropriate core display class (Bitmap, Shape, Sprite, TextField, etc).
MovieClip is a dynamic class that retains backwards compatibility with AS2. That means that if, while not recommended, require you add a property to a MovieClip, you can simply say myMC.myCustomProperty = "someValue", whereas with a Sprite, that will throw an error.
For this reason, they also say that using Sprites is more effective in terms of performance. You can find a discussion about this in this Adobe Forum post.

Related

AS3 - What is the best, or recommended way of wrapping Bitmaps into Sprite containers?

I'm learning AS3 using FlashDevelop IDE and Flex to compile.
I add images by creating a Bitmap class and then embedding a .png in the code, example:
Enemy.as
package enemies
{
import flash.display.Bitmap;
import flash.events.MouseEvent
[Embed(source="../../assets/gardengnome.png")]
public class Enemy extends Bitmap
{
public function Enemy()
{
trace("enemy constructed");
}
}
}
I have learned that in order to be able to handle MouseEvent I need to put this Bitmap into a Sprite container.
Now, not knowing any better this is the way I have done it:
I create a new variable to hold enemyContainer in Main.as and add it to the stage:
package
{
import enemies.Enemy;
import enemies.EnemyContainer;
import flash.display.Sprite;
import Player.Player;
public class Main extends Sprite
{
public var enemyContainer:EnemyContainer = new EnemyContainer();
public function Main():void
{
addChild(enemyContainer);
}
}
}
And then the EnemyContainer class calls the Enemy Bitmap that holds the graphic and adds it to itself as a child:
package enemies
{
import flash.display.Sprite;
import flash.events.MouseEvent
public class EnemyContainer extends Sprite
{
private var enemy:Enemy = new Enemy();
public function EnemyContainer()
{
trace("enemyContainer constructed");
addChild(enemy);
addEventListener(MouseEvent.CLICK, handleClick);
}
private function handleClick(e:MouseEvent):void
{
trace("Clicked Enemy");
}
}
}
I don't have enough experience yet to see any problems doing it this way. I can change the graphic in the Enemy Bitmap class without having to deal with anything else, and Main.as handles positioning of the EnemyContainer.
However, if there is a recommended, or more efficient way to handle this I'd like to learn it now before I get into a habit. Is there a better way to do this?
Thanks for any advice!
In your example it looks like you are creating 3 classes to implement the bitmap inside a sprite:
Enemy extends Bitmap
EnemyContainer extends Sprite
Main extends Sprite
Your method is totally valid, and you will not have a problem with it. In fact, there is no one best way to do this. What is best depends on the context. However, you may find it more easy to manage if you implement Enemy as part of EnemyContainer so that you have only two classes:
Main
EnemyContainer
In EmemyContainer you make a private class for the enemy bitmap like so:
package enemies
{
import flash.display.Sprite;
import flash.events.MouseEvent
public class EnemyContainer extends Sprite
{
[Embed(source="../../assets/gardengnome.png")]
private EnemyBitmap:Class;
public function EnemyContainer()
{
trace("enemyContainer constructed");
addChild(new EnemyBitmap()); // Creates a new instance of your bitmap class.
addEventListener(MouseEvent.CLICK, handleClick);
}
private function handleClick(e:MouseEvent):void
{
trace("Clicked Enemy");
}
}
}
You may additionally find it helpful to use the mouseChildren and buttonMode property of the Sprite, but that will depend on how you want the mouse interaction to work.
== In reply To Comments ==
To position the bitmap on registration center:
var temp:Bitmap = new EnemyBitmap() as Bitmap;
temp.x = -temp.width/2;
temp.y = -temp.height/2;
addChild(temp);
What you are doing is OK
If you want less classes you could also embed the bitmap in your container class
public class Enemy extends Sprite
{
[Embed(source="../../assets/gardengnome.png")]
private var assetClass:Class;
private var asset:Bitmap;
public function Enemy()
{
//init the class
//do this in a seperate method, because the constructor is executed by a just in time compiler. Means less code better performance.
init();
}
private function init():void
{
asset = new assetClass();
addChild(asset);
}
}
A noble effort, but try this instead as a best practice:
public class Enemy extends Sprite
{
public function Enemy()
{
var bmp = new EnemyBitmap(); // what is currently your Enemy class should be EnemyBitmap
addChild(bmp);
}
}
This technique is called "implementation" where the desired class (Bitmap) is loaded into a container instead of the container extending the Bitmap class itself ("inheritance").

AS3 - Can Bitmap classes dispatch mouse events?

I'm trying to learn AS3 and have run into a small problem.
I have a Bitmap class to which I add a MouseEvent.CLICK listener, but the event doesn't seem to be dispatched.
I use Flashdevelop to write AS3 code and Flex to compile.
I have two classes, Enemy.as and Player.as
The Player.as looks like this:
package Player
{
import flash.display.Sprite;
import flash.events.MouseEvent;
[Embed(source="../../assets/leek.swf", symbol="Leek")]
public class Player extends Sprite
{
public function Player()
{
trace("Player constructed");
addEventListener(MouseEvent.CLICK, handleClick);
}
private function handleClick(e:MouseEvent):void
{
trace("Clicked Player");
}
}
}
The Enemy.as looks like this:
package enemies
{
import flash.display.Bitmap;
import flash.events.MouseEvent
[Embed(source="../../assets/gardengnome.png")]
public class Enemy extends Bitmap
{
public function Enemy()
{
trace("enemy constructed");
addEventListener(MouseEvent.CLICK, handleClick);
}
private function handleClick(e:MouseEvent):void
{
trace("Clicked Enemy");
}
}
}
The two classes are pretty much identical except that one is a Sprite and I embedded a symbol from a swf file that I got from a tutorial, and the other is a Bitmap and I embedd a png file into that.
The Player class (the one that's a sprite and uses a symbol) fires off the MouseEvent.CLICK when I run the project and click on the Player image, but the Enemy class does not.
There are no compile warnings or errors, so I'm having a hard time understanding what is the issue exactly. Is it because one is a Sprite and the other a Bitmap, or is it because one uses a prepared symbol from a swf, while the other is just a png?
How can I make a Bitmap class respond to MouseEvent?
Thanks for any help!
From ActionScript® 3.0 Reference for the Adobe® Flash® Platform:
The Bitmap class is not a subclass of the InteractiveObject class, so
it cannot dispatch mouse events. However, you can use the
addEventListener() method of the display object container that
contains the Bitmap object.
Unfortunately Bitmap class doesn't dispatch mouse events you will have to wrap it inside a Sprite class.

Why can't I get access to an external class in actionscript 3?

I am working on a breakout game in adobe flash. I defined a document class, BreakOut.as, and set it to .fla file. I wrote another class Player.as, but I failed to get access to Player.as in my BreakOut.as. Here is the code:
BreakOut.as:
package
{
import flash.display.MovieClip;
import flash.display.Sprite;
public class BreakOut extends MovieClip
{
public function BreakOut()
{
var background:Background;
background= new Background();
addChild(background);
var playerone:Player;
playerone=new Player();
playerone.x=50;
playerone.y=50;
addChild(playerone);
}
}
}
Player.as:
package
{
import flash.display.MovieClip;
public class Player extends MovieClip
{
public function Player()
{
player.graphics.beginFill(0x000000);
player.graphics.drawRect(0,0,20,100);
}
}
}
Adobe flash keeps telling me: Access of undefined property Player. Well, Background.as is another class, and I can get access to it without any problems. But it just won't work on Player.as.
player.graphics.beginFill(0x000000);
player.graphics.drawRect(0,0,20,100);
By this, if you are trying to initialize Player by drawing a rectangle, you should be rather using this:
this.graphics.beginFill(0x000000);
this.graphics.drawRect(0,0,20,100);
Do note that Player.as should also be in the same path as the fla's classpath.

How to manipulate with symbol on stage from document class without creating a new instance

So I have one movie clip on stage rect_mc and document class Main.as ...
I can import movie clip to document class with
import rect_mc;
and create a new instance
public var rect:rect_mc = new rect_mc();
addChild(rect);
but is there any way to manipulate rect_mc without craating new instance and attaching it to a stage with addChild()
I am note sure what your question is. If you have the MovieClip on stage you can access it by its instance name. You dont need to create a new instance.
package
{
import flash.display.MovieClip;
import flash.display.Sprite;
public class Test extends Sprite
{
// you need to define a variable for the MovieClip
public var myRect : MovieClip;
public function Test()
{
super();
// Access the MovieClip any way you want by its instance name.
myRect.scaleX = 3.8;
}
}
}
If you are not going to instantiate any more instances of the MovieClip then you can get rid of the linkage and export properties for the MovieClip.
You can't manipulate rect_mc without creating an instance of it, but you don't actually have to add it to the stage before you do anything. You can still position/scale/rotate/whatever, you just won't see it

Custom button with image

Hi i'm trying to create a button in actionscript 3 that will be made by a custom image ( a car.jpg from my HDD ). Is it possible to do that with SimpleButton class ( i mean is there a way to load the image and attach it to the button ?) or is there another way?
If i would like to have animation also in the button when let's say i roll over the mouse pointer from the button what do i have to do?
ps: i would like to use only actionscript 3 ( i mean all the project is done as a .as file that is linked to Document class ).
Although George Profenza already pointed the best solution under the comment if feel curious how you could implement the SimpleButton class you might want to take a look into th as3 document reference examples:
adobe livedocs - SimpleButton Example
I have also wrote a simple example that only makes a "simple button" in a "complicated button" but makes use of SimpleButton class, so you can take a look how you can extend the class, and give to each state it's own graphic. Here is the code:
// this goes in your app
var button:MySimpleButton = new MySimpleButton();
addChild(button);
MySimpleButton.as
package
{
import flash.display.DisplayObject;
import flash.display.SimpleButton;
import flash.display.Sprite;
public class MySimpleButton extends SimpleButton
{
private var upAlpha : Number = 1;
private var overAlpha : Number = 0.5;
public function MySimpleButton(upState : DisplayObject = null, overState : DisplayObject = null, downState : DisplayObject = null, hitTestState : DisplayObject = null)
{
upState = new ButtonImgDisplayState( upAlpha);
overState = new ButtonImgDisplayState( overAlpha);
downState = new ButtonImgDisplayState( upAlpha);
hitTestState = new ButtonImgDisplayState( upAlpha);
super(upState, overState, downState, hitTestState);
}
}
}
ButtonImgDisplayState.as
package
{
import flash.display.Loader;
import flash.display.Sprite;
import flash.net.URLRequest;
public class ButtonImgDisplayState extends Sprite
{
public function ButtonImgDisplayState(_alpha:Number)
{
var my_loader : Loader = new Loader();
my_loader.load(new URLRequest("car.jpg"));
addChild(my_loader);
this.alpha = _alpha;
}
}
}
The thing about the SimpleButton is to spare you to set listeners, but you are obligated to go around the states that are separated DisplayObjects making you button a more rigid thing when dealing with transitions between states.
Hope you find this useful.