원활하게 반복되는 2D 멀티 플레이어 레벨을 만드시겠습니까?


15

최근 루핑 레벨 디자인을 할 수있는 2D 사이드 스크롤 멀티 플레이어 게임을 만드는 방법 (Think of Starbound 및 월드의 루핑 방법)에 대한 토론이있었습니다.

가장 간단한 방법은 플레이어를 한쪽으로 다른 곳으로 순간 이동시킬 수있는 방아쇠 구역이있는 직사각형 맵을 갖는 것이라고 생각했습니다. 그러나이 접근 방식의 명백한 문제는 한 번에 여러 플레이어가 맵의 가장자리에있는 경우입니다. 플레이어를 서로 앞에서 순간 이동시키고 싶지 않으며 다른 플레이어가 사라지지 않고 플레이어를 운반 할 수있는 방법이 필요합니다.

이 아이디어를 추가하고 문제를 해결하기 위해 다음을 생각해 냈습니다. 플레이어가 "복제 영역"(녹색 사각형)을 볼 수있는 트리거 영역 (이미지의 빨간색 사각형)이 있습니다. 이 녹색 사각형에서 트리거 영역의 반대쪽에있는 개체는 해당 복제 영역으로 복사됩니다 (A 및 B 모양으로 볼 수 있음). 플레이어가 "복제 구역"의 시작 가장자리에 도착하면 맵의 다른쪽으로 순간 이동됩니다.

영상

이 예제에서 플레이어 2는 플레이어 1을보고 있다고 생각하지만 실제로는 클론을보고 있습니다.

이것은 당면한 문제에 대해 약간 극단적이고 복잡해 보였습니다. 내 질문은 이제이 솔루션이 문제를 해결하는 데 좋은 접근법인지 또는이 문제를 해결할 수있는 더 간단한 방법이 있는지 아는 것입니다.


플레이어가 이전 영역으로 뒤로 이동할 수 있습니까?
XiaoChuan Yu

예, 앞뒤로 움직여서 "세계를 걸어 다니는"효과를줍니다. 스타
바운드

2
세상을 큰 동그라미로 만드는 것을 고려 했습니까? 또는 레벨을 큰 원으로 취급하고 평평한 2D 스테이지로 변환합니까?
Nzall

카메라 위치를 항상 제어중인 플레이어와 정렬 할 수 없습니까?
Ali1S232

답변:


16

이러한 모든 트리거가있는이 시스템은 소리가 너무 복잡하고 오류가 발생하기 쉽습니다.

모듈로를 사용하여 플레이어의 위치를 ​​다음과 같이 감쌀 수 있습니다. playerPositionX = playerPositionX % mapWidth

이렇게하면 플레이어가에 도달 playerPosition == mapWidth하면 playerPosition0으로 다시 재설정됩니다.

이 솔루션은 전체 렌더링 시스템으로 확장 될 수 있습니다.


1
위치가 순간 이동 된 플레이어를 본 플레이어가 근접한 문제가 아닌가?
KenQueso

이것을 렌더링 시스템으로 어떻게 확장 하시겠습니까?
Mikael Högström

플레이어는 항상 카메라 중앙에 있고지도를 감쌀 수 있습니다. 지구 모드에서 문명의지도처럼. 다른 접근법은 플레이어의 보이는 부분을 맵의 양쪽으로 렌더링하는 것입니다.
Exaila

4
@ MikaelHögström 평소와 같이 렌더링하지만 오른쪽 가장자리에 가까운 것은 왼쪽에서 두 번째로 렌더링해야합니다 (예 :) pos - map_width.
Mario

1
코드에서 '어떤 객체가이 좌표에 있는지'또는 '이 객체의 좌표가 무엇입니까'를 찾고 있다면 xcoord % mapWidth로 만들 것입니다. 코드없이 말하기는 어렵지만 올바르게 렌더링 될 수 있습니다.
Tin Man

13

표준 솔루션은 포털 을 사용하는 것 입니다. 예를 들어, 왼쪽과 오른쪽 끝을 연결하는 포털이있는 경우를 제외하고 하나의 레벨 만 있습니다.

해당 포털을 가로 질러 이동하는 모든 것은 좌표를 포털의 다른 쪽 끝으로 변환하므로 포털을 통해 무언가가 왼쪽으로 이동하면 레벨의 오른쪽에 다시 나타나고 그 반대도 마찬가지입니다.

카메라도 포털을 지원해야합니다. 포털이 카메라 내부에 있으면 포털의 양쪽에 레벨의 일부를 렌더링해야합니다. 매끄러운 타일 그래픽을위한 이미지 편집기에 익숙하다면 여기에서도 마찬가지입니다.

지루한 부분은 거리 나 경로 지정을 다루는 모든 것이 것이다 또한 지원 포털이 필요합니다. 여기에는 AI, 가시 거리 알고리즘, 소리 감쇠 등이 포함됩니다.

포털의 장점은 매우 강력하다는 것입니다. 빌드 엔진은 "진정한"3d 엔진이 아니더라도 다층 스토리 레벨을 시뮬레이션하는 데 사용했습니다. 일부 현대식 엔진은 포털을 사용하여 비 유클리드 공간을 만듭니다. Portal과 Antichamber는 3D에서 눈에 띄는 예입니다.


2
포탈 게임의 해설을 듣는 경우 포탈이 작동하는 방식의 일부는 구멍을 통해 보이는 것을 복제하여 구현됩니다. (그러나 렌더링보다는 물리학 적 이유로)
Mooing Duck

6

화면에 표시되는 내용과 메모리에있는 내용은 완전히 다른 것입니다. 세계에 대한 데이터로 채워야하는 창이 있다고 상상해보십시오. 창을 왼쪽에서 오른쪽으로 채 웁니다. 세계를 채우기 위해 데이터를 구문 분석하는 동안 세계의 끝에 도달하면 데이터의 시작 부분으로 돌아가십시오. 모듈로 연산을 사용하는 것이 이상적입니다. 모든 것을 위해 이것을해야한다는 것을 기억하십시오 . 발사체, 광선, 플레이어, 물리; 그들은 모두 세계 경계를 넘을 때 자신의 위치를 ​​감쌀 필요가 있습니다.

각 플레이어는 데이터를 공유하지만 데이터에 대한 자체 관점을 가지고 있습니다. 그들의 창문은 세계에서 어디에 서 있는지에 따라 다르게 채워집니다.

즉 클론을 만들거나 다른 사람을 텔레포트 할 필요가 없습니다. 본질적으로 문자를 서로의 화면에 렌더링하여 복제본 만듭니다.


3

월드에서 렌더링을 분리하면 복제 또는 순간 이동 인공물에 의존하지 않고 랩 어라운드 및 올바른 렌더링을 수행 할 수 있습니다.

첫째, 당신의 세계에는 고정 된 크기의 세계 0Width있습니다. 객체가 0 아래로 떨어질 때마다 끝까지 Width감싸고 객체가 끝날 때까지 감싸십시오. 이것은 당신의 세계에있는 모든 논리 객체가 항상 범위 안에 있다는 것을 의미합니다 0...Width.

둘째, 렌더링을 위해 위치에서 모듈로를 수행합니다. 따라서 화면의 왼쪽은 "Base"이고 오른쪽은 "Base + Size"입니다. 그래서 당신은 그 범위 내에서 무엇이든 세상을 살펴 봅니다. 실제로 모듈로 범위를 검색하여 다시 범위를 매핑합니다 0...Width.

검색 중 트릭 Base은 왼쪽 의 객체 위치를 반환하는 것 입니다. 이것은 화면의 로컬 좌표로 변환되므로 렌더러 자체는 모듈로에 대해 걱정할 필요가 없으며 조회 만 수행합니다.

각 렌더러는 한 위치의 오브젝트 만 처리하므로 아무것도 복제 할 필요가 없습니다.

세계가 세그먼트로 생성되거나 3D 구조를 사용하는 경우 세계를 세그먼트 화해야합니다. 따라서 하나의 연속적인 블록은 아니지만이 렌더링에 맞게 이동할 수 있습니다. 최소 2 개 이상의 블록이 필요하지 않습니다.


1

게임과 사용자에게 완전히 투명한 기본 데이터 구조로 래핑 된 세계를 구현하는 것이 합리적인 방법이라고 생각합니다. 따라서 일부 하위 수준에는 실제 좌표를 기본 맵 리소스로 래핑하는 mapCoordinate () 함수가 있습니다 ...

따라서 실제 월드의 너비가 10 단위에 불과하면 플레이어와 게임은이를 알 수 없습니다. 플레이어의 경우 세계는 무한하며 게임이 15 번 위치에있는 것을 요청하면 기본 함수는이 요청을 modulo10으로 변환하고 5 번 위치에 아이템을 포장합니다.

따라서 전체 게임 로직과 그 밖의 모든 것에는 모든 것의 사본이있는 무한한 큰 세계가있는 것과 같습니다.


1

똑같지는 않지만 게임 잼에서 비슷한 것을 구현했습니다. 이 게임에는 플레이어가 작은 원형 레벨로 움직이고 플레이어가 파이의 'x'위치에 도달했을 때 감싸졌습니다. 모든 것을 렌더링 한 다음 오프셋 카메라를 회전하여 진행 상황을 추적했기 때문에 렌더링이 쉬웠습니다. 위에서 제안한 것과 비슷한 것을 구현할 수 있습니다.

  • 그릴 때는 카메라 위치와 시야 범위를 고려하여 카메라 위치를 확인하고 그릴 필요가있는 것을 결정하십시오.
  • 카메라가지도의 '가장자리'를 지나는 경우 일반적으로 레벨의 너비를 해당 위치에 더하거나 빼서 해당 가장자리를 그릴 수 있도록 세계 반대편에서 적절한 양의 콘텐츠를 선택합니다.
  • 게임 로직은이 솔기를 알고 다른 답변에서 언급 한대로 조정해야합니다. 특히주의해야 할 것은 한 물체가 한쪽에 있지만 다른 쪽 물체와 충돌하는 충돌입니다.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.