Pixelgaps using scale on a 2D tile grid


#1

Hey guys. I have an annoying issue on my project im working on.
I’m generating a bunch of tiles, just with basic rects at a size of 32x32 pixels and putting them inside an array of arrays.

Like
Array[0][5] would be row 0, and tile 5 on the X-axis. (0,5) X,Y basically.

Every tile gets its own position, first tile got position 0,0, second tile position would be (0,32) (since its 32px wide)

Then I just draw them at 32x32px size using a double for loop looping through the array of array at their own respective position.
Everything works as expected, BUT, the issue arrives when I use p5 scale function.

On default scale, everything looks great, but at some levels of zoom, I get what it seems to be pixelgaps between the tiles.

At original scale https://imgur.com/LQplqkk

At scale 3, calucaled using scale(1/slidervalue) where slider value are just integers from a slider ranging from 1-5.
This is what happens: https://imgur.com/BviNGsb

As you can see the lines/gaps are appearing. They seem to be red, which is the background, so there is a real gap in between the tiles.

My transformation is made like this to follow the player and center it on screen:

    translate(width/2, height/2);
    scale(1/scl);
    translate(-player.position.x, -player.position.y);

Thats the first thing in my draw() loop, just after setting background.
I’m thinking its a AA or smoothing issue? Its weird because if I just add “WEBGL” on the createCanvas, the gaps go away and I can scale however I want. But I do not wish to use WEBGL in createcanvas cause I dont want to deal with third axis.

Example of my mapGenerator (ive removed some code thats not relevant)

    GenerateMap() {
        let map = [];


        for (let y = 0; y < this.mapHeight; y++) {

            map.push(new Array());

            for (let x = 0; x < this.mapWidth; x++) {

                map[y].push(this.GetTile(x * this.tileSize, y * this.tileSize));

            }
        }
        return map;
    }

GetTile just returns a new tile thats sets its x,y from the getTile arguments. Then the tile has their own draw() which renders a rect like this
rect(this.pos.x, this.pos.xy, 32,32)

And for the actual drawing, its just a double for, calling draw on every tile inside the array.

I’ve experimented with scale values, tile sizes and canvas sizes, but I still get this annoying issue. I’ve been fighting with it for three days now and I cant get it to work. Its so annoying as its the only thing hindering me from moving forward with my game.

If you need more details, just ask. I didnt post complete code as im thinking about doing a serious game of it at some point :slight_smile:

Thanks guys! <3


#2

To make it easier for you to help me, I made a simpler down version of it where you can see how my code is setup. Feel free to edit and help me out! <3
https://editor.p5js.org/tony32/sketches/SJEckVFk4


#3

Hi,

I think the reason it happens is because you are applying the scale to each one of your tiles:

scale(1/scl);
  
for(let y = 0; y < mapSizeY; y++){
  for(let x = 0; x < mapSizeX; x++){
    map[y][x].draw();
  }
}

If you do that, it messing up the borders because the math won’t always be perfect.

The idea to solve that would be to separate your logic from the drawing.

  • First you compute all the logic that you need to perform (no scale apply, no translation, just pure basic logic)
  • Then you draw in real size on a canvas and you resize that canvas.

Hope it helps!


#4

Thank you so much. I think I understand the problem now, but I aint sure how to solve it. Do you mean that I should resize the actual canvas? The one you create with createCanvas? I dont want to resize that window if thats what you mean.

I’ve thought of just having a scale variable and then drawing it like originalSize * scale, but thats annoying to apply on all things you got to render.


#5

I’m sorry, I am not using p5.js so I’m not using the right vocabulary. I’m not speaking about canvas but grahics.

You should have a look at this: https://p5js.org/reference/#/p5/createGraphics

Then you can display it the size you want.