2010-12-13 16 views
3

파이 게임 라이브러리를 사용하고 있습니다. 다음은 플레이어 처리 내 이벤트에 대한 의사 코드입니다 :파이 게임에서 플레이어가 부드럽게 움직입니다.

#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 

문제는 그 나는 화면에 내 마우스를 이동하고 이벤트를 처리하는 동안 나는, 동시에 키를 누르면있어 때때로 때 마우스의 이벤트는 대기열에 올려 져 있으며이 여러 번의 키 누름이 함께 실행되므로 플레이어는 엄청난 거리를 뛰어 넘는 것처럼 보입니다.

마우스를 전혀 움직이지 않으면이 문제가 발생하지 않습니다.

답변

0

아마도 이벤트 대기열이 여기서는 최상의 해결책이 아니며 대신 프레임 당 한 번 폴링이 더 좋을까요? 내 대답에

+0

프레임 당 한 번 폴링을하더라도 마우스를 움직일 때까지 제대로 작동합니다. 내가 마우스를 움직이면서 동시에 키를 누르면 플레이어는 같은 위치에서 멈추게됩니다. 4-5 초 후, 이전에 누르던 키에 따라 다시 움직입니다. – Karan

+0

Ok, 부분적으로 해결되었습니다. pygame.event.set_blocked를 사용하여 이벤트 대기열에서 mousemotion을 제거했습니다. 하지만 지금은 총알을 쏘기 위해 마우스 크릭을 사용하고 싶습니다 (사격 게임). 이것은 같은 문제를 일으키는 것인데,이 경우에는 마우스 클릭으로 인한 이벤트가 적기 때문에 플레이어는 작은 거리를 점프합니다 – Karan

1

업데이트 :

은 내가 매 프레임마다 키를 처리하는 방법을보고 내 게임 코드를 확인하고 내가() 이벤트에서 키 정보를 얻을 수 없지만 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()를 사용하여 위치 및 버튼을 직접 읽지 마십시오.

운동 코드는 게임이 가변 프레임 속도로 실행된다는 사실을 고려해야하며 (게임 속도를 일정하게 유지하기 위해 파이 게임을 강요하지 않는 한) 이동 벡터 계산에서 시간 델타를 사용하십시오.

내가 cooridinate 변수를 초기화 I는 다음과 같은 방법을 사용

1

...이 경우, X 및 Y에서

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

실제 플레이어 스프라이트 의해 사용 좌표 및 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

I 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 

이 방법.

관련 문제