As3 mouseover background not working as expected - actionscript-3

I'm not having any success, getting a background to show at 0.5 alpha on a mouseover, with a Sprite as the parent of a TextArea. The best I can get is the text appearing at 0.5 transparency on MouseOver, which is completely not what I'm looking for. I want the text at maximum alpha regardless of Mouse State and only the background(Sprite) to appear at half transparency on MouseOver. I'd rather avoid tweens if possible. Here's my code:
var textSprite:Sprite = new Sprite();
public function Main()
{
textSprite.graphics.beginFill(0x000000, 0);
textSprite.graphics.drawRect(94.95, 80.95, 390, 130);
textSprite.graphics.endFill();
textSprite.addChild(picArea1);//textarea added on stage, same dimensions, transparent background
textSprite.buttonMode = true;
textSprite.useHandCursor = true;
stage.addChild(textSprite);
textSprite.addEventListener(MouseEvent.MOUSE_OVER, applyAlpha);
textSprite.addEventListener(MouseEvent.MOUSE_OUT, noApplyAlpha);
}
function applyAlpha(event:MouseEvent):void {
textSprite.alpha = 0.5;
}
function noApplyAlpha(event:MouseEvent):void {
textSprite.alpha = 0;
}

Setting the sprite's alpha also affects all of it's children (by design) which is your current issue.
The way you're currently doing it (drawing the background with the graphics object), you'd have to redraw the graphics of the sprite on mouse over/out.
Here is method you could use:
public function Main()
{
drawTextBG(); //a new function I made to avoid duplicating code
textSprite.addChild(picArea1);//textarea added on stage, same dimensions, transparent background
textSprite.buttonMode = true;
textSprite.useHandCursor = true;
stage.addChild(textSprite);
textSprite.addEventListener(MouseEvent.MOUSE_OVER, applyAlpha);
textSprite.addEventListener(MouseEvent.MOUSE_OUT, noApplyAlpha);
}
//new function I made, this draws the background and makes the transparency the value passed in. I set the default to 1 (totally visible)
function drawTextBG(bgAlpha:Number = 1):void {
textSprite.graphics.clear();
textSprite.graphics.beginFill(0x000000, bgAlpha);
textSprite.graphics.drawRect(94.95, 80.95, 390, 130);
textSprite.graphics.endFill();
}
function applyAlpha(event:MouseEvent):void {
drawTextBG(.5); //redraw the background with half (.5) alpha
}
function noApplyAlpha(event:MouseEvent):void {
drawTextBG(); //redraw the background with the default value (1 - totaly visible)
}
Now, if your using a TLF (text-layout-framework) text field you can just use the backgroundColor and backgroundAlpha properties of the text field and forgo drawing a background manually.

Related

How to fill a rectangle with any color in AS3?

Am drawing a rectangle to move my scrubBar in a progressbar, it's working fine, now i need to fill the rectangle with some colors ?
private function startScrubbingOUT(_arg1:MouseEvent){
this.cueCard.stage.addEventListener(MouseEvent.MOUSE_UP, this.stopScrubbingOUT);
this.cueCard.stage.addEventListener(MouseEvent.MOUSE_MOVE, this.scrubBarIsMovingOUT);
this.scrubbing = true;
var _local2:Rectangle = new Rectangle(this.controls_mc.progressBar_mc.x, this.controls_mc.scrub_outpoint_mc.y, this.controls_mc.progressBar_mc.width, 0);
this.controls_mc.scrub_outpoint_mc.startDrag(false, _local2);
}
i had reffered Rectangle class here Rectangle Class
but i can't find any attribute to fill the Rectangle, help to figureout this

AS3 - How to use pixel/point detection with mouse event instead of object detection

This seems like it should be so easy that I'm embarrassed to ask, but I just can't get it.
I have a large round MovieClip (being used as a button). This MovieClip contains a PNG with a transparent background inserted into the MovieClip.
Due to its size there are large empty registration areas on the 4 corners (the bounding box).
How can I have the mouse register as being over only the circle pixels and not the blank space (of Alpha channel pixels) in the square boundary box?
Simple sample code:
public function simpleSample () : void
{
mc1.buttonMode = true;
mc1.addEventListener(MouseEvent.CLICK, doStuff);
}
public function doStuff (event:MouseEvent) : void
{
mc2.gotoAndStop(2);
}
Here are 3 different ways to accomplish this.
EDIT Since you've later explained that your button is an image, this first option won't work for you
If the shape flag on hitTestPoint works with your button (eg it's a shape), you can use hitTestPoint inside your mouse click handler to figure out if the click is actually over the object:
public function doStuff(event:MouseEvent){
//only continue if hit test point is true,
//the x and y values are global (not relative to the mc your testing as one might suppose)
//the third parameter should be true, so it takes into account the shape of object and not just it's bounds
if(mc1.hitTestPoint(stage.mouseX, stage.mouseY, true)){
mc2.gotoAndStop(2);
}
}
If the above doesn't work because you have bimtap data in your button, then an easy way to accomplish this is to just add a shape mask to the button.
So, either inside your button using FlasPro, mask everything with a circle shape, or, do it via code by doing the following when you first show the button:
var s:Shape = new Shape();
s.graphics.beginFill(0);
s.graphics.drawCircle(mc1.x + (mc1.width * .5), mc1.y + (mc1.height * .5), mc1.width / 2);
addChild(s);
mc1.mask = s;
If using an image as the button, or you want to set a threshold of how transparent to consider a click, then you can check the transparency of the pixel under the mouse:
function doStuff(event:MouseEvent){
//only continue if pixel under the mosue is NOT transparent
//first, you need a bitmap to work with
//if you know for sure the position of your bitmap, you can do something like this:
var bm:Bitmap = mc1.getChildAt(0) as Bitmap;
//annoyingly though, FlashPro makes timeline bitmaps shapes,
//so the above won't work UNLESS you take your bitmap in the FlashPro Library
//and export it for actionscript, giving it a class name, then it will be an actual bitmap on the timeline.
//As an alternative, you could (very CPU expensively) draw the whole button as a bitmap
var bmd:BitmapData = new BitmapData(mc1.width,mc1.height,true,0x00000000);
bmd.draw(mc1);
var bm:Bitmap = new Bitmap(bmd);
//we get the 32bit pixel under the mouse point
var pixel:uint = bm.bitmapData.getPixel32(bm.x + event.localX,bm.y + event.localY);
//then we grab just the Alpha part of that pixel ( >> 24 & 0xFF ).
//if the value is 0, it's totally transparent, if it's 255, it's totally opaque.
//for this example, let's say anything greater than 0 is considered good to be a click
if((pixel >> 24 & 0xFF) > 0){
mc2.gotoAndStop(2);
}
}

stage.swapChildren(MClip1, Mclip2); not working

i have made a drag and match game where i have a rectangle circle movieclip ..when rectangle/or circle hit a specific box rectangle will always be behind circle and circle will always be over retangle,if i drag rectangle first then circle its ok..but if i drag circle first then rectangle ..circle always takes its position behind ractengle i used stage.swapChildren(ccircle, crect) but its not working ...here is my code
crect.addEventListener(MouseEvent.MOUSE_DOWN, item_onMouseDown1);
function item_onMouseDown1(event:MouseEvent):void
{
crect = MovieClip(event.target);
startX1 = crect.x;
startY1 = crect.y;
crect.startDrag();
setChildIndex(crect, this.numChildren-1);
stage.addEventListener(MouseEvent.MOUSE_UP, stage_onMouseUp1);
}
function stage_onMouseUp1(event:MouseEvent):void {
stage.removeEventListener(MouseEvent.MOUSE_UP, stage_onMouseUp1);
crect.stopDrag();
if(crect.hitTestObject(box3))
{
TweenMax.to(crect, 0.5, {x:hit2X, y:hit2Y,height:height2Y, width:weight2X, ease:Cubic.easeOut});
//crect.mouseEnabled=false;
}
else
{
TweenMax.to(crect, 0.5, {x:startX1, y:startY1, ease:Bounce.easeOut});
}
}
ccircle.buttonMode=true;
ccircle.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown1);
function onMouseDown1(event:MouseEvent):void
{
ccircle = MovieClip(event.target);
startX1 = ccircle.x;
startY1 = ccircle.y;
ccircle.startDrag();
setChildIndex(ccircle, this.numChildren-1);
stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp1);
}
function onMouseUp1(event:MouseEvent):void {
stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp1);
ccircle.stopDrag();
if(ccircle.hitTestObject(box3))
{
TweenMax.to(ccircle, 0.5, {x:hit1X, y:hit1Y,height:height1Y, width:weight1X, ease:Cubic.easeOut});
//stage.swapChildren(ccircle, crect);
//setChildIndex(ccircle, this.numChildren-1);
//ccircle.mouseEnabled=false;
}
else
{
TweenMax.to(ccircle, 0.5, {x:startX1, y:startY1, ease:Bounce.easeOut});
}
}
You can't change ccircle index to -1. Only 0, 1, 2, ...
stage.setChildIndex(ccircle, -1);
You should write:
if (getChildIndex(ccircle) < getChildIndex(crect))
swapChildren(ccircle, crect);
It means: If ccircle is under crect then put ccircle on top.
You can just use
removeChild(crect);
addChild(crect);
That will always put crect on top. Of course if you need ccircle on top, do the same to it.
i simply set setChildIndex(crect, this.numChildren-2);
and setChildIndex(crect, this.numChildren-2); and its working perfect,because its not for setting circle on top only.while dragging i have to put dragged object on top of other objects..
I also found some info you can read on
Gary Rosenzweig website that I been studying myself on the display list in flash.
The site is http://flashgameu.com/ and scroll down an look for "understanding the display list."
It explains swapping children by name and also by location in the display list.
Watching his pod cast will help you understand the options using the display list with swapping children, addChild,removeChild and childIndex.
Its also free and a good site with some information on how to do things with flash and as3 programming.

how to retrieve a part of a bitmapdata which is in a particular color

I have a bitmapdata which contains two colors in it say black and white. Now the black area is transparent and the white area is visible. Now the image should be clickable only on the white areas and not on the black transparent area. How can we do this?
PS: The white areas are not in a regular locations I mean they are in random locations.
//add listener for mouse clicks
stage.addEventListener(MouseEvent.CLICK, eventHandler);
function eventHandler(event:MouseEvent):void
{
//1x1 bitmapData to store snapshot
var bmd:BitmapData = new BitmapData(1, 1);
//matrix object to 'move' stage so that pixel under mouse is effectively at 0,0
var matrix:Matrix = new Matrix();
//'move' stage according to mouse x,y values
matrix.translate(-event.stageX, -event.stageY);
//take snapshot of stage
bmd.draw(stage, matrix);
//get colour from snapshot data
var pixel:uint = bmd.getPixel(0, 0);
//trace result
trace("colour = "+pixel.toString(16));
}
Taken from http://blog.leeburrows.com/2011/06/get-pixel-colour-below-mouse-pointer/
Edit because I have time:
So in your case, instead of:
trace("colour = "+pixel.toString(16));
You would use:
if(pixel.toString(16) == "ffffff") // if clicked pixel is white
{
//do something
}
Sam's answer is great, but since you say you know that the pixel in question is part of a bitmapdata you could skip taking a snapshot of the stage and just check the bitmapdata directly instead. I think it could be as simple as:
stage.addEventListener(MouseEvent.CLICK, eventHandler);
function eventHandler(event:MouseEvent):void
{
if (myBitmapData.getPixel(event.stageX, event.stageY) == 0xffffff)
{
// do something
}
}
Also if you want to take alpha into consideration you will want to use getPixel32() instead of getPixel().

Transition between two images

I'm developing an ActionScript 3.0 app for Blackberry Playbook.
I'm using Loader Class to show an image.
I want to show another image, at the same place, when the user clicks on this image.
How can I do that? I would like to make a transition between these two images. The second image will go from 0 alpha to 100 alpha.
It all depends on the transition you want to do. For the simplest alpha, you can go through a Tweener engine like irot suggested, or you can do something simple yourself.
Simple:
Basically, when you click on the image, load in the next one (or have it already loaded). Start an enterframe listener to load it up. Something like:
// we're assuming that "image2" is the second image and it has an alpha
// of 0.0 and visible of false. "image1" is the first image and currently
// on stage
// the on click handler for the image
private function _onImageClick( e:MouseEvent ):void
{
// add a enter frame to the stage - I'm going to assume you
// have access through this.stage
this.stage.addEventListener( Event.ENTER_FRAME, this._onEnterFrame );
// make our second image visible so we can fade it up
this.image2.visible = true;
}
// called every frame
private function _onEnterFrame( e:Event ):void
{
// image2 is the second image
this.image2.alpha += 0.05; // slow fade
if( this.image2.alpha >= 1.0 )
{
this.image2.alpha = 1.0;
// hide the first image
this.image1.alpha = 0.0;
this.image1.visible = false;
// remove the enter frame event listener
this.stage.removeEventListener( Event.ENTER_FRAME, this._onEnterFrame );
}
}
Bit more complicated: Check out the BitmapData class and it's merge() or pixelDisolve() functions: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/BitmapData.html
Are you familiar with any Tween engines? I would recommend TweenLite if you are not.
What I would usually do is load all the images I plan to use and then stack two or more of them where I want them. Only one of these images will be visible at any time (alpha = 1).
On your click handler, you can do one of two things:
Tween the visible image's alpha down to 0, then have an onComplete handler tween your next image's alpha up to 1
Alternatively, you could just have two tweens running at once. One would tween the visible image's alpha down to 0, the other tweening the next image's alpha up to 1
irot