0

I am currently trying to make a top down shooter game, but I am having a bit of trouble trying to figure out how to move the map when the character moves (Up, down, left, and right). I want the map to always fill the screen but when the character moves the map will move with it. I have looked online trying to find some solutions but having a hard time trying to implement it into my own program.

import pygame
pygame.display.set_caption("TEST")

clock = pygame.time.Clock()

class Player():

  def __init__(self,x,y):
    self.Image = pygame.image.load("myAvatar.png").convert()

    self.rect  = self.Image.get_rect(topleft = (x,y))

  def getX(self):
    return self.rect.x

  def getY(self):
    return self.rect.y

  def handle_keys(self,screenHeight,screenWidth):
      key = pygame.key.get_pressed()
      dist = 1 

      if key[pygame.K_DOWN]: 
          self.rect.y += dist
          if self.rect.y > screenHeight:
            self.rect.y = screenHeight
    
      elif key[pygame.K_UP]: 
          self.rect.y -= dist
          if self.rect.y < 0:
            self.rect.y = 0  
      if key[pygame.K_RIGHT]: 
          self.rect.x += dist
          if self.rect.x > screenWidth:
            self.rect.x = screenWidth
      elif key[pygame.K_LEFT]: 
          self.rect.x -= dist
          if self.rect.x < 0:
            self.rect.x = 0 

  def draw(self, game_window,screenX,screenY):
    self.Image = pygame.transform.scale(self.Image,(20,20))
    game_window.blit(self.Image, (screenX, screenY))


class Map():
  def __init__(self):
    self.Image = pygame.image.load("testbackground.jpg").convert()
    self.rect = self.Image.get_rect()
    self.rect.x = 0
    self.rect.y = 0

  def getX(self):
    return self.rect.x

  def getY(self):
    return self.rect.y

  def setX(self,newX):
    self.rect.x = newX
  
  def setY(self,newY):
    self.rect.y = newY

  def draw(self, game_window,screenX,screenY):
    self.Image = pygame.transform.scale(self.Image,(800,800))
    game_window.blit(self.Image,(screenX, screenY))


class Enemy():

  def __init__ (self,x,y):
    self.Image = pygame.image.load("WC.jpg").convert()
    self.rect  = self.Image.get_rect(topleft = (x,y))

  def draw(self, game_window):
    self.Image = pygame.transform.scale(self.Image,(20,20))
    game_window.blit(self.Image, (self.rect.x, self.rect.y))


pygame.init()

clock = pygame.time.Clock()
screenWidth = 400
screenHeight = 400
game_window = pygame.display.set_mode((screenWidth,screenHeight))
player = Player(200,200)
map = Map()
enemy = Enemy(250,250)
leave = False
while not leave:
  for event in pygame.event.get():
    if event.type == pygame.QUIT:
      pygame.quit() 
      running = False

  playerX = player.getX()
  playerY = player.getY()

  mapX = map.getX()
  mapY = map.getY()

  screenX = playerX - (screenWidth/2)
  if screenX < 0:
    screenX = 0
  if screenX > (mapX - screenWidth):
    screenX = (mapX - screenWidth)

  screenY = playerY - (screenHeight/2)
  if screenY < 0:
    screenY = 0
  if screenY > (mapY - screenHeight):
    screenY = (mapY - screenHeight)
  
  player.handle_keys(screenHeight,screenWidth)

  map.draw(game_window,screenX,screenY)
  enemy.draw(game_window)
  player.draw(game_window,screenX,screenY)
  pygame.display.update()
  pygame.display.flip()
  clock.tick(60)


pygame.quit()
quit()
Jacob Lee
  • 4,405
  • 2
  • 16
  • 37
Shay
  • 35
  • 3

1 Answers1

0

You can move the camera like in this question:

Basically, every sprite has a position, and is drawn on the screen like this:

pos_on_the_screen = (posX - cameraX, posY - cameraY)

Then, the camera follows the player like this:

width, height = sceen_size
camera_pos = (player.posX - width / 2, player.posY - height / 2)

In this case, the player stays in the center of the screen.


If you want the camera to follow the player, but you don't want the player to be constantly in the center (it could move a little bit, but not exit the screen), you can use this method:

width, height = screen_size
if cameraX - playerX > 2 * width / 3: # player exits to the right
    cameraX = playerX - 2 * width / 3
elif cameraX - playerX < width / 3: # player exits to the left
    cameraX = playerX - width / 3
if cameraY - playerY > 2 * height / 3: # player exits to the bottom
    cameraY = playerY - 2 * height / 3
elif cameraY - playerY < height / 3: # player exits to the top
    cameraY = playerY - height / 3

In this example, the player never goes out of this space:

You can also use a more compact form:

width, height = screen_size
cameraX = min(max(cameraX, playerX - 2 * width / 3), playerX - width / 3)
cameraY = min(max(cameraY, playerY - 2 * height / 3), playerY - height / 3)

Example:

https://github.com/d-002/camera-scrolling

D_00
  • 1,440
  • 2
  • 13
  • 32
  • Hi thank you so much for you answer! I have experimented with it in my code and it kind of works. I am unsure as to which object I should set its position to cameraX and cameraY. I have tried putting into the map object using the posX - cameraX and the posY and cameraY. However the map doesn't fully stay on the screen as if you go up or to the left the character goes off the actual map picture. But if you go down or right it will stay on the map. It doesn't follow the player to the end of the map. Just stops movement until the player reaches the edge of the screen. – Shay May 26 '21 at 10:32
  • [**Here**](https://github.com/D-00-python/Camera-scrolling) is an example (what I've done about the scrolling sphere) – D_00 May 26 '21 at 14:19
  • Thanks so much! Just having a bit of trouble now setting the boundaries to stop the player from being able to move off the actual map picture. If you have any assistance that would be great. If not thank you again for all your help! – Shay May 26 '21 at 18:01
  • You can just limit the player like so: `playerX = min(max(playerX, left_border), right_size - player_width`, `playerY = min(max(playerY, top_border), bottom_border - player_height` – D_00 May 26 '21 at 19:11
  • https://stackoverflow.com/q/43142342 – D_00 May 26 '21 at 19:14
  • New GitHub link, even though the old one should redirect: https://github.com/d-002/Camera-scrolling – D_00 Sep 15 '22 at 18:43