Плавное движение игрока в пигме - PullRequest
3 голосов
/ 13 декабря 2010

Я использую библиотеку 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

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

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

Ответы [ 4 ]

1 голос
/ 22 декабря 2010

Обновление до моего ответа:

Я проверил свой игровой код, чтобы увидеть, как я обрабатываю ключи в каждом кадре, и кажется, что я не получаю информацию о ключах из событий, но использую 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 поддерживать постоянную частоту кадров) и использовать разницу времени вваши вычисления вектора движения.

1 голос
/ 30 декабря 2011

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

Я инициализирую переменные 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
0 голосов
/ 18 сентября 2013

Я бы не использовал 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

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

0 голосов
/ 13 декабря 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...