# Provide A Scrolling “Camera” View Over A 2D Game Map

I'm in the process of attempting to create a 2D MMO type game with Kryonet and some basic sprites, mostly for my own learning. I have the back end set up great (By my standards) and I'm moving on to actually getting some things drawn onto the map.

I cannot for the life of me figure out a solid way to have a "Camera" follow a player around a large area. The view pane for the game is 640 x 480 pixels, and each tile is 32x32 pixels (Thats 20 tiles wide and 15 high for the viewpane)

I have tried a couple things to do this, but they did not seem to work out so well. I had a JScrollPane with 9 "Viewpane"-sized canvases in it, and tried to have the JScrollPane move in accordance with the player. The issue came when I reached the end of the JScrollPane. I tried to "Flip" canvases, sending the canvas currrently drawing the player to the middle of the 9 and load the corresponding maps onto the other ones. It was slow and worked poorly.

I'm looking for any advice or previous experience with this; any ideas?

Thank you!

Edit and Clarification: I did not mean to mention Kryonet, I was merely providing peripheral information in case there was something that would help which I could not foresee.

Instead of having an array of 9 canvases, why not just have one large canvas loading a large map every once in a while? I'm willing to have "load times" where as with the canvas array I would have none (in theory) to give the user a smooth experience.

I could just change the size and location of the map with a modified setBounds() call on the canvas in a layered pane (layered because I have hidden swing items, like inventories and stuff)

I'll try it out and post here how it goes for people asking the same question.

• I'm not sure what benefits a JScrollPane lends to the type of project you're talking about. Perhaps you could elaborate further? – user15573 Apr 21 '12 at 7:43
• A ScrollPane allows for me to have a literal "Camera" in the sense that I'm drawing the world on objects inside the scroll pane, and then I only have to move to pane in order to see the world. Edit: It was an easier way for me to visualize and think about displaying the world to the player. I realize I could have simply used a canvas and loaded tiles into memory and drawn them as the need arose, however that was no fun. :) – SeaShepard Apr 21 '12 at 15:23

I had this exact same scroll pane problem in an early prototype of a 2D platform game.

My setup was:

• JFrame, containing
• JScrollPane, containing
• JPanel (<- this is where I draw my level)

The frame has a fixed size (800x600, or whatever), likewise with the scroll pane. The JPanel has a size == the size of the level.

To scroll, don't mess with scroll pane movement; as you've noticed, it's jumpy and looks really bad (double buffering--or lack thereof--has nothing to do with it). Instead, when you render your JPanel, use Graphics.translate (http://docs.oracle.com/javase/6/docs/api/java/awt/Graphics.html#translate(int, int)) to shift the origin of your coordinates. You'll have to calculate the exact x and y translate values based on the movement of the player in relation to the level (taking into account the edges of the level, of course).

In summary:

Your initial intuition makes sense: when the player moves, move the view of the scroll pane around the level. This is what we generally expected from most programs we use that have some scrolling functionality. However, the better (and smoother) solution is the opposite: move the level, not the view.

To put it another way: If your player moves to the right, don't scroll to the right--just move the level to the left. Think about it that way.

I can't help with Kryonet-related stuff, but as far as I know Kryonet just handles the networking so you are on your own for the game-enine part, right? Also your question doesn't seem Kryonet-specific.

You're talking about a JScrollPane and canvas, I'm assuming you got a canvas inside a Frame window of some sort and that you can do pretty much what you want with those.

On the canvas you render the tiles to compose the whole map (or maybe render them all to a single macro-texture and store it to have less rendering calls).

To begin with you would need a timer to get time-based input (including scrolling). You could also want the amount of scrolling be related to the speed of the character being followed.

An easy way to get the scrolling done (and the character movement) is to store the character's logical position on the server-side and let every player see his own character graphic surrounding.

That means that only the coordinates of the characters on the server will change. On the client, it's the map the moves around.

After getting the input to start the scrolling and the direction to scroll (2D game, so N/S/W/E), just translate all the tiles (or the macro texture) in the opposite direction, where the time-slice received from a timer defines how much to scroll.

After that, update the logical position of the character on the server, and that's basically done.

Since you are also saying that it's slow (client-side I guess), you should create as many textures as possibile before starting the actual playing.

Also, as the character moves around, you could try to create a 'buffer' of tiles on the client, preloading some extra tiles to cover a wider area around the character as it moves around and discarding (only if needed to free some memory) the ones that become too far to be useful.

That way you will alsway have a 'safe area' to move inside without needing any new loading. Also reusing the same textures in patterns is a good thing to do.

That should cover the map scrolling in a basic way.

• Thank you, however I had all of that done already (I apologize, that wasn't clear). For whatever reason the drawing was slow and "flickery" whenever the scrollpane moved. I buffered, double buffered triple buffered and uber buffered to no avail. I'm trying a different strategy; I posted it in the main question. Thank you for your answer though! – SeaShepard Apr 21 '12 at 6:42