AS3: Apply Mask to Multiple MovieClips - actionscript-3

I have two MovieClips onscreen, and I want to apply the same mask to both. I set the the masks using
mc1.mask = mymask;
mc2.mask = mymask;
Only mc2 receives the mask. How can I set the same mask for two different MovieClips without having to resort to putting them both in a single MovieClip?

Make the mask a class and use instances of this class to mask each movie clip.
Your class could have set properties or if needs be you could pass parameters in the constructor for more flexibility...
var mask1:MyMask = new MyMask();
var mask2:MyMask = new MyMask();
mc1.mask = mask1;
mc2.mask = mask2;

if you are attempting to apply the same mask on both of your two sprites you can set the 2 sprite objects as children of a display object container and assign the mask to the container.

Related

AS3 - Setting layer above parent Object

Is it possible to set the visibility of a Child of an object which is a Child of the Stage above the Stage?
For example, if the Overworld is a Child of the Stage, and a PlayerCharacter is also a Child of the Stage, can the Player Character walk behind parts of the Overworld, for example Trees?
You can use:
parent.setChildIndex(Overworld, 1)
parent.setChildIndex(PlayerCharacter , 2)
If the depth (z order) of the objects is constant I suggest using layers. Adding three sprites on to your stage. Like background, gameobjects and foreground. Saves a lot of trouble.
public Sprite foregroundLayer = new Sprite();
public Sprite objectLayer = new Sprite();
public Sprite backgroundLayer = new Sprite();
Add them to the stage in your game initialisation in the desired order.

Constrain drag of movie clip to mask, with stage & mc scaling

I'd like to constrain the drag of a movieclip to a mask called themapmask. The draggable mc's name is mapcontainer.themap. It's parent, mapcontainer, is scaled proportionately with the stage. How can i constrain the dragged mc to the mask? The code below works on load, but not when the stage is scaled.
function constrainMap():void {
leftedge = themapmask.x+mapcontainer.themap.width/2-mapcontainer.x;
rightedge= themapmask.x+themapmask.width-mapcontainer.width/2-mapcontainer.x;
topedge = themapmask.y+mapcontainer.themap.height/2-mapcontainer.y;
bottomedge = themapmask.y+themapmask.height-mapcontainer.height/2-mapcontainer.y;
if (mapcontainer.themap.x>leftedge) mapcontainer.themap.x=leftedge;
if (mapcontainer.themap.y>topedge) mapcontainer.themap.y=topedge;
if (mapcontainer.themap.x<rightedge) mapcontainer.themap.x=rightedge;
if (mapcontainer.themap.y<bottomedge) mapcontainer.themap.y=bottomedge;
}
The Sprite.startDrag function accepts a second argument especially for drag area constraints, and the DisplayObject.getBounds function returns a rectangle with the boundaries of the applied-to object within the context of the argument DisplayObject. So, basically, what you need to do is:
mapcontainer.themap.startDrag(false /*or true*/, themapmask.getBounds(mapcontainer));
and you can let go of the whole constrainMap function altogether.

Apply smoothing to scaled display object

I have a display object (not image) that I'm scaling down. It has the same jaggies and aliased edges that an image does when it's scaled. Is there a way to smooth that display object in the same way the image is smoothed?
Update
This is an interactive display object (sprite) with interactive child display objects. I can't draw it to a bitmap.
You can try forcing the display object into "3d" mode by adding a Matrix3D transform to it. The easiest way to do that is to simply give it a rotationX value:
myDisplayObject.rotationX = 0.0;
You can also try checking the "hinting" box on your shapes (sometimes this makes circles & ovals get sort of strange shaped, so it's a gamble), and you can try selecting "Cache as bitmap" from the render dropdown.
Do bicubic resampling on the sprite with Pixel Blender?
http://blog.onthewings.net/2009/08/25/bicubic-resampling-by-pixel-bender/
You can try to set the smoothed property of the bitmap object to true and than scale it:
look here
You Display object must contain a Bitmap, or is the Bitmap itself...
Have you tried setting stage.quality = stageQuality.High;?
Also if you did that and you want to set the smoothing manually you can try the Lanczos re-sampling function (I did not made it).
Warning: you don't want to use this function every frame since it's pretty performance heavy!
First you need to draw you displayObject to an Bitmap with BitmapData:
var bmd:BitmapData = new BitmapData(dispObject.width, dispObject.height, true, 0);
//Create new bitmapData with the same size as your object and with transparancy.
bmd.draw(dispObject);
//Draw you displayObject onto the empty Bitmap
var b:Bitmap = new Bitmap(bmd, true);
//Create the bitmap container and load the data, and the true turns smoothing on!
addChild(b);
//Add it to the stage and now you can use the scale and width variables like this
b.x = dispObject.x;
b.y = dispObject.y;
b.scaleX = dispObject.scaleX;
b.scaleY = dispObject.scaleY;

AS3 scale x and y using tween to give movieclip bounce effect

I am trying to give my "buttons" a bounce in effect using the tween class. I am also trying to make my code more efficent by using a function to handle this effect for all my buttons.
var MusicClip:MovieClip = new music_mc();
var MoviesClip:MovieClip = new movie_mc();
var GameClip:MovieClip = new game_mc();
MusicClip.y = 63;
MusicClip.x = 577;
MoviesClip.y = 87;
MoviesClip.x = 401;
GameClip.y = 75;
GameClip.x = 151;
addChild(MusicClip);
addChild(MoviesClip);
addChild(GameClip);
This is where I am having a hard time. I thought I had to tween both the
scaleX and scaleY for all three MovieClips, but the button just appears on the
stage and doesn't animate in. Also if I can put this code in a function so I
don't have to write it for every button (and future buttons) that would be great.
var scaleTween:Tween=new Tween(MusicClip,"scaleX",Elastic.easeOut,0,1,1,true);
var scale2Tween:Tween=new Tween(MusicClip,"scaleY",Elastic.easeOut,0,1,1,true);
I am not getting any error but there is no bouncing in effect.
You need to assign listeners to your MovieClips that will perform an action when you do something. You can use a single event handler for all of your MovieClips:
MusicClip.addEventListener(MouseEvent.MOUSE_OVER,bounceButton);
MusicClip.addEventListener(MouseEvent.MOUSE_OVER,bounceButton);
MoviesClip.addEventListener(MouseEvent.MOUSE_OVER,bounceButton);
function bounceButton(event:MouseEvent):void
{
var scaleTween:Tween=new Tween(event.target,"scaleX",Elastic.easeOut,0,1,1,true);
var scale2Tween:Tween=new Tween(event.target,"scaleY",Elastic.easeOut,0,1,1,true);
}
Note that rather than specifying any one MovieClip as the tween target, you are using event.target, which will refer to the MovieClip you have rolled over.
On an unrelated note, it is good practise to start instance names with a lower case letter. This helps to distinguish them from class names which by convention have uppercase letters to start each word:
var myVariable:MyClass;

Create a MovieClip out of another object

In my Actionscript program, I draw a polygon using the methods:
this.graphics.moveTo()
and
this.graphics.lineTo()
In the update function of the polygon model I change it a bit, and then draw it all over again. Eventually, every call to the update() function draws the updated polygon and I can see it changes.
On some point of the program, I want to be able to use this polygon as a movieclip, so I
can attach a mask to it - so as the polygon drawn over and over again, I could see a nice
background in the form of that polygon, fills it inside.
Problem is - I do not know how to take this array of points I have, which is my polygon representation, and turn it into a movieclip ( if possible at all... )
If you have any other recommendations how to implement the above, It would be great.
You can just create a new MovieClip and use it's graphics for drawing. So instead of using this.graphics.moveTo / lineTo, try this:
var mc:MovieClip = new MovieClip();
mc.graphics.moveTo(...);
mc.graphics.lineTo(...);
this.addChild(mc);
A convenient way of drawing, if you want to type less, is to do something like this:
var mc:MovieClip = new MovieClip();
with(mc.graphics) {
clear();
lineStyle(...);
moveTo(...);
lineTo(...);
...
ect.
}
this.addChild(mc);
I suggest you take a look at Point class. For example,
var p1:Point = new Point(100,150);
Then you can have an array of points
var arrPoints:Array = new Array(p1,p2,p3);
With a for loop, you can decide if i==0 you use moveTo and for the rest use lineTo. You can have a special condition at the end to close your polygon, i==arrPoints.length-1.
So, basically create a movieclip object, use its graphic property to fill it with the points you defined in your array. As long as your points are in a movieclip, you can mask it. Finally, that "this" notation you used is probably referring to the main movieclip which is the stage.
var mc:MovieClip = new MovieClip();
mc.graphics.moveTo(p1.x,p1.y);
will draw your graphics into your mc.