I've been working on different scrolling algorithms for my JS-based game. My main problem is that I need to draw a huge map and also have it scroll smoothly. I've made a few attempts and while they're efficient (code and framerate wise) they still look jumpy and have to redraw constantly (though not each frame, it's still too much redrawing for my taste).
My latest idea is to implement some kind of 3x3 grid around the camera which will scroll with delay. What do I mean "with delay" ? well, if you have played Diablo II before, try to get a Maphack app and enable the Automap Screen Area feature: You see, Diablo II's map is made through a concept of "rooms" and those adjacent to the player in a specific area (usually screen size) are drawn offscreen to allow the scrolling.
I want to implement that in an orthogonal perspective (this is, 2D zelda-like), just like this:
The blue grid is made out of canvases around my camera's position. I know I can position them with the simple x+(floor(camera.x / tile_size) * tile_size) formula and with some offsets have them move around the camera like this:
THE PROBLEM arises when the drawn offscreen areas must remain in the same position to allow the scrolling. I've made a second image which illustrates this:
Notice how the colored tiles (or offscreen areas of screen size) remain in the same position UNTIL they get "too far" from the camera (the red dot). HOWEVER, while they have the same position, notice the Tile # (below each blue grid tile) change. I can't do it that way because it would require to redraw, and my goal is to avoid such redraw if the position hasn't changed.
This means however, that, taking in example blue tile 6 (located at 0,1 at the first animation frame) it changes to tile 5 and then to tile 1. While this is true, the idea is to keep it at tile 6, and only re-use the farthest canvases in the closest ones that need to be redrawn.
I'm illustrating my problem this way because my previous question didn't even get a single comment ( https://stackoverflow.com/questions/22185858/infinite-scroll-a-canvas-with-a-tiled-map-without-redrawing/22277681 ) so I had to work and answer my own question... something that doesn't even help either because someone else might have had a better idea, but nobody did, it seems.
That's why I'm asing here in gamedev, maybe here are some more skilled people who can have an idea or a shot at what I'm attempting to do. Also, please, I'm not interested in using other game or JS engines. If I were I wouldn't be asking this here as I know they implement tile scrolling and such, but this is both for my own learning and for creating a custom engine suited for my own game's needs.
Any help then, is really welcome.
Thanks in advance! - DARKGuy
EDIT: Well alright, after struggling for like 2 days straight on this issue I finally managed to do it. I didn't want to do it with this kind of coords, so I wonder is there any way to optimize this code or to avoid it to do those increments and instead use a formula that would absolutely position them?
Here's the code I'm using (cv = canvas, cx = context("2d"), grid = 3x3 array of canvases. Also, I'm using a 32x32 "grid" just to see how it works. The size should be screen size (or region size, in my engine's case)):
for(ix = 0; ix < grid.length; ix++)
for(iy = 0; iy < grid.length; iy++) {
cv = grid[iy][ix];
if(cam.x - cv.x > 48)
cv.x += 32 * 3;
if(cam.x - cv.x < -48)
cv.x -= 32 * 3;
if(cam.y - cv.y > 48)
cv.y += 32 * 3;
if(cam.y - cv.y <- 48)
cv.y -= 32 * 3;
cx.fillStyle = cv.color;
cx.fillRect(cv.x, cv.y, 32, 32);
}