업데이트를 위해 유휴 시간 (RPG) 게임 사용


9

턴 기반 RPG 게임을하는 경우 게임이 'wait_for_player_input'을 통해 반복되므로 아무 일도 일어나지 않을 때가 많이 있습니다. 당연히 이번에는 물건을 업데이트하는 것이 합리적입니다.

그러나 이것은 즉시 스레드되어야한다고 제안하는 것 같습니다. 단일 스레드에서 이런 종류의 디자인이 가능합니까?

loop:  
if not check_something_pressed:  
    update_a_very_small_amount  
else  
  keep going

그러나 'a_very_small_amount'가 각 루프마다 단일 객체 만 업데이트한다고하면 업데이트 속도가 매우 느려집니다.

단일 스레드에서이 문제를 어떻게 해결 하시겠습니까?

편집 : 나는 파이썬에 더 구체적인 것이 좋을지라도 합리적인 언어처럼이 언어에 무관심한 태그를 붙였습니다. ;-)

두 번째 편집 :이 게임은 애니메이션 구성 요소를 계획하지 않습니다. 즉, 현재 플레이어 대기 입력으로 실행 중이며 모든 것을 업데이트하고 그립니다. 따라서 X FPS보다는 사용자의 속도에 따라 다릅니다.

답변:


7

예, 단일 스레드에서 가능합니다. 그러나 일반적으로 스페어 사이클이있는 경우가 아니라 프레임마다 객체를 업데이트하려고합니다. 애니메이션과 움직임이 프레임 속도와 연결이 끊어지며 그렇지 않으면 고르지 않게 보입니다. AI 업데이트 또는 실시간이 아닌 다른 것에 대해 이야기하고 있다면 타이머를 사용하십시오. 대상 프레임 속도가 무엇인지 알아야하며 유휴 시간은 다른 모든 작업이 완료된 후 남은 시간이됩니다.

게임의 60 FPS를 목표로하고 있다고 가정 해 봅시다. 16.667ms로 각 프레임에 필요한 모든 작업을 수행 할 수 있습니다. 게임을 시작할 때 사용 가능한 최고 해상도 타이머를 사용하여 현재 시간을 얻고 16.667ms를 추가하고 어딘가에 저장하십시오. 파이썬에서 함수는 time ()이라고 생각합니다. 언어에서 일한 지 오래되었습니다. 처리가 완료된 후 기록 된 시간과 현재 시간을 확인하는 루프를 입력하십시오. 현재 시간이 프레임 종료 시간보다 짧은 경우 update_a_very_small_amount. 작은 업데이트는 빨리 처리해야하기 때문에 프레임 끝을 지나는 처리에 대해서는별로 걱정하지 않습니다. 다음 프레임이 시작될 때까지 약간의 지연이 발생하며이를 처리하기에 충분한 유휴 시간이있는 것 같습니다.

프레임 처리가 완료되면 마지막 프레임의 끝 부분에 저장된 시간에 16.667ms를 추가하여 다음 프레임의 끝 위치를 찾으십시오. 현재 시간 + 16.667ms를 사용하고 처리가 계속되면 마지막 프레임이 지나간 시간만큼 다음 프레임의 끝이 밀려납니다.

다시 : 두 번째 편집

명확히하기 위해 여기서는 프레임 속도라는 용어를 사용하여 메인 루프를 통한 반복을 나타냅니다. 그것이 사용자의 입력 속도를 기반으로한다면, 당신의 목표는 단순히 게임을 반응 적으로 느끼게하는 것입니다. 그렇지 않으면 입력을 확인하고 루프를 통과 할 때마다 10 초가 걸리더라도 모든 것을 업데이트 할 수 있습니다. 그래도 반응을 느끼려면 초당 20 회 정도의 입력을 확인하여 실제로 이러한 프레임을 그리지 않더라도 20FPS의 효과적인 프레임 속도를 얻을 수 있습니다. 입력을 다시 확인하기 전에 업데이트하는 데 50ms가 걸립니다.


2

들어 파이썬 특별히 시도하고 사용할 수있는 코 루틴을 여러 업데이트 호출을 통해 계산을 할 수 있습니다.

... 코 루틴은 서브 루틴을 일반화하여 특정 위치에서 실행을 일시 중단 및 재개하기위한 여러 진입 점을 허용하는 프로그램 구성 요소입니다 ...

PEP-0342 는 파이썬에서 코 루틴 구현을 자세히 설명합니다.

단일 스레드에서 멀티 스레딩을 시뮬레이션 할 수있는 고유 한 스케줄러 및 작업을 생성 할 수 있습니다. Javascript가 단일 프로세스에서 실행 되더라도 Javascript 프레임 워크가 다중 스레드와 같은 처리를 허용하는 것과 같은 방식입니다.


1

네 가능합니다. 게임에는 일종의 메인 게임 루프가 있습니다. 이 같은:

while(gameRunning)
{
  checkUserInput()
  updateGame()
  renderGame()
}

updateGame에서는 게임 오브젝트를 반복하고 "약간"업데이트 할 수 있습니다. 이 방법으로 계산을 많이하면 게임이 중단됩니다. 따라서 이러한 계산을 분할하여 게임 루프의 여러 반복을 실행하는 방법이 필요합니다.

그것들을 나누는 방법은 빌드하는 게임의 종류에 따라 다릅니다. A *를 사용하여 미로를 통한 경로를 계산하는 경로 찾기 루틴이 있다고 가정하십시오. 일정 시간이지나거나 고정 된 반복 횟수 후에 알고리즘을 중지하고 계산 된 경로를 지금까지 유지 한 다음 제어를 게임 루프로 되돌려 놓아야합니다. 다음 번에 updateGame을 호출하면 경로 찾기가 계속됩니다. 문자를 계산하는 동안 부분 경로를 따라 문자를 이동할 수도 있습니다.

대부분의 경우 updateGame 호출이 너무 오래 걸리는 것에 대해 걱정할 필요가 없습니다.

"조기 최적화는 모든 악의 근원입니다!"
업데이트 루틴에서 성능 병목 현상이 발생하면 조사하고 최적화해야합니다. 게임의 어떤 부분을 계산하는 데 가장 많은 시간이 걸리는지 미리 알 수 없으므로 잘못된 것을 최적화하는 데 시간이 낭비 될 수 있습니다.


1

귀하의 질문을 이해하는 방법은 기본적으로 협동 멀티 태스킹에 대해 묻는 것입니다.

기본 인프라는 함수 포인터의 목록으로, 모든 라운드 로빈 방식으로 호출되며 (보다 정교한 우선 순위 지정이 필요한 경우 제외) 이러한 모든 기능은 "작은 작업"을 수행하여 게임을 방해하지 않을 정도로 작습니다. 부진 해지다 스레드가 뜨거워지기 전에 DOS와 스레드를 지원하지 않는 모바일 장치 에서도이 작업을 수행했습니다.

제 생각에 더 좋은 질문은 플레이어가 움직일 때까지 어떻게해야하는지입니다. 어떤 종류의 것들이 프로세서 집약적이어서 어쨌든 즉석에서 수행 할 수 없으며, 동시에 플레이어가 단지 약간의 이동 키를 망치면 게임이 할 수없는 선택 사항입니다 이것을 처리하는 시간. 따라서 수천 개의 AI에 대해 A *를 계산하는 것과 같은 것들이 없습니다.

제 생각에는 더 나은 해결책은 단순히 항복 / 절전 상태를 유지하고 컴퓨터의 전원 관리 기능을 사용하는 것입니다. 노트북 사용자는 더 좋아할 것입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.