Чертежи прямо над игроком

Обновлено: перепостил вопрос, чтобы он был понятнее.

Моя проблема в том, что прямоугольники плеера не находятся на плеере из-за смещения камеры. В результате игра выглядит так (см. изображение 1). Не работает из-за смещения камеры. Я успешно переместил желтый прямоугольник над игроком, но у меня возникли проблемы с перемещением красного прямоугольника.

Я добавил комментарии к моему классу камеры, объясняющие, что я пробовал и заметил. Когда я удаляю смещение до 0, прямоугольники располагаются так, как я хочу (но, очевидно, камера больше не работает). На изображении 2 показано, чего я пытаюсь достичь.

Это изображение 1: https://i.stack.imgur.com/JnFPH.png

Это изображение 2: https://i.stack.imgur.com/NNw1e.png

Вот ссылка на минимальный код, необходимый для воспроизведения моей проблемы (я старался сделать как можно короче):

from sys import exit
import math

pygame.init()

# window and text
WIDTH = 1280 
HEIGHT = 720
FPS = 60
screen = pygame.display.set_mode((WIDTH,HEIGHT))
pygame.display.set_caption('Zombie Game')
clock = pygame.time.Clock()

# loads imgs
background = pygame.image.load("background/gamemap4.png").convert()

class Player(pygame.sprite.Sprite):
    def __init__(self, pos):
        super().__init__()
        self.image = pygame.image.load("handgun/move/survivor-move_handgun_0.png").convert_alpha()
        self.image = pygame.transform.rotozoom(self.image, 0, 0.35)
        self.base_player_image = self.image

        self.pos = pos
        self.base_player_rect = self.base_player_image.get_rect(center = pos)
        self.rect = self.base_player_rect.copy()
 
        self.player_speed = 10 

    def player_turning(self): 
        self.mouse_coords = pygame.mouse.get_pos() 

        self.x_change_mouse_player = (self.mouse_coords[0] - (WIDTH // 2))
        self.y_change_mouse_player = (self.mouse_coords[1] - (HEIGHT // 2))
        self.angle = int(math.degrees(math.atan2(self.y_change_mouse_player, self.x_change_mouse_player)))
        self.angle = (self.angle + 360) % 360

        self.image = pygame.transform.rotate(self.base_player_image, -self.angle)
        self.rect = self.image.get_rect(center=self.base_player_rect.center)

    def player_input(self):   
        self.velocity_x = 0
        self.velocity_y = 0

        keys = pygame.key.get_pressed()
        if keys[pygame.K_w]:
            self.velocity_y = -self.player_speed
        if keys[pygame.K_s]:
            self.velocity_y = self.player_speed
        if keys[pygame.K_d]:
            self.velocity_x = self.player_speed
        if keys[pygame.K_a]:
            self.velocity_x = -self.player_speed
            
        if self.velocity_x != 0 and self.velocity_y != 0: # moving diagonally
            self.velocity_x /= math.sqrt(2)
            self.velocity_y /= math.sqrt(2)

        if keys[pygame.K_SPACE]:
            self.shoot = True
        else:
            self.shoot = False

        if event.type == pygame.KEYUP:
            if event.key == pygame.K_SPACE:
                self.shoot = False

    def move(self):
        self.base_player_rect.centerx += self.velocity_x
        self.base_player_rect.centery += self.velocity_y
                     
    def update(self):   
        pygame.draw.rect(screen, "red", self.base_player_rect, width=2)
        pygame.draw.rect(screen, "yellow", self.rect, width=2)
        
        self.player_turning()
        self.player_input()    
        self.move()

class Camera(pygame.sprite.Group): 
    def __init__(self):
        super().__init__()
        self.offset = pygame.math.Vector2()
        self.floor_rect = background.get_rect(topleft = (0,0))

    def custom_draw(self):
        # self.offset.x = player.rect.centerx - (WIDTH // 2) # if i comment out these 2 lines, it works how I want.
        # self.offset.y = player.rect.centery - (HEIGHT // 2)

        #draw the floor
        floor_offset_pos = self.floor_rect.topleft - self.offset
        screen.blit(background, floor_offset_pos)

        for sprite in all_sprites_group: 
            offset_pos = sprite.rect.topleft - self.offset
            # sprite.rect.x -= self.offset.x # This sets the YELLOW rectangle over the player
            # sprite.rect.y -= self.offset.y # This sets the YELLOW rectangle over the player

            # player.base_player_rect.x -= self.offset.x # Attempting to draw red rectangle over the player - breaks the game
            # player.base_player_rect.y -= self.offset.y # # Attempting to draw red rectangle over the player - breaks the game
               
            screen.blit(sprite.image, offset_pos)

# Groups
all_sprites_group = pygame.sprite.Group()
obstacles_group = pygame.sprite.Group()

player = Player((900,900))
all_sprites_group.add(player)
 
camera = Camera()

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            exit()    
    camera.custom_draw()
    all_sprites_group.update()
    pygame.display.update()
    clock.tick(FPS)```

@ Rabbid76 Я перепостил свой вопрос, надеюсь, он сформулирован лучше.

juba1029 14.01.2023 10:33
Инструменты для веб-скрапинга с открытым исходным кодом: Python Developer Toolkit
Инструменты для веб-скрапинга с открытым исходным кодом: Python Developer Toolkit
Веб-скрейпинг, как мы все знаем, это дисциплина, которая развивается с течением времени. Появляются все более сложные средства борьбы с ботами, а...
Библиотека для работы с мороженым
Библиотека для работы с мороженым
Лично я попрощался с операторами print() в python. Без шуток.
Эмиссия счетов-фактур с помощью Telegram - Python RPA (BotCity)
Эмиссия счетов-фактур с помощью Telegram - Python RPA (BotCity)
Привет, люди RPA, это снова я и я несу подарки! В очередном моем приключении о том, как создавать ботов для облегчения рутины. Вот, думаю, стоит...
Пошаговое руководство по созданию собственного Slackbot: От установки до развертывания
Пошаговое руководство по созданию собственного Slackbot: От установки до развертывания
Шаг 1: Создание приложения Slack Чтобы создать Slackbot, вам необходимо создать приложение Slack. Войдите в свою учетную запись Slack и перейдите на...
Учебник по веб-скрапингу
Учебник по веб-скрапингу
Привет, ребята... В этот раз мы поговорим о веб-скрейпинге. Целью этого обсуждения будет узнать и понять, что такое веб-скрейпинг, а также узнать, как...
Тонкая настройка GPT-3 с помощью Anaconda
Тонкая настройка GPT-3 с помощью Anaconda
Зарегистрируйте аккаунт Open ai, а затем получите ключ API ниже.
1
1
68
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Поскольку игрок всегда находится в центре экрана, прямоугольники также всегда находятся в центре экрана:

Pygame.draw.rect(screen, "red", self.base_player_rect, width=2) pygame.draw.rect(screen, "yellow", self.rect, width=2)

base_rect = self.base_player_rect.copy()
base_rect.center = (WIDTH // 2), (HEIGHT // 2)
pygame.draw.rect(screen, "red", base_rect, width=2)
rect = self.rect.copy()
rect.center = (WIDTH // 2), (HEIGHT // 2)
pygame.draw.rect(screen, "yellow", rect, width=2)

Вы также можете скопировать прямоугольники, сдвинуть их по смещению и нарисовать в классе Camera:

class Camera(pygame.sprite.Group): 
    def __init__(self):
        super().__init__()
        self.offset = pygame.math.Vector2()
        self.floor_rect = background.get_rect(topleft = (0,0))

    def custom_draw(self):
        self.offset.x = player.rect.centerx - (WIDTH // 2)
        self.offset.y = player.rect.centery - (HEIGHT // 2)

        #draw the floor
        floor_offset_pos = self.floor_rect.topleft - self.offset
        screen.blit(background, floor_offset_pos)

        # draw the rectangles
        base_rect = player.base_player_rect.copy().move(-self.offset.x, -self.offset.y)
        pygame.draw.rect(screen, "red", base_rect, width=2)
        rect = player.rect.copy().move(-self.offset.x, -self.offset.y)
        pygame.draw.rect(screen, "yellow", rect, width=2)

        for sprite in all_sprites_group: 
            offset_pos = sprite.rect.topleft - self.offset
            screen.blit(sprite.image, offset_pos)

Также вам нужно синхронизировать центр прямоугольников после перемещения игрока:

class Player(pygame.sprite.Sprite):
    # [...]

    def move(self):
        self.base_player_rect.centerx += self.velocity_x
        self.base_player_rect.centery += self.velocity_y
        self.rect.center = self.base_player_rect.center          # <---

Другие вопросы по теме