Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (483)
Games in Android Showcase (110)
games submitted by our members
Games in WIP (550)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  What tiles are currently visible in a viewport  (Read 848 times)
0 Members and 1 Guest are viewing this topic.
Offline Mads

JGO Ninja


Medals: 26
Projects: 3
Exp: 6 years


One for all!


« Posted 2012-10-24 20:29:10 »

I've been wrestling with this for a while, and it's really boilerplate code. I found myself writing weird cases for different scenarios with if-statements and it was just a mess, when it really should only be one line of code. I hope one of you can help me, and I think a lot of you have this code lying around somewhere.

What I need is a way to calculate the first visible tile, and the last visible tile on both axises. This is for optimising rendering of my tiled map. I am currently drawing all tiles in the map, when in reality only about 140 can be visible at any given time.
The variables I have access to is the viewport dimensions, tile dimensions and the offset of viewport on the map.

I thank you very much for being such awesome individuals. Smiley

Offline Regenuluz
« Reply #1 - Posted 2012-10-24 20:35:50 »

Well, if you know the width and height of the screen, you can figure out how many tiles on each axis you need.

And if you know the (x,y) position of the player(assuming he's always in the middle), then you can calculate which tile he should be on.

From this you know you have to render all tiles from player_x_tile - x_tiles/2 to player_x_tile + x_tiles/2 in width and it's the same for height.

Though you'll also need to throw in a buffer zone, or else you'll be able to see edges without any tiles rendered.


EDIT:
Actual code I use for this thing.
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
// Tiles on the screen
int tilesAcross = (int) Math.ceil(this.me.getWidth() / MapEditor.TILE_SIZE) + 3;
int tilesDown = (int) Math.ceil(this.me.getHeight() / MapEditor.TILE_SIZE) + 3;

// Tile the player is on
int ptx = this.me.player.x / MapEditor.TILE_SIZE;
int pty = this.me.player.y / MapEditor.TILE_SIZE;

// The offset of the tile
int xOffset = this.me.player.x % MapEditor.TILE_SIZE;
int yOffset = this.me.player.y % MapEditor.TILE_SIZE;


Note the +3 in tilesAcross and tilesDown. That's the buffer to make sure it'll never show any black edges. Smiley
Offline Mads

JGO Ninja


Medals: 26
Projects: 3
Exp: 6 years


One for all!


« Reply #2 - Posted 2012-10-24 20:51:43 »

I sincerely salute you for your post. It's awesome. I'm serious. However, there's one flaw:
I don't have a centered actor in this game Sad

I have very similar code to yours in other prototypes - I think yours is neater though. I'll definitely keep it.  Smiley

Instead of a centralized player in my game, I have the offset at which the map is drawn. This can be both negative and positive, and that makes it hard for me.

Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Regenuluz
« Reply #3 - Posted 2012-10-24 20:57:05 »

Sounds like you can just translate that offset to a position on the map, and then do the same thing. Smiley

I'm not sure why you'd have negative values in the offset though. I'd always just keep the top left point of the map as (0, 0). ^_^
Offline Mads

JGO Ninja


Medals: 26
Projects: 3
Exp: 6 years


One for all!


« Reply #4 - Posted 2012-10-24 21:09:56 »

Sounds like you can just translate that offset to a position on the map, and then do the same thing. Smiley

I'm not sure why you'd have negative values in the offset though. I'd always just keep the top left point of the map as (0, 0). ^_^

Negative offset is when the top-left corner of the map goes off-screen. On a large map, this will happen every time a map bigger than the viewport is displayed.

Offline Regenuluz
« Reply #5 - Posted 2012-10-25 06:22:04 »

Hm, I'm not sure how you handle that.

When my player is located in the top left, he's at (0, 0) and when he moves right it's in a positive direction, same goes for down. This way my location range just goes from x = [0..width_in_pixels], y = [0..height_in_pixels] (width/height being that of the map).

Here's my complete render code, and as you can see, then the "player" is actually just an offset in this case. So if I'd want my player to be able to move independent of the viewport, I'd just keep track of him and my offset, both in the same way as I explained above. Smiley

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
public void render(Graphics2D g) {
   // Tiles on the screen
  int tilesAcross = (int) Math.ceil(this.me.getWidth() / MapEditor.TILE_SIZE) + 3;
   int tilesDown = (int) Math.ceil(this.me.getHeight() / MapEditor.TILE_SIZE) + 3;

   // Tile the player is on
  int ptx = this.me.player.x / MapEditor.TILE_SIZE;
   int pty = this.me.player.y / MapEditor.TILE_SIZE;

   // The offset of the tile
  int xOffset = this.me.player.x % MapEditor.TILE_SIZE;
   int yOffset = this.me.player.y % MapEditor.TILE_SIZE;

   int tilesRendered = 0;

   for (int x = 0; x < tilesAcross; x++) {
      for (int y = 0; y < tilesDown; y++) {
         tilesRendered++;

         int tx = ptx + x - tilesAcross / 2;
         int ty = pty + y - tilesDown / 2;

         int rx = x * MapEditor.TILE_SIZE - (MapEditor.TILE_SIZE + xOffset) - 16;
         int ry = y * MapEditor.TILE_SIZE - (MapEditor.TILE_SIZE + yOffset) - 10;

         if (tx < 0 || tx >= this.me.map.width || ty < 0 || ty >= this.me.map.height) {
            g.setColor(Color.BLACK);
            g.fillRect(rx, ry, MapEditor.TILE_SIZE, MapEditor.TILE_SIZE);
            continue;
         }

         Tile currentTile = this.me.map.getTile(tx, ty);
         g.drawImage(currentTile.getImage(), rx, ry, null);

         drawCorners(rx, ry, currentTile, g);
      }
   }

   // Paint the player
  g.setColor(Color.black);
   g.drawLine(this.me.getWidth() / 2, this.me.getHeight() / 2 - 3, this.me.getWidth() / 2, this.me.getHeight() / 2 + 3);
   g.drawLine(this.me.getWidth() / 2 - 3, this.me.getHeight() / 2, this.me.getWidth() / 2 + 3, this.me.getHeight() / 2);
}


(this.me is a reference to the MapEditor object)

Here's a screenshot of my Map Editor:

The little x in the middle of the water is the "players" location

The map is 100x100 tiles, so 3200x3200 pixels. Smiley

As you can see, there's no negative offsets. ^_^

I hope this helps a little
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

CopyableCougar4 (15 views)
2014-08-22 19:31:30

atombrot (28 views)
2014-08-19 09:29:53

Tekkerue (25 views)
2014-08-16 06:45:27

Tekkerue (23 views)
2014-08-16 06:22:17

Tekkerue (15 views)
2014-08-16 06:20:21

Tekkerue (22 views)
2014-08-16 06:12:11

Rayexar (61 views)
2014-08-11 02:49:23

BurntPizza (39 views)
2014-08-09 21:09:32

BurntPizza (31 views)
2014-08-08 02:01:56

Norakomi (37 views)
2014-08-06 19:49:38
List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06

List of Learning Resources
by SilverTiger
2014-07-31 11:54:12

HotSpot Options
by dleskov
2014-07-08 01:59:08
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!