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()
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 (link):