Target flash - problem with mask

Hi,
Im using mask to cut some part of image, on neko it’s working great. but on flash it’s like on this image:

this is my function that generate mask:

private function generate_mask():Sprite{

	var mask:Sprite = new Sprite();
	mask.graphics.clear();
	mask.graphics.lineStyle(2, 0x000000, 0x000000, false);
	mask.graphics.beginFill(0x000000, 1);
	var p0:Point = this._hex.hex_corner(0);
	var p1:Point ;
	this.graphics.moveTo(p0.x, p0.y);
	for(i in 1...6){
		p1 = this._hex.hex_corner(i);
		mask.graphics.lineTo(p1.x,p1.y);
	}
	mask.graphics.lineTo(p0.x, p0.y);
	return mask;
}

and I use it like this:

var bmp_sprite = new Sprite();
	bmp_sprite.addChild(this._bmp);
	var mask_ = generate_mask();
	bmp_sprite.mask = mask_;
	addChild(bmp_sprite);
	bmp_sprite.addChild(mask_);

this_bmp is Bitmap object passed to this class.

so - what is wrong? it’s great on neko but in flash its look just ugly :smile:
please help

I don’t know if this has anything to do with your problem, but why has your hexagon got 7 vertices instead of 6?

he’s not :smile:

first move cursor to first point:

 this.graphics.moveTo(p0.x, p0.y);

than i draw lines to 5 points:

for(i in 1...6){
		p1 = this._hex.hex_corner(i);
		mask.graphics.lineTo(p1.x,p1.y);
	}

and than back to first point:

mask.graphics.lineTo(p0.x, p0.y);

probably You thing of this loop 1…6 ?
just try:
haxe example

You’re not selling this to me :smile:

p0 is this._hex.hex_corner(0); (note the index is 0)
p1 loops through the indexes 1…6

Thus he’s moving to 0 then drawing a line to index 1 (and I suppose lineTo also moves the pointer to the position he’s drawn the line to) and so on for index 2, 3, 4, 5 and 6.

I guess index 0 and 6 have the exact same position. Or at least they should :smile:

Here’s a sketch of what I mean (sorry for being so bad at sketching stuff)

nope :smile:

there are no such thing as index 6 - as You suggested.
first part is correct, moveto 0.
than loop (lineto) move to 1,2,3,4,5 and that’s it!
than after loop I draw another line from 5 to 0 :smile:

for(i in 1…6) mean 1,2,3,4,5 not 1,2,3,4,5,6 as You suggested.

Damn me! :smile: You’re right and I should file a petition to make that “for” loop behave like it’s written :wink:

What I read is: for all the values of i included in 1 through 6

That syntax is deceiving, thanks for pointing it out!
You can tell that I never use it :stuck_out_tongue:

for me it’s intuitive, same as in python:

In [2]: range(1,6)
Out[2]: [1, 2, 3, 4, 5]

Does it look right if you add your shape to the display list instead of using it as a mask? I assume it does, but just to check

Yes it’s looks ok, also as I mentioned before - on neko it looks ok:

i also tried:

  • setting mask.cacheAsBitmap = true;
  • adding mask to masked sprite (as child) or to stage

effect is stil the same.

this is how it looks when I add only mask to stage instead of using it as a mask and not adding masked sprite to stage:

so I checked points that i’m drawing lines to, in neko:

TokenUI.hx:91: 57.3205080756888,40
TokenUI.hx:96: 37.3205080756888,74.6410161513775
TokenUI.hx:96: -2.67949192431122,74.6410161513776
TokenUI.hx:96: -22.6794919243112,40
TokenUI.hx:96: -2.67949192431125,5.35898384862247
TokenUI.hx:96: 37.3205080756888,5.35898384862246
and flash:
TokenUI.hx:91: 57.32050807568877,40
TokenUI.hx:96: 37.32050807568878,74.64101615137754
TokenUI.hx:96: -2.679491924311222,74.64101615137756
TokenUI.hx:96: -22.67949192431123,40.00000000000001
TokenUI.hx:96: -2.6794919243112467,5.358983848622465
TokenUI.hx:96: 37.32050807568878,5.358983848622458

so it should work, right?

but it’s not…

Perhaps it might work differently if you start at a different point, or go counter-clockwise instead of clockwise? We don’t have any control over Flash Player, so it might be worth trying a couple alternative paths to draw

So you are sure your mask render as a black filled hexagone on flash? Strange because I use mask (with different shapes like stars, circles…) on flash target without issue. Your problem looks like more like a filling shape bug to me.
Anyway, you shoud probably add mask.graphics.endFill(); before returning your mask just to be sure flash do not take the first 3 points he found as first shape to fill… (But if you checked your mask sprite correctly display as a full black hexagone, this is not the issue)
Also, Did you try to have a png hexagonal mask as asset and to apply it to your bmp_sprite (rather than doing your mask on the fly). Just to be sure that the issue is with the masking function and not with the function generating the mask…?

Yes, You are right Thomas, this is not masking problem, I added endFill but it don’t change anything.

singmajesty - so i did, this is different but still wrong:

    this.graphics.moveTo(p0.x, p0.y);
	var r = [5,4,3,2,1];
	for(i in r){
		p1 = this._hex.hex_corner(i);
		mask.graphics.lineTo(p1.x,p1.y);
	}
	mask.graphics.lineTo(p0.x, p0.y);
	mask.graphics.endFill();

Looks like a flash.bitmapdata.fill issue…
To circumvent the problem, If suggest you to use a png picture of a black hexagon as an asset and to scale, translate it if needed to create your mask rather than trying to create the shape on the fly…

Else, you could try to directly use a bitmapdata from a shape as a mask (this is the method I use when I want to create my own mask on the fly rather than having a png mask as embeded asset)

var data:BitmapData = new BitmapData(width, height, true, 0x0);
var hs:Shape = new Shape();
var g:Graphics = hs.graphics;
g.beginFill(0x000000);
var p0:Point = this._hex.hex_corner(0);
	var p1:Point ;
	g.moveTo(p0.x, p0.y);
	for(i in 1...6){
		p1 = this._hex.hex_corner(i);
		g.lineTo(p1.x,p1.y);
	}
	g.lineTo(p0.x, p0.y);
g.endFill();
data.draw(hs);

maybe using a Shape would fix your issue…

Two more ideas

Try different starting points (it may prefer one over another)

Or on Flash, make it out of two shapes, cut it in half, draw the top, then bottom

I just don’t get it. I have other sprite with method like this (for generating hexes for map):

private function generateShape(color:Int, bgcolor:Int, border:Float = .2):Void{
		this.graphics.clear();
		this.graphics.lineStyle(2, color, border, false);
		this.graphics.beginFill(bgcolor, .2);
		var p0:Point = this._hex.hex_corner(0);
		var p1:Point ;
		this.graphics.moveTo(p0.x, p0.y);
		for(i in 1...6){
			p1 = this._hex.hex_corner(i);
			this.graphics.lineTo(p1.x,p1.y);
		}
		this.graphics.lineTo(p0.x, p0.y);
		this.graphics.endFill();
	} 

and it’s working great on flash. it’s basicly the same code…so why?

So you tested this function with a non transparent bgcolor (not 0x00… or 0) and it works?
If yes, why not just reuse this fucntion for your mask whith a black color and bgcolor ?

it’s basicly the same function (copy&paste) but it generating new sprite instead of drawing on existing one (using “this”)

Well I don’t really know. Use this function with a black background color just to be sure it works as expected (because in the picture you pasted, you use a texture as background of you map hexagones so we can’t see the background to check the filling is working as expected…)

Anyway, in your first function change

mask.graphics.lineStyle(2, 0x000000, 0x000000, false);

to

mask.graphics.lineStyle(2, 0x000000, 0, false);

it should have no incidence but you are using an UInt rather than a Float as alpha value :wink:

i changed code before to:
mask.graphics.lineStyle(2, 0x000000, 0x000000, false);
mask.graphics.beginFill(0xff0000);
without texture, results are on images with red hexagons.