Почему мой цикл приложения pygame не работает должным образом? [дубликат]

avatar
AsianTemptation
25 февраля 2020 в 04:04
221
1
3

Я работаю над очень грубой 2D-приключенческой игрой с видом сверху после беглого просмотра документации pygame. Тем не менее, я столкнулся с небольшим препятствием после того, как не смог ничего найти в системе камеры, и обнаружил, что большинству руководств по камере более 5 лет, и, похоже, они больше не работают. Кто-нибудь может помочь мне собрать камеру?

Это мой основной исполняемый скрипт

import sys, pygame
from PlayerObject import Player

pygame.init()

screen_height = 180
screen_width = 320
map_height = 1080
map_width = 1920

num_objects = 5

screen = pygame.display.set_mode((screen_width, screen_height))
player_image = pygame.image.load('models/hero.bmp').convert()
background = pygame.image.load('models/lobby.bmp').convert()
screen.blit(background, (0, 0))
objects = []

# randomly generates 5 entities with the 1st one being the controlled character
for i in range(num_objects):
    o = Player(player_image, random.randint(0, screen_width), random.randint(0, screen_height), 10)
    objects.append(o)

while 1:

    keys = pygame.key.get_pressed()
    if keys[pygame.K_LEFT]:
        screen.blit(background, objects[0].pos, objects[0].pos)
        objects[0].move_left()
        screen.blit(objects[0].image, objects[0].pos)
    if keys[pygame.K_RIGHT]:
        screen.blit(background, objects[0].pos, objects[0].pos)
        objects[0].move_right()
        screen.blit(objects[0].image, objects[0].pos)
    if keys[pygame.K_UP]:
        screen.blit(background, objects[0].pos, objects[0].pos)
        objects[0].move_up()
        screen.blit(objects[0].image, objects[0].pos)
    if keys[pygame.K_DOWN]:
        screen.blit(background, objects[0].pos, objects[0].pos)
        objects[0].move_down()
        screen.blit(objects[0].image, objects[0].pos)
        screen.blit(background)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()

    for o in objects:
        screen.blit(background, o.pos, o.pos)
    for num in range(num_objects - 1):
        objects[num + 1].rand_move()
    for o in objects:
        screen.blit(o.image, o.pos)

    pygame.display.update()
    pygame.time.delay(100)

Это мой класс игрока

import random

map_height = 180
map_width = 320

class Player:
    def __init__(self, image, width, height, speed):
        self.speed = speed
        self.image = image
        self.pos = image.get_rect().move(width, height)
        self.image = image

    def set_speed(self, speed):
        self.speed = speed

    def rand_move(self):
        x = random.randint(-self.speed, self.speed)
        y = random.randint(-self.speed, self.speed)
        self.pos = self.pos.move(x, y)

        # keeps player in boundaries
        if self.pos.left < 0:
            self.pos.left = 0
        if self.pos.right > map_width:
            self.pos.right = map_width
        if self.pos.top < 0:
            self.pos.top = 0
        if self.pos.bottom > map_height:
            self.pos.bottom = map_height

    def move_left(self):
        speed = self.speed
        self.pos = self.pos.move(-speed, 0)
        if self.pos.left < 0:
            self.pos.left = 0

    def move_right(self):
        speed = self.speed
        self.pos = self.pos.move(speed, 0)
        if self.pos.right > map_width:
            self.pos.right = map_width

    def move_up(self):
        speed = self.speed
        self.pos = self.pos.move(0, -speed)
        if self.pos.top < 0:
            self.pos.top = 0

    def move_down(self):
        speed = self.speed
        self.pos = self.pos.move(0, speed)
        if self.pos.bottom > map_height:
            self.pos.bottom = map_height
Источник

Ответы (1)

avatar
Rabbid76
25 февраля 2020 в 08:31
2

Ваше основное непонимание заключается в том, что вы пытаетесь нарисовать фон в позиции объекта, затем вы перемещаете объект и blit, наконец, он оказывается в новой позиции. Это все не нужно.
Обычно вся сцена рисуется в каждом кадре в основном цикле приложения. Достаточно нарисовать фон для всего окна и blit каждого объекта поверх него. Обратите внимание, вы не сразу видите изменения поверхности окна. Изменения становятся видимыми, когда отображение обновляется с помощью pygame.display.update() или pygame.display.flip():

Основной цикл приложения должен:

  • обрабатывать события с помощью pygame.event.pump() или pygame.event.get().
  • обновлять игровые состояния и позиции объектов в зависимости от входных событий и времени (соответственно кадров)
  • очистить весь экран или нарисовать фон
  • отрисовать всю сцену (blit все объекты)
  • обновите отображение с помощью pygame.display.update() или pygame.display.flip()

например:

while 1:

    # handle events
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()

    # update objects (depends on input events and frames)
    keys = pygame.key.get_pressed()
    if keys[pygame.K_LEFT]:
        objects[0].move_left()    
    if keys[pygame.K_RIGHT]:
        objects[0].move_right()
    if keys[pygame.K_UP]:
        objects[0].move_up()
    if keys[pygame.K_DOWN]:
        objects[0].move_down()

    for num in range(num_objects - 1):
        objects[num + 1].rand_move()

    # draw background
    screen.blit(background, (0, 0))

    # draw scene
    for o in objects:
        screen.blit(o.image, o.pos)

    # update dispaly
    pygame.display.update()
    pygame.time.delay(100)

Минимальный пример: repl.it/@Rabbid76/PyGame-MinimalApplicationLoop><1638568229936022993

AsianTemptation
26 февраля 2020 в 06:28
0

Во-первых, большое спасибо за ответ! Думаю, после прочтения ваших комментариев и возни с кодом, который вы привели в качестве примера, я стал немного лучше понимать блитинг. Говоря об этом, я изменил screen.blit(background, (0,0) на screen.blit(background, (-L+скорость, -T+скорость) где L и T - прямые позиции моего персонажа, а скорость как далеко персонаж перемещается в каждом кадре. Это имитирует камеру, но кажется, что персонаж достигает края экрана до того, как карта заканчивается. Я пытался возиться с этим, но ничего не работает, у вас есть какие-либо предложения? Спасибо!!

Rabbid76
26 февраля 2020 в 07:26
0

@AsianTemptation "но кажется, что персонаж достигает края экрана до того, как карта заканчивается." Я понятия не имею, что вы имеете в виду. Это новый вопрос?

AsianTemptation
26 февраля 2020 в 23:43
0

Что ж, мой первоначальный вопрос был о том, как создать работоспособную камеру, и я построил очень грубую камеру, в которой персонаж движется быстрее, чем обновляется карта под ним. Я не знаю, как это описать, но кажется, что он движется относительно окна экрана, и я не знаю, как удерживать его в центре.

Rabbid76
27 февраля 2020 в 07:37
0

@AsianTemptation Ваш вопрос слишком широкий. Пожалуйста, прочтите Как задать хороший вопрос? и Как создать минимальный, полный и проверяемый пример. Я рекомендую показать все, что вы уже пробовали, и снова задать открытый вопрос.