게임에서 시간 역전 메커니즘


10

게임에서 시간 조작 메커니즘이 일반적으로 어떻게 설계되는지 궁금합니다. 특히 시간 반전에 관심이 있습니다 (최신 SSX 또는 페르시아 왕자와 같은 종류).

이 게임은 2D 하향식 슈팅 게임입니다.

내가 디자인 / 구현하려는 메커니즘에는 다음 요구 사항이 있습니다.

1) 플레이어 캐릭터 이외의 개체의 행동은 완전히 결정적입니다.

  • 실체가 취하는 행동은 레벨 시작 이후 진행된 프레임 및 / 또는 화면에서 플레이어의 위치를 ​​기준으로합니다.
  • 레벨 동안 설정된 시간에 엔티티가 생성됩니다.

2) 시간 역전은 실시간으로 되돌아 가서 작동합니다.

  • 플레이어 동작도 반대로되어 플레이어가 수행 한 작업을 반대로 재생합니다. 리버스 타임 동안 플레이어는 제어 할 수 없습니다.
  • 반전에 소요되는 시간에는 제한이 없으며 원하는 경우 레벨의 처음으로 되돌릴 수 있습니다.

예로서:

프레임 0-50 :이 시간 동안 플레이어가 20 유닛을 앞으로 이동합니다. 프레임 20에서 적 1이 스폰됩니다. 프레임 40-40 동안 적 1이 10 유닛을 왼쪽으로 이동합니다. 플레이어가 프레임 45에서 총알을 쏜다. 프레임 50

이것을 뒤집 으면 실시간으로 재생됩니다 :이 시간 동안 플레이어가 20 단위 뒤로 뒤로 이동합니다. 적 1이 프레임 50에서 되살아납니다. 총알이 프레임 50에 다시 나타납니다. 총알이 뒤로 이동하고 5가 사라집니다 (50-45). 프레임 20.

움직임을 보면서 나는 이것을 달성하는 방법에 대한 몇 가지 아이디어를 가지고 있었고, 시간이 지남에 따라 행동이 바뀌는 인터페이스가 있다고 생각했습니다. 이와 같은 일을하는 대신 :

void update()
{
    movement += new Vector(0,5);
}

나는 이런 식으로 할 것입니다 :

public interface movement()
{
    public void move(Vector v, Entity e);
}

public class advance() implements movement
{
    public void move(Vector v, Entity e)
    {
            e.location += v;
    }
}


public class reverse() implements movement
{
    public void move(Vector v, Entity e)
    { 
        e.location -= v;
    }
}

public void update()
{
    moveLogic.move(new vector(5,0));
}

그러나 나는 이것이 현명한 성능이 아니라는 것을 깨달았고 더 진보 된 작업 (곡선 경로를 따라 부드럽게 움직이는 등)을 위해 신속하게 복잡해질 것입니다.


1
모든 것을 보지는 못했지만 (YouTube 흔들리는 캠, 1.5 시간) 조나단 블로우가 그의 게임 브레이드에서이 아이디어를 사용했을 것입니다.
MichaelHouse

답변:


9

명령 패턴을 살펴볼 수 있습니다 .

기본적으로 엔티티가 취하는 모든 가역적 조치는 명령 오브젝트로 구현됩니다. 이러한 모든 개체는 Execute () 및 Undo ()와 올바른 타이밍을위한 타임 스탬프 속성과 같은 필요한 모든 것을 구현합니다.

엔티티가 가역적 조치를 수행 할 때마다 먼저 적절한 명령 오브젝트를 작성하십시오. Undo 스택에 저장 한 다음 게임 엔진에 피드하여 실행하십시오. 시간을 되돌리려면 스택 맨 위에서 작업을 팝하고 Undo () 메서드를 호출합니다.이 메서드는 Execute () 메서드와 반대입니다. 예를 들어, 지점 A에서 지점 B로 점프하는 경우 B에서 A로 점프를 수행합니다.

텍스트 편집기 또는 페인트 프로그램의 실행 취소 / 다시 실행 기능과 마찬가지로 작업을 팝한 후 원하는대로 앞뒤로 이동하려면 다시 실행 스택에 저장하십시오. 물론 애니메이션을 뒤로 재생하려면 "되감기"모드도 지원해야합니다.

더 많은 게임 디자인 shenanigan을 위해 모든 엔티티가 자체 스택에 조치를 저장하도록하여 서로 독립적으로 실행 취소 / 재실행 할 수 있습니다.

명령 패턴에는 다른 장점이 있습니다. 예를 들어, 스택의 모든 객체를 파일로 저장하고 재생 시간에 게임 엔진에 하나씩 공급하기 만하면되기 때문에 재생 레코더를 만드는 것은 매우 사소한 일입니다. 하나.


2
부동 소수점 정밀도 문제, 가변 시간 단계 등으로 인해 게임에서 액션의 가역성은 매우 감동적 일 수 있습니다 . 대부분의 상황에서 다시 작성하는 것보다 해당 상태를 저장하는 것이 훨씬 안전합니다.
Steven Stadnicki

@StevenStadnicki 어쩌면 가능하지만 확실히 가능합니다. 내 머리 꼭대기에서 C & C Generals는 이렇게합니다. 최대 8 명의 플레이어가 한 시간 동안 재생하며 최악의 경우 수백 kB로 무게가 나가며 모든 RTS 게임이 멀티 플레이어를 수행하지 않는 경우 가장 많이 추측하는 방법입니다. 매 프레임마다 단위의 엔진을 업데이트해야합니다. 예, 확실히 실행 가능합니다.
핵 워스

3
재생은 되감기와 는 매우 다릅니다. 예를 들어 x_0 = 0으로 시작하고 각 단계마다 델타 v_n을 추가하여 프레임 n, x_n에서 위치를 찾는 작업이 반드시 뒤로 재생되는 것은 아니기 때문에 되감기와 는 매우 다릅니다. ; (x + v_n) -v_n은 부동 소수점 수학에서 x와 일관되게 동일하지 않습니다. '해결 방법'이라고 말하기는 쉽지만 많은 외부 라이브러리를 사용할 수없는 것을 포함하여 잠재적으로 완전한 분해 검사에 대해 이야기하고 있습니다.
Steven Stadnicki

1
일부 게임의 경우 접근 방식이 가능할 수 있지만 시간 역전을 메커니즘으로 사용하는 AFAIK 대부분의 게임 은 모든 프레임에 대해 관련 상태 저장 되는 OriginalDaemon의 Memento 접근 방식에 가까운 것을 사용합니다 .
스티븐 스타드 니키

2
단계를 다시 계산하고 몇 초마다 키 프레임을 저장하여 되감기는 어떻습니까? 부동 소수점 오류는 몇 초만에 큰 차이를 만들지 않습니다 (물론 복잡성에 따라 다름). 또한 비디오 압축에서도 작동하는 것으로 나타났습니다. P
Tharwen

1

Memento 패턴을 볼 수 있습니다. 주요 목적은 오브젝트 상태를 롤백하여 실행 취소 / 다시 실행 조작을 구현하는 것이지만 특정 종류의 게임에서는 충분합니다.

실시간 루프 게임의 경우 각 작업 프레임을 상태 변경으로 간주하여 저장할 수 있습니다. 이것은 간단한 구현 방법입니다. 대안은 객체의 상태가 변경 될 때 트랩하는 것입니다. 예를 들어, 강체에 작용하는 힘이 언제 변하는 지 감지합니다. 속성을 사용하여 변수를 가져오고 설정하는 경우 비교적 간단한 구현 일 수 있습니다. 어려운 부분은 모든 객체에 대해 동일한 시간이 아니기 때문에 상태를 롤백 할시기를 식별하는 것입니다. 시스템 시작부터 프레임 수로 롤백 시간).


0

특별한 경우에는 되감기를 통해 롤백을 처리하면 정상적으로 작동합니다. AI 장치에 경로 탐색을 사용하는 경우 롤백 후에 장치를 겹치지 않도록 다시 계산해야합니다.

문제는 운동 자체를 처리하는 방식입니다. 과거의 정보 (위치, 순력 등)를 추적하는 적절한 물리 엔진 (2D 하향식 사수는 매우 간단합니다) 단단한 기초. 그런 다음 롤백 단계의 최대 롤백 및 세분성을 결정하면 원하는 결과를 얻을 수 있습니다.


0

이것은 흥미로운 아이디어입니다. 나는 그것에 대해 조언 할 것입니다.

작업이 항상 게임 상태에 동일한 영향을 미치기 때문에 게임 포워드 재생은 정상적으로 작동합니다. 그렇다고 리버스 작업이 원래 상태를 나타내는 것은 아닙니다. 예를 들어, 모든 프로그래밍 언어에서 다음 표현식을 평가하십시오 (최적화 해제)

(1.1 + 3 - 3) == 1.1

C 및 C ++에서는 최소한 false를 반환합니다. 차이는 작을 수 있지만 10 초 동안 60fps에서 얼마나 많은 오류가 누적 될 수 있는지 상상해보십시오. 플레이어가 단지 무언가를 그리워하지만 게임이 뒤로 재생되는 동안 때리는 경우가 있습니다.

0.5 초마다 키 프레임을 저장하는 것이 좋습니다. 너무 많은 메모리를 차지하지 않습니다. 그런 다음 키 프레임 사이를 보간하거나 두 키 프레임 사이의 시간을 시뮬레이션 한 다음 뒤로 재생할 수 있습니다.

게임이 너무 복잡하지 않은 경우 게임 상태의 키 프레임을 1 초에 30 번 저장 한 후 뒤로 재생하십시오. 각각 2D 위치를 가진 15 개의 객체가있는 경우 압축없이 최대 MB까지 최대 1.5 분이 소요됩니다. 컴퓨터에는 기가 바이트의 메모리가 있습니다.

너무 복잡하지 말고 게임을 거꾸로 재생하기가 쉽지 않으며 많은 오류가 발생합니다.

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