-
-
Save PrimaryFeather/2422317 to your computer and use it in GitHub Desktop.
package starling.extensions | |
{ | |
import flash.display3D.Context3D; | |
import flash.geom.Point; | |
import flash.geom.Rectangle; | |
import starling.core.RenderSupport; | |
import starling.core.Starling; | |
import starling.display.DisplayObject; | |
import starling.display.Sprite; | |
import starling.errors.MissingContextError; | |
public class ClippedSprite extends Sprite | |
{ | |
private var mClipRect:Rectangle; | |
public override function render(support:RenderSupport, alpha:Number):void | |
{ | |
if (mClipRect == null) super.render(support, alpha); | |
else | |
{ | |
var context:Context3D = Starling.context; | |
if (context == null) throw new MissingContextError(); | |
support.finishQuadBatch(); | |
support.scissorRectangle = mClipRect; | |
super.render(support, alpha); | |
support.finishQuadBatch(); | |
support.scissorRectangle = null; | |
} | |
} | |
public override function hitTest(localPoint:Point, forTouch:Boolean=false):DisplayObject | |
{ | |
// without a clip rect, the sprite should behave just like before | |
if (mClipRect == null) return super.hitTest(localPoint, forTouch); | |
// on a touch test, invisible or untouchable objects cause the test to fail | |
if (forTouch && (!visible || !touchable)) return null; | |
if (mClipRect.containsPoint(localToGlobal(localPoint))) | |
return super.hitTest(localPoint, forTouch); | |
else | |
return null; | |
} | |
public function get clipRect():Rectangle { return mClipRect; } | |
public function set clipRect(value:Rectangle):void | |
{ | |
if (value) | |
{ | |
if (mClipRect == null) mClipRect = value.clone(); | |
else mClipRect.setTo(value.x, value.y, value.width, value.height); | |
} | |
else mClipRect = null; | |
} | |
} | |
} |
Hi felipevex!
Thanks a lot for your error report, and for the nice words about Starling!
You're perfectly right, the class was missing two imports. I've added them right away!
As for the wrong position of the clip rectangle: I agree, this is a little misleading. I wrote it in the description of the extension, but it's easy to miss: the clip rectangle is always given in stage coordinates. That's why they don't react as you expected them to.
The reason I made it that way is the following: you can't rotate the clip rectangle; this is a technical limitation of the "scissor rectangle" I'm using here. I thought that when I put the clip rectangle on the stage, this becomes more obvious (you can't rotate the stage, anyway), and it allows you to move the clipped sprite through a stationary clipping area.
I agree that this is not the most intuitive way, though. In the future, Starling will contain real masks that can be rotated and scaled with their objects. And I will consider changing the implementation of the clipped sprite to work different. In the meantime, you've found a solution for your project, anyway! =)
Thanks again!
Best regards,
Daniel
Hi, Im having an issue with the class.
Currently Im working with 320x480 dimensions, and I've managed so it works on multiple devices just as Sony Ericsson and Galaxy Tab 10.1; I test on my computer 320x480, and then deploy to the Galaxy Tab; the clipRect works fine there on my computer and with the Galaxy Tab, but at the time I tested on the Sony Ericsson (480x854) the mask has a displacement; closer the current mask is to the top left is fine, but from that point, the mask moves a bit proportionally
This is the init code on the Main class
var screenWidth:int;
var screenHeight:int;
screenWidth = stage.fullScreenWidth;
screenHeight = stage.fullScreenHeight;
var viewPort:Rectangle = new Rectangle(0, 0, screenWidth, screenHeight);
_starling = new Starling(Game, stage, viewPort);
_starling.stage.stageWidth = 320;
_starling.stage.stageHeight = 480;
_starling.start();
I have a Sprite Class(Masked) wich inside has both, the ClippedSprite instance (_mask) and the Sprite (_item) to be masked;
then I need 9 instances of Masked, all those inside a class Container, and finally Container is added to the Sprite window inside the main Game class; those 9 items are sorted in a grid, each value of the grid is given manually, and both the _item and _maks use those values;
it sounds a little messed up, but the code works locally and with the Galaxy Tab 10.1.
I don't know if the ratio of 320x480 has been broken, but if it is, the other objects in the game also should be misplaced and it is not the case.
I suspect is something with the scale factor, but my factor is 1, so it should not be broken.
I hope you can take a look, thanks in advance.
Hi Daniel, thanks for your answer.
The clipRect works great now! but i have a new issue, the "touch area" remains misplaced, so again, far from top left the mask is moved, and near is better placed.
Thanks again for your amazing work with the framework.
Ah, damn, I overlooked that! Now that part works, too. I've reduced some code duplication along the way.
Thanks for the compliments! I'm glad that you chose Starling for your project! =)
Best regards,
Daniel
Hi Daniel, thank you so much, the code works perfectly now!
Thanks again for your work
Sebastian
You're welcome! I'm glad to hear it works now! =)
Hello, I'm trying to use this clipped sprite. I added various Movieclip to it, but, whatever values I put to the clipper rectangle, I always see all the animation (even when width and height of the clipper are 1)
Hi - Thanks for this extension. Useful!
Looks like current implementation doesn't support scale -- if you scale the ClippedSprite, the clipping rect doesn't react as you'd expect (it stays the same size). Children sprites of the ClippedSprite, however, scale as you'd expect.
I'm wondering if translating the desired scale to x and y values and then updating the clipRect is ideal, or if perhaps there's a better way like using a matrix or just resetting the cliprect after the scale is complete - even though visually this wouldn't look correct during the scale.
I'll run some tests and will report back when / if I find a path. Thanks.
Daniel,
I see the ClippedSprite hasn't been updated for 7 months. Is it still compatible with latest Starling?
As of Starling 1.4 there is no need for ClippedSprite anymore, as Sprite class features a clipRect parameter that does the same thing. See http://gamua.com/blog/2013/09/starling-14/ for more info.
Hi Daniel! You did an amazing job with Starling. THANK YOU VERY MUCH!
So, I'm not a good english speaker but i will try, ok?
I Think i got a problem some problems with the ClippedSprite:
Example:
var clip:ClippedSprite = new ClippedSprite();
clip.clipRect = new Rectangle(0, 0, 20, 20);
clip.x = 10;
var image:Image = new Image(SOME TEXTURE)
clip.addChild(image);
starling.stage.addChild(clip);
///////
To make things right i add some code at render() function before setScissorRectangle line:
//////
public override function render(support:RenderSupport, alpha:Number):void
{
if (mClipRect == null) super.render(support, alpha);
else
{
var context:Context3D = Starling.context;
if (context == null) throw new MissingContextError();
Thank you again!