2
\$\begingroup\$

I have currently a pygame program that stores tiles in a 2d list like

[[1,1,1]
 [1,1,1]
 [1,1,1]]

where the 1 is a tile object. I have the character centered in the middle of the screen, and I am trying to find the best way to make it so the 'camera' scrolls along with the character. I suppose I could have it so that it only draws the tiles that are in the current window range, but I feel like this will cause problems later. My goal is to have the an entire map, say 100x100 tiles that are drawn but only a small section is shown. So the enemies I generate would still be walking around the map, and things would be going normally except I can only see a small part of it. Is there a way I can take advantage of surfaces in pygame to do this more effectively?

Some relevant code.

def drawMap(self, screen):
    for y in range(self.height):
        for x in range(self.width):
            self._mapData[y][x].draw(screen, x*48,y*48)

This is in the TileMap class and each index is a Tile object, which has a draw method. My initial idea was to change both the range() calls to draw only the area of the map I want to but then I don't know how to account for enemies off the screen because they are defined by their x and y location relative to the TileMap I create.

I am thinking there is maybe something I can do with a larger pygame surface object that I do not realize so I figured I would ask this here.

\$\endgroup\$

1 Answer 1

3
\$\begingroup\$

You accomplish the scrolling by moving the camera, and calculating the screen position for a tile based on the current camera position. You can skip drawing of any tiles that are not on screen.

def drawMap(self, screen, camera_x, camera_y):
    for y in range(self.height):
        for x in range(self.width):
            tile_position_x = (x * TILE_WIDTH) - camera_x
            tile_position_y = (y * TILE_HEIGHT) - camera_y
            if (onscreen(tile_position_x, tile_position_y)):
                self._mapData[y][x].draw(screen, x*TILE_WIDTH,y*TILE_HEIGHT)

def onscreen(x, y):
    return not (x < TILE_WIDTH or x > SCREEN_WIDTH or
                y < TILE_HEIGHT or y > SCREEN_HEIGHT)
\$\endgroup\$
2
  • \$\begingroup\$ Oh I see, but what is the significance of checking x < TILE_WIDTH and Y < Tile_HEIGHT in the onscreen function? \$\endgroup\$
    – Ryan
    Commented Feb 3, 2013 at 0:16
  • \$\begingroup\$ Because if a tile is 50 pixels wide but it is positioned at x=-40, then 10 pixels of it would be onscreen. (Assuming your sprites have an origin at 0,0, as is the usual default.) \$\endgroup\$
    – Kylotan
    Commented Feb 3, 2013 at 10:47

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .