# Smooth Scrolling Theory

## Recommended Posts

NickyP101    146
Hey all :) Still working on my first game. Getting close to finnished though! Just wondering if someone could help me understand how i can implement smooth scrolling? Im making the game in Java. Currently i draw the tiles viewable on the screen to the BufferedStrategy and show that, the player movies 1 tile at a time. Currently im drawing 16x16 tiles to the screen, for smooth scrolling would i have to draw say 20x20 tiles and then clip the image? I really just dont understand the concept of smooth scrolling. Any help would be greatly appreciated :) Thanks in advance, Nick! [Edited by - NickyP101 on March 29, 2005 3:24:37 AM]

##### Share on other sites
NickyP101    146
Ok after further thinking my first idea wont be good enough (i wont draw the image to a buffered image and then draw that to the BufferedStrategy - Massive performance loss (This was my first mistake i had a FPS of 20 by drawing go the buffered image of 800x800 and then drawing that to the BufferedStragegy, but when i drew the tiles directly to the BufferedStrategy FPS was 100)). I need to clip the neccessary tiles and then draw them to the BufferedStrategy.

I cant get the algoritm around my head, Any help would be awsome!!! Thanks in advance, Nick

##### Share on other sites
Dmytry    1151
1: all performance issues is purely java problem. Normally, you should be able to draw on screen at some hundreds FPS even with software.

2:

Let x,y, is position of 0,0corner of screen on map in pixels (x and y is non-negative), and each tile is L pixels big. Let your screen is MxN tiles big. You need to draw tiles using that:

offset_x=-(x % L);// how much to offset drawing.
offset_y=-(y % L);
for(i=y/L;i<=(y+N)/L +1;++i){// it draws M+1xN+1 tiles . When screen is aligned at tile boundary, it is enough to draw MxN, but if we will handle it specially, that will result in framerate changes.
for(j=x/L;j<=(x+M+L)/L +1;++j){
SetDrawingPositionTo(offset_x+j*L,offset_y+i*L);
DrawTile(map(j,i));
}
}

Assuming tile is drawn in LxL rectangle x,y to x+L-1,y+L-1
This thing draws all visible tiles with apporiate offset. ("DrawTile" must clip out tiles that is partially outside of screen...)

##### Share on other sites
NickyP101    146
Awsome :) Thanks for the help. Can you just help me clear some things up:

1.

SetDrawingPositionTo(offset_x+j*L,offset_y+i*L);
DrawTile(map(j,i));

("DrawTile" must clip out tiles that is partially outside of screen...)

So from that information are you saying that SetDrawingPositionTo will return a negative value in some cases, or a value which is larger than the width and height?

So if the drawing position was -3, 0 i was clip the tile from (3,0 end of tile width,0)

And if the drawing position was larger than the dimentions, say the screen is 800, 800 and the drawing position is 799, 0 then i would clip from (0,0, 1,0)

Am i way of the idea here?

Sorry btw lol usually im a little bit faster than this, this is my first game lol had a big day at school and working on a dead brain :) wont stop me programming though, cant wait till i go to uni :P programming subjects lol

##### Share on other sites
Dmytry    1151
Quote:
 Original post by NickyP101Awsome :) Thanks for the help. Can you just help me clear some things up:1.SetDrawingPositionTo(offset_x+j*L,offset_y+i*L);DrawTile(map(j,i));("DrawTile" must clip out tiles that is partially outside of screen...)So from that information are you saying that SetDrawingPositionTo will return a negative value in some cases, or a value which is larger than the width and height?So if the drawing position was -3, 0 i was clip the tile from (3,0 end of tile width,0)And if the drawing position was larger than the dimentions, say the screen is 800, 800 and the drawing position is 799, 0 then i would clip from (0,0, 1,0)Am i way of the idea here?Sorry btw lol usually im a little bit faster than this, this is my first game lol had a big day at school and working on a dead brain :) wont stop me programming though, cant wait till i go to uni :P programming subjects lol

yes, draw tile must draw tile starting from position that has been set, clipped by border of screen. Drawing position could be negative for border tiles that is partially outside screen.

other than that, there's some typo/bug, sorry. There must be offset_x = -x and offset_y=-y , that's because how i,j iterate....

corrected:
for(i=y/L;i<=(y+N)/L +1;++i){// it draws M+1xN+1 tiles . When screen is aligned at tile boundary, it is enough to draw MxN, but if we will handle it specially, that will result in framerate changes.
for(j=x/L;j<=(x+M)/L +1;++j){
SetDrawingPositionTo(j*L - x, i*L - y);
DrawTile(map(j,i));
}
}

edit: another typo fixed. Lol.

[Edited by - Dmytry on March 30, 2005 3:43:34 AM]

##### Share on other sites
Guest Anonymous Poster
Hey its NickyP101 :)

Thanks for your help, ill try implement that tonight! Nice algorithm too, did you come up with that, or is it a commonly used algorithm?

Anyway thanks again,

Nick

##### Share on other sites
Dmytry    1151
came up with it... not a big thing. It just draws all visible tiles with apporiate offset. (if corner of view is at map location x,y, offset must be -x,-y). Idea is simple, draw all tiles that camera could see , with apporiate offset. (Fixed another minor typo....)

##### Share on other sites
NickyP101    146
Hey champ, ok soo ive done a little bit of work on implementing your algorithm: This is what i have:

        //x = x position of screen on map        //y = y position of screen on map        float L = 50;        float M = 800;        float N = 800;        float offset_x=((float)(x / L * 100));        System.out.println("x = " + x + ". And x &#47; L = " + (float)(x / L) + " and multiply that by 100 = " + (float)(x / L * 100));        System.out.println("OffsetX =  " + offset_x);        float offset_y=((float)(y / L * 100));        System.out.println("y = " + y);        System.out.println("OffsetY =  " + offset_y);        for(float i=y/L;i<=(float)((y+N)/L +1);++i){            for(float j=x/L;j<=(float)((x+M)/L +1);++j){                //SetDrawingPositionTo(j*L - offset_x, i*L - offset_y);                //DrawTile(map(j,i));                                float xDraw =  (float)j*L - offset_x;                float yDraw =  (float)i*L - offset_y;                if(map[Math.round(i)][Math.round(j)] == 0){                        //g2D.drawImage(grass, 0, 0, (int)(50 - xDraw), 0, (int)(-1*xDraw), 0, L, 0, null);                        g2D.drawImage(grass, (int)xDraw, (int)yDraw, null);                }                if(map[Math.round(i)][Math.round(j)] == 1){                    g2D.drawImage(rock, (int)xDraw, (int)yDraw, null);                }                if(map[Math.round(i)][Math.round(j)] == 2){                                        g2D.drawImage(rock, (int)xDraw, (int)yDraw, null);                }                if(map[Math.round(i)][Math.round(j)] == 4){                    g2D.drawImage(water, (int)xDraw, (int)yDraw,  null);                }                        }         }

Ok kinda working, kinda not. Firstly after moving right 3 pixels lines start appearing on the screen, when i have scrolled a tiles width (i think thats the distance) it skips a complete tile, ummm after moving about 3 tiles along the x-axis the rest of the map doesnt fell the end of the screen. So in other words i have ruined your algorithm some how. Please tell me how i could hve possible stuffed this up :( haha last 3 days just havnt been myself, bit of flu going around.