Deleting a shape via code - actionscript-3

Pretty basic question here, but its still got me a little confused..
I have an object(navigation menu bar) that I want to change the colors on with code, so in an updateColor function, I get the bounds of the object (which is a drawing shape contained in a movieclip) and redraw a new shape on top of it with the new color, but I've noticed that the last shape still exists behind this redraw.
I tried using obj.graphics.clear(); before the redraw but that didn't get rid of the original shape. Is there another command that I'm overlooking?

Unless you drew the object you wish to remove within the same graphics object, clearing won't work. You need to remove the DisplayObject.
Depending on the number of children you can do:
obj.removeChildAt(0);
This also removes movieclips / buttons you placed on the stage manually.
If you have a reference to the DisplayObject you wish to remove you can simply do
obj.removeChild(backgroundClip);
Note that you can also change the color of a DisplayObject directly:
import flash.geom.ColorTransform;
...
public var test:MovieClip; //instance on stage
...
var cf:ColorTransform = test.transform.colorTransform;
cf.color = 0xff0000;
test.transform.colorTransform = cf;

while(this.numChildren)
{
this.removeChildAt(0);
}
Will clear child object on this MovieClip,
if it's clearing too much, then put the shape drawing in a subclip, and clear the subclip.

Related

How to use a mask in actionscript 3.0?

I want to mask the png image pattern.png with another image - mask.png, but it doesn't work at all and I can't find the reason. Instead of masking the image, the mask just disappears and the pattern stays the same as it was.
I tried making a MovieClip, drawing e.g. a circle and using that as the mask instead of mask.png and it works just fine. Is it because you can't use loader objects as masks? How do I make it work?
edit: After changing the size of mask.png to be smaller than the pattern, I've realized that it actually does kind of work, but what happens is instead of cutting the pattern into the shape I've drawn in the png file it just cuts it into the shape of the entire file, as in, it counts the rectangular transparent background as well. How can I make it cut out just the shape?
var mask:Loader = new Loader();
mask.load(new URLRequest("mask.png"));
var pattern:Loader = new Loader();
pattern.load(new URLRequest("pattern.png"));
pattern.contentLoaderInfo.addEventListener(Event.COMPLETE, loadComplete);
function loadComplete(e:Event):void {
addChild(pattern);
addChild(mask);
pattern.mask = mask;
}
Your code is looks correctly. The mask property of DisplayObject wants DisplayObject too. But try to make few things, to find the trouble:
You have only one listener, to pattern.png. But you must be sure, that mask.png has loaded already too.
Despite that Loader is DisplayObject too - try to get content from loader for mask, and just after that try to use it.
*Ah, and one more thing. You must at first add listener, and only later try to load.

Add Child Behind existing object AS3

I have made a game using Flash CS5 (as3) and I am trying to add a child to the stage behind objects that are already there. For example, I have a bar at the bottom of the screen that is there from the time you start the game and I have falling objects that I want to fall behind it, but instead they fall in front of it because I added them to the stage after. Is there a way of adding the falling objects behind it without having to keep re-adding the bar to the stage? Thanks in advance.
Rather than layering, I'd use adjust the index of each object using addChildAt and setChildIndex.
The following line adds your falling object behind every other DisplayObject on the stage (in this case, you should probably add your bar to the stage first)
stage.addChildAt(fallingObject, 0);
You can create Sprites to act as layers, and add the different objects to them. Here is an example that adds a layer for adding whatever you want behind the bar layer, and THEN adds the bar layer, so it will be on top. It's super rough since you don't have any code to reference:
package {
import flash.display.*;
public class Test extends MovieClip {
var barLayer:Sprite;
var objectLayer:Sprite;
public function Test() {
var objectLayer = new Sprite();
//add the object layer to your main Class
this.addChild(objectLayer);
//now you can add movie clips or sprites to objectLayer whenever you like
//then create the bar layer
var barLayer = new Sprite();
//add your bar Display Object here
var bar = new MovieClip();//draw the bar or reference the library object you've created
barLayer.addChild(bar);
//now add the barLayer
this.addChild(barLayer);
}
}
}

flash actionscript 3.0 hide part of an image

I am working on a flash sound mixer application with multiple sound channels, and I am having trouble with the lights beside the volume knob.
Is there a way to hide just a part of an image?
On the image below, image-2 is on top of image-1 to create some kind of volume level indicator effect, and how much of image-2 is shown depends on the value of the volume.
image-url: http://s30.postimg.org/r3ow1g5bl/volume_lights_level.png
I've tried by just reducing the height of image-2, but it looks awful and distorted.
Is there something in flash that works closely the same as CSS's behavior.
example: I'll just make image-2 a background of a shape, and when I reduce the shape's height, the image-background does not get distorted or changes it's height as well.
By searching for solutions, I have come across the mask property, but I don't quite understand how it works, and most of the examples shown are images placed inside circles.
Is the mask property applicable in this situation?
I'm quite new to flash so I don't know a lot of things yet.
You can indeed use a mask.
How to programmatically create your mask
Put an occurrence of your image named myImage on the stage, and put over this occurrence a mask named myMask with the same dimensions. You can apply myMask mask to myImage using it's mask property like below:
Main Timeline
myImage.mask = myMask;
function mouseMoveHandler(e:MouseEvent):void {
myMask.height = myImage.y - e.stageY;
}
stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
You have just to adapt this code to your animation, in the function where you click your button.
I got it working now, many THANKS #VC.One. heres how I did it.
Imported img-2 to stage, converted it into symbol(type:Movie Clip), assigned instance name: img2_mc.
I created a new layer for the mask, drawn a rectangle using rectangle tool, converted it also to symbol(type:Movie Clip), assigned instance name: mask_mc.
Then applied the mask to img2_mc.
/* the code */
img2_mc.mask = mask_mc;
function onEnterFrame(event:Event):void{
var volumeKnob_y = volSliderKnobOn.y + 12; // adjust it to the center of the knob
mask_mc.height = volumeKnob_y;
}

How to add movieclip inside textfield

I would like to add a movieclip to a textfield. The objective is to be able to scroll the movie clip, since the uiscrollbar only works for textfield, i think my solution to scrolling the movie clip is to put it inside a textfield.
I have tried something like:
myText.addChild(myClip);
but failed with error: 1061: Call to a possibly undefined method addChild through a reference with static type flash.text:TextField.
The problem is that a TextField is not a DisplayObjectContainer, so you can't add children.
(The good news is that there are a number of alternate solutions you can find through Google)
You won't be able to add it to a textfield and I'm not exactly sure what you're mean by "scrolling the movie clip" but assuming you have a movieclip that is larger than the area you want to display it, something like this might work:
<s:Group>
<s:Scroller>
<mx:SWFLoader source="#Embed(source='movieclip.swf')"/>
</s:Scroller>
</s:Group>
Sorry if this is a bit of a thread-jack, but I recently had a situation where I needed this type of functionality. And while I'm sure you no longer need an answer to this, I hope that the solution that I came up with will help someone else.
Dear god, why would someone do this?!
In my particular case, I had an extremely long textfield that needed to scroll. In my experience, scrolling by moving the movieclip vertially is unreliable when dealing with extremely long textfields which necessitated that I use the Adobe/Flash uiscrollbar-esk method of adjusting the scrollV of the text field.
This was further complicated by the need for both in-line images which pulled from the library (as opposed to an external source) as well as a black-box border around a section of the text, both of which needed to scroll along with the text.
In a nutshell, one would probably only need to do something like this for a completely self contained swf and under extenuating circumstances (like pharma banners).
Inserting Images From Library:
To accomplish this you need to create a movieclip from an image in the library and export that movieclip for Actionscript. Then, in your code, add something like this:
//This is a string from your textfield that you will replace with an image
var matchForImageSplit:String = 'IMAGE 1 GOES HERE';
//This is the code to replace the above string
//Here, "Image1" is the class name of the exported MovieClip
var imageToAdd:String = '<img src="Image1" />';
my_text.htmlText = my_text.htmlText.split(matchForImageSplit).join(imageToAdd);
Adding the black-box border around text:
This was a bit more tricky. What I had to do was create a MovieClip with a border at the size I needed and give it a name. Then I positioned it behind the text where it was supposed to go, and enclose all of that in a parent_mc movieclip.
I then had to code the box to move along with the scrolling. The below is specific my project, but this is the gist of it:
//THIS CODE IS NON-FUNCTIONAL AND SHOULD ONLY BE USED AS A REFERENCE
//Redundant - just making the example more clear.
var my_text:TextField = parent_mc.my_text;
var borderBox:Sprite = parent_mc.borderBox;
//Vars for calculating position and movement
var borderBoxStartY:Number = borderBox.y;
var incrementRate:Number = my_text.textHeight/my_text.numLines;
var sPos:Number;
var top:Number = dragger.y;
var bottom:Number = (dragger.y + track.height) - dragger.height;
var range:Number = bottom - top;
var ctrl:Number = parent_mc.y; //"parent_mc" is the parent MC that contains the textField and borderBox
function dragScroll():void {
ratio = my_text.maxScrollV/range;
sPos = (dragger.y * ratio) - ctrl;
my_text.scrollV = Math.ceil(sPos);
borderBox.y = ((borderBoxStartY + incrementRate) - (my_text.scrollV * incrementRate));
}
One caveat to note before trying all of this is that when utilizing scrollV, text is moved line-by-line and therefore does NOT scroll smoothly (as it would with position based scrolling). This can result in the scrolling looking "jerky".
EDIT:
I should also note that this was all custom programmed and does not actually utilize the scrollPane/uiscrollbar components, but behaves in the same fashion.

Movieclip stacking in Actionscript

I'm building a game of which the interface is one of the first items to load on screen. Sound button, pause and all the bits -
During the game - all manor of things are dynamically added and removed to the stage. Therefore my interface goes behind my game scene.
How do I ensure the movieclip always stays on top?
Can I override the addChild of my Document Class and every time a new child is added, I restack the interface to the top?
You can use setChildIndex to rearrange objects that are already contained within a MovieClip or Sprite. For example, if you have an object called container, which contains a redBall, blueBall and many other ball objects, you can use the following to make sure redBall is behind everything else:
container.setChildIndex(redBall, 0);
Equally you can make sure that blueBall will be displayed infront of everything else using:
container.setChildIndex(blueBall, container.numChildren-1);
addChildAt will sort you out for adding children straight into their correct position, and setChildIndex will allow you to re-position objects already placed. Hope that helps.
debu
Look into addChildAt, it allows you to specify the index that the new object should be added too.
http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/display/DisplayObjectContainer.html#addChildAt%28%29
A good strategy is to keep all interface elements in one parent Sprite/MovieClip, and all game assets in another. (With the interface one on top)
With your guys suggestion I made this, apparently, if you addChild an object already on the screen, it's simply reindex'd to the top. Does this look ok?
private var topLevelChildrenArray:Array = [];
public function addTopLevelChild(child:DisplayObject):DisplayObject
{
topLevelChildrenArray.push(child)
return this.addChildAt( child, this.numChildren - 1 );
}
override public function addChild(child:DisplayObject):DisplayObject
{
this.addChildAt(child, this.numChildren);
for each(var topChild:DisplayObject in topLevelChildrenArray)
{
super.addChild(topChild);
}
return child
}