Showing posts with label sprite. Show all posts
Showing posts with label sprite. Show all posts

Wednesday, August 17, 2011

One image, three states of button.


When we want to create custom button, usually three states considered: mouse over (roll over), mouse out (roll out) and press (click, release). If it is advanced, with multiple animations, and differences between those free states, theres no other way to create each of them separately. But if You need quite simple button which changes its color, look at this example.

Firstly some declarations:

private var _loader:Loader;


private var _colorTransform:ColorTransform;
private var _rollOverColorTransform:ColorTransform;
private var _clickColorTransform:ColorTransform;
        
private var _color:uint;
private var _rollOverColor:uint;
private var _clickColor:uint;

We also have to define values:

_color = 0xFFFFFF;
_rollOverColor = 0xFF6600;

We load image:

_loader = new Loader();
_loader.load(new URLRequest(url));
addChild(_loader);
buttonMode = true;

Prepare transformations for switching states:

_colorTransform = _loader.transform.colorTransform;
_colorTransform.color = _color;
_loader.transform.colorTransform = _colorTransform;
            
_rollOverColorTransform = _loader.transform.colorTransform;
_rollOverColorTransform.color = _rollOverColor;


_clickColorTransform = _loader.transform.colorTransform;
_clickColorTransform.color = _clickColor;

Then we set listeners:

addEventListener(MouseEvent.ROLL_OVER, handleRollOver);
addEventListener(MouseEvent.ROLL_OUT, handleRollOut);
addEventListener(MouseEvent.MOUSE_DOWN, handleMouseDown);

And handlers for events:


private function handleRollOver(e:MouseEvent):void
{
    _loader.transform.colorTransform = _rollOverColorTransform;
}
    
private function handleRollOut(e:MouseEvent):void
{
    _loader.transform.colorTransform = _colorTransform;
}
        
private function handleMouseDown(e:MouseEvent):void
{
    _loader.transform.colorTransform = _clickColorTransform;
}

And it's done!

Check it:




Thursday, April 7, 2011

Cast vs as operator

I was wondering what's the difference between different types of casting. So I made some tests

var test1:Number;
trace( test1 as String); trace( test1.toString()); trace( String(test1));

//Output:
//null
//NaN
//NaN

OK, so we have two types casting. While 'as' returns us not defined String type (casted value also was not defined), standard casting creates instance that tries to use data casted type

Let's try the opposite way. But this time on defined instance

var test2:String = '100';  
trace( test2 as Number); 
trace( Number(test2));



//Output:
//null
//100

Casting give us instance with data gathered from base class. But 'as' operator one more time returns null. I wondered how does it work. And I found. Check this example:


var test3:Sprite = new Sprite(); 
trace( test3 as DisplayObject); 
trace( test3 as MovieClip);


Operator 'as' is concatenation of checking type of data and casting data. It casts only when base type is descendant of casted type. If expression is inherits casted class then it's returned. Otherwise it returns null

Friday, March 11, 2011

ADDED vs. ADDED_TO_STAGE

ADDED and ADDED_TO_STAGE are two events that are dispatched on object when this is added as child to displayed parent. But there is a reason why they both exist. Here is small study on differences.

Case #1 - adding object to stage.
in this case we're adding class (named A) to main class which is stage. both listeners are added as in presented code:

public class A extends Sprite
{
    public function A()
    {
        trace('A A()');
        super();

        addEventListener(Event.ADDED, _handleAdded);
        addEventListener(Event.ADDED_TO_STAGE, _handleAddedtoStage);
    }

    private function _handleAdded(event:Event):void
    {
        trace('A added');
    }

    private function _handleAddedtoStage(event:Event):void
    {
        trace('A AddedtoStage');
    }
}


And here is main class code:

public function Blog()
{
    trace('Blog Blog()');
    var a:A = new A();

    trace('adding A to stage');
    addChild(a);
}


Here is result of experiment:

Blog Blog()
A A()
adding A to stage
A added
A AddedtoStage


Conclusion: both events works works similar. What is more, everytime ADDED is before ADDED_TO_STAGE. Flash is not working parallely so there must be some reason of this constant order. If You switch adding listeners result is the same. This shows that ADDED is always dispatched before ADDED_TO_STAGE.

Case #2 - cascade adding objects to stage
Now we add one more object, so structure will look like this:

Stage(Blog) -> A -> B

Main class of Blog stays same as in previous example. Class A is modified to create instance and load into itself object of type B. Here is code of class A:

public class A extends Sprite
{
    public function A()
    {
        trace('A A()');
        super();

        addEventListener(Event.ADDED_TO_STAGE, _handleAddedtoStage);
        addEventListener(Event.ADDED, _handleAdded);

        var b:B = new B();
        addChild(b);
    }

    private function _handleAdded(event:Event):void
    {
        trace('A added');
    }

    private function _handleAddedtoStage(event:Event):void
    {
        trace('A AddedtoStage');
    }
}


And here we have source of class B. It looks like class A in previous case:

public class B extends Sprite
{
    public function B()
    {
        trace('B B()');
        super();

        addEventListener(Event.ADDED_TO_STAGE, _handleAddedtoStage);
        addEventListener(Event.ADDED, _handleAdded);
    }

    private function _handleAdded(event:Event):void
    {
        trace('B added');
    }

    private function _handleAddedtoStage(event:Event):void
    {
        trace('B AddedtoStage');
    }
}


And let's see what now happens:

Blog Blog()
A A()
B B()
B added
A added
adding A to stage
A added
A AddedtoStage
B AddedtoStage


Conclusion: First thing is that an event ADDED is captured in class A twice. Once when object is added to this class as child and once when the object itself is added to parent. Second and most important part delay between capturing those event. This shows that event ADDED is dispatched each time when method addChild (or AddChildAt) are called. And this event is dispatched first. ADDED_TO_STAGE is dispatched when object or it's parent or a structure of objects of many levels are added to displayed class on stage. And this event goes as second. Last thing - ADDED_TO_STAGE event is propagated from stage to it's children and to further levels of descendants


Thursday, March 10, 2011

Simple mask

Mask is a layer that covers our appropriate object. It is always problem what is mask and what is masked. And what should be on mask layer. So here is short description with example. Look at this schema:
From the right:
  • back - complete image that is covered
  • mask - objects and shapes here creates holes through which we see image from back
  • result - this is what we get as result of using mask
Background can be everything. In this example it's a simple image:

_background = new _BackGround();
addChild(_background);

Mask can be simple shape. If it's static it don't have to be added as child to stage. But if we want do some action on mask it's neccesary:

var mask:Sprite = new Sprite();
mask.graphics.beginFill(0xFF6600, 1);
mask.graphics.drawRect(-40, -40, 80, 80);
mask.graphics.endFill();
addChild(mask);
_background.mask = mask;
mask.startDrag(true);

In this example mask is a draggable square that follows mouse cursor. Check it!



Monday, February 28, 2011

9-scale resizing

If You want to create component properly scalable remember about resizing shapes. Problem occurs during resizing for example rectangles. Border of 2 pixels thick becomes really big. Because object is resized as-is proportionally with content and graphic.
Here is the proof:

To avoid this problem You should use 9-scale. This property (officialy named scale9Grid) is avaiable in Movieclips, Sprites and so on. Here is example of code how to use it:

var background3 = new Sprite();
background3.graphics.lineStyle(2, 0xd61e31);
background3.graphics.beginFill(0xFFFFFF, 1);
background3.graphics.drawRect(0, 0, 40, 40);
background3.graphics.endFill();


//here comes 9-scaling
var grid:Rectangle = new Rectangle(5, 5, 30, 30);
background3.scale9Grid = grid;


Rectangle that is created above creates 9 regions in our object (which also is rectangle shaped). Picture below shows regions. Points A(5,5) and B(30,30) shows coordinates of lines which are regions borders.


Those 9 regions can be grouped to 4 types. Each type is scaled in different way:
  • corners - four corners are not scaled. They are constant
  • long vertical sides - middle-left region and middle-right regions are scaled only in Y axis
  • long horizontal sides - center-top and center-bottom regions are scaled only in X axis
  • middle-center - this region is scaled in both directions

Here is description from API