AS3 - Adjust image colors - actionscript-3

I'm adjusting image colors through the function below. The problem is that if I need to switch a colorFilter value to 0 it's not working but if I enter 0.1 instead of 0 it works.
How to make it work without that workaround?
import fl.motion.AdjustColor;
import flash.filters.ColorMatrixFilter;
var colorFilter:AdjustColor = new AdjustColor();
var mColorMatrix:ColorMatrixFilter;
var mMatrix:Array = [];
var MC:MovieClip = new MovieClip();
function adjustColors():void
{
colorFilter.hue = 50;
colorFilter.saturation = 50;
colorFilter.brightness = 50;
colorFilter.contrast = 12;
mMatrix = colorFilter.CalculateFinalFlatArray();
mColorMatrix = new ColorMatrixFilter(mMatrix);
MC.filters = [mColorMatrix];
}

I tested this by adding an argument to adjustColors() and calling it twice, and I see the same problem. I think it's just a bug where it ignores zero values.
It's not much of a better workaround, but if you just create a new AdjustColor each time, it should work correctly:
import fl.motion.AdjustColor;
import flash.filters.ColorMatrixFilter;
var colorFilter:AdjustColor = new AdjustColor();
var mColorMatrix:ColorMatrixFilter;
var mMatrix:Array = [];
var MC:MovieClip = new MovieClip();
function adjustColors():void
{
colorFilter = new AdjustColor();
colorFilter.hue = 50;
colorFilter.saturation = 50;
colorFilter.brightness = 50;
colorFilter.contrast = 12;
mMatrix = colorFilter.CalculateFinalFlatArray();
mColorMatrix = new ColorMatrixFilter(mMatrix);
MC.filters = [mColorMatrix];
}

Here is my workaround for reference:
Just use the logical OR assignment when you set each property.
That way if a value is 0 it will evaluate to false and .1 will be assigned instead:
var colorMat:ColorMatrixFilter = new ColorMatrixFilter();
var colorAdjust:AdjustColor = new AdjustColor();
const colorsAdj:Array =
[
// BRIGHTNESS, CONTRAST, SATURATION, HUE
[-20,0,20,-50],
[0,0,0,0],
[0,0,0,17]
];
function setColorMat(colorID:int):void
{
colorAdjust.brightness = colorsAdj[colorID][0] ||= .1;
colorAdjust.contrast = colorsAdj[colorID][1] ||= .1;
colorAdjust.saturation = colorsAdj[colorID][2] ||= .1;
colorAdjust.hue = colorsAdj[colorID][3] ||= .1;
colorMat.matrix = colorAdjust.CalculateFinalFlatArray();
}
That way you avoid recreating a new ColorMatrixFilter each time, in case it really change something...
And you keep a nice clean array... ;-)

Related

how to call just 2 value in array randomly specific location flash

I've 3 mc. I want to call 2 of them on stage randomly in specific locations. I don't know how to call them. I just tried with array. I think array is the best way but still confused.
this's code I tried :
import flash.geom.Point;
var Batumc:batu_mc = new batu_mc(); // creates a instance of the movieclip, i.e, an object
var Batumc1:L = new L();
var Pisangmc:pisang_mc = new pisang_mc();
var Batumc2:MovieClip = new MovieClip();
var Status:int = 0;
button.addEventListener(MouseEvent.CLICK, tombol);
function tombol(e:MouseEvent):void{
//addChild(Batumc);
//addChild(Batumc1);
//addChild(Pisangmc);
var P:Array = [new Point(80.2, 100), new Point(260, 100), new Point(430, 100)];
var M:Array = [Batumc, Batumc1, Pisangmc];
//random benda
var benda:int = Math.random()*M.length;
// Remove the selected benda from its list.
M.splice(benda, 1);
while (M.length){
// Get the last MovieClip and remove it from the list.
Batumc2 = M.pop();
trace(Batumc2);
// Produce a random Point.
var anIndex:int = Math.random() * P.length;
var aPo:Point = P[anIndex];
// Remove the selected Point from its list.
P.splice(anIndex, 1);
// Move the selected MovieClip to the selected Point coordinates.
Batumc2.x = aPo.x;
Batumc2.y = aPo.y;
addChild(Batumc);
addChild(Batumc1);
addChild(Pisangmc);
}
Status = 1;
}
button.addEventListener(Event.ENTER_FRAME, frame);
function frame(e:Event):void{
if(Status == 1 ){
removeChild(Batumc2);
Status = 0;
}
}
when i run this code, sometimes 3 mc appear again
I think the problem is with this line:
M[i] = P.splice(randomPos, 1);
You assign M[i] (array of mc) with value from P (array of points), so M[i] = array with point and not an mc.
If you want to avoid such issues you can use Vectors instead of arrays. Its more efficient and also must contain the type you declared.
Vector class Docs.
To use the vector, instead of:
var P:Array = [...];
var M:Array = [...];
Do:
var P:Vector.<Point> = new <Number>[...];
var M:Vector.<MovieClip> = new <MovieClip>[...];
And the rest is just like arrays (pop, push, slice, ...)
To remove item from M, just splice M, i don't understand why you need to iterate over M.
M.splice(randomPos, 1);
Try getDefinitionByName
var myClass:Class = getDefinitionByName("Class_Name") as Class;
var classInstance:MovieClip = new myClass as MovieClip;
addChild(classInstance);
You just have to determine the specific location in the array for the mc'c, beside that you can get the classes from the library like this;
var locations:Array = [{xpos:100, ypos:12} , {xpos:30, ypos:50} , {xpos:400, ypos:28}, ......];
for(var i:uint=0; i<YOUR_MCS_LENGTH; i++) {
var myClass:Class = getDefinitionByName("Batumc"+i) as Class;
var mc:MovieClip = new myClass as MovieClip;
mc.x = locations[i].xpos;
mc.y = locations[i].ypos;
}
I have followed your advice #Özgün Sandal, but I get this error
ReferenceError: Error #1065: Variable Batumc10 is not defined.
at global/flash.utils::getDefinitionByName()
at nyoba9_fla::MainTimeline/frame1()
this my code :
import flash.utils.getDefinitionByName;
import flash.geom.Point;
var Batumc:batu_mc = new batu_mc(); // creates a instance of the movieclip, i.e, an object
var Batumc1:L = new L();
var Pisangmc:pisang_mc = new pisang_mc();
var P:Array = [new Point(80.2, 100), new Point(260, 100), new Point(430, 100)];
var M:Array = [Batumc, Batumc1, Pisangmc];
for(var i:uint=0; i<M.length; i++) {
var myClass:Class = getDefinitionByName("Batumc1"+i) as Class;
var mc:MovieClip = new myClass as MovieClip;
// Produce a random Point.
var anIndex:int = Math.random() * P.length;
var aPo:Point = P[anIndex];
// Remove the selected Point from its list.
P.splice(anIndex, 1);
mc.x = aPo.x;
mc.y = aPo.y;
}
where's my fault?

Using a variable to replace portion of code? AS3

How do I get the var sliderthumb to replace [sliderthumb] in my code below? Thanks for your help.
var sliderthumb:String = "foo";
function natureThumb(){
Sprite(naturepage.sliders.[sliderthumb].getChildAt(1)).height = Sprite(naturepage.sliders.[sliderthumb].getChildAt(1)).width = 65;
}
Just remove the dot.
Sprite(naturepage.sliders[sliderthumb].getChildAt(1)).height
There is a method for displayObjectContainer called getChildByName that allow to access child display objects by its name. Hope this helps!
var sliderthumb:String = "foo";
function natureThumb(){
Sprite(naturepage.sliders.getChildByName(sliderthumb).getChildAt(1)).height = Sprite(naturepage.sliders.getChildByName(sliderthumb).getChildAt(1)).width = 65;
}
Well both answers provided can sorta be right depending on how the OP set things up, but wanted to add some clarification. First I would modify the code to be this:
var sliderthumb:String = "foo";
function natureThumb(){
var sp:Sprite = naturepage.sliders.[sliderthumb].getChildAt(1) as Sprite;
sp.height = sp.width = 65;
}
if you setup the object like
var mySprite:Sprite = new Sprite();
mySprite.id = "foo";
then this will work (assuming you want the second child of the object foo which is a child of sliders)
function natureThumb(){
var sp:Sprite = naturepage.sliders[sliderthumb].getChildAt(1) as Sprite;
sp.height = sp.width = 65;
}
if you instead setup your object like
var mySprite:Sprite = new Sprite();
mySprite.name = "foo";
then this will work
function natureThumb(){
var sp:Sprite = naturepage.sliders.getChildByName(sliderthumb).getChildAt(1) as Sprite;
sp.height = sp.width = 65;
}

How to create a series of class instances in a for loop, as3

In my library I have a bunch of classes named tip1, tip2, tip3, tip4...and so on. Is it possible to create one instance of each on the stage using a for loop? I tried this but it didn't seem to work.
var tips:int = 12;
for(var i:int = 1; i<=tips; i++){
var tipName:String = "tip"+i
var tip:MovieClip = new tipName();
tip.name = "tip" + i
tip.x = stage.width;
tip.y = 0;
addChild(tip);
}
Any help would be appreciated. Thanks!
You were missing the "getDefinitionByName" part.
// Up top
import flash.utils.getDefinitionByName;
// Down below
var tips:int = 12;
for (var i:int = 1; i < tips; ++i ) {
var myClass:Class = getDefinitionByName('tip' + i) as Class;
var tip:Object = new myClass();
tip.name = "tip" + i;
....
}
Instead of
var tip:MovieClip = new tipName();
Try (written from memory)
var clazz:Class = getDefinitionByName(tipName) as Class;
var tip:MovieClip = new clazz();
Also, you generally want to use stage.stageWidth instead of stage.width, since the latter will return the stage bounding box width (which might not be the same as the area the swf file covers).

AS3 removing dynamically created child movieclips

I'm fairly new to AS3. Anyways, I'm try to remove a dynamically created child movieclip when clicked on. When a dirt block is clicked on, which is a child movieclip of 'world' I want to remove it.
I've tried various ways of removing it using removeChild. I've also tried moving the function inside/outside of the for loop that creates the movieclips.
var blockCount:Number = 0;
var blockArray:Array = [];
var world:MovieClip = new World();
world.x = 50;
world.y = 50;
world.name = "world";
addChild(world);
for(var i:Number=1;i<=100;i++){
blockCount++;
var tempGrassBlock:MovieClip = new GrassBlock();
tempGrassBlock.x = i*16;
tempGrassBlock.y = 256;
tempGrassBlock.name = "b"+blockCount;
world.addChild(tempGrassBlock);
tempGrassBlock.addEventListener(MouseEvent.CLICK, removeBlock);
function removeBlock(event:Event){
world.removeChild(getChildByName(event.target.name));
}
}
Thanks for the help.
Try this
function removeBlock(event:Event){
world.removeChild(event.currentTarget as DisplayObject);
}
No function definition should be inside a for. I changed that in your code and rewrited a little below:
var blockCount:Number = 0;
var blockArray:Array = [];
var world:MovieClip = new World();
world.x = 50;
world.y = 50;
world.name = "world";
addChild(world);
for(var i:Number=1;i<=100;i++){
blockCount++;
var tempGrassBlock:MovieClip = new GrassBlock();
tempGrassBlock.x = i*16;
tempGrassBlock.y = 256;
tempGrassBlock.name = "b"+blockCount;
world.addChild(tempGrassBlock);
tempGrassBlock.addEventListener(MouseEvent.CLICK, removeBlock);
}
function removeBlock(event:MouseEvent){
trace("Is click really working? This target name is " + event.currentTarget.name);
world.removeChild(event.currentTarget));
}

Dynamic vars MovieClips in AS3

Hello I'm trying to do this (in as2 this worked but not in as3) I looked on google for 3 hours, but still don't found a solution (thans for your help) :
import flash.display.MovieClip;
var mcContainer:MovieClip = new MovieClip();
var mcImage0:MovieClip = new MovieClip();
var mcImage1:MovieClip = new MovieClip();
var mcImage2:MovieClip = new MovieClip();
var mcImage3:MovieClip = new MovieClip();
mcImage0.name = "Boy";
mcImage1.name = "Girl";
mcImage2.name = "Woman";
mcImage3.name = "Man";
var ArrayNamesOfMC:Array = new Array();
var i:int = 4;
while(i--) {
ArrayNamesOfMC.push(["mcImage"+i].name);
}
This donsn't work :
ArrayNamesOfMC.push(["mcImage"+i].name);
This is the simple answer to your question:
var mcImage0:MovieClip = new MovieClip();
var mcImage1:MovieClip = new MovieClip();
var mcImage2:MovieClip = new MovieClip();
var mcImage3:MovieClip = new MovieClip();
mcImage0.name = "Boy";
mcImage1.name = "Girl";
mcImage2.name = "Woman";
mcImage3.name = "Man";
var ArrayNamesOfMC:Array = new Array();
var i:int = 3;
while (i >= 0)
{
ArrayNamesOfMC.push(MovieClip(this["mcImage" + i]).name);
i--;
}// end while
The following may not be relevant in your case as I'm not quite sure what the purpose of your application is, but this is probably a better approach:
var sprites:Vector.<Sprite> = new Vector.<Sprite>();
var names:Vector.<String> = new <String>["Boy", "Girl", "Woman", "Man"];
for (var i:uint = 0; i < names.length; i++)
{
var sprite:Sprite = new Sprite();
sprite.name = names[i];
sprites.push(sprite);
}// end for
Disregard this if it is not applicable in your case.
this should do the trick:
var _movieClip:MovieClip = ("mcImage" + i) as MovieClip;
ArrayNamesOfMC.push(_movieClip.name);
Taurayi's answer is an interesting technique that I didn't know about.
Personally I would recommend restructuring your code to put all the movieclips in an array, like so:
var mcImages:Array = new Array();
for (var i = 0; i < 4; i++) {
mcImages.push(new MovieClip);
}
mcImages[0].name = "Boy";
trace(mcImages[0].name);
Incidentally, your while loop was constructed incorrectly. You need a condition in the parentheses and then do the decrement inside the loop. But with all your movieclips in an array then you can use this much simpler approach to loop through all of them:
for each (var mc in mcImages) {
trace(mc.name);
}