Jump to content
This forum will be closing down. Please move to the respective dedicated project forums.

Potential sprite cross-browser rendering bug when using graphic objects


thatguychrisw
 Share

Recommended Posts

I think I may have stumbled across a rendering bug that occurs when graphic objects are added as children to sprite objects.  

This code:

let graphics = this.game.add.graphics();
graphics.lineStyle(2, 0x0000FF, 1); 
graphics.drawRect(0, 0, 32, 32); 

let sprite = this.game.add.sprite(center.x, center.y); 
sprite.addChild(graphics); 

this.game.add.existing(sprite);


Results in different dimensions for the sprite in (Safari / Firefox) and Chrome.  Chrome reports the sprite's dimensions relative to the graphic object (32x32), however Safari and Firefox both incorrectly render the sprite's dimensions as (1x1) from a call to this.game.debug.spriteInfo().

It causes my tetris pieces to render differently in both browsers.  In Safari / Firefox, I am forced to set the rectangle to the dimensions of (1x1) and use the sprite's width and height properties to set the dimensions correctly.  However, this breaks the sprite in Chrome.

EDIT:

It appears the offender is this property: "sprite.texture.frame.width".  In Safari it's 1 and in Chrome it's 32.

 

Link to comment
Share on other sites

That's odd, `sprite.width` shouldn't depend on any child objects. It should come from the __default texture (which happens to be 32 × 32 also).

Did you use `generateTexture()`?

What are the sprite dimensions if you remove

sprite.addChild(graphics);

?

Link to comment
Share on other sites

I've tried that using the following:

let graphics = this.game.add.graphics();
graphics.lineStyle(2, 0x0000FF, 1);
graphics.drawRect(0, 0, 30, 30);

let texture = graphics.generateTexture();
let sprite = this.game.add.sprite(center.x, center.y, texture);
        
this.game.add.existing(sprite);


This should produce a sprite with a dimension of (32x32) (due to the line style adding two pixels).  This does produce the desired sprite result, but for some reason the graphic is being drawn to the screen twice.  Once at the position defined in "drawRect", and another in the sprite call. (see attached screenshot).

I appreciate your feedback, would love to get to the bottom of this.  It's more about discovering why the texture dimensions aren't updating at this point for me, rather than trying to practically apply it.  

I've recently learned that dynamically creating a bitmapdata spritesheet is more efficient than re-drawing graphic objects.

Screen Shot 2017-01-22 at 9.49.56 AM.png

Link to comment
Share on other sites

The sprite with no key assigned should always be 32×32 (the size of the __default texture) whether it has children or not, unless you change its size or scale. I ran the example and I get 32×32 (correct) not 1×1:

I'd expected that the Graphics child would influence sprite.getBounds().width, but that doesn't seem to be the case.

If you instead use graphics.generateTexture() as the sprite's key, then sprite.width should reflect the graphic's width.

Link to comment
Share on other sites

It could be.  I had that issue with Firefox, I had to refresh the page to get the correct dimensions and artwork to show up.  From Safari's point of view, it appears broken on the initial load though however.  

Does the graphic draw commands return BitmapData?  Also, how is it possible that the squares are being rendered twice in my example?

Link to comment
Share on other sites

The problem is with the __default texture itself. I think it's because the default texture and BitmapData#generateTexture() both create images via Data URIs, and Chrome loads these synchronously and Firefox/Safari load them synchronously (like regular images) and then cache them. I don't know if Graphics#generateTexture() has the same problem.

19 hours ago, thatguychrisw said:

Also, how is it possible that the squares are being rendered twice in my example?

The first is the original Graphics object, which is still in-world, and the second is the sprite using the generated texture. Switch to

let graphics = this.game.make.graphics();

 

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...