Flash CS5...elements are snapping to pixels while moving? - actionscript-3

I have an imported png in a 'info_icon' symbol.
I have another imported png in a 'info_content' symbol.
I have some code that allows you to drag an instance of a 'map' symbol around. Inside this map symbol are instances of 'info_icon' and 'info_content'.
When I drag the map slowly, I can see the info_icon instances and info_content instances, jiggle ever so slightly...I think to line up to pixels.
I'm trying to figure out how to stop that. I'm looking at the pixelSnapping property and it doesn't seem to be helping...perhaps I'm using it wrong.
info_button_mc.pixelSnapping = PixelSnapping.NEVER;

Make sure to set smoothing to true on the bitmap.
Try setting scaleX to 0.999 or something like that (in other words, close enough to 1 that you can't tell it's being scaled).
For some reason smoothing doesn't seem to actually get applied unless the scale of the object is something other than 1.
Remember you should be working with bitmaps here, so make sure to export the PNG for ActionScript (right click on PNG->properties) and give it a class name and then:
var bitmap : Bitmap = new Bitmap(new YourPNG(), PixelSnapping.NEVER);
addChild(bitmap);
bitmap.smoothing = true;
bitmap.scaleX = 0.999;

Is info_button_mc a MovieClip or a Bitmap? In addition to what Pixel Elephant suggested, make sure the cacheAsBitmap property is false on the bitmap and its container (if the container is involved with the bitmap's movement). CacheAsBitmap will always pixel snap and it's worth noting that any filters you may have active automatically set cacheAsBitmap to true.

Instead of setting the scale to 0.999 which will result in a blurry image, try rendering your image at double resolution (as in the source image: png, bitmap, whatever - make it twice as big in each dimension as what you actually want in the swf) and then setting the scale to .5. In my experience, this is the best of both worlds. That said, it still may not be perfect enough for text - but it is substantially better quality than setting the scale to 0.999.

Related

As3 change object width/height, then set new size scale as 1

I have an object manipulation function that(right now) manipulates the scale of the objects inside of an array to give real-time size changes in relation with each other.
What I would like to know is if there's a way to change an object's width/height(to fit the screen size since it's a mobile app) and then reset the scale so that the new width/height has a scaleX/scaleY value of 1.
The width/height are properties that directly influence the scale of a DisplayObject. You cannot resize it without affecting the scale.
You can however:
Draw the image as bitmap
Redraw it if it's a primitive
Put it in a holder
A little about every solution:
Drawing a DisplayObject (or any IBitmapDrawable) is done through creating a BitmapData and using a draw() call. The up-side is that it will be a bitmap and thus save some rendering time. The downside is that if it's a large image it will take memory (can be critical for mobile) and it won't have interactivity/animation unless you make a script that would read the animation.
If you're drawing the element though the Graphics class's API, you might just make something like a resize() method that you would call on window resize/flip-orientation. Just utilise the clear() method of the Graphics object and redraw the whole thing.
Lastly, probably your best pick. Resize your object. Make a new Sprite (I choose Sprite because it's interactive and you probably want that) and add the resized object to that newly made sprite while the Sprite is just added to the display list like you added the resized object before. If it's hard to understand, here's some code:
myResizeableObject.width = newWidth;
myResizeableObject.scaleY = newScaleY;
var holderSprite:Sprite = new Sprite();
myResizeableObject.parent.addChild(holderSprite); // if you don't have a specific place to add the myResizeableObject, don't use myResizeableObject.parent - it's ugly
holderSprite.addChild(myResizeableObject);
Hope that helps you!

hitTestPoint with 'shapeFlag=true' doesn't work in AS3

I simply added a sprite in AS3:
Sprite myspr = new Sprite();
myspr.addChild(mybitmap);
addChild(myspr);
Then I added an event. I did hitTestPoint for checking mouse is over my sprite or not.
stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseCheck);
private function mouseCheck(evt:MouseEvent):void {
var xx:int = stage.mouseX;
var yy:int = stage.mouseY;
if(myspr.hitTestPoint(xx, yy, true)) {
...
// I'm checking mouse over here.
}
evt.updateAfterEvent();
}
Problem is: hitTestPoint gives true when mouse comes to full boundary box. But it should give true only if mouse comes on transparent isometric sprite.
Is there a solution for this, thanks in advance.
this should help. You need pixel perfect detection.
Actionscript 3 pixel perfect collision. How to? (learning purposes)
http://www.freeactionscript.com/2011/08/as3-pixel-perfect-collision-detection/
http://www.anotherearlymorning.com/2009/07/pixel-perfect-collision-detection-in-actionscript-3/
http://old.troygilbert.com/2009/08/pixel-perfect-collision-detection-revisited/
There's a few ways I usually do hit testing.
1) The easiest way is to use a an already made class that you can find online. Some people much smarter than me have created complex classes that allow for much better pixel to pixel interaction. The ones listed by Paras are all good. The problem with these is, for newer users, it can be hard to understand all the code and how to implement them. Usually it is simple once you understand what is going on though. You just replace your hit test with the class file and then enter in the correct arguments.
2) Another method is to actually go into the symbol, create a new layer, and then draw a rectangle(just turn the alpha down to 0%) where you want the hit test to work. This may seem like a stupid method, after all we are just confined to a square once again. BUT, it will actually work MUCH better than you'd expect. Just draw the square maybe slightly smaller than the height and width of your character you're detecting the hit test on, and you should be good to go. Give it an instance name (the hit square that is) and then just perform the hitTest with that square instead of the actual sprite. It works wonderfully and is a very simple solution. For what you're explaining though, this sounds like it might not work. This method is more from a gamer standpoint. It looks good when attacking and getting hit by enemies, but isn't necessarily exact. Also, if you want to do this with two characters (maybe a large attack hitting an enemy) simply draw a hit box for both sprites. This is probably a little more basic than using a pre-made pixel perfect hit detection test, but it works extremely well and takes only a few minutes.

Speeding up masks AS3

I'm currently doing the following when applying a mask to a MovieClip:
mc1.cacheAsBitmap = true;
_mask.cacheAsBitmap = true;
mc1.mask = _mask;
Which works great, however...
mc1 is a complex vector animation, and cacheing it as a bitmap in order to mask it has pretty big memory implications from what I can see, and have read.
Is their another way to implement masks? Or a way to optimise the usual solution?
Thanks
edit
Both the mask and mc1 are MovieClips, and they have been added to the stage, the mask is a gradient.
I am using Flash CS6, both movieclip and mask are added to the timeline, where they are being animated
You can use http://www.greensock.com/blitmask/
Quote from the documentation:
Can’t I just set the target DisplayObject’s cacheAsBitmap property to true and get the same result? Why use BlitMask?
If you set a DisplayObject’s cacheAsBitmap property to true, Flash takes a bitmap capture of that object so that when you move it (only
altering the x and/or y properties), the text and vectors don’t need
to be re-rasterized again before being rendered to the screen.
However, Flash would still need to concern itself with extra pixels on
every frame if you’re masking them to only show a small portion of the
area. BlitMask, however, only cares about that smaller masked area
(after the initial capture of course) which alleviates Flash from
having to even think about the extra pixels.

AS3 Animation with Bitmaps

I'm doing an animation class in ActionScript 3 and would like to know the most efficient way to do it.
Currently what I do is get an image (sprite sheet) and keep all the frames in an array of Bitmaps, then add each frame as a child and I put setVisible = false except the frame I have to show.
The other way I can think of is to have only one Bitmap added as a child and every time frame has to be changed, I copy the pixels to the Bitmap using copyPixels function.
There is somewhat more efficient than either of these alternatives?
Thanks
Keep all your frames in a vector of BitmapData. Then use a single Bitmap and change it's bitmapData property when you want to change frames.
Copypixels is quite fast.
There's an excellent comparison of rendering methods here at 8bitrocket.com; I would suggest giving it a read.

slightly blurred text and bitmaps AFTER 3d transformation

I have a series of movieclips containing both bitmaps and text.
After applying some 3d transformations and moving in 3d space, my text and bitmaps are slightly blurred. This is AFTER I reset all the 3d coordinates (ie z=0, rotationX=0, rotationY=0)
Has anyone else encountered this? Is there a solution to get my crisp text and bitmaps back?
this is a very interesting error.
the blur that appears is actually improper anti-aliasing, or smoothing that is usually solved by rendering the font with fine colors along the edges. in this case, it is in fact caused by 3D transformations and can be solved by nullifying the matrix3D after the animation:
myTextContainer.transform.matrix3D = null;
you could also write:
myTextContainer.transform.matrix = new Matrix();
but with this approach you'll have to import flash.geom.Matrix.
both options will also reset to zero the x and y coordinates, and possibly other important settings of the animated display object, so you'll also have to assign those values to variables and reapply them after nullifying the transform matrix.
it seems that once a font is transformed, it loses this fine color tinting. non transformed fonts have these color details while transformed fonts become completely desaturated.
attached is a zoomed in detail of 12 point font which exhibits this loss of color detail. the top string has no 3D transformation while the bottom string was animated onto the stage via rotationY.
here is the same image saturated to 90% to show the colors more clearly:
these color details are easier to see on grey text.
i believe this error has been present since Flash Player 9 / AVM2 was first introduced. additionally, the fine color detail around the properly rendered font was much more saturated in early versions of the Flash player, which, in my opinion, made the fonts look much better - although the difference could be considered negligible by non perfectionists unlike myself.
You need to make sure you set the matrix3D property to null on any objects that you've applied 3D transformation to.
Looking up another post on 3d issues and came across the solution.
You need to remove all 3d transformations by applying a new transfrom.matrix
var tempMatrix:Matrix = new Matrix();
this.transform.matrix = tempMatrix;
An Even better answer is to use this fix. It's one I used to use all the time.
/**
* Fixes the slight distortion that occurs when an object has a 3D transform associated with it.
* #param di:DisplayObject The DisplayOjbect to fix.
*/
public function fix3DBlur(di:DisplayObject):void {
di.scaleX = di.width / (di.width - 1);
di.scaleY = di.height / (di.height - 1);
}
This function sets a slightly offset scaleX and scaleY. It seems weird, but they when you make 3d adjustments to the object using any 3d property it keep it from looking blurry. You can always remove the 3DTransform, but sometimes you need it to stay in place.
I place this function on a Utilities3D class I have.