레벨에 정의 된 객체의 지속 상태를 어떻게 구현할 수 있습니까?


17

재검토 할 수있는 일련의 상호 연결된 레벨로 구성된 2D Metroidvania를 개발 중입니다.

각 레벨은 Tiled TMX 파일로 표시되며, 여기에서 다른 스프라이트 클래스의 다양한 오브젝트 (예 : 적, 픽업, 레버 등)가 생성되는 위치를 지정했습니다. 새 게임을 시작하거나 저장된 게임을로드하거나 레벨을 변경하면 게임 루프가 해당 TMX 파일을 통해 실행되고 해당 레벨의 모든 객체를 생성합니다.

레벨 변경을 다음과 같은 방식으로 처리합니다. Player오브젝트가 오브젝트와 교차하는 경우 새 맵 (교차 된 포털과 연관된 맵)을로드하고 새 맵에서 적절한 위치에 플레이어를 배치 Portal하는 change_map()메소드가 호출됩니다.

일부 객체에는 레벨 변경과 게임 저장 및 종료를 통해 지속 되고 싶은 상태가 있습니다 . 예를 들어, 플레이어가 문을 잠금 해제하고 문의 상태 속성이 "열기"로 설정되어 있으면 플레이어가 돌아올 때 문이 열려고합니다. 왼쪽과 오른쪽으로 설정할 수있는 레버 및 기타 다양한 객체와 비슷한 것을 원합니다. 또한, 플레이어는 때때로 플레이어가 해당 지역을 다시 방문 할 때 리스폰하고 싶지 않은 아이템을 수집했을 것입니다.

제 질문은 이런 종류의 지속성을 어떻게 처리 할 수 ​​있습니까?

파이썬에서 일하고 있지만 추상화 할 수는 없다고 생각합니다.

답변:


27

나는이 문제를 지나치게 생각하지 않으면 최상의 결과를 얻을 수 있으므로 다른 저장 데이터와 함께 저장 한 다음 이전 상태에 액세스해야 할 때 주문형으로로드하는 간단한 키 값 저장 시스템을 게임에 구현하기 만하면됩니다.

흐름은 다음과 같이 보일 수 있습니다.

  1. 파일에서로드 레벨
  2. 타일 ​​/ 객체를 배치하기 전에 "영구"속성이 있는지 확인하십시오.
    1. 예인 경우 : 저장된 키-값 쌍을 확인하여 속성과 일치하는 키를 확인하고 적절한 값을 가져옵니다.
    2. 그렇지 않은 경우 : 개체를 정상적으로 배치하십시오
  3. 플레이어가 레벨을 나가면 "지속적"속성을 가진 모든 객체를 통해 게임 루프를 저장하고 키-값 쌍으로 저장합니다.

간단한 2D 게임에 사용하는 것을 기반으로 한 의사 코드 예제는 다음과 같습니다.

def load_map(map):
    for y in range(0, height):
        for x in range(0, width):
            tile = map[x, y]

            for property in tile.properties:
                if is_persistent(property.name):
                    // Name prefixed with "persistent" means that it's persistent
                    // so we load the value from out persistent storage
                    property.value = persistent_values[property.name]

def save_map(map):
    ... everything in load_map ...
    if (property.name.matches("persistent_*")):
        // Name prefixed with "persistent" means that it's persistent
        // so we save the value to persistent storage
        persistent_values[property.name] = property.value

def is_persistent(name):
    return name.matches("persistent_*") and persistent_values.contains(name)

그런 다음이 속성을 사용하여 상태를 확인할 수 있습니다.

def draw():
    if properties["persistent_is_pressed"].value:
        draw_sprite(button_pressed)
    else:
        draw_sprite(button_unpressed)

def on_pressed():
    properties["persistent_is_pressed"].value = not properties["persistent_is_pressed"].value

Tiled 와 같은 타일 맵 편집기를 사용하는 경우 다음과 같은 속성을 추가하는 것은 매우 쉽습니다.

재산 추가

희망적으로 이것은 가능한 간단한 상태를 구현하는 방법에 대한 아이디어를 줄 것입니다!


이것은 내 상황에 적용하는 방법을 정확히 이해하기 위해 고심하고 있지만 매우 유용합니다. 좀 더 생각해 볼게요.
GoldenGremlin

가치를 절약 할 수있는 방법을 찾는 데 어려움을 겪고 있다고 생각합니다. 저장할 때 TMX 데이터의 타일을 반복하지 않습니다. 오히려 all_sprites 그룹의 스프라이트 객체를 반복합니다. 맵을로드 할 때 스프라이트 객체를 인스턴스화 할 때 TMX 객체의 TMX 속성을 매개 변수로 사용하지만 그 속성을 만지지 않으므로 스프라이트 객체의 변경 사항을 추적하지 않습니다.
GoldenGremlin

1
@dietestus 아마도 스프라이트 객체에 properties대신 수정 하는 필드를 제공하고 수정해야 할 properties속성을 나타내는 타일 ​​만 사용해야합니다 (그러나 모든 데이터는 스프라이트에 저장 됨). 스프라이트에서 타일을 전달할 수도 있습니다. 스프라이트에서 타일을 수정할 수 있습니다 :) 만약 내가 무슨 의사 코드를 모의 할 수 있는지 잘
모르겠다면

3
@dietestus 영구 엔티티 (door, lever)와 상호 작용하자마자 새 상태를 키-값 맵에 저장합니다. 저장할 때지도를 반복 할 필요가 없습니다. 이미지도에 모든 것이 있습니다.
Herr Derb

1
@dietestus 네, 당신은 :) 키가 속성 이름이고 값이 (잘 ... 값)있는 간단한 사전입니다. 동일한 타일에 여러 객체가 있어도 고유 키가있는 한 아무 것도 변경되지 않습니다.
Charanor
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.