Плавное движение игрока в pygame

Я использую библиотеку pygame. Ниже приведен псевдокод моей обработки событий для игрока:

#generates multiple events for keys that are held down
pygame.key.set_repeat(30,30)

for event in pygame.event.get()

   nextPos = currentPos

   if(keyUp):
       if event.key == w :
         key_w = false
       #do the same for s, a and d

   if(keyDown):
       if event.key == w:
         key_w = true
       #same for s,a and d

   if(key_w):
      #update nextPos

   #do same for key_s, key_a and key_d

   currentPos = nextPos

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

Эта проблема не возникает, если я вообще не двигаю мышью.


person Karan    schedule 13.12.2010    source источник


Ответы (4)


Обновите мой ответ:

Я проверил свой игровой код, чтобы увидеть, как я обрабатываю ключи в каждом кадре, и кажется, что я не получаю ключевую информацию из событий, а использую pygame.key.get_pressed ():

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            gl.loop_main_loop = False # exit main loop and terminate 
    keys = pygame.key.get_pressed()
    for key, state in enumerate(keys):
        if (key in self.key_handlers) and state:
            self.key_handlers[key]() # call key handler proc

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

Просто не забудьте использовать дельта-время при вычислении вектора хода, если в вашей игре нет фиксированной частоты кадров.


Возможно, лучшая идея состоит в том, чтобы во время каждого процесса сначала обрабатывать все события клавиатуры и создавать собственное представление состояния клавиш, то есть структуру, которая сообщает вам, какие важные для вас клавиши (например, WSAD) работают или не работают. Когда все события были обработаны в этом кадре, запустите код движения, используя данные вашего ключевого статуса.

Не используйте события mousemotion для отслеживания вашей мыши, а считывайте положение и кнопки напрямую, используя pygame.mouse.get_pos () и pygame.mouse.get_pressed ().

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

person Maciej Miąsik    schedule 22.12.2010

Я использую следующий метод ...

Я инициализирую переменные cooridinate ...

x = 300
y = 300
pX = 0
pY = 0

В этом случае x и y - это фактические координаты, используемые спрайтом игрока, а pX и pY используются обработчиком событий.

Затем я использую следующий код в обработчике событий ...

for event in pygame.event.get(): 
    if event.type == pygame.QUIT: 
        sys.exit(0)

    if event.type == pygame.KEYDOWN and event.key == pygame.K_LEFT:
        pX -= 2
    if event.type == pygame.KEYDOWN and event.key == pygame.K_RIGHT:
        pX += 2
    if event.type == pygame.KEYDOWN and event.key == pygame.K_UP:
        pY -= 2
    if event.type == pygame.KEYDOWN and event.key == pygame.K_DOWN:
        pY += 2       

    if event.type == pygame.KEYUP and event.key == pygame.K_LEFT:
        pX += 2
    if event.type == pygame.KEYUP and event.key == pygame.K_RIGHT:
        pX -= 2
    if event.type == pygame.KEYUP and event.key == pygame.K_UP:
        pY += 2
    if event.type == pygame.KEYUP and event.key == pygame.K_DOWN:
        pY -= 2

Наконец, в основном игровом цикле, где обрабатываются координаты игрока, я помещаю ...

x += pX
y += pY
person user1122136    schedule 30.12.2011

Может быть, очередь событий здесь не лучшее решение, и вместо этого, скажем, опрос один раз за кадр будет лучше?

person Tyler Eaves    schedule 13.12.2010
comment
даже если я опрашиваю один раз за кадр, он работает нормально, пока я не наведу указатель мыши. Когда я начинаю перемещать мышь и одновременно нажимаю клавишу, игрок застревает в той же позиции. Через 4-5 секунд он снова начинает двигаться в соответствии с клавишами, которые я нажимал ранее. - person Karan; 13.12.2010
comment
Хорошо, это частично решено. Я удалил mousemotion из очереди событий с помощью usng pygame.event.set_blocked. Но теперь я хочу использовать щелчок мышью, чтобы стрелять пулями (это игра-шутер). Это вызывает ту же проблему, хотя в этом случае, поскольку количество событий, вызванных щелчками мыши, невелико, игрок прыгает на небольшое расстояние. - person Karan; 13.12.2010

Я бы не использовал pygame.event.get ()

На мой взгляд, лучший ввод для движения игрока pygame.key.get_pressed ()

Я бы отформатировал это так:

while True:
    keys = pygame.key.get_pressed()
    if keys[K_a]:
        player.pos.x -= 10
    if keys[K_d]:
        player.pos.x += 10
    if keys[K_w]:
        player.pos.y -= 10
    if keys[K_s]:
        player.pos.y += 10

Таким образом, система будет проверять нажатие клавиш на каждом кадре.

person Newbie404    schedule 18.09.2013