PyGame rect.move движение не функционирует должным образом

#python #pygame

#python #pygame

Вопрос:

Я разрабатываю свое первое приложение pygame в виде клона brick breaker. Для управления игроком я проверяю удержание клавиш в основном игровом цикле, а затем перерисовываю спрайт объекта player в каждом кадре, как показано во фрагменте кода ниже:

 class Player():

def __init__(self):
    self.sprite = pg.transform.scale(pg.image.load('49-Breakout-Tiles.png'), (61,16))
    self.rect = self.sprite.get_rect()
    self.rect.right  = displayRect.center[0]-25
    self.rect.top  = displayRect.center[1] 450
    self.draw(0)

def draw(self, x):
    pg.draw.rect(display, black, (self.rect.x, self.rect.y, 61, 16))
    self.rect.right  = x

    if not displayRect.contains(self.rect):
        self.rect.right -= x

    display.blit(self.sprite, self.rect)


#from gameloop
moveNeg, movePos = False, False

while True:
    for event in pg.event.get():
        if event.type == pg.KEYDOWN:
            if event.key == pg.K_LEFT or event.key == pg.K_a:
                moveNeg = True
            if event.key == pg.K_RIGHT or event.key == pg.K_d:
                movePos = True
        if event.type == pg.KEYUP:
            if event.key == pg.K_LEFT or event.key == pg.K_a:
                moveNeg = False
            if event.key == pg.K_RIGHT or event.key == pg.K_d:
                movePos = False

    if moveNeg:
        player.draw(-1)
    if movePos:
        player.draw(1)
  

Этот код работает нормально, а также гарантирует, что манипулятор игрока остается в пределах границ отображения.

Однако для объекта ball я пытаюсь использовать rect.move(x,y) для его перемещения. Я уже пробовал с rect.right и rect.top , но объект ball по-прежнему не отвечает. Вот код, который у меня есть на данный момент:

 class Ball():

def __init__(self):
    self.sprite = pg.transform.scale(pg.image.load('58-Breakout-Tiles.png'), (16, 16))
    self.rect = self.sprite.get_rect()
    self.rect.x  = displayRect.center[0]
    self.rect.y  = displayRect.center[1]
    self.dir = [random.uniform(-1.0,1.0), random.uniform(-1.0,1.0)]
    print(self.dir)

def draw(self, xy):
    pg.draw.rect(display, black, (self.rect.x, self.rect.y, 16, 16))
    self.rect = self.rect.move(xy[0], xy[1])
    display.blit(self.sprite, self.rect)
  

Шар центрируется при инициализации объекта (как показано в строках 3/4 __init__ функции, но я не понимаю, почему это повлияет на движение шара rect . Также для наглядности, self.dir используется для придания мячу случайного начального направления, и я знаю, что он способен двигаться вверх с этой текущей конфигурацией.

Поскольку я новичок в pygame, это полностью сбивает меня с толку относительно того, почему моя логика ошибочна, поэтому любая помощь очень ценится. Спасибо

Комментарии:

1. Вы уверены, что xy переменная, передаваемая в draw, отлична от нуля? Вы пробовали с обновлением rect.x и rect.y ?

2. @Hoog Я тестировал его с различными вариантами чисел от -1 до 1, включая 1 и 0,5. Я также пробовал с обновлением rect.x и rect.y , но безуспешно.

3. Важно то, что это уменьшает проблему, если бы вы удалили эту часть перед публикацией вашего вопроса, никто не стал бы тратить свое время на поиск там, и вы, вероятно, получили бы ответ раньше

4. Я не вижу, чтобы вы где-либо вызывали ball draw

5. На этот вопрос нельзя ответить с помощью опубликованного вами кода. Вам нужно будет показать, где создается Ball экземпляр, где и как вы изменяете xy и куда вы вызываете Ball.draw . При публикации такого вопроса вы должны предоставить минимальный, но работоспособный пример. Итак, возьмите свой код и удалите все, что не связано с Ball .

Ответ №1:

pygame.Rect.move сам Rect объект не изменяется, но он возвращает новый Rect объект (вероятно, название метода вводит в заблуждение).

Это означает, что

 self.rect.move(xy[0], xy[1])
  

ничего не меняет. Вы должны присвоить прямоугольник, который возвращается .move , «самому себе»:

 self.rect = self.rect.move(xy)
  

В качестве альтернативы вы можете использовать pygame.Rect.move_ip() , перемещает прямоугольник «на место» и изменяет Rect объект:

 self.rect.move_ip(xy[0], xy[1])
  

Комментарии:

1. спасибо, что избавили меня от этой ошибки, однако, как я сказал в своих комментариях к Hoog, я также пытался изменить значения rect.x и rect.y перед использованием rect.move , и это не дало никакого эффекта. Тем не менее, я благодарю вас и обновил код до того, что вы предлагаете..