Open serbol opened 5 years ago
Try something like this:
function round()
{
viewport.x = Math.round(viewport.x)
viewport.y = Math.round(viewport.y)
viewport.width = Math.round(viewport.width)
viewport.height = Math.round(viewport.height)
}
viewport.on('moved-end', round)
viewport.on('zoomed-end', round)
Works fine on moved-end, but not on zoomed-end. Seems like there is no way to round viewport width or/and height.
Hmmm...I checked the code, and I think the issue is with Math.round and the precision of rounding floating numbers.
If you add a console.log at the start and end of the round() function, you see that Math.round is being called on the width/height. You can find info and workarounds here: https://stackoverflow.com/questions/1458633/how-to-deal-with-floating-point-number-precision-in-javascript
Good luck!
Actually, for me viewport.width === worldWidth? Is that ok? I think this parameter - worldScreenWidth need to be rounded.
Ah, that may be a problem. worldScreenWidth is calculated, not directly set:
get worldScreenWidth
{
return this.screenWidth / this.scale.x
}
You can reverse it and solve for this.scale.x to find the right value to round, but that likely will result in a floating point precision problem. Why does it need to be rounded?
When I render a tiled-map I use container with sprites. One square sprite for each tile. On zoom in or zoom out I always get this net:
That's because of float values for viewport width, height, x, y.
I'm not sure I follow. The viewport is over the entire map. Why would its float value impact the locations of the sprites within containers within the viewport?
Just a thought: have you tried to extrude your sprite textures? I sometimes saw this issue when working with pixel graphics. I fixed it by extruding my textures (there's usually an option in your sspritesheet generator). Extruding pushes the color past the texture's edges so there's an extra pixel to work with when the scale changes.
I had this function to create map:
const createMapSprite = mapData => {
const mapContainer = new PIXI.Container();
const tileSetImage = PIXI.Texture.from('/map/desert.png');
let row, col, sprite, texture;
mapData.layers.forEach(layer => {
if(layer.type == 'tilelayer') {
row = 0;
col = 0;
layer.data.forEach(index => {
if(index > 0) {
texture = new PIXI.Texture(tileSetImage, new PIXI.Rectangle(getSourceX(index), getSourceY(index), mapData.tilewidth, mapData.tileheight));
sprite = new PIXI.Sprite(texture);
sprite.x = col * mapData.tilewidth;
sprite.y = row * mapData.tileheight;
mapContainer.addChild(sprite);
}
col++;
if(col > (mapData.width - 1)) {
col = 0;
row++;
}
});
}
});
return mapContainer;
};
Then I performed:
const mapCanvas = createMapSprite(desertMap);
viewport.addChild(mapCanvas);
I solved this issue by updating this line:
sprite = new PIXI.Sprite(texture); -> sprite = new PIXI.TilingSprited(texture, mapData.tilewidth, mapData.tileheight);
But appeared freezes on move :-(
Ok, anyway, will try to play with sprite parameters.
I need to round x, y, worldScreenWidth and worldScreenHeight value on drag and wheel. Are there any opportunities to perform it?
Currently on zoom end or drag end I get something like this : { height: 646.6777064089624, width: 862.2369418786166, x: 6.126561955558547e-14, y: 6.126561955558547e-14, }
But I want this: { height: 647, width: 862, x: 6, y: 6, }