How to properly draw from a tile set onto a JavaFX Canvas, taking into account Retina (and similar) displays?

985 views Asked by At

I'm making a simple tile-based game in JavaFX. The tiles are 32x32 pixels, and the various tiles are laid out in a grid in the tile sheet image (which is loaded in memory as a JavaFX Image object). I'm drawing the map on a JavaFX Canvas object, and to draw a tile I use the GraphicsContext.drawImage method, specifying a source 32x32 region in the tile sheet Image and a destination 32x32 region on the Canvas. This is all very standard looking.

Unfortunately, this produces incorrect results on my Mac, due to the Retina screen. It seems that JavaFX is doing some transformations to the image to display it at the "correct" resolution. I don't necessarily have a problem with this; however, in doing this transformation, it is sampling from the wrong pixels in the source image. For example, if I draw the first tile, which occupies the pixels in the first 32 rows and columns of the tile set image, JavaFX will actually sample the pixels in row and columns 33 in whatever transformation it does. So, for instance, my first tile is ocean (and mostly blue) and my second tile is desert (and mostly yellow), but all ocean tiles are drawn with a yellow strip on their right side since JavaFX is sampling from the desert tile to draw the ocean. (This yellow is also not the yellow in the source image: it's been blended with the blue somewhat.)

I know two methods to deal with this issue:

  1. Manually render images, using PixelReader and PixelWriter (see here). This is definitely not the right way to do things!

  2. Put each tile into its own Image object. This is a possible solution, but a little annoying when there are hundreds of tiles to keep track of.

So, my question is: what's the correct way to do this? That is, if one has a bitmapped image, how can one draw some region of it onto a JavaFX GrahpicsContext so that only the pixels in that region affect what is drawn?

1

There are 1 answers

2
mipa On

Actually the answer I gave in the link you cited above contains all the information that you need. I do not want to repeat myself but the best thing you could probably do is to provide your map at a higher resolution so that you have 64x64 tiles which you can draw on a 32x32 canvas region.