0

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?

Community
  • 1
  • 1
Winnie
  • 25
  • 2

1 Answers1

0

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.

mipa
  • 10,369
  • 2
  • 16
  • 35
  • Thanks for your reply! I suppose this will work, but it's also not really the right way to do this -- if some invents a display like Retina but where the resolution is x3 or x4 instead of x2 then the same problems will appear. There should be a way to do this that will work on any display. – Winnie Dec 31 '16 at 20:32
  • I fear you are waiting for a miracle. There is no better way of dealing with this unless you want to use vector tiles. If memory is not of a concern for you, you could also always use a high-res tile map and scale that down for the current display. That should of course work too. – mipa Dec 31 '16 at 21:02