I'm working on a minigame that needs a tiled background, tiles that I pick from a png tileSet (16x16 tiles). Even if the tiles are 16x16, they are displayed as 32x32 tiles on the canvas from a spriteSheet (see code below). The issue is it seem that when I enlarge artificially the size of the tile, it takes a tiny part of the tile that is next to it. An image might describe it better than words :
You can see in the water part, there is a pinkish line, that shouldn't be here (I checked that there were no separations on the tileset, and 0,0 is at the right place i believe). I also tried to use the native size of the tiles (16x16 instead of 32x32) for the background, no pink line to be seen and also the grey grid disappeared:
So i guess it comes from the 32x32, but i have no idea how to fix it ... Here is the code i use to load the tileset and display the background :
loadImage('/img/dungeon.png')
.then(image => {
const sprites = new SpriteSheet(image, 16, 16);
sprites.define('stone_floor', 1, 0, 32, 32);
sprites.define('water', 2, 7, 32, 32);
sprites.define('wall_top', 2, 0, 32, 32);
sprites.define('void', 0, 0, 32, 32);
sprites.define('stone_floor&water', 3, 7, 32, 32);
loadLevel('1-2')
.then(level => {
drawBackground(level.background, context, sprites);
})
});
SpriteSheet class :
class SpriteSheet {
constructor(image, width, height, offset = 0){
this.image = image;
this.width = width;
this.height = height;
this.offset = offset;
this.tiles = new Map();
}
define(name, x, y, imgw, imgh){
const buffer = document.createElement('canvas');
buffer.width = imgw;
buffer.height = imgh;
buffer
.getContext('2d')
.drawImage(this.image,
x * this.width + x*this.offset, y * this.height + y*this.offset,
this.width, this.height,
0, 0, imgw, imgh);
this.tiles.set(name, buffer);
}
draw(name, context, x, y){
const buffer = this.tiles.get(name);
context.drawImage(buffer, x, y);
}
drawTile(name, context, x, y){
const buffer = this.tiles.get(name);
context.drawImage(buffer, x * buffer.width, y * buffer.height);
}
}
PS : this project is highly based on MethMethMethod's tutorial : video
ctx.imageSmoothingEnabled = false;
If you wish to keep the filtering then the only option is to increase the tile size to 18 by 18 adding a border around the tile to match the edge colour. You still only render the 16*16 tile but the filtering will sample from the border pixels rather than the neighboring tile – Blindman67