Reputation: 11
I had a problem with creating camera in pygame, I assumed code below should work but our player is moving faster than camera and is going out of the window. Somebody know what's the issue?
import pygame, sys
class Player(pygame.sprite.Sprite):
def __init__(self, pos, group):
super().__init__(group)
self.image = pygame.image.load('./chatacters/players/player_one.png').convert_alpha()
self.rect = self.image.get_rect(center=(640, 360))
self.direction = pygame.math.Vector2()
self.speed = 5
# key inputs
def input(self):
keys = pygame.key.get_pressed()
if keys[pygame.K_UP]:
self.direction.y = -1
elif keys[pygame.K_DOWN]:
self.direction.y = 1
else:
self.direction.y = 0
if keys[pygame.K_LEFT]:
self.direction.x = -1
elif keys[pygame.K_RIGHT]:
self.direction.x = 1
else:
self.direction.x = 0
# Moving using inputs
def move(self, speed):
if self.direction.magnitude() != 0:
self.direction = self.direction.normalize()
self.rect.center += self.direction * speed
# updating drawing
def update(self):
self.input()
self.move(self.speed)
class Camera(pygame.sprite.Group):
def __init__(self):
super().__init__()
self.display_surface = pygame.display.get_surface()
self.offset = pygame.math.Vector2()
self.half_w = self.display_surface.get_size()[0] // 2
self.half_h = self.display_surface.get_size()[1] // 2
self.map = pygame.image.load('./map/level_data/level.png').convert_alpha()
self.rect = self.map.get_rect(topleft=(0, 0))
def custom_draw(self, player):
self.offset.x = player.rect.centerx - self.half_w
self.offset.y = player.rect.centery - self.half_h
ground_offset = self.rect.topleft - self.offset
self.display_surface.blit(self.map, ground_offset)
class Game():
def __init__(self):
# Settings
self.WIDTH = 1280
self.HEIGHT = 720
self.FPS = 60
pygame.init()
pygame.display.set_caption('BetterFortinite')
self.screen = pygame.display.set_mode((self.WIDTH, self.HEIGHT))
self.clock = pygame.time.Clock()
self.camera_group = Camera()
self.player = Player((100, 200), self.camera_group)
def game(self):
while True:
self.clock.tick(self.FPS)
self.screen.fill('black')
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
# self.screen.fill("WHITE")
self.camera_group.custom_draw(self.player)
self.player.move(5)
self.player.update()
self.camera_group.draw(self.screen)
# self.camera_group.update()
pygame.display.update()
if __name__ in '__main__':
game = Game()
game.game()
I'm taking the center position of player rect minus half of the width size. Same with height and setting with it my offset. Then I'm setting my ground_offset as cords of topleft screen rect minus offset. What is wrong with this formula?
Upvotes: 0
Views: 121
Reputation: 1255
The problem is not with your formula, but with the code itsself. In the main game loop, you have:
self.player.move(5)
self.player.update()
While Player.update
contains:
def update(self):
self.input()
self.move(self.speed)
As you can see, player.move is called twice. This means that the player is moved twice as much as intended and thus twice as fast as the camera, causing both to move at a different speed.
The solution to this problem would be to remove one of the calls of Player.move
. I would remove the one in the main game loop as it uses a hardcoded value rather than the Player.speed
constant, but it doesn't really matter which one you remove.
Upvotes: 1