Раздражающее дрожание спрайтов в Pygame platformer (нерешенный, но закрытый)

#python #pygame

#python #pygame

Вопрос:

Я пытаюсь создать платформер в Pygame. Я, будучи идиотом, не использую классы, что, вероятно, облегчило бы мою работу. Это для школьного проекта, срок сдачи через 2 дня, поэтому у меня нет времени на внедрение классов. Я пытаюсь заставить плеер столкнуться с землей, но когда это происходит, я получаю дрожание спрайтов (например, спрайт слегка «отскакивает»)

Вот функции (touchingGround обрабатывает столкновение с землей):

 def touching(entityDat,entityRect,rlist,cpos):
    entityRect.center = (entityDat[0] - cpos[0],entityDat[1] - cpos[1])
    entityDat[4] = False
    for i in rlist:
        if entityRect.colliderect(i):
            entityDat[4] = True
            return True
def touchingGround(entityDat,entityRect,rlist,cpos,gravity):
    while touching(entityDat,entityRect,rlist,cpos):
        if entityDat[5]:
            entityDat[1]  = gravity/10
        else:
            entityDat[1] -= gravity/10
        entityDat[3] = 0
    if touching(entityDat,entityRect,rlist,cpos):
        if entityDat[5]:
            entityDat[1]  = entityDat[3]
        else:
            entityDat[1] -= entityDat[3]
        entityDat[3] = 0
def walk(entityDat,entityRect,rlist,cpos):
    entityDat[0]  = entityDat[2]
    if touching(entityDat,entityRect,rlist,cpos):
        entityDat[0] -= entityDat[2]
        entityDat[2] = 0
  

вот обработчик движения:

 if not moveLock:
        #player movement
        touching(playerDat,playerRect,rlist,cpos)
        if jump or playerDat[3] < 4:
            playerDat[3]  = gravity
        elif not touching(playerDat,playerRect,rlist,cpos):
            playerDat[3]  = gravity * 2
        touchingGround(playerDat,playerRect,rlist,cpos,gravity)
        playerDat[1]  = playerDat[3]
        playerDat[2] *= 0.7
        if moveRight:
            playerDat[2]  = 3
        if moveLeft:
            playerDat[2] -= 3
        if playerDat[2] > -0.5 or playerDat[2] < 0.5:
            walk(playerDat,playerRect,rlist,cpos)
        if touching(playerDat,playerRect,rlist,cpos) and jump == True:
            playerDat[3] = 20
            jump = False
        playerRect.center = (playerDat[0] - cpos[0],playerDat[1] - cpos[1])
  

и вот ключ к тому, что означают все значения playerDat:

 playerDat = [0:xPos,1:yPos,2:xMomentum,3:yMomentum,4:touchingGround,5:goingUp?,6:direction,7:frame]
  

Извините, если я должен был включить больше, но в любом случае спасибо.

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

1. Не могли бы вы, пожалуйста, объяснить, что вы подразумеваете под «дрожанием спрайтов».

2. Не могли бы вы указать нам репозиторий с выполняемым кодом? На какой платформе?

3. «Дрожание спрайтов», когда спрайт слегка подпрыгивает (или дрожит, как это лучше назвать) на платформе. Сам обработчик перемещения находится в цикле выполнения, и это единственный подходящий материал. Остальное — обработка событий и переменных.

Ответ №1:

Это не весь соответствующий код, поэтому можно только немного догадываться, но из того, что я вижу:

  • Почему у вас есть while touching(...): in touchingGround ? Это не весь ваш код, но он действительно выглядит так, как и должен быть if touching(...): . Это потому, что именно так вы реализуете gravity, чтобы заставить спрайт «падать»? Если это так, вам не следует делать это таким образом, while цикл в значительной степени заблокирует любое другое обновление. Вы должны обновлять позицию y в каждом кадре во время вашего основного while цикла (того, что с событиями).

  • Обычно, если спрайт «дрожит», это означает, что он перемещается взад и вперед, что, в свою очередь, означает, что его позиция меняется, рисуется, снова меняется, рисуется снова. Вот почему вам следовало включить цикл, в котором вы фактически рисуете спрайт. Скорее всего, происходит то, что вы проверяете и меняете положение спрайта несколько раз в цикле, и это вызывает его дрожание.

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

1. Извините за нерелевантный код. Спасибо за помощь. У меня есть много оснований полагать, что причина не в этом, но с информацией, которую я вам дал, нет способа узнать это. Я считаю, что мой код можно исправить, но я думаю, что этот конкретный поток — безнадежное дело. Я собираюсь провести еще несколько исследований для дальнейшего использования и начать все сначала. Еще раз спасибо за помощь, но мой код достаточно чистый, чтобы я знал, что проблема не в этом. Я знаю из тестов, что это как-то связано с импульсом и избыточной коррекцией, но я не предоставлял эти тесты, поэтому никто не мог этого знать. Извините и спасибо.