Monday, August 6, 2018

java - 2d very large tile based game, zoom and pan considerations


what's a sensible way of implementing zoom and panning for my game?


each tile is very large, 100,000 x 100,000 pixels, with some objects possibly being only a single pixel at maximum zoom (small objects in a vast vast space).


I want to be able to zoom out so the view encompasses the entire chunk/tile, possibly two chunks if objects are near the border, I also want to replace the image used for the objects with an icon past a certain level of zoom.



I'd like to have this drawn on a jpanel in an applet with a swing based ui. graphically I was aiming to keep it simple and just use graphics2d functions. should I be looking at using LWJGL or is this overkill.


I realise these sorts of questions get asked a lot, but I'm concerned there are special considerations for having such large tiles.


Thanks



Answer



Tiles are a way to stretch large or repeatable data from a massive file onto a display. The only reason to use tiles is to increase that efficiency.


Solution A:


Make your original tiles far smaller, and use a simple tile only to outside screen boundaries system. Although I have a fairly good idea what you're trying to do, and this won't work.


Solution B:


Every X interpolation. Let's assume we have enough memory to store 4 notice I didn't say 2, when the user is in a corner of one tile, you will need to render 4 tiles. (1) the tile the user is in then the (3) possible tiles that could be moved to in one screen.


Now let's pretend we are maximum possible zoom on one tile, we are so close that one pixel on the tile = one pixel on the screen.



int ScreenPositionX = -1;
int ScreenPositionY = -1;
for(int X = TopLeftPixel.X; X < BottomRightPixel.X; X++)
{
ScreenPositionX++;

for(int Y = TopLeftPixel.Y; Y < BottomRightPixel.Y; Y++)
{
ScreenPositionY++;
PutPixelOnScreen[ScreenPositionX, ScreenPositionY] = GetPixelFromMemory[X, Y]

}
}

So we keep track of which pixel we are putting on screen (blitting) and the location we are at in the texture. We start the for loops at the top left pixel of the texture to be drawn, and we iterate through to the last (bottomright) pixel of the texture to be drawn.


But once the user zooms out to a ratio of say 10 pixels on the tile = 1 pixel on the screen, we need to handle what should and shouldn't be drawn. The easiest method is to simply skip pixels: (assuming you can find the topLeft and bottomRight * scale pixels)


int ScreenPositionX = -1;
int ScreenPositionY = -1;
int SkipTen = 10; //This is our scale value, 10 on texture = 1 on screen
for(int X = TopLeftPixel.X; X < BottomRightPixel.X; X += SkipTen)
{

ScreenPositionX++;
for(int Y = TopLeftPixel.Y; Y < BottomRightPixel.Y; Y += SkipTen)
{
ScreenPositionY++;
PutPixelOnScreen[ScreenPositionX, ScreenPositionY] = GetPixelFromMemory[X, Y]
}
}

That's the simplest way, and has little overhead. You complicate things more if some pixels should be represented always over others. Say in a 10 pixel space you have one black pixel, the rest white. You could choose of the 10 pixels which has the highest count and represent the pixel as that color, but then we lose our black pixel. So we can instead check if there is a black pixel in those 10, to always draw black. You can complicate things more by converting this into a symbol on screen after a certain zoom ratio has been reached. Keep in mind this kind of a realtime system starts to slow down quite quickly if you throw in averaging, weighted systems for every pixel to be drawn. Ideally the textures should be prerendered to depth, or if this is a gargantuan system like google maps, you could render on demand and save renders.


Also sorry this isn't in java, it's not my language, but the concepts are all there. I can clear up anything just comment questions.



No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...