0
\$\begingroup\$

Afternoon all,

I just cannot get this to work properly and I'd really appreciate any help. I have a camera that follows the player around a 2d tile based map. However, I want the camera to move only when the player touches the outer edge and at that point to only move enough to get the player out of the edge. So if the player is 2 tiles into the left most edge then move the camera 2 tiles to the left.

I currently have the following bugs:

  1. The camera doesnt move to the player on game start, until the player moves.
  2. The camera doesnt render differing amounts of tiles around the edges.
  3. The camera follows the player at all times, rather than scrolling when at the edge.

The camera's movement code seems to work fine so I believe the issue is in the way I am assigning the target or obtaining the offset. Here's the specific code for that.

def set_target(self, position: Tuple[int, int], ignore_edge: bool = False):
    """
    Set the target position.
    """
    x, y = position

    # centre the target
    half_width = (self.columns // 2) - 2  # -2 to offset against the rounding of row/columns
    half_height = (self.rows // 2) - 2

    if self.is_in_camera_edge(position) or ignore_edge:
        offset_x, offset_y = self.get_edge_offset(position)

        new_x = x + offset_x
        new_y = y + offset_y

        self.target_x = clamp(new_x - half_width, 0, self.map_width - half_width)
        self.target_y = clamp(new_y - half_height, 0, self.map_height - half_height)

    self.is_dirty = True

    def get_edge_offset(self, target_pos: Tuple[int, int]) -> Tuple[int, int]:
        """
        Determine how far the player is into the edge of the camera
        """
        x, y = target_pos
        edge_size = self.edge_size
        dir_x = 0
        dir_y = 0

        if x < self.start_x + edge_size:
            dir_x = x - (self.start_x + edge_size)

        elif x > self.end_x - edge_size:
            dir_x = x - (self.end_x - edge_size)

        if y < self.start_y + edge_size:
            dir_y = y - (self.start_y + edge_size)

        elif y > self.end_y - edge_size:
            dir_y = y - (self.end_y - edge_size)

        return dir_x, dir_y 

And here's the code in full.

I would really appreciate any suggestions or thoughts. I am pulling my hair out after days of getting nowhere with this.

\$\endgroup\$
1
  • \$\begingroup\$ I'm wondering why you're making it hard for yourself?! Right now, add in some extra background/side tiles, and leave the player in the middle of the screen. Plenty of existing professionally-produced games do it this way. It's simple, fast and looks good. \$\endgroup\$ – Kingsley Oct 16 '20 at 1:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.